なんだか,pear コマンドで install しようとするとエラーになる.
家や社サーバでは大丈夫で,社のローカルテストマシン( Miracle Linux 2.0,PHP-4.3.1 )でだけおかしいみたい.
pear install
しようとすると,
「Could not get contents of package "~~.tgz" Invalid tgz file.
」とか言われる.
ってことで調査してみますよ……
まず件のメッセージで grep -R 'Invalid tgz file' /usr/local/lib/php/*
とか実行.
メッセージは /usr/local/lib/php/PEAR/Common.php
にあるらしいです.
該当箇所をチェック.
$tar = new Archive_Tar($file);
if ($this->debug <= 1) {
$tar->pushErrorHandling(PEAR_ERROR_RETURN);
}
$content = $tar->listContent();
if ($this->debug <= 1) {
$tar->popErrorHandling();
}
if (!is_array($content)) {
$file = realpath($file);
return $this->raiseError("Could not get contents of package \"$file\"".
'. Invalid tgz file.');
}
えーつまり,$tar->listContent()
がエラーなのでこのメッセージになってるわけだ.
PHP の PEAR ライブラリは,バイナリとかではなく全く完全な PHP コードで書かれているので,
/usr/local/lib/php
からカレントにコピーしてきてやって,
そっちを好き放題にいじりつつデバッグ出来るのです.
この場合にはカレントに Archive というディレクトリを掘って Tar.php をコピーしてくる.
(include_dir はデフォルトで先頭に "." がいるのでこちらが優先して読まれる)
ってことで,ここんとこで print_r( $tar )
してみると,
どうも $tar->_compress_type
が none
になってるよ!
gzip 圧縮されてるのを素の tar だと思い込んで構造をゲット出来てなかった模様.
で,次に Archive/Tar.php の gzip 圧縮自動判定部分をチェック.
if ($fp = @fopen($p_tarname, "rb")) {
// look for gzip magic cookie
$data = fread($fp, 2);
fclose($fp);
if ($data == "\37\213") {
$this->_compress = true;
$this->_compress_type = 'gz';
$data == "\37\213"
って辺りがぷんぷん臭うですよ.
しかし確かに gzip のヘッダは 0x1F 0x8B なので,これ自体が間違ってるわけではない.
ここんとこの比較で何故か失敗してると見た.
で,アレコレ調査してった結果……
どうも "\37\213"
という表記で生成される文字列が,
その通りのバイト列になってないようだ.
さらに調べると,どうも 8bit 目が 1 の文字コードがシカトされて,
この文字列は "\37"
という文字列になってしまっているらしい.
何でだ? バグかと思って PHP-4.3.4(現時点で最新)をビルドしなおして確認したけどやっぱダメだ.
ま,とりあえずここんとこを直しちゃえば動くわけなんだけど.
if ($data == sprintf( '%c%c', 037, 0213 )) {
$this->_compress = true;
$this->_compress_type = 'gz';
これで動くようになった. や,なった,って,なんでこんなことになっちゃってるのかの原因が不明なんですが……(笑) なんかライブラリの方がおかしいのかな……うー他のマシンでこの現象が出ない…… マシン環境によるものなら,とりあえずこのマシンでは上記の問題は理解&解決したので, 放置しちゃおうかしらん(笑)