printf(" SaltwaterC ");

Developer blog

  Archive for the ‘Linux’ Category


Firebug 1.5 + Firefox 3.5.7 + Ubuntu Hardy amd64

Firebug este o unealtă indispensabilă activităților de dezvoltare web pe care le execut. Din păcate, actualizările se lasă cu urmări câteodată. Precum zice în titlu, am încercat combinația nefericită de mai sus. Buba stă în Firebug: 64 bit Firefox on Linux crashes with Firebug 1.5.0. Am mers pe firul epic al poveștii de pe issue tracker și mi-am resetat preferințele. Crash-ul reapare atunci când se reactivează tab-ul Net sau Console. Din nefericire, echipa Firebug aruncă vina către Ubuntu, desi eu mi-am făcut propriul build personalizat de Firefox, deci problema cred că zace undeva prin ceva bibliotecă livrată cu Ubuntu din moment ce versiunea de Firefox îmi aparține.

Soluția de moment: downgrade la Firebug 1.4: http://getfirebug.com/releases/firebug/1.4/

PS: Firefox 3.6 sub Hardy amd64 este probabil cea mai instabilă versiune lansată vreodată. Am avut versiuni de Firefox Alpha sau Beta ce erau mai stabile de atât.

Actualizare de Virtualbox. Acum ce? Management de procese? Reboot!

Băieții aceștia faini de la Sun Microsystems au ‘ghiara’ pe VirtualBox de la băieții de la Innotek. Vremuri istorice tulburi cu un produs mediocru. Între timp Sun-ul a băgat camionul de dolari în proiect și a început să se distingă din mulțime printr-un backend foarte puternic. Pe subsemnatul l-a convins să renunțe la VMware Server pentru acele ’server consolidation deployment’ ce mai apărea prin rețelele locale pe unde operez. Tot istoric vorbind, pentru Windows se distribuiau două pachete, unul pentru x86 și unul pentru x86-64. În prezent se distribuie unul singur ce se instalează în funcție de contextul platformei.

Bun. La partea cu instalarea îmi doream să ajung. Mai bine zis la partea cu actualizarea. De regulă pe un Ubuntu Server ce mai rulează servicii mici/medii VirtualBox are bunul simț să ruleze în background ca daemon printr-un simplu init script. În concluzie actualizările le fac atunci când îmi mai aduc aminte să deschid interfața grafică. Sub Windows în schimb este o jucărie unde mai testez ultimele apariții în domeniul OS. Dar aici mă lovesc suficient de des de acea fereastră ce mă anunță faptul că a apărut o nouă versiune. Click – download  – next, next, next … gata. În teorie era gata. În practică 3.0.12, adică ultima versiune, refuză să adauge orice fel de HDD virtual nou și am o mică bănuială despre imposibilitatea de a adăuga noi mașini virtuale.

Mă apuc să lucrez în calculator să văd ce se întâmplă (doctore). Cretinătatea aceea de installer nu a închis VBoxSVC înainte de instalare. Adică acel serviciu ad-hoc din arhitectura VirtualBox ce se ocupă de mașinile virtuale atâta timp cât rulează cel puțin una. În mod normal stă închis acel proces. Ridicolul merge mai departe. Acel proces, VBoxSVC dă un ‘lock’ exclusiv pe fișierele de configurare astfel încât să nu apară chestia aceea numită ‘race condition’ în geek language. Iar acel proces nu mai vrea să moară. Task Manager-ul e inutil ca de obicei la omorât procese încăpățânate. Am scos artileria grea: Advanced Process Termination (APT). Pe lângă o duzină de metode de kill, știe două metode de kernel kill și încă două de crash kill. Kernel kill pe Windows 7 x64 nu are suport. Nu mi-am spart capul cu hack-ul de OS. Din păcate metodele din user mode au dat greș. Windows încă e copil mic și udă patul atunci când vine vorba de procese încăpățânate. Sistemele UNIX-like (ex: Linux, FreeBSD) rămân în situația penibilă de mai sus atunci când un proces rămâne blocat în ‘IO wait state & friends’. Soluția este evidentă: reboot. Dar m-am cam săturat să rămân cu procese blocate pentru ca Windows e rebut la management-ul lor din ‘user mode’. Iar VirtualBox e rebut la actualizare și nu își știe închide serviciul înainte de un nou ‘deploy’. În mod curios, procesul blocat nu apare în APT. Dar APT are o jucărie numită ‘Custom PID’ pentru a da kill după kill.

Problema mail() din Zend Server Community Edition – Debian Repository

Din plictiseală sau datorită faptului că în mod repetitiv m-am tot lovit de Zend Server CE printre plimbările mele pe Web, m-am decis să renunț la versiunea implicită ce vine în reopository-ul sistemului de operare de pe mașina de dezvoltare (Ubuntu Hardy) și să pun în schimb Zend Server. Zis și făcut. Țac, țac, țac – zgomot de taste – instalarea a mers ca unsă.

Din păcate, ocazional, dezvolt și aplicații ce au nevoie de acces la funcția mail(), funcție ce altceva înafară de FALSE aka FAIL nu știa să returneze. Verific Postfix-ul – rula de zor. Deci nu era bubă de MTA. NU, nu suport Sendmail. Iau o porție de copypasta de pe php.net, pun totul întrun fișier php, rulez în shell – surpriză:

sh: -t: not found

Mă scarpin cu o mână în cap și cu cealaltă în dos. Ceva îmi pute – și nu era de la a doua mână. Încep să sap pentru a afla ce pește prăjt au făcut cei de la Zend cu php.ini de încearcă să ruleze aplicația ‘-t’. Crăp un output de phpinfo() in Firefox și mă luminez:

sendmail_path Local Value: -t -i Master Value: -t -i

Erm, WTF Zend? Casc vinovatul (/usr/local/zend/etc/php.ini) și caut linia cu pricina ce bine mersi era comentată. Cică în mod implicit ar trebui să fie ’sendmail -t -i’, dar se pare că opțiunea nu este hardcodată ca atare. Soluția e la mintea cocoșului:

sendmail_path = sendmail -t -i

Restart la Apache2. Merge? Merge. Shell-ul este fericit deasemenea.

Gnome History

Acesta este inca unul dintre acele posturi despre intalnitele “OS annoyances“. Desi primele 3 rezultate din Google Search-ul de mai sus fac referire la Windows OS, de data aceasta Gnome in implementarea Debian/Ubuntu iese la rampa. Posibil si sub alte distributii pentru ca imi miroase a problema din upstream in loc sa fie o problema a Debian+derivatii.

M-am trezit inca de dimineata cu gand rau impotriva Gnome History. Din pacate gandul meu a fost mai slab decat implementarea incapatanata a celor ce au gandit Gnome-ul din acest punct de vedere si n-au pus pe undeva o optiune pentru dezactivarea acestei functii, optiune ce sa fie demna de ‘Captain Obvious’, altfel spus, la mintea cocosului. Daca in trecut istoricul se tinea in fisierul ~/.recently-used iar un simplu:

chmod -c 400 ~/.recently-used

era suficient pentru a opri atrocitatea, in prezent (de la Gutsy si pana in prezent daca nu ma insel) lucrurile sunt sensibil mai diferite. Numele fisierului s-a schimbat intre timp in .recently-used.xbel. Nu aceasta ar fi problema esentiala daca metodele clasice ar functiona. Am incercat schimbarea ACL-urilor precum am pus mai sus: ceva le restaureaza. Am pus symlink catre /dev/null … ceva sterge link-ul si restaureaza fisierul. L-am creat de sub root si l-am lasat asa … ceva ii restaureaza ACL-urile si le pune iarasi pe contul meu. Parca era un film de acela prost cu Greuceanu ce omoara balauri alimentati cu baterii Duracell ce tot primesc resurect. Din fericire acesta a fost balaur pe 2 biti (4 capete). Cine stie bancul cu balaurul pe 8 biti, pricepe.

Metode exista, si sunt doua la numar. Prima desi functioneaza, este trista pentru ca are prostul obicei de a genera erori GTK in shell:

rm ~/.recently-used.xbel ; mkdir ~/.recently-used.xbel

Se pare ca e o piatra prea tare de rumegat pentru implementarea incapatanata prezentata mai sus.

Dar are dezavantajul erorilor din shell. Fericitii (ca mine) ce folosesc ext3 pe post de filesystem (nu cunosc utilitare echivalente pentru reiser, xfs, jfs – nu dati cu pietre) pot apela la o smecherie ce marcheaza fisierul ca immutable iar la incercarea de a face ceva, o sa se loveasca de un raspuns mai incapatanat de la Sfantul Kernel:

sudo chattr +i ~/.recently-used.xbel

Chestia asta il va opri pe mucos sa mai salveze istoricul, ba mai mult, scuteste shell-ul de erori neinteresante.

Determinarea corecta a MIME Type in PHP 5

Din start mentionez ca acest mic tutorial este dedicat fisierelor ce au ca directie un host *nix, iar functionalitatea implicita este satisfacuta pentru Ubuntu/Debian. Se poate aplica cu modificarile de rigoare si sub alte distributii. O sa il structurez pe pasi pentru o aplicare mai usoara. Nu am incercat pentru PHP 4, desi majoritatea pasilor s-ar putea sa fie valabili.

Introducere

Determinarea MIME Type-ului corect pentru un fisier este o problema esentiala. Nu o sa explic si de ce … daca nu stii de ce, atunci tutorialul acesta iti depaseste nivelul cunostintelor. Atunci cand se face upload la un fisier printr-un form, sau se doreste import-ul unui fisier, se poate intampla ca extensia fisierului sa nu reflecte realitatea sau ca aceasta sa lipseasca cu desavarsire, fapt ce va duce la varii probleme. Array-ul $_FILES ce ia valori in functie de continutul unui form ce are specificat in mod explicit enctype=”multipart/form-data” se prea poate sa nu contina valoarea corecta a mime type-ului pentru $_FILES['file_input_name']['type'] deoarece detectia mime-ului cade pe spinarea browserului iar in majoritatea cazurilor acesta se foloseste de extensia fisierului deci va esua in cazurile descrise mai sus. Este nevoie ca informatia sa fie interpretata citind headerele fisierului si folosindu-ne de mime magic.

PECL si fileinfo

Nu o sa imi pierd timpul sa explic ce e PECL. Google este de mare ajutor. Din pacate in repository-urile Ubuntu/Debian, extensia fileinfo nu este disponibila in mod implicit. Din fericire este disponibila prin intermediul PECL. Acum incepe treaba sa fie paroasa.

In primul rand, este nevoie de una bucata compilator. Exista un pachet ce le face pe toate, deci:

sudo apt-get install build-essential

Bun. Avem compilator, avem PECL (presupun, daca n-ai HTTP server si PHP – citesti degeaba). Pentru build-ul fileinfo mai este nevoie de pachete de development, deci:

sudo apt-get install libmagic-dev php5-dev

ce va instala headerele de development pentru libmagic, phpize si alte chestii. Faceti acum, sau regretati mai tarziu. Acum este timpul sa compilam extensia fileinfo folosind pecl:

sudo pecl install fileinfo

Daca maraie vreo eroare la configure, instalati pachetul de development aferent (pentru cei somnorosi, are sufixul -dev). Daca maraie vreo eroare la compile, imi pare rau, nu va pot ajuta. Pe masina de devel a functionat fara probleme. Daca nu maraie nici o eroare, ar trebui sa indice faptul ca extensia a fost instalata cu succes. Ar trebui sa fie ceva de genul:

Build process completed successfully
Installing ‘/usr/lib/php5/20060613+lfs/fileinfo.so’
install ok: channel://pear.php.net/Fileinfo-1.0.4

Daca ati ajuns pana aici, mai este putin si usor. Extensiile instalate prin intermediul PECL nu sunt incarcate in mod automat, spre deosebire de cele instalate din repository-urile Ubuntu/Debian folosind apt-get sau alternativa (cu mici exceptii, spre exemplu mcrypt.so trebuie incarcat in mod explicit – nenea maintainer a fost cascat). Pentru a mentine ideea si spiritul Debian, incarcarea modulului se va face folosind directorul de fisiere alternative de configurare pentru PHP. Tastati urmatoarele chestii intr-un terminal (da stiu, copy-paste e mai comod):

cd /etc/php5/conf.d/; sudo touch fileinfo.ini; sudo nano fileinfo.ini

Bagati urmatoarea linie in acel fisier:

extension=fileinfo.so

dupa care salvati cu Ctrl+O. Inchideti editorul text folosind Ctrl+X. Nu, nu sunt vim maniac, sa nu aud de el. Acum este timpul sa se dea restart la HTTP server pentru a incarca noua configuratie. Ar trebui sa fie valabil si pentru cei cu GCI/FastCGI (eventual alt HTTP server gen lighttpd), desi subsemnatul e de ala cu Apache 2+PHP5 handler, deci in cazul meu (si al majoritatii):

sudo /etc/init.d/apache2  reload

ce va duce la un graceful restart (aka restart fara downtime) urmat de incarcarea noilor fisiere de configurare. Daca totul e ok, noul modul de PHP ar trebui sa fie incarcat. phpinfo(); ar trebui sa indice acest fapt, atat in lista de fisiere de configurare alternative (cele din /etc/php5/conf.d) cat si prin faptul ca ar trebui sa indice pe undeva in mod explicit faptul ca fileinfo este incarcata.

Utilizarea fileinfo pentru a afla MIME Type

Acum sa trecem la lucruri grele. fileinfo contine niste functii smechere asemanatoare cu fopen. Pentru ubergeeks exista modul orientat obiect de lucru cu ele (php.net/finfo_open explica), dar subsemnatul se multumeste cu trei apeluri procedurale din moment ce nu exista nici un avantaj real in cazul de fata pentru a defini un obiect si a-l distruge dupa ce se afla mime-ul. Pentru cei dornici sa isi implementeze o clasa proprie … este alta poveste. Eu mi-am facut o functie custom ce am inclus-o in API-ul central ce primeste ca parametru calea fisierului si imi returneaza mime-ul in caz de succes sau un cod de eroare pentru debug in caz de esuare. Miezul problemei sta in:

$finfo=finfo_open(FILEINFO_MIME, "/usr/share/misc/magic");
if(!$finfo)
	die("Can't open the fileinfo database.");
$mime=finfo_file($finfo, $fileName);
finfo_close($finfo);

Si cam atat. Succes si spor la treaba.


Designed by: studentzFM | Theme made for free by: Casino , punkzFM and mygroovez | Heavily modified by SaltwaterC