index

2003年 12月
 
  1 2 3 4 5 6 7
  8 9 10 11 12 13 14
  15 16 17 18 19 20 21
  22 23 24 25 26 27 28
  29 30 31        
2004年 1月
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
2004年 2月
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29

アレ

PEAR install でエラー   ▽20040122a #日記

なんだか,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_typenone になってるよ! 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';
  

これで動くようになった. や,なった,って,なんでこんなことになっちゃってるのかの原因が不明なんですが……(笑) なんかライブラリの方がおかしいのかな……うー他のマシンでこの現象が出ない…… マシン環境によるものなら,とりあえずこのマシンでは上記の問題は理解&解決したので, 放置しちゃおうかしらん(笑)

index