[Megoldva] File teljes elérési útja form input esetén hogyan?

Írtam C-ben egy programot, ami USB-n kommunikál egy mikrokontrolleres hardware-rel. Írtam php-ben egy programot, ami szerver oldalon generál a böngészőnek egy oldalt, illetve exec() függvénnyel hívja a C-ben írt programomat, s a mikrokontrolleres hardware válaszától függő tartalmat generál.

Eddig jó. Viszont van olyan eset, amikor ki kellene tallóznom egy file-t egy formon belül a böngészőben, majd ennek a file-nak a nevét teljes elérési úttal paraméterül át kellene adni az én C-ben írt programomnak, amelyet a webszerver által futtatott php kód hív az exec() függvénnyel. Viszont csak a filenév jön vissza, a full path nem, amivel viszont így semmire sem megyek. Annyit találtam a neten, hogy security risk lenne, ha a full path elérhető lenne, tehát ez nem bug, hanem feature.

Eleve nem értem, mire jó az, ha van egy filenév path nélkül. Ekkor a php script megérzi, hogy a gépen lévő 43 azonos nevű, ám különböző file-ból melyikre gondolt, aki kitallózta az adott file-t?

Hogy kell ezt csinálni?
 

Hozzászólások

Szerkesztve: 2023. 08. 11., p – 21:46

Azt kellene elsőnek megérteni, hogy böngésző = kliens oldal, PHP = szerver oldal. Semmi közöd ahhoz mi van a kliens oldalon, és ne is akarj ott semmilyen fájlban matatni. A "security risk" az túl enyhe kifejezés erre. A fájlt először fel kell töltened a szerverre (form, multipart/form-data). A PHP-vel eléred az ideiglenesen feltöltött fájlt, a $_FILES tömbben ott lesz. Ezt kellene move_uploaded_file()-al átmozgatnod egy általad meghatározott helyre, és azzal menni tovább. Olvasnivaló (RTFM): https://www.php.net/manual/en/features.file-upload.php

Az világos, hogy a php a szerveren fut, s a kliens rendereli, amit a szerver összerakott dinamikusan. Működik is, amit eddig írtam. Abban igazad van, hogy ha a kliensen böngészek ki valamit, annak az elérési útjával semmire sem megy a szerver, tehát a tartalmat is át kell küldeni.

Az zavart meg, hogy nekem ugyanazon a gépen fut a webszerver, mint amin a böngésző, így nyilván a kitallózott file teljes elérési útja is elegendő lett volna, mert a szerver ugyanazt a filerendszert látja, illetve látná, mert a document root fölé szerintem nem lát, ami valljuk be, kész szerencse. :)

Szóval igazad van, muszáj áttolni a file tartalmát, hiszen általában a kliens és a szerver nem ugyanaz a gép, továbbá a szerver nem látja a teljes filerendszert.

Akkor megnézem a linkelt irodalmat! :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez úgy marha jó, de van esély vékony kliens megoldás implementálására? Lehet hardware vezérlő GUI-t böngészőben implementálni? Tegyük fel, hogy irtózom a GTK4-től, meg attól, hogy lényegében inicializálásban megírom az egész felületet, a végén meghívom a fő végrehajtó ciklusát, aztán ha valami esemény van, az event handler callback függvényeim hívódnak vissza. Fúj, de undorító ez így, még ha logikus is. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Írd meg a fájl tallózást http protokollon át, kliens-szerver architektúrával. A standard form fájlválasztó helyett kérd le a szervertől a fájlok listáját adott könyvtárra, jelenítsd meg html-ben, aztán ha könyvárra kattintasz akkor kérd le annak a listázását és frissítsd a nézetet... remélem érthető. Vigyázz hogy legyen megfelelő autentikáció vagy tűzfal, ne férjenek hozzá illetéktelenek a teljes fájlszerkezet fájlneveihez.

Értem, amit írsz, és jó is, de ezt az irányt nem erőltetem, mert ez az én tévedésem volt abból fakadóan, hogy a szerver és a kliens gép ugyanaz. Általánosabb viszont az, hogy a kliensen zajlik a tallózás, és valóban elküldi a file tartalmát a szervernek, majd az felhasználja. Amúgy 500-600 kB körül van a file mérete - firmware upgrade egyébként -, tehát nem hatalmas file-okat kell küldeni, minden nehézség nélkül tárolható RAM-ban akár. Ráadásul még base64-et sem kell ráhúzni, mert text, Intel hex formátum.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Még akkor is, ha a szerver és a kliens egy gépen fut, a kettő elkülönül. A webszerver, meg a PHP a docroot-ból tájékozódik, onnan eredően látja a szerverre feltöltött fájlokat. Így 1:1-ben sose tudod kezelni a fájlokat kliens és szerver között.

The world runs on Excel spreadsheets. (Dylan Beattie)

Nem baj, a webfejlesztés ilyen, hogy saját szabályai vannak, szokni kell, ha előtte nem ebben utaztál. Sőt, hova ne tovább, még a PHP-t is elhagyhatod, C-ben írható dinamikus oldal, végül is közönséges C konzolos (CLI, stdio-s) program, ami HTML kódot köp ki (printf-fel vagy amivel akarod) az stdout-ra, a legtöbb webszerver tudja ezt CGI-vel vagy FastCGI-vel kezelni, futtatni. Ha C-ben írod a feltöltős oldalt, akkor nem kell külön hívogatnod a másik C-s programodat, hanem közvetlenül egybeillesztheted a kettőt. Ezen az oldalon van rá példa, igaz ez Bash, de épp így lehet POSIX shell script-ben, C-ben, C++-ban, Lua-ban, Python-ban, Lisp-ben, stb. is írni, ki mit ismer, tanult. Nem muszáj a klasszik webnyelveket használni, mint PHP, Perl.

Szerk.: persze ha valami nagy webes projektről van szó, CMS, vagy céges intranet, meg valami széles publikumnak webre szánt interface-e, akkor azért jobb maradni a bejáratott PHP-s megoldásnál, hiszen ezt eleve erre fejlesztették, vagy benne egy csomó hasznos függvény, eljárás, meg az egész erre van optimalizálva sebességügyileg is, akkor felesleges C-ben, vagy akármiben újra feltalálni a kereket. De egy szimpla böngészőben feltöltős, meg firmware-mókolás, meg otthoni egyszerű webszerveres, 1-2 oldalas, aloldalas kisebb projekthez simán jó lehet a C vagy shell script CGI, nem kell PHP-t telepíteni, konfigurálni, update-elni, meg a biztonsági rései miatt aggódni.

The world runs on Excel spreadsheets. (Dylan Beattie)

Az igazsághoz tartozik, hogy elmerengtem azon, talán jobb lett volna a C-ben írt programomat java script-ből, böngészőből hívni, de egyrészt a js-hez nagyon hülye vagyok, másrészt nem szeretnék mindent elölről kezdeni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ez viszonylag egyszerűnek tűnik.
A php-nál az elérési út alapban mindig relatív a document roothoz. Ha kilistázol egy filenevet a fileból és visszaadod, akkor az relatívként lesz kezelve, kivéve, ha teljes elérési utat adsz át. Erre az egyik megoldás, hogy egy változóként átküldöd a filelnévlistád munkakönyvtárának az abszolút elérési útját a form egy rejtett változójaként. Mikor visszaküldöd a formot, akkor összefűzöd az elérési utat és a filenevet, és utána úgy manipulálod tovább. Ez biztonsági szempontból nem épp a legszebb, mert egy támadó képet kaphat a szerver könyvtárfelépítéséről, vagy épp más stringet injektálhat. A másik megoldás, hogy csinálsz egy hash táblázatot a munkakönyvtárakról és csak a hasht küldöd át rejtett változóként.
Harmadik megoldás, hogy hasht generálsz a fileok teljes elérési útjáról ( $ilenamehash=md5(realpath($filename)); ) és a filenevekkel valamilyen kulcs-érték  pár módon jeleníted meg a formban (radio-button, select).

"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Nem egészen. Ha van egy input type="file" name="fw" tag-em, akkor a $_POST["fw"] értéke például az lesz hogy "firmware.hex", de az nem fog kiderülni, hogy ezt a file browsing ablakban milyen elérési útról tallóztam ki. Ha több azonos nevű file van a gépen más elérési utakon, sosem derül ki, melyik volt az.

De én tévedtem azért, mert a szerver és a kliens ugyanazon a gépen futott. Ha egy kliens gépen kitallózok egy file-t, akkor azt általános esetben nem találom meg a szerveren, pláne nem ugyanazon az elérési úton, hiszen az egy másik filerendszer, tehát nyilván a kliens gépről a file tartalmát el kell küldeni a szervernek, majd ott a scriptem átadja annak a programnak, amelyik a konkrét esetben letölti a firmware-t a hardware-nek.

Szóval azt néztem be, hogy a konkrét esetben a kliens és a szerver ugyanaz a gép volt. Ráadásul a szerver nem lát a document root fölé, tehát már csak ezért sem menne, de a SELinux is megfogná.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Tallózni egy file-t böngészőben, azt paraméterül átadni egy programomnak, amely letölti a műszernek, az a flash-ébe írja, utána újra letöltésre kerül, ekkor ellenőrzi, hogy jó-e, majd átadja rá a vezérlést, s immáron az új firmware fut. :)

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Úgy értem, hogy a félreértésed tekintetében mi az elvárt? A fileok egyébként a szerveren keletkeznek valami más miatt, vagy tényleg a kliensnél vannak?

Mert első esetben kell csinálnod a phpben valamit, ami kilistázza az ott levő fileokat, aztán összerak belőlük egy formot.

Második esetben meg meg kell fogni a feltöltött filet, el kell menteni valahova, majd elindítani a programoddal. Azon is érdemes gondolkozni, hogy mi lesz utána a feltöltött fileok sorsa.

Illetve ha ez bármennyire publikus, akkor tényleg megfontolandó, hogy ne a php hívja közvetlenül (web irányból exec az biztonsági bajok forrása szokott lenni), hanem valahogyan figyeld, ami történik, pl az emlegetett inotify nem rossz. (Cserébe ha mondjuk szeretnél valami visszajelzést, azt pl bonyolítja)

(Egyébként az esphomenak van egy webes dashboardja, az direktben tudja használni a böngészőből a kliens soros portjait, hogy flasheljen, ha ilyesmi a cél, lehet, hogy érdemes megnézni, hogy csinálja.)

A file-ok lényegtelenek, azok az én gépemen keletkeznek, mert én írom a firmware-t, én fordítom le. Aztán persze felteszem a céges szerverre, ha arra érdemesnek látom, s akkor már bárki eléri, tallózhatja hálózaton. De nyilván nem várhatom, hogy kliens és szerver ugyanazon a gépen fusson, s ezáltal ugyanazt a filerendszert lássák - a document root miatt amúgy ez sem igaz -, így tehát az a helyes, ha a kliensen kitallózott file tartalmát elküldjük a szerverre, majd ott átadjuk a programomnak paraméterül.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Persze, hiszen ez úgy indult, hogy de jó is volna egy GUI Linuxra is, ahol meg lehet nézni a paramétereket, illetve állítani lehet azokat. Ellenben html, css, php nekem jobban megy - bár egyáltalán nem vagyok ezekben sem expert -, mint a GTK4-gyel való ügyetlenkedés. További előny, hogy a vékonykliens az multiplatform. És akkor már valóban vicces móka, hogy lehet másik gépről kezelni, mint amin a szerver fut, s amelyre egyúttal USB-n a műszer kötve van.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

További előny, hogy a vékonykliens az multiplatform. És akkor már valóban vicces móka, hogy lehet másik gépről kezelni, mint amin a szerver fut, s amelyre egyúttal USB-n a műszer kötve van.

Azt értem, hogy vicces, csak egyébként tényleg usecase? Vagy úgyis az lesz, hogy localra lesz dugva? Mert ha túlnyomó részt igen, akkor szopatod a mindenséget azzal, hogy webszervert és phpt kell harákolni arra a kliensre. Persze, docker/podman, de azért nem tűnik valami nagyon userfriendlinek. Akkor már tényleg inkább megnézném ezt a web serial dolgot (bár ahhoz gondolom undorító jst kell írni, ami nincs a listátban, de usecase tekintetében sokkal szexibb)

Egyébként a gtk is crossplatfrom, ráadásul C, amit elvileg beszélsz. Bár ténykérdés, hogy object oriented ettől függetlenül.

[troll]

Ellenben html, css, php nekem jobban megy - bár egyáltalán nem vagyok ezekben sem expert -, mint a GTK4-gyel való ügyetlenkedés.

Azért tudva, hogy a gtk c-ben van, és látva a topic alap problémáját, ez kissé ijesztő :D

[/troll] 

A GTK4-gyel az a bajom, hogy nagyon sok doksit kell olvasni hozzá, s ha nincs benne rutinod, nem tudod, milyen, a problémához jól illeszkedő makrók vannak előre definiálva, rengeteg saját típus van, amelyeket szokni kell, csillió paraméter, struktúra, minden, ami nem megugorhatatlan, de egy css-ben átírni, hogy padding-right: 5px; azért sokkal kényelmesebb. A C-ben nem a nyelv a nehéz, hanem a konkrét környezetben megérteni, mire gondolt a költő, milyen adatstruktúrákat, függvényeket, vezérlési szerkezeteket talált ki, s ezeket hogyan lehet jól használni. Felületes sem lehetsz, mert van, ami malloc()-ot hív, a visszaadott címre teszi a kimenetét, aztán, ha az már nem kell, neked kell felszabadítanod a helyet. Tehát, ha nem olvas az ember figyelmesen doksit, a memory leak melegágya.

Sokkal jobban szeretek úgy C-ben programozni, amikor nem, vagy alig használok kész library-t, s szinte mindent magamnak írok meg, mert ott töviről hegyire mindent ismerek, s akár a hívott függvénybe is belenyúlok, ha az a célszerű.

Mondom, inkább demo, most egy szerver van, amin ezt az egészet csinálom, a saját gépem. Elsősorban nekem kell, de ha valaki lát benne fantáziát, akkor kitalálódhat, hogy ez jó lesz még valamire. Meguntam azt, hogy cserélgetem az USB kábelt a windows-os és linuxos gépek között.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Értem én ezt, de azért a gtk (vagy qt, vagy vx, csak ezek alapból cpp, bár az pont segít ebben az esetben), nem annyira katasztrófák ám ebből a szempontból. A gtk is objektum szemléletű, a malloc/freek helye emiatt elég egyértelmű. A te problémád pedig ha jól értem, UI szempontból egy igen nem valami bonyi probléma, van egy konfigos beviteli formod, meg talán valami dashboard szerű értékekkel, illetve egy firmware feltöltés. Ehhez a kód szerintem kb annyi, hogy megcsinálod az ablakot gladeben, aztán vmi handler függvényeket megírsz a gombnyomogatásra az alján, ahonnan meg már hívhatod a saját kódod és jó idő, a gui kód rohadtul minimális lesz.

Nem akarlak rábeszélni (sok szempontból valóban a webgui szokott lenni a nyerő), de kliensnek egy teljes LAMP stacket elvárni kicsit vastag. Meg ha már webes gui, én ez alapján inkább tényleg mennék a js irányból direktben serialt baszogatósba, azt akár bele lehet wrappelni vmi electronba vagy ilyesmi.

Egyrészt ne mozgasd már a célpontot :), másrészt pont azt mondom, hogy ha valójában csak neked kell, valójában csak a saját gépedről, akkor előrébb leszel, ha benyomsz vmi gui toolkitet, és nem kell kerülgetned egy webszerverben a projekted architekturális izéit, amik láthatólag kicsit útban vannak. De te tudod :)

A yad tenyleg jo. Sok ev utan most nezem ujra...

Bonyolultnak tunik, de faek egyszeru ez a pelda: https://yad-guide.ingk.se/examples/examples.html#_system_informations

Locsemegenek kb. ennyi kellhet.

1) tobb tab --> Eleg komplex applikacio irhato ala.

2) stdinrol frissitheto, keresheto (^S) text widget (--text-info)  --> ilyenbe irkalhatja, ami a mikrovezerlorol vagy a programozo toolbol jon

3) stdinrol frissitheto, klikkelheto lista (--list --listen --dclick-action= ...) --> ezzel meg kuldozgetheti a filenevet ahova erzi

Ganyoltam egy kis pelda script. Csak ki kell cserelni par parancsot (pl az "rm -rf /"-t), hogy ne okozzon tul nagy kart.

A file listaban mehet a duplaklikk.

#!/bin/bash

export KEY=$RANDOM

export mypipe1=$(mktemp -u)
mkfifo $mypipe1

export mypipe2=$(mktemp -u)
mkfifo $mypipe2

function readsomething {
    exec 1> $mypipe1
    exec 2> /dev/null
    echo -e "\f"
    date
}
export -f readsomething

function listfiles {
    exec 1> $mypipe2
    exec 2> /dev/null
    echo -e "\f"
    find /tmp
}
export -f listfiles

function fileselectaction {
    echo Ezt valasztottad $1
}
export -f fileselectaction

exec 900<> $mypipe1
exec 901<> $mypipe2

yad --plug=$KEY --tabnum=1 --text="Ezt olvastuk." --text-info < $mypipe1  &

yad --plug=$KEY --tabnum=2 --text="Valassz filet." --list --quoted-output --column="File neve" --dclick-action='bash -c "fileselectaction %s"'   < $mypipe2 &

yad --notebook --stack --key=$KEY --tab="Olvaso" --tab="Listazo" --button 'Olvass:bash -c "readsomething"' --button 'Listazz:bash -c "listfiles"' --button "Exit:0"


rm -f $mypipe1 $mypipe2

 

Idokozben visszajott par rossz emlek. Peldaul, hogy a multi tab notebook egyes lapjain nem lehet csak ugy mindenfele gomb, vagy tobbfele input mezo. Ebbol a szempontbol ez se sokkal jobb, mint a zenity. A form itt is mukodik, de abban peldaul rettenet megoldani egy hasonlo file selectort. Gyanitom, hogy a GTK dialog ilyen es kesz...

"Azért tudva, hogy a gtk c-ben van, és látva a topic alap problémáját, ez kissé ijesztő :D"
Azért egy finom GTK vagy Qt programozás még egy veretes C huszárt is képes megizzasztani, különösen mikor multiplatformmá válik a dolog...

Annó gabucino mondta: "A http az új soros port..."
És rohadtul igaza van, mert az összes szívást amit egy GUI adhat két pillanat alatt el lehet tűntetni és platformfüggetlenné lehet tenni a dolgot, arról nem beszélve, hogy az egész mehet localban és távoli eléréssel.

"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Azért egy finom GTK vagy Qt programozás még egy veretes C huszárt is képes megizzasztani, különösen mikor multiplatformmá válik a dolog...

Persze. De ez nem egy bonyolult probléma. Ráadásul azért lássuk be, hogy ha locsemege kolléga topicot kellett nyisson arról, hogy valójában hogy is vannak itt a fileok, akkor ebben nem veretes huszár.

És rohadtul igaza van, mert az összes szívást amit egy GUI adhat két pillanat alatt el lehet tűntetni és platformfüggetlenné lehet tenni a dolgot, arról nem beszélve, hogy az egész mehet localban és távoli eléréssel.

Persze, a usecasek nagy részénél ez igaz is (leszámítva a két pillanatot, amennyire én látom random spa libbel / gui framwrokkel ugyanúgy meg lehet izzadni egy veretes frontend huszárnak is, ha nem trivi a felület), de vannak olyanok, ahol ez nem biztos, hogy igaz, gyanús, hogy lehet ez is olyan, hogy a kolléga a gombhoz akarja varrni a kabátot.

Igen, és elsőre is egyértelmű volt, hogy nagyon nincs meg a kép a fejedben erről a hogy működik egy browser/szerver dologról, mert akkor nem okozott volna zavart az erőben, ugyanis elég az ég kék, a fű meg zöld szintű alapvetés. Az is beszédes, mikor azt hiszed, hogy cssben padding righttal és hasonlókkal egyszerűbb valahogy kinéző guit csinálni, mint valamelyik vastagklienses izében. Nincs ezzel semmi gond, nem érthet mindenki mindenhez, csak innen úgy tűnik, hogy az alternatívához se kell többet tanulnod.

Veled még sohasem fordult elő, hogy tévedtél? Mondom, azért történt, mert a szerver és a kliens ugyanazt az fs-t látja, s rá voltam bandzsulva, mondván, adjuk át a file nevét elérési úttal, aztán meg is vagyunk. De azért tévedtem, mert nem másik gépen futott, holott valóban futhatna. Másik gép, másik fs esetén már jól látszik, hogy valóban semmire sem megyünk egy elérési úttal és filenévvel, a tartalmat is át kell tolni a dróton.

Ha segíteni akarsz, akkor hajrá, ha meg nem, pusztán azért ne szólj hozzá, hogy egyfolytában leszólj, mert nekem meglehetősen rosszindulatúnak tűnnek a hozzászólásaid. Egyrészt nem vagyok webfejlesztő, másrészt nem azzal volt a baj, hogy nem tudtam, mi hol fut, hanem azzal, hogy a konkrét esetben ez összemosódott, s így elszúrtam.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Segíteni akarok, csak nem veszed észre. Mint mondtam, értem mi történt, és nincs ezzel semmi baj (le is írtam!), simán csak pontosan az látszik belőle, amit le is írtál: hogy ne vagy webfejlesztő, és nagyon kevés rutinod van benne (mert különben nem mosódott volna össze). És innen kintről nézve meg látszik, hogy a webes izével t rohadtul nem triviális  az csinálni, amit akarsz, ahhoz nem egy túl jó eszköz, faragni kell (legkésőbb akkor fogsz rájönni, hogy szopó van, mikor a kiolvasott értékeket szeretnéd normálisan prezentálni). És a vége várhatóan meg katyvasz lesz és/vagy sokkal több időd fogja elvinni, mint gondolod. Csak ezt nem látod, mert nincs rutinod.

Ezzel szemben húzódzkodsz egy olyat technológiától, hogy sok időt fog elvinni, és szopni fogsz vele, amiben meg van rutinod, sokkal könnyebben illeszteni a valódi bajodra, és azoktól a dolgoktól, amiket felsoroltál, pont nem igazán kell tartani benne. Nem bonyi, nem kell sokat szopni, és a padding írogatása helyett egy handy editorban összerakhatod az ablakot. (Hell, miután nem segítettem, reakcióként belinkelték neked a toolt, ami kód nélkül összerakja neked a guit).

Mindezt azért, mert szexinek hangzik a lehet hogy egyszer talán esetleg jó lenne ezt másik gépen csinálni. Én meg csak felhívom a figyelmed, hogy szerintem épp szaladsz be a faszerdőbe.

Egyéb másban nem is tudom, milyen segítség kéne, már vagy hárman leírták, hogy hogyan kell phpban kezelni, amit keresel, és őszintén szólva, miután túl vagy a homlokra csapós momentumon, feltételezem rólad, hogy már magadtól is röhögve ki tudtad volna guglizni, hogy hogyan kell csinálni, mert nem vagy óvodás.

Sőt, ma már meg is csináltam a file upload-ot hibakezeléssel együtt.

Most azon mélázom - viszont erre találtam neten megoldást -, hogyan lehet js-ből kérést indítani a szervernek úgy, hogy a válasz a js-nek adódjék át, s ne generálódjon újra az egész oldal, mert úgy szeretnék mérési értékeket frissíteni, hogy ne renderelje mindig az egész oldalt, s ne villóddzon.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ja, nem arra gondoltam, csak telón felületesen átfutva úgy tűnt, hogy csinál olyat, hogy a js kód nem csak egy string literal, hanem php változókat kever bele. Ami triviális esetekben akár működhet is, de rohadt átláthatatlan, debuggolhatatlan katyvasz benyomását kelti, és igazából nem nagyon látom, hogy mi szükség volna bárhol ilyesmire, meg kell ezt oldani szépen a jsben, ha igény van rá.

De egyébként kérdésed így is jogos, és a nyilván való randa faktoron túl (ami lássuk be, phpnál már majdnem mindegy :D) azért vannak praktikus előnyei a jsek külön kiszolgálásának:

  • eleve gyorsabb statikusan kiszolgálni, mint megkérni a phpt, hogy generátorozza. Statikus tartalmat általában szeretünk kiszolgálni közvetlen a webszerverrel
  • A browser tudja cachelni, úgy még gyorsabb
  • nálad ez ugyan nem szempont, de adott esetben a mindenféle cdn is hasznos tud lenni, hogy neked ne legyen annyi trafficod, a kliens helyben hozzá közelről kapja a cucc egy részét.

A három ajánlás közül az elsőt választottam. Csábított a harmadik az egyszerűsége miatt, de nem volt járható a js változó értékadásába php kód írása, mert már a js-t is php-ben generáltam, tehát ha oda írom a php kódot, az már literális lesz, saját outputját nem fogja újra interpretálni. Talán eval() lehetne, vagy nem tudom, ezen nem tűnődtem el.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

> de nem volt járható a js változó értékadásába php kód írása, mert már a js-t is php-ben generáltam, tehát ha oda írom a php kódot, az már literális lesz,

Valamit félreértesz. A php on the fly generálja a javascriptet. Azt teszel bele php ból amit csak akarsz. Adhatsz js változónak értéket úgy hogy beleirod var a=<? echo $a ?>. Ezt csak egyszer értelemzi a php. Csak arra kell figyelni  h mielött bármit kiirnál, tudatni kell a böngészővel, h ez egy javascript tipusú fájl lesz, ehhez ki kell küldeni a megfelelő headert asszem: text/javascript ill. még a böngésző cachet tiltó headert. Ezt php ból is meg tudod csinálni. Egy sor user case van, amikor az üzleti logikától függ, hogy mi kerül a js-be, pl. ürlapoknál előfordul, hogy nem fix h milen input mezők vannak benne,  ilyenkor a kliensi oldali validálás is változik, amihez tartozó js kódot kérésenként kell generálni. NIncs szükség semmiféle eval() ra. 

"antiegalitarian, antiliberal, antidemocratic, and antipopular"

A böngésző, biztonsági okokból, nem tudja a lokális elérési utat átadni. (Bár már létezik a  showDirectoryPicker(); de még nincs implementálva Firefoxban)
Ezt meg lehet kerülni, ha a file mellé, küllön mezőben szövegként kézzel adod meg. Probléma, hogy ezt meg külön kell tárolni, tehát szerver oldalon vagy elkezdesz adatbázisost játszani, vagy az összefűzött filenév és könyvtár elérési útvonalból generálsz egy Base16 stringet és azt adod  meg filenévnek szerver oldalon.Lehet még Base32-t is használni, de akkor le kell cserélni az =-et valami, más, filerendszer számára is emészthető karakterre.

"Maradt még 2 kB-om. Teszek bele egy TCP-IP stacket és egy bootlogót. "

Szerkesztve: 2023. 08. 12., szo – 12:09

Csatlakoznek az elottem szolokhoz, tenyleg az a legegyszerubb ha hagyod siman klasszik modon (HTTP streamen) feltolteni a file-t, majd a PHP megfelelo $_FILES[] vagy ekvivalens modon kiszeded a tartalmat, beteszed /tmp, /dev/shm, stb ala, aztan hajra. Gondolj bele hogy parszaz k-nyi nyers adatmozgatas (meg a webszerver maga meg a php, meg kb minden egyebed) az lepkefingnyi eroforrasigeny magahoz a bongeszodhoz kepest, szoval ez minden csak nem szuk keresztmetszet. Sporolsz vele 0.001%-ot valami splice-jellegu transzferen es cserebe lesz egy csomo potencialis inkompatibilitasod, security issue, kesobbiekben nem tudod szetvalasztani a szerver-kliens gepet, kijon raderoltetik az 537ik ujabb verziojat a szaros bongeszonek es mar nem ugy fog mukodni ez sem, stbstb. 

Ha tenyleg *.hex-ekkel dolgozol, akkor opcionalisan lehet az hogy a kliens a file tartalmat beletolti egy input mezobe, es akkor $_POST-tal veszed at, mar rogton memoriaba van/lesz a cucc (es nem fogja a PHP ugy passiobol lerakni egy file-ba, mikor lehet hogy nem is oda kell, hanem csak pipe-oltatnad tovabb valamibe, stb). Tkp az input mezo lehet akar hidden is. Csak egy otlet.

az eredeti elkepzeleshez:

ha a fajlrendszer ide vonatkozo reszet becsatolnad a webszerver eleresi utjaba, akkor elerned a webszerver alol is a fajlokat. a frontenden csinalj egy sha256-ot a kivalasztott fajl tartalmarol, igy a szerveren a neven kivul a tartalmat is le tudod ellenorizni oly modon, hogy egyezik-e a hash.

de a feltoltos modszer egyszerubb.

esetleg a c programodat hasznalhatnad cgi-kent, egybol az kapna meg az adatokat.

neked aztan fura humorod van...

Szerkesztve: 2023. 08. 12., szo – 16:08

vicces ez a topik :-D

Remélem ez valami barkács dolog, és nem produkiós környezetben csinálod! Exec-ben user inputot futtatni? Brrr.. Inkább figyeld a feltöltési könyvtárat inotify-jal és az vagy esetleg cron event triggerelje az usb-re töltést. Általánosan minden webes ürlapon feltöltött fájlt át kell nevezni ki nem található névre; virusirtót futtatni rá. Ideiglenesen is olyan könyvtárba kell tenni, amit más nem tud olvasni (másik host felhasználói sem);ha ez egy szöveges fájl korlátozott karakterekkel akkor validálni is lehet az alapján. 

"antiegalitarian, antiliberal, antidemocratic, and antipopular"

Lassíts! Van egy műszer, amelynek rengeteg - tényleg nagyon sok - paramétere konfigurálható illetve kiolvasható. Ezen felül a firmware upgrade-elhető. Minderre kollégák írtak vastagkliens megoldást Windows-ra, én írtam terminálos programot firmware upgrade-re, és parancsok küldésére Linuxra, de fejembe vettem, hogy kéne valami linuxos GUI. GTK4 undorító, bár nem megugorhatatlan, aztán úgy döntöttem, legyen vékonykliens megoldás, böngésző adja a GUI-t, httpd (Apache) webszerverben futó php script ingerelje a C-ben írt programomat, ami USB-n kommunikál a műszerrel, illetve generálja a szerver oldalon a weblapot, amelyet a böngésző renderel, s így lesz ebből egy grafikus felhasználói felület. Na jó, ettől még mérni nem lehet vele, de felkonfigurálni már igen, illetve firmware-t cserélni is.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

De ez milyen műszer? Egy darab műszer, v. sok van belőle? Telepítve van és oda kell utazni hozzá konfigurálni, meg kiolvasni a paramétereket?  Vagy egy laborban van eleve rádugva a szgépre? 
Ha megcsinálod a konfiguráló ürlapot webes felülettel, akkor esetleg lehet távolról is basztatni, a windowsos kollegák meg mehetnek kapálni :-D Illetve egyezményes API és akkor mehet ez is az is. 

"antiegalitarian, antiliberal, antidemocratic, and antipopular"

Egyelőre a bele kilóg az asztalomon, csövek, folyadékok, optika, meg minden, szóval most senki ne fárasszon azzal, hogy de legyen titkosítás, toronyóra lánccal. Munka, de kicsit hobby is. :) Windowsos kollégák nem mennek kapálni, hanem megtanulnak seperc alatt linuxos környezetben dolgozni, sőt, motiváltak ebben, mert tetszik nekik, hogy újat tanulhatnak. Én csak a saját munkámat könnyítendő demóként írom ezt a vékonykliens megoldást, amíg rám nem zúdul egy következő vaskos hardware tervezési feladat, majd annak a firmware-ből való kezelése, ami meg C programozás.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Lenne itt egy ötlet. Kicsit  "out of the box", de érdemes lehet elgondokodni rajta.

Egy kis automatizáció,  git,  és valamilyen CI szoftver (Jenkins, Gitlab CI, TravisCI, CircleCI etc. )  lehetne ideális. Ezek addig vinnék a folyamatot, hogy elkészülne egy bináris, egy hozzá tartozó hash kód és feltöltődne egy (akár Artifactory szerű) tárolóba, ahonnan read only access-el az új firmware verzió elérhető lenne a céleszköz számára. Ez eddig mondjuk CI workflow is lehetne.

Ha új verziót akarsz tesztelni, akkor git tag segíthet (van sokféle és más megoldási lehetőség is) és meghív egy programot (trigger) , ami feltölti az új firmware-t az eszközre, majd mehet az upgrade. (Itt nem tudom mi a pontos folyamat jelenleg, így ez csak egy javaslat, feltételezés részemről)

Tudom elsőre kicsit talán ágyúval verébre, de hosszabb távon sokat lehetne nyerni vele.

Azt nem tudom mennyire lehet azt a vonalat belevinni, hogy maga a firmware is támogathatna automata frissítés keresést és ha van újabb, akkor első körben egy (virtuális)  gomb megnyomása után indulna a firmware upgrade.

Ez lehetne, akár egy előre mutató megoldás is sztem. és a PHP-s vonaltól is megszabadulnál.

A fentiek közül, ha nincs semmi hozzá, akkor a Gitlab viszonylag könnyen tanulható saját tapasztalat alapján és a forráskód is verziókövetve lenne és a CI is könnyen menedzselhető.

Remélem ha konkrét megoldást nem is, de egy jó alap ötletet sikerül adni.

Verziókezelés most is van, egyetlen kornyadt SSD-re nem bíznám egy műszer firmware-ének fejlesztését, s előfordulhat olyan, amikor egy új verzióról kiderül, hogy hatalmas regressziót tartalmaz, így legalább a fejlesztést segítendő ki kell húzni repóból korábbi változatot átmenetileg.

Ami a többit illeti, szigorú előírások vonatkoznak a műszerre, tehát a firmware utólag már nem módosítható, ezért az egész kizárólag a fejlesztési fázisban érdekes, ami viszont több éves nagyságrendű.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

"a firmware utólag már nem módosítható"

Ez nem tudom, hogyan kapcsolódik ahhoz, amit írtam. Amit én ajánlottam az egy "zárt" megoldás a kódtól a kész firmware-ig.  A különböző verziókat csak tárolni kell az artifactory-ban és mindig csak az utolsót láthatja a firmware-be épített update megoldás (feltételezve, hogy minden eszköz mindig legutolsó verzión van), az is csak olvasható az updater számára.

Az artifactory, lehet egy egyszerű web szerver is akár ahova a buildet még scp-vel mondjuk felmásolja a könyvtába, majd létre lehetne hozni egy "latest"  mappát, amiben egy darab symlink van, ami mutat a legutolsó firmware-re. Ez minden release build után frissül.

Arra, hogy egy SSD-re nem bíznád a fejlesztést. A verzió kezelő is ott fut vagy máshol?  Ha ugyanott, akkor kód sincs jó helyen. Erre külön eszközt célszerű beüzemelni. Ha már van külön eszköz, akkor futhatna ott a javasolt megoldás.

Ha a firmware gyártása szigorú feltételekhez van kötve, akkor egy Gitlab saját eszközön hostolva tud elég zárt lenni, mert van saját CI-ja is, ezért is javasoltam erre a Gitlabot. CI pipeline-ok futhatnak külön gépen is ( Gitlab esetén Gitlab runnernek hívják pl.) ,  mert ha az a gép kiesik, akkor sincs semmi gond, adatot nem vesztettél.

Ha valami miatt rollback kell és a verziózás csak előre mehet, akkor tagging ismét lehet gyors és jó megoldás.  Pl. az 1.2.3 verzió hibás (git tag 1.2.3). Ilyen esetben a rollback - nagyon lesarkítva - egy újabb git tag, ami ugyanaz a verzió lesz, ami a hatalmas regesszió előtt volt vagyis a git tag 1.2.2 és az 1.2.4 ugyanoda fog mutatni. Ez bár nem szép, de szemléltetés szempontjából egyszerű. Az igazi megoldás ugye egy kicsit bonyolultabb. Egy branch létrehozása a hibás releaseből (itt lesz következő release vagy hotpatch) , a default branch,  amiből a releasek születnek ott vissza kell vonni az utolsó MR-t (feltételezve, hogy minden release előtt van egy MR és pontosan egy). Utána a visszavonás commit lesz meg tag-elve az új verzióval, ami a régi lesz tulajdonképpen(illetve a szoftverben is léptetni a verziószámot, amit megtehetne a CI pipeline maga is akár ).

Ha nincs sok erőforrásod otthon én egy RPi-re tennék (ha van otthon RPi) egy Gitlabot és külső HDD-re tárolnék mindent. A buildek meg futnának az én gépemen, amiben van komolyabb teljesítmény. Amennyiben ezt egyedül csinálod, otthon akkor kb. ezt csinálnám.

Remélem lesz pár hasznos dolog a fent leírtak között.

Köszönöm az infókat.

Ez nem tudom, hogyan kapcsolódik ahhoz, amit írtam.

A field-en lévő gépeken nincs firmware frissítés, csak devel státuszban a cégnél.

A verzió kezelő is ott fut vagy máshol?

SVN szerver céges szerveren, amelyen van rendszeres snapshot meg backup is, a kliens nálam, de épp ezért semmi vész, ha összedől a saját gépem. Otthoni gépemre is kihúzom a repót - home office -, azon RAID1 van, így ott elég valószínűtlen a hardware-es disk elhalás miatti adatvesztés.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Köszönöm szépen az információkat.

Az SVN-hez nagyom rég óta nem volt szerencsém sajnos. A legtöbb helyen átálltak Git-re, így én is váltottam egy ideje.

A field-en lévő gépeken nincs firmware frissítés, csak devel státuszban a cégnél.

Az utóbbit nem lenne jó esetleg automatizálni?

SVN + valami egyszerű CI pipeline sztem jó lehetne. Így mehetne a Devel eszközökre CD-vel. Modjuk egy konténer, ami lekéri a lefordított firmware-t, majd a megadott eszközre, vagy eszközökre intézi a frissítést?

Itt azt próbálnám kihozni a dologból, hogy ne egy kézi megoldásra keressünk script megoldást, ami ugyanazt támogatja, csinálja, hanem próbálja meg az ember megnézni, hogy milyen modern tool-ok állnak rendelkezésre.

Mi lenne ha az egész folyamat (build, build tárolás, illetve maga a firmware frissítés is) bent futna. A fejlesztői gépen, csak local buildek lennének.

Ha nem akarsz ennyire belebonyolódni, akkor SSH-n (scp parancs) felmásolni egy helyre, egy simlink a latest verzióra, aztán triggerelni a megfelelő parancsokkal a firmware upgrade-et.

most nem olvastam ujra vegig az egesz forumot, de a microcontroller ki tud menni a netre? mert enelkul nem mukodik az automata frissites.

raadasul ha a fielden nem lesz firmware frissites, lehet hogy jobb is, ha nem tud kimenni a netre.

neked aztan fura humorod van...

Szerkesztve: 2023. 08. 15., k – 12:42
<!DOCTYPE html>
<html>
<head>
    <title>File Picker and Uploader</title>
</head>
<body>
    <h2>File Picker and Uploader</h2>

    <?php
    $directory = 'firmwares'; // Replace with the actual directory path

    if (isset($_POST['submit'])) {
        $selectedFile = $_POST['selected_file'];
        $escapedFile = escapeshellarg($selectedFile); // Sanitize the selected file for shell command
        $filePath = $directory . '/' . $selectedFile; // Concatenate directory to file name
        $command = "echo " . escapeshellarg($filePath); // Use the concatenated file path in the command
        $output = shell_exec($command); // Execute the shell command
        echo "Command output: <pre>$output</pre>";
    }

    if (isset($_POST['upload'])) {
        if (isset($_FILES['uploaded_file'])) {
            $uploadFile = $_FILES['uploaded_file']['name'];
            $uploadPath = $directory . '/' . $uploadFile;
            
            if (move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $uploadPath)) {
                echo "File uploaded successfully.";
            } else {
                echo "Error uploading file.";
            }
        }
    }

    $files = scandir($directory);
    ?>
    
    <form method="post">
        <h3>File List:</h3>
        <table border="1">
            <tr>
                <th>File Name</th>
                <th>Select</th>
            </tr>
            <?php foreach ($files as $file) {
                if ($file != '.' && $file != '..') {
                    echo '<tr>';
                    echo '<td>' . $file . '</td>';
                    echo '<td><input type="radio" name="selected_file" value="' . $file . '"></td>';
                    echo '</tr>';
                }
            } ?>
        </table>

        <br>
        <input type="submit" name="submit" value="Flash">
    </form>

    <br>

    <form method="post" enctype="multipart/form-data">
        <h3>Upload File:</h3>
        <input type="file" name="uploaded_file">
        <input type="submit" name="upload" value="Upload">
    </form>
</body>
</html>

PHP-hoz nem értek, de csináltattam neked cthatgpt-vel egy ilyet, próbáld ki

Szerkesztve: 2023. 08. 16., sze – 12:51

a) simán feltöltöd a fájlt (6-700 Kb. NEM mennyiség semmilyen PC-n)

b) csináltsz file tallózót weben

c) ha már desktop klienst akarsz írni láthatóan, akkor desktop klienst írsz, nem webezel (eleve, exec PHP-ből az brr, persze van az úgy...)

d) nem nyúlsz, amihez nem értesz (bónuszként megfogadod, hogy nem okoskodsz application level programming témában a microcontrolleres tapasztalataiddal, ha ennyire fogalmatlanul állsz az egészhez)

Egyébként az A-t javaslom, ha már egyszer egy szerencsétlen webes dolgot csinálsz, mert ki a tököm akar fájlrendszeren matatni, hogy aztán attól a folyamattól teljesen elválva kelljen egy webes felületen kimatatni? Teljesen agyfasz megoldás.

Igen, a). Meg b), hiszen a kitallózott lesz feltöltve.

Ami a c)-t illeti, a kísérletnek épp a vékony kliens megoldás a lényege részemről, nem akarom, hogy Linux-only legyen, amikor az egész cégnél én használok Linuxot, bár hamarosan a fejlesztésen fognak többen is, s ennek oka van. Azt értem, hogy php-ből az exec() nem vonzó, de nem lesz publikus hálózatra kitéve ez az egész.

Ami a d)-t illeti, nem értem, mi a bántás oka. Amihez értek, azt jó eséllyel egyből megoldom, abban nem kérdezek, inkább segítek. Ha kérdezek, az azért van, mert vagy nem tudom, vagy benéztem valamit, vagy még nem jutott eszembe a megoldás. Okoskodik a fene, mondom, hogy magamnak csinálom, aztán lehet, hogy beszivárog a köztudatba, ezt még nem tudom. Sokat tanulok közben, s kétséget kizáróan igen lassan, de haladok vele, az történik, amit szeretnék.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

d csak onnan, hogy eszembe jutott, amikor le lettünk hurrogva, hogy ezt vagy azt hogyan akartuk megoldani valami high level nyelvben azzal az indokkal, hogy merthogy a mikrokontrollerek és hiába mondtuk el 60x, hogy az már az alkalmazásfejlesztés is teljesen más régió, tovább erőltetted. Most, hogy látom, hogy egy tényleges webes feladathoz mennyire fogalmatlanul állsz és miket emelsz ki ("600 kb elfér a memóriában"), még jobban feljön az emlék.

b-hez egyébként hozzáteszem, hogy szerintem teljesen agyfasz megoldás, hogy először odateszed valahova egy fájlkezelőben, majd egy böngészőben kikeresed ugyanazt. Azon túl felesleges extra komplexitásnak érzem egy tallózó megírását (vagy akár beemelését egy késznek), sokkal egyszerűbb és a megszokott webes workflowba illeszkedőbb simán egy fájlfeltöltés. Szerver oldali dolog meg a szerveré, kliens oldalié meg a kliensé, az, hogy egy gépen fut, az éppen kurvára egy nagy véletlen, arra építeni... nem is csak antipattern, de erősen felvet bennem kérdéseket.

"nem akarom, hogy Linux-only legyen"

Mondjuk egy PHP-t csomagolni mellé se annyira szép, ha desktopban akarod használni. Bár tény, hogy működik.

Mikrokontrollerekben a néhány tíz byte RAM-tól a néhány MiB-ig reális beszélni, elsődlegesen ehhez vagyok szokva, így nekem nyilván fájdalmas, ha valaki képes esetleg 32 bites változóban egy bool-t tárolni. Nyilván tudom, hogy 8 GiB RAM-ba valahogy bele lehet gyűrni 600 kB-ot, és még lötyög is. Amikor az általad említett hozzászólásokat írtam, akkor az fájt nekem mindig, hogy nagyon egyoldalúan beszéltek többen, beszéltetek a számítástechnikáról, mintha csak PC, mainframe, szuperszámítógép és cluster létezne, s olyan megállapításokat tettetek, amelyek nem voltak általánosságban igazak. Mert ugye, mi van akkor, ha az órajelet nem GHz-ben, hanem csak MHz-ben mérik, s mi van akkor, ha a RAM-ot nem GiB-ban, hanem csak B-ban számolják, és a programtár is néhány kB legfeljebb. Ezek korrekciók voltak részemről azért, hogy lássunk már messzebb egy nyamvadt PC-n még akkor is, ha nap mint nap én magam is PC-n dolgozom.

Ami a fogalmatlanságomat illeti, az annak folyománya, hogy nem vagyok webfejlesztő. Viszont elég sokat programoztam - igen, elsősorban mikrokontrollerekre -, így az algoritmizálás nem okoz problémát, sokkal inkább a helyi viszonyokat kell szoknom. A php, js, html, css, DOM környéke az, amit bogarásznom kell, mert nincs bennem rutinból. Azt meg sokszor írtam, hogy tévedtem a kérdésem kapcsán, mert megzavart, hogy a kliens és szerver a konkrét esetben ugyanazon a gépen fut. Ebből viszont nem következik, hogy ki akarom használni azt, hogy kliensen és szerveren szinkronban van a két fs, mert történetesen ugyanaz. Ez pusztán tévedés volt, nem akarom ezt kihasználni, mert nyilván förtelem, erre nem szabad építeni.

Ami a b)-t illeti, szerintem félreértés lesz. Lefordítom a C-ben írt kódot a mikrokontrollerre. A mikrokontrollernek van boot loadere, mert írtam hozzá. Van hozzá ezzel a boot loaderrel kompatibilis, C-ben írt bináris programom, ami képes kommunikálni az MCU bootloader-ével USB porton. Ez command line-ból remekül működik, csak vékonykliens GUI-t akarok írni hozzá. Kitallózom a letöltendő Intel hex file-t, majd át kell adnom a firmware-t letöltő programomnak.

Persze nem ez a fő attrakció, mert van egy rakás diagnosztikai mérés paraméter, amelyet meg kell jeleníteni, illetve egy rakás beállítandó paraméter, amit állítani lehet. Ezek a fontosabbak, de ha már ezt megcsinálom, legyen ott a firmware upgrade is. Ennek kapcsán kérdeztem, bár kétségkívül butaságot.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Azért nem reagáltam a hozzászólásodra, mert jóhiszeműen segítettél, én viszont nem próbáltam ki, mert nem kész megoldásra vágyom, hanem csak arról van szó, hogy van egy elképzelésem, valahol tartok a kódomban, valamivel megakadok, s ha azt sikerül megoldani, akkor tudom írni az egészet tovább. Ebbe semmiképp sem illik valami kész, konkrét megoldás.

De egyébként a feltöltést már megoldottam, most más részét írom a kódnak.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE