Как стать автором
Поиск
Написать публикацию
Обновить

Восстанавливаем работу «испорченного» php-cgi

Так получилось, что я все еще являюсь пользователем старого доброго виртуального хостинга у одного из хостеров. Код сайта написан для LAMP, но в модульном PHP оператора отсутствовала часть необходимых библиотек, поэтому пришлось собрать свой PHP и использовать его в качестве CGI. Один раз собрал все это дело, подключил и забыл до того дня пока не получил письмо от хостера о том, что на сервере будет производиться плановое обновление версий ПО, и это может затронуть работу пользовательских cgi-приложениий скомпилированных на сервере. Результаты обновлений увидел уже на следующий день т.к. запросы к сайту стали возвращать 500 (Internal Server Error).

Иду смотреть, что стало с моим бинарем
$ ./php -v
/libexec/ld-elf.so.1: Shared object "libpng.so.6" not found, required by "php"


еще раз проверяю библиотеки с которыми был скомпилирован php-cgi
$ ldd ./php
./php:
        libcrypt.so.5 => /lib/libcrypt.so.5 (0x285cc000)
        libmysqlclient.so.15 => /usr/local/lib/mysql/libmysqlclient.so.15 (0x285f2000)
        libm.so.5 => /lib/libm.so.5 (0x28751000)
        libz.so.5 => /lib/libz.so.5 (0x2876b000)
        libgd.so.4 => /usr/local/lib/libgd.so.4 (0x2877d000)
        libfreetype.so.9 => /usr/local/lib/libfreetype.so.9 (0x287c6000)
        libbz2.so.4 => /usr/lib/libbz2.so.4 (0x2883f000)
        libpng.so.6 => not found (0x0)
        libjpeg.so.11 => /usr/local/lib/libjpeg.so.11 (0x28850000)
        libgdbm.so.4 => /usr/local/lib/libgdbm.so.4 (0x28886000)
        libxml2.so.5 => /usr/local/lib/libxml2.so.5 (0x2888e000)
        libiconv.so.3 => /usr/local/lib/libiconv.so.3 (0x289b8000)
        libc.so.7 => /lib/libc.so.7 (0x28ab0000)
        libpng15.so.15 => /usr/local/lib/libpng15.so.15 (0x28bcc000)

Проверяю наличие «libpng» на сервере
$ ls -l /usr/local/lib/|grep 'png*.*so'
lrwxr-xr-x   1 root  wheel        11 Aug 22 13:23 libpng.so -> libpng15.so
lrwxr-xr-x   1 root  wheel        14 Aug 22 13:23 libpng15.so -> libpng15.so.15
-rwxr-xr-x   1 root  wheel    171916 Aug 22 13:23 libpng15.so.15

Либы есть, но нет файла «libpng.so.6» линк на который остался в моем бинарнике. Версии хостер обновил, а симлинки оставить забыл, видимо. Собирать php повторно из исходников было лень т.к. не помню точной конфигурации, поэтому решил воспользоваться старым «читерским» методом, поправив имя файла библиотеки в самом бинарнике. Как мы видели ранее, к библиотеке теперь можно обратиться через «libpng.so», поэтому в бинаре нужно выполнить замену подстроки libpng.so.6 на libpng.so

Открываем бинарный файл (лучше копию) в vi и переходим в hex-режим (Esc:%!xxd)

Находим строку с вхождением «libpng»
/libpng

0021df0: 322e 736f 2e34 006c 6962 706e 672e 736f 2.so.4.libpng.so
0021e00: 2e36 006c 6962 6a70 6567 2e73 6f2e 3131 .6.libjpeg.so.11

Видим, что символы точка и шесть (ascii: 2e36) в имени файла нам все портят, и нужно от них избавиться.

Заполняем нулями эти два байта

0021df0: 322e 736f 2e34 006c 6962 706e 672e 736f 2.so.4.libpng.so
0021e00: 0000 006c 6962 6a70 6567 2e73 6f2e 3131 ...libjpeg.so.11

Выходим (обязательно) из hex-режима (Esc:%!xxd -r) и сохраняемся (Esc:wq)

Проверяем
$ ./php -v
PHP 5.2.17 (cgi) (built: Mar 12 2012 18:02:07)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies

На это ушло максимум 2 минуты, а это быстрее чем вспоминать старый конфиг, и компилировать.

P.S. На сервере стоит freebsd, а вытащить строку конфига, как выяснилось позже, можно было так

$ strings phpbad|grep \/configure|sed s/\'//g
./configure  --prefix=/var/www --with-mysql=/usr/local --enable-ftp --enable-dbase --with-gdbm --with-ndbm --with-iconv=/usr/local --with-gd=/usr/local --enable-gd-native-ttf=/usr/local --with-jpeg-dir=/usr/local --with-png-dir=/usr/local --with-freetype-dir=/usr/local --with-ttf --with-zlib-dir=/usr --disable-posix --enable-mbstring --enable-force-cgi-redirect --enable-inline-optimization --without-pear --disable-debug
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.