From 434926a39e85930949dabe93bde603baf5e665a7 Mon Sep 17 00:00:00 2001 From: Pierre Joye Date: Tue, 17 Jun 2003 17:13:19 +0000 Subject: [PATCH] MFH,(4.3.3RC1) --- pear/Archive/Tar.php | 540 +++++++++++++++++++++++++-------- pear/CMD.php | 6 +- pear/Console/Getopt.php | 6 +- pear/OS/Guess.php | 6 +- pear/PEAR.php | 10 +- pear/PEAR/Autoloader.php | 6 +- pear/PEAR/Builder.php | 20 +- pear/PEAR/Command.php | 6 +- pear/PEAR/Command/Auth.php | 6 +- pear/PEAR/Command/Build.php | 12 +- pear/PEAR/Command/Common.php | 6 +- pear/PEAR/Command/Config.php | 6 +- pear/PEAR/Command/Install.php | 123 +++++++- pear/PEAR/Command/Package.php | 57 ++-- pear/PEAR/Command/Registry.php | 38 ++- pear/PEAR/Command/Remote.php | 6 +- pear/PEAR/Common.php | 23 +- pear/PEAR/Config.php | 6 +- pear/PEAR/Dependency.php | 55 +++- pear/PEAR/Frontend/CLI.php | 12 +- pear/PEAR/Installer.php | 76 ++++- pear/PEAR/Packager.php | 6 +- pear/PEAR/Registry.php | 6 +- pear/PEAR/Remote.php | 6 +- pear/System.php | 4 +- pear/package-PEAR.xml | 2 +- pear/package.dtd | 16 +- pear/scripts/pearcmd.php | 6 +- pear/scripts/pearwin.php | 6 +- pear/template.spec | 48 ++- 30 files changed, 853 insertions(+), 273 deletions(-) diff --git a/pear/Archive/Tar.php b/pear/Archive/Tar.php index ff20b7eb56..c244aafed8 100644 --- a/pear/Archive/Tar.php +++ b/pear/Archive/Tar.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -39,6 +39,11 @@ class Archive_Tar extends PEAR */ var $_compress=false; + /** + * @var string Type of compression : 'none', 'gz' or 'bz2' + */ + var $_compress_type='none'; + /** * @var file descriptor */ @@ -64,41 +69,61 @@ class Archive_Tar extends PEAR function Archive_Tar($p_tarname, $p_compress = null) { $this->PEAR(); + $this->_compress = false; + $this->_compress_type = 'none'; if ($p_compress === null) { if (@file_exists($p_tarname)) { - if ($fp = @fopen($p_tarname, "r")) { + if ($fp = @fopen($p_tarname, "rb")) { // look for gzip magic cookie $data = fread($fp, 2); + fclose($fp); if ($data == "\37\213") { - $p_compress = true; + $this->_compress = true; + $this->_compress_type = 'gz'; + // No sure it's enought for a magic code .... + } elseif ($data == "BZ") { + $this->_compress = true; + $this->_compress_type = 'bz2'; } } } else { // probably a remote file or some file accessible // through a stream interface if (substr($p_tarname, -2) == 'gz') { - $p_compress = true; + $this->_compress = true; + $this->_compress_type = 'gz'; + } elseif ((substr($p_tarname, -3) == 'bz2') || + (substr($p_tarname, -2) == 'bz')) { + $this->_compress = true; + $this->_compress_type = 'bz2'; } } + } else { + if ($p_compress == 'gz') { + $this->_compress = true; + $this->_compress_type = 'gz'; + } else if ($p_compress == 'bz2') { + $this->_compress = true; + $this->_compress_type = 'bz2'; + } } $this->_tarname = $p_tarname; - if ($p_compress) { // assert zlib extension support - $extname = 'zlib'; + if ($this->_compress) { // assert zlib or bz2 extension support + if ($this->_compress_type == 'gz') + $extname = 'zlib'; + else if ($this->_compress_type == 'bz2') + $extname = 'bz2'; + if (!extension_loaded($extname)) { - if (OS_WINDOWS) { - @dl("php_$extname.dll"); - } else { - @dl("$extname.so"); - } + PEAR::loadExtension($extname); } if (!extension_loaded($extname)) { die("The extension '$extname' couldn't be found.\n". - "Please make sure your version of PHP was built". + "Please make sure your version of PHP was built ". "with '$extname' support.\n"); return false; } } - $this->_compress = (bool)$p_compress; } // }}} @@ -311,6 +336,43 @@ class Archive_Tar extends PEAR } // }}} + // {{{ addString() + /** + * This method add a single string as a file at the + * end of the existing archive. If the archive does not yet exists it + * is created. + * + * @param string $p_filename A string which contains the full filename path + * that will be associated with the string. + * @param string $p_string The content of the file added in the archive. + * @return true on success, false on error. + * @access public + */ + function addString($p_filename, $p_string) + { + $v_result = true; + + if (!@is_file($this->_tarname)) { + if (!$this->_openWrite()) { + return false; + } + $this->_close(); + } + + if (!$this->_openAppend()) + return false; + + // Need to check the get back to the temporary file ? .... + $v_result = $this->_addString($p_filename, $p_string); + + $this->_writeFooter(); + + $this->_close(); + + return $v_result; + } + // }}} + // {{{ extractModify() /** * This method extract all the content of the archive in the directory @@ -358,6 +420,27 @@ class Archive_Tar extends PEAR } // }}} + // {{{ extractInString() + /** + * This method extract from the archive one file identified by $p_filename. + * The return value is a string with the file content, or NULL on error. + * @param string $p_filename The path of the file to extract in a string. + * @return a string with the file content or NULL. + * @access public + */ + function extractInString($p_filename) + { + if ($this->_openRead()) { + $v_result = $this->_extractInString($p_filename); + $this->_close(); + } else { + $v_result = NULL; + } + + return $v_result; + } + // }}} + // {{{ extractList() /** * This method extract from the archive only the files indicated in the @@ -417,10 +500,14 @@ class Archive_Tar extends PEAR // {{{ _openWrite() function _openWrite() { - if ($this->_compress) - $this->_file = @gzopen($this->_tarname, "w"); + if ($this->_compress_type == 'gz') + $this->_file = @gzopen($this->_tarname, "wb"); + else if ($this->_compress_type == 'bz2') + $this->_file = @bzopen($this->_tarname, "wb"); + else if ($this->_compress_type == 'none') + $this->_file = @fopen($this->_tarname, "wb"); else - $this->_file = @fopen($this->_tarname, "w"); + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); if ($this->_file == 0) { $this->_error('Unable to open in write mode \''.$this->_tarname.'\''); @@ -462,10 +549,14 @@ class Archive_Tar extends PEAR // ----- File to open if the normal Tar file $v_filename = $this->_tarname; - if ($this->_compress) + if ($this->_compress_type == 'gz') $this->_file = @gzopen($v_filename, "rb"); - else + else if ($this->_compress_type == 'bz2') + $this->_file = @bzopen($v_filename, "rb"); + else if ($this->_compress_type == 'none') $this->_file = @fopen($v_filename, "rb"); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); if ($this->_file == 0) { $this->_error('Unable to open in read mode \''.$v_filename.'\''); @@ -479,10 +570,14 @@ class Archive_Tar extends PEAR // {{{ _openReadWrite() function _openReadWrite() { - if ($this->_compress) + if ($this->_compress_type == 'gz') $this->_file = @gzopen($this->_tarname, "r+b"); - else + else if ($this->_compress_type == 'bz2') + $this->_file = @bzopen($this->_tarname, "r+b"); + else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "r+b"); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); if ($this->_file == 0) { $this->_error('Unable to open in read/write mode \''.$this->_tarname.'\''); @@ -497,10 +592,14 @@ class Archive_Tar extends PEAR function _close() { if (isset($this->_file)) { - if ($this->_compress) + if ($this->_compress_type == 'gz') @gzclose($this->_file); - else + else if ($this->_compress_type == 'bz2') + @bzclose($this->_file); + else if ($this->_compress_type == 'none') @fclose($this->_file); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); $this->_file = 0; } @@ -536,16 +635,87 @@ class Archive_Tar extends PEAR } // }}} + // {{{ _writeBlock() + function _writeBlock($p_binary_data, $p_len=null) + { + if ($this->_file) { + if ($p_len === null) { + if ($this->_compress_type == 'gz') + @gzputs($this->_file, $p_binary_data); + else if ($this->_compress_type == 'bz2') + @bzwrite($this->_file, $p_binary_data); + else if ($this->_compress_type == 'none') + @fputs($this->_file, $p_binary_data); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); + } else { + if ($this->_compress_type == 'gz') + @gzputs($this->_file, $p_binary_data, $p_len); + else if ($this->_compress_type == 'bz2') + @bzwrite($this->_file, $p_binary_data, $p_len); + else if ($this->_compress_type == 'none') + @fputs($this->_file, $p_binary_data, $p_len); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); + + } + } + return true; + } + // }}} + + // {{{ _readBlock() + function _readBlock($p_len=null) + { + $v_block = null; + if ($this->_file) { + if ($p_len === null) + $p_len = 512; + + if ($this->_compress_type == 'gz') + $v_block = @gzread($this->_file, 512); + else if ($this->_compress_type == 'bz2') + $v_block = @bzread($this->_file, 512); + else if ($this->_compress_type == 'none') + $v_block = @fread($this->_file, 512); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); + + } + return $v_block; + } + // }}} + + // {{{ _jumpBlock() + function _jumpBlock($p_len=null) + { + if ($this->_file) { + if ($p_len === null) + $p_len = 1; + + if ($this->_compress_type == 'gz') + @gzseek($this->_file, @gztell($this->_file)+($p_len*512)); + else if ($this->_compress_type == 'bz2') { + // ----- Replace missing bztell() and bzseek() + for ($i=0; $i<$p_len; $i++) + $this->_readBlock(); + } else if ($this->_compress_type == 'none') + @fseek($this->_file, @ftell($this->_file)+($p_len*512)); + else + $this->_error('Unknown or missing compression type ('.$this->_compress_type.')'); + + } + return true; + } + // }}} + // {{{ _writeFooter() function _writeFooter() { if ($this->_file) { // ----- Write the last 0 filled block for end of archive $v_binary_data = pack("a512", ''); - if ($this->_compress) - @gzputs($this->_file, $v_binary_data); - else - @fputs($this->_file, $v_binary_data); + $this->_writeBlock($v_binary_data); } return true; } @@ -661,10 +831,7 @@ class Archive_Tar extends PEAR while (($v_buffer = fread($v_file, 512)) != '') { $v_binary_data = pack("a512", "$v_buffer"); - if ($this->_compress) - @gzputs($this->_file, $v_binary_data); - else - @fputs($this->_file, $v_binary_data); + $this->_writeBlock($v_binary_data); } fclose($v_file); @@ -679,6 +846,35 @@ class Archive_Tar extends PEAR } // }}} + // {{{ _addString() + function _addString($p_filename, $p_string) + { + if (!$this->_file) { + $this->_error('Invalid file descriptor'); + return false; + } + + if ($p_filename == '') { + $this->_error('Invalid file name'); + return false; + } + + // ----- Calculate the stored filename + $p_filename = $this->_translateWinPath($p_filename, false);; + + if (!$this->_writeHeaderBlock($p_filename, strlen($p_string), 0, 0, "", 0, 0)) + return false; + + $i=0; + while (($v_buffer = substr($p_string, (($i++)*512), 512)) != '') { + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + } + + return true; + } + // }}} + // {{{ _writeHeader() function _writeHeader($p_filename, $p_stored_filename) { @@ -687,7 +883,7 @@ class Archive_Tar extends PEAR $v_reduce_filename = $this->_pathReduction($p_stored_filename); if (strlen($v_reduce_filename) > 99) { - if (!$this->_writeLongHeader($p_stored_filename)) + if (!$this->_writeLongHeader($v_reduce_filename)) return false; } @@ -739,24 +935,83 @@ class Archive_Tar extends PEAR $v_checksum += ord(substr($v_binary_data_last,$j,1)); // ----- Write the first 148 bytes of the header in the archive - if ($this->_compress) - @gzputs($this->_file, $v_binary_data_first, 148); - else - @fputs($this->_file, $v_binary_data_first, 148); + $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%6s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); - if ($this->_compress) - @gzputs($this->_file, $v_binary_data, 8); - else - @fputs($this->_file, $v_binary_data, 8); + $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive - if ($this->_compress) - @gzputs($this->_file, $v_binary_data_last, 356); - else - @fputs($this->_file, $v_binary_data_last, 356); + $this->_writeBlock($v_binary_data_last, 356); + + return true; + } + // }}} + + // {{{ _writeHeaderBlock() + function _writeHeaderBlock($p_filename, $p_size, $p_mtime=0, $p_perms=0, $p_type='', $p_uid=0, $p_gid=0) + { + $p_filename = $this->_pathReduction($p_filename); + + if (strlen($p_filename) > 99) { + if (!$this->_writeLongHeader($p_filename)) + return false; + } + + if ($p_type == "5") { + $v_size = sprintf("%11s ", DecOct(0)); + } else { + $v_size = sprintf("%11s ", DecOct($p_size)); + } + + $v_uid = sprintf("%6s ", DecOct($p_uid)); + $v_gid = sprintf("%6s ", DecOct($p_gid)); + $v_perms = sprintf("%6s ", DecOct($p_perms)); + + $v_mtime = sprintf("%11s", DecOct($p_mtime)); + + $v_linkname = ''; + + $v_magic = ''; + + $v_version = ''; + + $v_uname = ''; + + $v_gname = ''; + + $v_devmajor = ''; + + $v_devminor = ''; + + $v_prefix = ''; + + $v_binary_data_first = pack("a100a8a8a8a12A12", $p_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); + $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $p_type, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, ''); + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i=0; $i<148; $i++) + $v_checksum += ord(substr($v_binary_data_first,$i,1)); + // ..... Ignore the checksum value and replace it by ' ' (space) + for ($i=148; $i<156; $i++) + $v_checksum += ord(' '); + // ..... Last part of the header + for ($i=156, $j=0; $i<512; $i++, $j++) + $v_checksum += ord(substr($v_binary_data_last,$j,1)); + + // ----- Write the first 148 bytes of the header in the archive + $this->_writeBlock($v_binary_data_first, 148); + + // ----- Write the calculated checksum + $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_binary_data = pack("a8", $v_checksum); + $this->_writeBlock($v_binary_data, 8); + + // ----- Write the last 356 bytes of the header in the archive + $this->_writeBlock($v_binary_data_last, 356); return true; } @@ -801,33 +1056,21 @@ class Archive_Tar extends PEAR $v_checksum += ord(substr($v_binary_data_last,$j,1)); // ----- Write the first 148 bytes of the header in the archive - if ($this->_compress) - @gzputs($this->_file, $v_binary_data_first, 148); - else - @fputs($this->_file, $v_binary_data_first, 148); + $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%6s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); - if ($this->_compress) - @gzputs($this->_file, $v_binary_data, 8); - else - @fputs($this->_file, $v_binary_data, 8); + $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive - if ($this->_compress) - @gzputs($this->_file, $v_binary_data_last, 356); - else - @fputs($this->_file, $v_binary_data_last, 356); + $this->_writeBlock($v_binary_data_last, 356); // ----- Write the filename as content of the block $i=0; while (($v_buffer = substr($p_filename, (($i++)*512), 512)) != '') { $v_binary_data = pack("a512", "$v_buffer"); - if ($this->_compress) - @gzputs($this->_file, $v_binary_data); - else - @fputs($this->_file, $v_binary_data); + $this->_writeBlock($v_binary_data); } return true; @@ -871,7 +1114,7 @@ class Archive_Tar extends PEAR if (($v_checksum == 256) && ($v_header['checksum'] == 0)) return true; - $this->_error('Invalid checksum : '.$v_checksum.' calculated, '.$v_header['checksum'].' expected'); + $this->_error('Invalid checksum for file "'.$v_data['filename'].'" : '.$v_checksum.' calculated, '.$v_header['checksum'].' expected'); return false; } @@ -905,25 +1148,16 @@ class Archive_Tar extends PEAR $v_filename = ''; $n = floor($v_header['size']/512); for ($i=0; $i<$n; $i++) { - if ($this->_compress) - $v_content = @gzread($this->_file, 512); - else - $v_content = @fread($this->_file, 512); + $v_content = $this->_readBlock(); $v_filename .= $v_content; } if (($v_header['size'] % 512) != 0) { - if ($this->_compress) - $v_content = @gzread($this->_file, 512); - else - $v_content = @fread($this->_file, 512); + $v_content = $this->_readBlock(); $v_filename .= $v_content; } // ----- Read the next header - if ($this->_compress) - $v_binary_data = @gzread($this->_file, 512); - else - $v_binary_data = @fread($this->_file, 512); + $v_binary_data = $this->_readBlock(); if (!$this->_readHeader($v_binary_data, $v_header)) return false; @@ -934,6 +1168,56 @@ class Archive_Tar extends PEAR } // }}} + // {{{ _extractInString() + /** + * This method extract from the archive one file identified by $p_filename. + * The return value is a string with the file content, or NULL on error. + * @param string $p_filename The path of the file to extract in a string. + * @return a string with the file content or NULL. + * @access private + */ + function _extractInString($p_filename) + { + $v_result_str = ""; + + While (strlen($v_binary_data = $this->_readBlock()) != 0) + { + if (!$this->_readHeader($v_binary_data, $v_header)) + return NULL; + + if ($v_header['filename'] == '') + continue; + + // ----- Look for long filename + if ($v_header['typeflag'] == 'L') { + if (!$this->_readLongHeader($v_header)) + return NULL; + } + + if ($v_header['filename'] == $p_filename) { + if ($v_header['typeflag'] == "5") { + $this->_error('Unable to extract in string a directory entry {'.$v_header['filename'].'}'); + return NULL; + } else { + $n = floor($v_header['size']/512); + for ($i=0; $i<$n; $i++) { + $v_result_str .= $this->_readBlock(); + } + if (($v_header['size'] % 512) != 0) { + $v_content = $this->_readBlock(); + $v_result_str .= substr($v_content, 0, ($v_header['size'] % 512)); + } + return $v_result_str; + } + } else { + $this->_jumpBlock(ceil(($v_header['size']/512))); + } + } + + return NULL; + } + // }}} + // {{{ _extractList() function _extractList($p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path) { @@ -973,16 +1257,11 @@ class Archive_Tar extends PEAR clearstatcache(); - While (!($v_end_of_file = ($this->_compress?@gzeof($this->_file):@feof($this->_file)))) + While (strlen($v_binary_data = $this->_readBlock()) != 0) { $v_extract_file = FALSE; $v_extraction_stopped = 0; - if ($this->_compress) - $v_binary_data = @gzread($this->_file, 512); - else - $v_binary_data = @fread($this->_file, 512); - if (!$this->_readHeader($v_binary_data, $v_header)) return false; @@ -1073,17 +1352,11 @@ class Archive_Tar extends PEAR } else { $n = floor($v_header['size']/512); for ($i=0; $i<$n; $i++) { - if ($this->_compress) - $v_content = @gzread($this->_file, 512); - else - $v_content = @fread($this->_file, 512); + $v_content = $this->_readBlock(); fwrite($v_dest_file, $v_content, 512); } if (($v_header['size'] % 512) != 0) { - if ($this->_compress) - $v_content = @gzread($this->_file, 512); - else - $v_content = @fread($this->_file, 512); + $v_content = $this->_readBlock(); fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); } @@ -1103,24 +1376,18 @@ class Archive_Tar extends PEAR } } } else { - // ----- Jump to next file - if ($this->_compress) - @gzseek($this->_file, @gztell($this->_file)+(ceil(($v_header['size']/512))*512)); - else - @fseek($this->_file, @ftell($this->_file)+(ceil(($v_header['size']/512))*512)); + $this->_jumpBlock(ceil(($v_header['size']/512))); } } else { - // ----- Jump to next file - if ($this->_compress) - @gzseek($this->_file, @gztell($this->_file)+(ceil(($v_header['size']/512))*512)); - else - @fseek($this->_file, @ftell($this->_file)+(ceil(($v_header['size']/512))*512)); + $this->_jumpBlock(ceil(($v_header['size']/512))); } + /* TBC : Seems to be unused ... if ($this->_compress) $v_end_of_file = @gzeof($this->_file); else $v_end_of_file = @feof($this->_file); + */ if ($v_listing || $v_extract_file || $v_extraction_stopped) { // ----- Log extracted files @@ -1137,9 +1404,12 @@ class Archive_Tar extends PEAR } // }}} - // {{{ _append() - function _append($p_filelist, $p_add_dir='', $p_remove_dir='') + // {{{ _openAppend() + function _openAppend() { + if (filesize($this->_tarname) == 0) + return $this->_openWrite(); + if ($this->_compress) { $this->_close(); @@ -1148,7 +1418,12 @@ class Archive_Tar extends PEAR return false; } - if (($v_temp_tar = @gzopen($this->_tarname.".tmp", "rb")) == 0) { + if ($this->_compress_type == 'gz') + $v_temp_tar = @gzopen($this->_tarname.".tmp", "rb"); + elseif ($this->_compress_type == 'bz2') + $v_temp_tar = @bzopen($this->_tarname.".tmp", "rb"); + + if ($v_temp_tar == 0) { $this->_error('Unable to open file \''.$this->_tarname.'.tmp\' in binary read mode'); @rename($this->_tarname.".tmp", $this->_tarname); return false; @@ -1159,39 +1434,58 @@ class Archive_Tar extends PEAR return false; } - $v_buffer = @gzread($v_temp_tar, 512); + if ($this->_compress_type == 'gz') { + $v_buffer = @gzread($v_temp_tar, 512); - // ----- Read the following blocks but not the last one - if (!@gzeof($v_temp_tar)) { - do{ - $v_binary_data = pack("a512", "$v_buffer"); - @gzputs($this->_file, $v_binary_data); - $v_buffer = @gzread($v_temp_tar, 512); + // ----- Read the following blocks but not the last one + if (!@gzeof($v_temp_tar)) { + do{ + $v_binary_data = pack("a512", $v_buffer); + $this->_writeBlock($v_binary_data); + $v_buffer = @gzread($v_temp_tar, 512); - } while (!@gzeof($v_temp_tar)); - } + } while (!@gzeof($v_temp_tar)); + } - if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) - $this->_writeFooter(); + @gzclose($v_temp_tar); + } + elseif ($this->_compress_type == 'bz2') { + $v_buffered_lines = array(); + $v_buffered_lines[] = @bzread($v_temp_tar, 512); + + // ----- Read the following blocks but not the last one + while (strlen($v_buffered_lines[] = @bzread($v_temp_tar, 512)) > 0) { + $v_binary_data = pack("a512", array_shift($v_buffered_lines)); + $this->_writeBlock($v_binary_data); + } - $this->_close(); - @gzclose($v_temp_tar); + @bzclose($v_temp_tar); + } if (!@unlink($this->_tarname.".tmp")) { $this->_error('Error while deleting temporary file \''.$this->_tarname.'.tmp\''); } - return true; - } + } else { + // ----- For not compressed tar, just add files before the last 512 bytes block + if (!$this->_openReadWrite()) + return false; - // ----- For not compressed tar, just add files before the last 512 bytes block - if (!$this->_openReadWrite()) - return false; + clearstatcache(); + $v_size = filesize($this->_tarname); + fseek($this->_file, $v_size-512); + } - clearstatcache(); - $v_size = filesize($this->_tarname); - fseek($this->_file, $v_size-512); + return true; + } + // }}} + // {{{ _append() + function _append($p_filelist, $p_add_dir='', $p_remove_dir='') + { + if (!$this->_openAppend()) + return false; + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) $this->_writeFooter(); @@ -1298,4 +1592,4 @@ class Archive_Tar extends PEAR // }}} } -?> \ No newline at end of file +?> diff --git a/pear/CMD.php b/pear/CMD.php index f69f0f35f1..d8e5939feb 100755 --- a/pear/CMD.php +++ b/pear/CMD.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/Console/Getopt.php b/pear/Console/Getopt.php index 8adad5e277..1f98a1c083 100644 --- a/pear/Console/Getopt.php +++ b/pear/Console/Getopt.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/OS/Guess.php b/pear/OS/Guess.php index 959476d69a..7cbd988af0 100644 --- a/pear/OS/Guess.php +++ b/pear/OS/Guess.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR.php b/pear/PEAR.php index 8c536d717c..3062194d5c 100644 --- a/pear/PEAR.php +++ b/pear/PEAR.php @@ -7,8 +7,8 @@ // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -63,7 +63,7 @@ ini_set('track_errors', true); * destructor, use error_log(), syslog() or something similar. * * IMPORTANT! To use the emulated destructors you need to create the - * objects by reference, ej: $obj =& new PEAR_child; + * objects by reference: $obj =& new PEAR_child; * * @since PHP 4.0.2 * @author Stig Bakken @@ -224,7 +224,9 @@ class PEAR * * @param mixed $data the value to test * @param int $code if $data is an error object, return true - * only if $obj->getCode() == $code + * only if $code is a string and + * $obj->getMessage() == $code or + * $code is an integer and $obj->getCode() == $code * @access public * @return bool true if parameter is an error */ diff --git a/pear/PEAR/Autoloader.php b/pear/PEAR/Autoloader.php index 3fec4c19cf..f211a184e5 100644 --- a/pear/PEAR/Autoloader.php +++ b/pear/PEAR/Autoloader.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Builder.php b/pear/PEAR/Builder.php index c778623869..13c3f36f60 100644 --- a/pear/PEAR/Builder.php +++ b/pear/PEAR/Builder.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -310,7 +310,7 @@ class PEAR_Builder extends PEAR_Common if ($what != 'cmdoutput') { return; } - $this->log(3, rtrim($data)); + $this->log(1, rtrim($data)); if (preg_match('/You should update your .aclocal.m4/', $data)) { return; } @@ -320,8 +320,8 @@ class PEAR_Builder extends PEAR_Common $apino = (int)$matches[2]; if (isset($this->$member)) { $this->$member = $apino; - $msg = sprintf("%-22s : %d", $matches[1], $apino); - $this->log(1, $msg); + //$msg = sprintf("%-22s : %d", $matches[1], $apino); + //$this->log(1, $msg); } } } @@ -352,6 +352,11 @@ class PEAR_Builder extends PEAR_Common if (!$pp) { return $this->raiseError("failed to run `$command'"); } + if ($callback && $callback[0]->debug == 1) { + $olddbg = $callback[0]->debug; + $callback[0]->debug = 2; + } + while ($line = fgets($pp, 1024)) { if ($callback) { call_user_func($callback, 'cmdoutput', $line); @@ -359,6 +364,9 @@ class PEAR_Builder extends PEAR_Common $this->log(2, rtrim($line)); } } + if ($callback && isset($olddbg)) { + $callback[0]->debug = $olddbg; + } $exitcode = @pclose($pp); return ($exitcode == 0); } diff --git a/pear/PEAR/Command.php b/pear/PEAR/Command.php index 7e23acab32..543032715d 100644 --- a/pear/PEAR/Command.php +++ b/pear/PEAR/Command.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Command/Auth.php b/pear/PEAR/Command/Auth.php index 3978ac6ec9..141a4b1f8f 100644 --- a/pear/PEAR/Command/Auth.php +++ b/pear/PEAR/Command/Auth.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Command/Build.php b/pear/PEAR/Command/Build.php index ed97903454..323a2543cc 100644 --- a/pear/PEAR/Command/Build.php +++ b/pear/PEAR/Command/Build.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -66,7 +66,7 @@ Builds one or more extensions contained in a package.' $params[0] = 'package.xml'; } $builder = &new PEAR_Builder($this->ui); - $this->verbose = $this->config->get('verbose'); + $this->debug = $this->config->get('verbose'); $err = $builder->build($params[0], array(&$this, 'buildCallback')); if (PEAR::isError($err)) { return $err; @@ -79,8 +79,8 @@ Builds one or more extensions contained in a package.' function buildCallback($what, $data) { - if (($what == 'cmdoutput' && $this->verbose > 1) || - ($what == 'output' && $this->verbose > 0)) { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { $this->ui->outputData(rtrim($data), 'build'); } } diff --git a/pear/PEAR/Command/Common.php b/pear/PEAR/Command/Common.php index 3544e2f9cb..ab91f6329b 100644 --- a/pear/PEAR/Command/Common.php +++ b/pear/PEAR/Command/Common.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Command/Config.php b/pear/PEAR/Command/Config.php index f18491903d..90f26ef17c 100644 --- a/pear/PEAR/Command/Config.php +++ b/pear/PEAR/Command/Config.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Command/Install.php b/pear/PEAR/Command/Install.php index 4ecfb33390..8a3d48e884 100644 --- a/pear/PEAR/Command/Install.php +++ b/pear/PEAR/Command/Install.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -196,7 +196,25 @@ more stable. Uninstalls one or more PEAR packages. More than one package may be specified at once. '), - + 'bundle' => array( + 'summary' => 'Unpacks a Pecl Package', + 'function' => 'doBundle', + 'shortcut' => 'bun', + 'options' => array( + 'destination' => array( + 'shortopt' => 'd', + 'arg' => 'DIR', + 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', + ), + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'Force the unpacking even if there were errors in the package', + ), + ), + 'doc' => ' +Unpacks a Pecl Package into the selected location. It will download the +package if needed. +'), ); // }}} @@ -297,6 +315,101 @@ specified at once. } // }}} -} + + // }}} + // {{{ doBundle() + /* + (cox) It just downloads and untars the package, does not do + any check that the PEAR_Installer::_installFile() does. + */ + + function doBundle($command, $options, $params) + { + if (empty($this->installer)) { + $this->installer = &new PEAR_Installer($this->ui); + } + $installer = &$this->installer; + if (sizeof($params) < 1) { + return $this->raiseError("Please supply the package you want to bundle"); + } + $pkgfile = $params[0]; + + if (preg_match('#^(http|ftp)://#', $pkgfile)) { + $need_download = true; + } elseif (!@is_file($pkgfile)) { + if ($installer->validPackageName($pkgfile)) { + $pkgfile = $installer->getPackageDownloadUrl($pkgfile); + $need_download = true; + } else { + if (strlen($pkgfile)) { + return $this->raiseError("Could not open the package file: $pkgfile"); + } else { + return $this->raiseError("No package file given"); + } + } + } + + // Download package ----------------------------------------------- + if ($need_download) { + $downloaddir = $installer->config->get('download_dir'); + if (empty($downloaddir)) { + if (PEAR::isError($downloaddir = System::mktemp('-d'))) { + return $downloaddir; + } + $installer->log(2, '+ tmp dir created at ' . $downloaddir); + } + $callback = $this->ui ? array(&$installer, '_downloadCallback') : null; + $file = $installer->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback); + if (PEAR::isError($file)) { + return $this->raiseError($file); + } + $pkgfile = $file; + } + + // Parse xml file ----------------------------------------------- + $pkginfo = $installer->infoFromTgzFile($pkgfile); + if (PEAR::isError($pkginfo)) { + return $this->raiseError($pkginfo); + } + $installer->validatePackageInfo($pkginfo, $errors, $warnings); + // XXX We allow warnings, do we have to do it? + if (count($errors)) { + if (empty($options['force'])) { + return $this->raiseError("The following errors where found:\n". + implode("\n", $errors)); + } else { + $this->log(0, "warning : the following errors were found:\n". + implode("\n", $errors)); + } + } + $pkgname = $pkginfo['package']; + + // Unpacking ------------------------------------------------- + + if (isset($options['destination'])) { + if (!is_dir($options['destination'])) { + System::mkdir('-p ' . $options['destination']); + } + $dest = realpath($options['destination']); + } else { + $pwd = getcwd(); + if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) { + $dest = $pwd . DIRECTORY_SEPARATOR . 'ext'; + } else { + $dest = $pwd; + } + } + $dest .= DIRECTORY_SEPARATOR . $pkgname; + $orig = $pkgname . '-' . $pkginfo['version']; + + $tar = new Archive_Tar($pkgfile); + if (!@$tar->extractModify($dest, $orig)) { + return $this->raiseError("unable to unpack $pkgfile"); + } + $this->ui->outputData("Package ready at '$dest'"); + // }}} + } + +} ?> diff --git a/pear/PEAR/Command/Package.php b/pear/PEAR/Command/Package.php index ed0fb671c6..986c6c7dab 100644 --- a/pear/PEAR/Command/Package.php +++ b/pear/PEAR/Command/Package.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -442,11 +442,12 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm putenv("TEST_PHP_EXECUTABLE=$php"); $ip = ini_get("include_path"); $ps = OS_WINDOWS ? ';' : ':'; - $run_tests = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . 'run-tests.php'; + $run_tests = $rtsts = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . 'run-tests.php'; if (!file_exists($run_tests)) { $run_tests = PEAR_INSTALL_DIR . DIRECTORY_SEPARATOR . 'run-tests.php'; if (!file_exists($run_tests)) { - return $this->raiseError("No `run-tests.php' file found"); + return $this->raiseError("No run-tests.php file found. Please copy this ". + "file from the sources of your PHP distribution to $rtsts"); } } $plist = implode(" ", $params); @@ -560,6 +561,16 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm // }}} // {{{ doMakeRPM() + /* + (cox) + TODO: + - Fill the rpm dependencies in the template file. + IDEAS: + - Instead of mapping the role to rpm vars, perhaps it's better + to use directly the pear cmd to install the files by itself + in %postrun so: + pear -d php_dir=%{_libdir}/php/pear -d test_dir=.. + */ function doMakeRPM($command, $options, $params) { @@ -582,22 +593,14 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm array('installroot' => $instroot, 'nodeps' => true)); $pkgdir = "$info[package]-$info[version]"; -// print "instroot=$instroot\n"; -// print_r($info); -// return true; - $info['rpm_xml_dir'] = '/var/lib/pear'; $this->config->set('verbose', $tmp); - if (!$tar->extractList("$pkgdir/package.xml", $tmpdir, $pkgdir)) { + if (!$tar->extractList("package.xml", $tmpdir, $pkgdir)) { return $this->raiseError("failed to extract $params[0]"); } if (!file_exists("$tmpdir/package.xml")) { return $this->raiseError("no package.xml found in $params[0]"); } -// System::mkdir("-p $instroot$info[rpm_xml_dir]"); -// if (!@copy("$tmpdir/package.xml", "$instroot$info[rpm_xml_dir]/$info[package].xml")) { -// return $this->raiseError("could not copy package.xml file: $php_errormsg"); -// } if (isset($options['spec-template'])) { $spec_template = $options['spec-template']; } else { @@ -618,10 +621,26 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm foreach ($info['filelist'] as $name => $attr) { if ($attr['role'] == 'doc') { $info['doc_files'] .= " $name"; - } elseif ($attr['role'] == 'src') { - $srcfiles++; + // Map role to the rpm vars + } else { + $c_prefix = '%{_libdir}/php/pear'; + switch ($attr['role']) { + case 'php': + $prefix = $c_prefix; break; + case 'ext': + $prefix = '%{_libdir}/php'; break; // XXX good place? + case 'src': + $srcfiles++; + $prefix = '%{_includedir}/php'; break; // XXX good place? + case 'test': + $prefix = "$c_prefix/tests/" . $info['package']; break; + case 'data': + $prefix = "$c_prefix/data/" . $info['package']; break; + case 'script': + $prefix = '%{_bindir}'; break; + } + $info['files'] .= "$prefix/$name\n"; } - $info['files'] .= "$attr[installed_as]\n"; } if ($srcfiles > 0) { include_once "OS/Guess.php"; @@ -630,7 +649,7 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm } else { $arch = 'noarch'; } - $cfk = array('master_server', 'php_dir', 'ext_dir', 'doc_dir', + $cfg = array('master_server', 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'test_dir'); foreach ($cfg as $k) { $info[$k] = $this->config->get($k); @@ -650,7 +669,7 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm fwrite($wp, $spec_contents); fclose($wp); $this->ui->outputData("Wrote RPM spec file $spec_file", $command); - + return true; } diff --git a/pear/PEAR/Command/Registry.php b/pear/PEAR/Command/Registry.php index 20860cf4a2..a4a40c8111 100644 --- a/pear/PEAR/Command/Registry.php +++ b/pear/PEAR/Command/Registry.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -227,7 +227,7 @@ installed package.' return $info; } if (empty($info)) { - $this->ui->displayError("Nothing found for `$params[0]'"); + $this->raiseError("Nothing found for `$params[0]'"); return; } unset($info['filelist']); @@ -284,6 +284,36 @@ installed package.' $info[$key] = $dstr; break; } + case 'provides' : { + $debug = $this->config->get('verbose'); + if ($debug < 2) { + $pstr = 'Classes: '; + } else { + $pstr = ''; + } + foreach ($info[$key] as $p) { + if ($debug < 2 && $p['type'] != "class") { + continue; + } + // Only print classes when verbosity mode is < 2 + if ($debug < 2) { + if ($i++ > 0) { + $pstr .= ", "; + } + $pstr .= $p['name']; + } else { + if ($i++ > 0) { + $pstr .= "\n"; + } + $pstr .= ucfirst($p['type']) . " " . $p['name']; + if (isset($p['explicit']) && $p['explicit'] == 1) { + $pstr .= " (explicit)"; + } + } + } + $info[$key] = $pstr; + break; + } default: { $info[$key] = implode(", ", $info[$key]); break; diff --git a/pear/PEAR/Command/Remote.php b/pear/PEAR/Command/Remote.php index 85695fd104..b3f1e14315 100644 --- a/pear/PEAR/Command/Remote.php +++ b/pear/PEAR/Command/Remote.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Common.php b/pear/PEAR/Common.php index 94898fae6d..daab6ce8fa 100644 --- a/pear/PEAR/Common.php +++ b/pear/PEAR/Common.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -935,7 +935,11 @@ class PEAR_Common extends PEAR if (isset($pkginfo['provides'])) { foreach ($pkginfo['provides'] as $key => $what) { $ret .= "$indent \n"; + $ret .= "name=\"$what[name]\" "; + if (isset($what['extends'])) { + $ret .= "extends=\"$what[extends]\" "; + } + $ret .= "/>\n"; } } if (isset($pkginfo['filelist'])) { @@ -1175,6 +1179,10 @@ class PEAR_Common extends PEAR } $this->pkginfo['provides'][$key] = array('type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->pkginfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } } foreach ($srcinfo['declared_methods'] as $class => $methods) { foreach ($methods as $method) { @@ -1243,6 +1251,7 @@ class PEAR_Common extends PEAR $declared_methods = array(); $used_classes = array(); $used_functions = array(); + $extends = array(); $nodeps = array(); for ($i = 0; $i < sizeof($tokens); $i++) { if (is_array($tokens[$i])) { @@ -1273,6 +1282,7 @@ class PEAR_Common extends PEAR case T_CLASS: case T_FUNCTION: case T_NEW: + case T_EXTENDS: $look_for = $token; continue 2; case T_STRING: @@ -1280,6 +1290,8 @@ class PEAR_Common extends PEAR $current_class = $data; $current_class_level = $brace_level; $declared_classes[] = $current_class; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; } elseif ($look_for == T_FUNCTION) { if ($current_class) { $current_function = "$current_class::$data"; @@ -1319,6 +1331,7 @@ class PEAR_Common extends PEAR "declared_methods" => $declared_methods, "declared_functions" => $declared_functions, "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, ); } @@ -1344,6 +1357,7 @@ class PEAR_Common extends PEAR $decl_c = @array_merge($decl_c, $tmp['declared_classes']); $decl_f = @array_merge($decl_f, $tmp['declared_functions']); $decl_m = @array_merge($decl_m, $tmp['declared_methods']); + $inheri = @array_merge($inheri, $tmp['inheritance']); } $used_c = array_unique($used_c); $decl_c = array_unique($decl_c); @@ -1353,6 +1367,7 @@ class PEAR_Common extends PEAR 'declared_methods' => $decl_m, 'declared_functions' => $decl_f, 'undeclared_classes' => $undecl_c, + 'inheritance' => $inheri, ); } diff --git a/pear/PEAR/Config.php b/pear/PEAR/Config.php index 5059284b97..0358d7c8a2 100644 --- a/pear/PEAR/Config.php +++ b/pear/PEAR/Config.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Dependency.php b/pear/PEAR/Dependency.php index 22173ce625..b9c70ef318 100644 --- a/pear/PEAR/Dependency.php +++ b/pear/PEAR/Dependency.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | @@ -19,12 +19,6 @@ // // $Id$ -/** -* Methods for dependencies check. Based on Stig's dependencies RFC -* at http://cvs.php.net/cvs.php/pearweb/rfc -* (requires php >= 4.1) -*/ - require_once "PEAR.php"; define('PEAR_DEPENDENCY_MISSING', -1); @@ -33,15 +27,32 @@ define('PEAR_DEPENDENCY_UPGRADE_MINOR', -3); define('PEAR_DEPENDENCY_UPGRADE_MAJOR', -4); define('PEAR_DEPENDENCY_BAD_DEPENDENCY', -5); +/** + * Dependency check for PEAR packages + * + * The class is based on the dependency RFC that can be found at + * http://cvs.php.net/cvs.php/pearweb/rfc. It requires PHP >= 4.1 + * + * @author Tomas V.V.Vox + * @author Stig Bakken + */ class PEAR_Dependency { + /** + * Constructor + * + * @access public + * @param object Registry object + * @return void + */ function PEAR_Dependency(&$registry) { $this->registry = &$registry; } + /** - * This method maps the xml dependency definition to the - * PEAR_dependecy one + * This method maps the XML dependency definition to the + * corresponding one from PEAR_Dependency * * $opts => Array * ( @@ -50,6 +61,10 @@ class PEAR_Dependency * [version] => 3.4 * [name] => HTML_Common * ) + * + * @param string Error message + * @param array Options + * @return boolean */ function callCheckMethod(&$errmsg, $opts) { @@ -287,7 +302,12 @@ class PEAR_Dependency /** * Converts text comparing operators to them sign equivalents - * ex: 'ge' to '>=' + * + * Example: 'ge' to '>=' + * + * @access public + * @param string Operator + * @return string Sign equivalent */ function signOperator($operator) { @@ -303,7 +323,15 @@ class PEAR_Dependency } } - + /** + * Convert relation into corresponding code + * + * @access public + * @param string Relation + * @param string Version + * @param string Requirement + * @return integer + */ function codeFromRelation($relation, $version, $req) { $code = PEAR_DEPENDENCY_BAD_DEPENDENCY; @@ -325,5 +353,4 @@ class PEAR_Dependency return $code; } } - ?> diff --git a/pear/PEAR/Frontend/CLI.php b/pear/PEAR/Frontend/CLI.php index ba30702813..5213ea9c91 100644 --- a/pear/PEAR/Frontend/CLI.php +++ b/pear/PEAR/Frontend/CLI.php @@ -5,10 +5,10 @@ +----------------------------------------------------------------------+ | Copyright (c) 1997-2003 The PHP Group | +----------------------------------------------------------------------+ - | This source file is subject to version 2.02 of the PHP license, | + | This source file is subject to version 3.0 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | - | available at through the world-wide-web at | - | http://www.php.net/license/2_02.txt. | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | @@ -91,6 +91,9 @@ class PEAR_Frontend_CLI extends PEAR // }}} // {{{ displayError(eobj) + /** + * @param object PEAR_Error object + */ function displayError($eobj) { return $this->_displayLine($eobj->getMessage()); @@ -99,6 +102,9 @@ class PEAR_Frontend_CLI extends PEAR // }}} // {{{ displayFatalError(eobj) + /** + * @param object PEAR_Error object + */ function displayFatalError($eobj) { $this->displayError($eobj); diff --git a/pear/PEAR/Installer.php b/pear/PEAR/Installer.php index 6f77dbd8dc..615a9c98a3 100644 --- a/pear/PEAR/Installer.php +++ b/pear/PEAR/Installer.php @@ -5,16 +5,17 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Stig Bakken | // | Tomas V.V.Cox | +// | Martin Jansen | // +----------------------------------------------------------------------+ // // $Id$ @@ -40,6 +41,7 @@ define('PEAR_INSTALLER_SKIPPED', -1); * * @since PHP 4.0.2 * @author Stig Bakken + * @author Martin Jansen */ class PEAR_Installer extends PEAR_Common { @@ -115,7 +117,7 @@ class PEAR_Installer extends PEAR_Common parent::PEAR_Common(); $this->setFrontendObject($ui); $this->debug = $this->config->get('verbose'); - $this->registry = &new PEAR_Registry($this->config->get('php_dir')); + //$this->registry = &new PEAR_Registry($this->config->get('php_dir')); } // }}} @@ -487,12 +489,11 @@ class PEAR_Installer extends PEAR_Common $options['installroot'] = substr($options['installroot'], 0, -1); } $php_dir = $this->_prependPath($php_dir, $options['installroot']); - $this->registry = &new PEAR_Registry($php_dir); $this->installroot = $options['installroot']; } else { - $registry = &$this->registry; $this->installroot = ''; } + $this->registry = &new PEAR_Registry($php_dir); $need_download = false; // ==> XXX should be removed later on $flag_old_format = false; @@ -599,12 +600,18 @@ class PEAR_Installer extends PEAR_Common // Check dependencies ------------------------------------------- if (isset($pkginfo['release_deps']) && empty($options['nodeps'])) { - $error = $this->checkDeps($pkginfo); - if ($error) { + $dep_errors = ''; + $error = $this->checkDeps($pkginfo, $dep_errors); + if ($error == true) { + if (empty($options['soft'])) { + $this->log(0, substr($dep_errors, 1)); + } + return $this->raiseError("$pkgname: Dependencies failed"); + } else if (!empty($dep_errors)) { + // Print optional dependencies if (empty($options['soft'])) { - $this->log(0, $error); + $this->log(0, $dep_errors); } - return $this->raiseError("$pkgname: dependencies failed"); } } @@ -784,22 +791,38 @@ class PEAR_Installer extends PEAR_Common // }}} // {{{ checkDeps() - function checkDeps(&$pkginfo) + /** + * Check if the package meets all dependencies + * + * @param array Package information (passed by reference) + * @param string Error message (passed by reference) + * @return boolean False when no error occured, otherwise true + */ + function checkDeps(&$pkginfo, &$errors) { + if (empty($this->registry)) { + $this->registry = &new PEAR_Registry($this->config->get('php_dir')); + } $depchecker = &new PEAR_Dependency($this->registry); $error = $errors = ''; - $failed_deps = array(); + $failed_deps = $optional_deps = array(); if (is_array($pkginfo['release_deps'])) { foreach($pkginfo['release_deps'] as $dep) { $code = $depchecker->callCheckMethod($error, $dep); if ($code) { - $failed_deps[] = array($dep, $code, $error); + if (isset($dep['optional']) && $dep['optional'] == 'yes') { + // Ugly hack to adjust the error messages + $error = str_replace('requires ', '', $error); + $error = ucfirst($error); + $error = $error . ' is recommended to utilize some features.'; + $optional_deps[] = array($dep, $code, $error); + } else { + $failed_deps[] = array($dep, $code, $error); + } } } $n = count($failed_deps); if ($n > 0) { - $depinstaller =& new PEAR_Installer($this->ui); - $to_install = array(); for ($i = 0; $i < $n; $i++) { if (isset($failed_deps[$i]['type'])) { $type = $failed_deps[$i]['type']; @@ -824,7 +847,28 @@ class PEAR_Installer extends PEAR_Common break; } } - return substr($errors, 1); + return true; + } + + $count_optional = count($optional_deps); + if ($count_optional > 0) { + $errors = "Optional dependencies:"; + + for ($i = 0; $i < $count_optional; $i++) { + if (isset($optional_deps[$i]['type'])) { + $type = $optional_deps[$i]['type']; + } else { + $type = 'pkg'; + } + switch ($optional_deps[$i][1]) { + case PEAR_DEPENDENCY_MISSING: + case PEAR_DEPENDENCY_UPGRADE_MINOR: + default: + $errors .= "\n" . $optional_deps[$i][2]; + break; + } + } + return false; } } return false; diff --git a/pear/PEAR/Packager.php b/pear/PEAR/Packager.php index 69279c4465..507b9f6041 100644 --- a/pear/PEAR/Packager.php +++ b/pear/PEAR/Packager.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Registry.php b/pear/PEAR/Registry.php index 97102eb636..252b0e7f58 100644 --- a/pear/PEAR/Registry.php +++ b/pear/PEAR/Registry.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/PEAR/Remote.php b/pear/PEAR/Remote.php index 6b90b0c7da..b7e34911e3 100644 --- a/pear/PEAR/Remote.php +++ b/pear/PEAR/Remote.php @@ -5,10 +5,10 @@ // +----------------------------------------------------------------------+ // | Copyright (c) 1997-2003 The PHP Group | // +----------------------------------------------------------------------+ -// | This source file is subject to version 2.02 of the PHP license, | +// | This source file is subject to version 3.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/System.php b/pear/System.php index 1265da629c..8f5e5fae51 100644 --- a/pear/System.php +++ b/pear/System.php @@ -7,8 +7,8 @@ // +----------------------------------------------------------------------+ // | This source file is subject to version 2.0 of the PHP license, | // | that is bundled with this package in the file LICENSE, and is | -// | available at through the world-wide-web at | -// | http://www.php.net/license/2_02.txt. | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | // | If you did not receive a copy of the PHP license and are unable to | // | obtain it through the world-wide-web, please send a note to | // | license@php.net so we can mail you a copy immediately. | diff --git a/pear/package-PEAR.xml b/pear/package-PEAR.xml index ad739feae8..a9ec21d377 100644 --- a/pear/package-PEAR.xml +++ b/pear/package-PEAR.xml @@ -25,7 +25,7 @@ mj - helper + developer Martin Jansen mj@php.net diff --git a/pear/package.dtd b/pear/package.dtd index 9dfb7cba1f..2515b738c2 100644 --- a/pear/package.dtd +++ b/pear/package.dtd @@ -1,5 +1,5 @@