diff options
author | Stig Bakken <ssb@php.net> | 2001-08-28 11:41:13 +0000 |
---|---|---|
committer | Stig Bakken <ssb@php.net> | 2001-08-28 11:41:13 +0000 |
commit | 28caf732a7a29f97f41905e59cfec9014864b178 (patch) | |
tree | 3f9ce6e9b1587350b09de5aa2c1e15096aaf3f28 | |
parent | 513874acc7d0c4841d4b2d279b8d81f56248798f (diff) | |
download | php-git-28caf732a7a29f97f41905e59cfec9014864b178.tar.gz |
* MFH PEAR stuff
* copied in Archive_Tar class from pear/Archive_Tar
-rw-r--r-- | pear/Archive/Tar.php | 880 | ||||
-rw-r--r-- | pear/CODING_STANDARDS | 250 | ||||
-rw-r--r-- | pear/Makefile.in | 7 | ||||
-rw-r--r-- | pear/PEAR.php | 2 | ||||
-rw-r--r-- | pear/PEAR/Common.php | 182 | ||||
-rw-r--r-- | pear/PEAR/Installer.php | 12 | ||||
-rw-r--r-- | pear/PEAR/Packager.php | 17 | ||||
-rw-r--r-- | pear/PEAR/WebInstaller.php | 26 | ||||
-rw-r--r-- | pear/package.dtd | 111 | ||||
-rw-r--r-- | pear/scripts/pearize.in | 115 |
10 files changed, 1196 insertions, 406 deletions
diff --git a/pear/Archive/Tar.php b/pear/Archive/Tar.php new file mode 100644 index 0000000000..3c6759bae5 --- /dev/null +++ b/pear/Archive/Tar.php @@ -0,0 +1,880 @@ +<?php +/* vim: set ts=4 sw=4: */ +// +----------------------------------------------------------------------+ +// | PHP version 4.0 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2001 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 2.02 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. | +// | 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: Vincent Blavet <vincent@blavet.net> | +// +----------------------------------------------------------------------+ +// +// $Id$ + +require_once 'PEAR.php'; + +class Archive_Tar extends PEAR +{ + var $_tarname; + var $_compress; + + // ----- File descriptor (when file is opened or 0 if closed) + var $_file; + + // {{{ constructor + function Archive_Tar($p_tarname, $p_compress = false) + { + $this->PEAR(); + $this->_tarname = $p_tarname; + $this->_compress = $p_compress; + } + // }}} + +/* + // {{{ constructor + function Archive_Tar($p_tarname, $p_filelist, $p_compress = false) + { + $this->PEAR(); + $this->_tarname = $p_tarname; + $this->_compress = $p_compress; + + if (!$this->create($p_filelist)) + return 0; + } + // }}} +*/ + + // {{{ destructor + function _Archive_Tar() + { + $this->_close(); + $this->_PEAR(); + } + // }}} + + // {{{ create() + function create($p_filelist) + { + return $this->createModify($p_filelist, "", ""); + } + // }}} + + // {{{ add() + function add($p_filelist) + { + return $this->addModify($p_filelist, "", ""); + } + // }}} + + // {{{ extract() + function extract($p_path="") + { + return $this->extractModify($p_path, ""); + } + // }}} + + // {{{ listContent() + function listContent() + { + $v_list_detail = array(); + + if ($this->_openRead()) { + if (!$this->_extractList("", $v_list_detail, "list", "", "")) { + unset($v_list_detail); + return(0); + } + $this->_close(); + } + + return $v_list_detail; + } + // }}} + + // {{{ createModify() + function createModify($p_filelist, $p_add_dir, $p_remove_dir="") + { + $v_result = true; + + if (!$this->_openWrite()) + return false; + + if ($p_filelist != "") { + if (is_array($p_filelist)) + $v_list = $p_filelist; + elseif (is_string($p_filelist)) + $v_list = explode(" ", $p_filelist); + else { + $this->_cleanFile(); + $this->_error("Invalid file list"); + return false; + } + + $v_result = $this->_addList($v_list, "", ""); + } + + if ($v_result) { + $this->_writeFooter(); + $this->_close(); + } else + $this->_cleanFile(); + + return $v_result; + } + // }}} + + // {{{ addModify() + function addModify($p_filelist, $p_add_dir, $p_remove_dir="") + { + $v_result = true; + + if (!@is_file($this->_tarname)) + $v_result = $this->createModify($p_filelist, $p_add_dir, $p_remove_dir); + else { + if (is_array($p_filelist)) + $v_list = $p_filelist; + elseif (is_string($p_filelist)) + $v_list = explode(" ", $p_filelist); + else { + $this->_error("Invalid file list"); + return false; + } + + $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir); + } + + return $v_result; + } + // }}} + + // {{{ extractModify() + function extractModify($p_path, $p_remove_path) + { + $v_result = true; + $v_list_detail = array(); + + if ($v_result = $this->_openRead()) { + $v_result = $this->_extractList($p_path, $v_list_detail, "complete", 0, $p_remove_path); + $this->_close(); + } + + return $v_result; + } + // }}} + + // {{{ extractList() + function extractList($p_filelist, $p_path="", $p_remove_path="") + { + $v_result = true; + $v_list_detail = array(); + + if (is_array($p_filelist)) + $v_list = $p_filelist; + elseif (is_string($p_filelist)) + $v_list = explode(" ", $p_filelist); + else { + $this->_error("Invalid string list"); + return false; + } + + if ($v_result = $this->_openRead()) { + $v_result = $this->_extractList($p_path, $v_list_detail, "complete", $v_list, $p_remove_path); + $this->_close(); + } + + return $v_result; + } + // }}} + + // {{{ _error() + function _error($p_message) + { + // ----- To be completed + $this->raiseError($p_message); + } + // }}} + + // {{{ _warning() + function _warning($p_message) + { + // ----- To be completed + $this->raiseError($p_message); + } + // }}} + + // {{{ _openWrite() + function _openWrite() + { + if ($this->_compress) + $this->_file = @gzopen($this->_tarname, "w"); + else + $this->_file = @fopen($this->_tarname, "w"); + + if ($this->_file == 0) { + $this->_error("Unable to open in write mode '".$this->_tarname."'"); + return false; + } + + return true; + } + // }}} + + // {{{ _openRead() + function _openRead() + { + if ($this->_compress) + $this->_file = @gzopen($this->_tarname, "rb"); + else + $this->_file = @fopen($this->_tarname, "rb"); + + if ($this->_file == 0) { + $this->_error("Unable to open in read mode '".$this->_tarname."'"); + return false; + } + + return true; + } + // }}} + + // {{{ _openReadWrite() + function _openReadWrite() + { + if ($this->_compress) + $this->_file = @gzopen($this->_tarname, "r+b"); + else + $this->_file = @fopen($this->_tarname, "r+b"); + + if ($this->_file == 0) { + $this->_error("Unable to open in read/write mode '".$this->_tarname."'"); + return false; + } + + return true; + } + // }}} + + // {{{ _close() + function _close() + { + if ($this->_file) { + if ($this->_compress) + @gzclose($this->_file); + else + @fclose($this->_file); + + $this->_file = 0; + } + + return true; + } + // }}} + + // {{{ _cleanFile() + function _cleanFile() + { + _close(); + @unlink($this->tarname); + + 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); + } + return true; + } + // }}} + + // {{{ _addList() + function _addList($p_list, $p_add_dir, $p_remove_dir) + { + $v_result=true; + $v_header = array(); + + if (!$this->_file) { + $this->_error("Invalid file descriptor"); + return false; + } + + if (sizeof($p_list) == 0) + return true; + + for ($j=0; ($j<count($p_list)) && ($v_result); $j++) { + $v_filename = $p_list[$j]; + + // ----- Skip the current tar name + if ($v_filename == $this->_tarname) + continue; + + if ($v_filename == "") + continue; + + if (!file_exists($v_filename)) { + $this->_warning("File '$v_filename' does not exist"); + continue; + } + + // ----- Add the file or directory header + if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) + return false; + + if (is_dir($v_filename)) { + if (!($p_hdir = opendir($v_filename))) { + $this->_warning("Directory '$v_filename' can not be read"); + continue; + } + $p_hitem = readdir($p_hdir); // '.' directory + $p_hitem = readdir($p_hdir); // '..' directory + while ($p_hitem = readdir($p_hdir)) { + if ($v_filename != ".") + $p_temp_list[0] = $v_filename."/".$p_hitem; + else + $p_temp_list[0] = $p_hitem; + + $v_result = $this->_addList($p_temp_list, $p_add_dir, $p_remove_dir); + } + + unset($p_temp_list); + unset($p_hdir); + unset($p_hitem); + } + } + + return $v_result; + } + // }}} + + // {{{ _addFile() + function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir) + { + if (!$this->_file) { + $this->_error("Invalid file descriptor"); + return false; + } + + if ($p_filename == "") { + $this->_error("Invalid file name"); + return false; + } + + // ----- Calculate the stored filename + $v_stored_filename = $p_filename; + if ($p_remove_dir != "") { + if (substr($p_remove_dir, -1) != '/') + $p_remove_dir .= "/"; + + if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) + $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); + } + if ($p_add_dir != "") { + if (substr($p_add_dir, -1) == "/") + $v_stored_filename = $p_add_dir.$v_stored_filename; + else + $v_stored_filename = $p_add_dir."/".$v_stored_filename; + } + + if (strlen($v_stored_filename) > 99) { + $this->_warning("Stored file name is too long (max. 99) : '$v_stored_filename'"); + fclose($v_file); + return true; + } + + if (is_file($p_filename)) { + if (($v_file = @fopen($p_filename, "rb")) == 0) { + $this->_warning("Unable to open file '$p_filename' in binary read mode"); + return true; + } + + if (!$this->_writeHeader($p_filename, $v_stored_filename)) + return false; + + 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); + } + + fclose($v_file); + + } else { + // ----- Only header for dir + if (!$this->_writeHeader($p_filename, $v_stored_filename)) + return false; + } + + return true; + } + // }}} + + // {{{ _writeHeader() + function _writeHeader($p_filename, $p_stored_filename) + { + if ($p_stored_filename == "") + $p_stored_filename = $p_filename; + $v_reduce_filename = $this->_pathReduction($p_stored_filename); + + $v_info = stat($p_filename); + $v_uid = sprintf("%6s ", DecOct($v_info[4])); + $v_gid = sprintf("%6s ", DecOct($v_info[5])); + $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename))); + + clearstatcache(); + $v_size = sprintf("%11s ", DecOct(filesize($p_filename))); + + $v_mtime = sprintf("%11s", DecOct(filemtime($p_filename))); + + if (is_dir($p_filename)) + $v_typeflag = "5"; + else + $v_typeflag = ""; + + $v_linkname = ""; + + $v_magic = ""; + + $v_version = ""; + + $v_uname = ""; + + $v_gname = ""; + + $v_devmajor = ""; + + $v_devminor = ""; + + $v_prefix = ""; + + $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); + $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $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 + if ($this->_compress) + @gzputs($this->_file, $v_binary_data_first, 148); + else + @fputs($this->_file, $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); + + // ----- 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); + + return true; + } + // }}} + + // {{{ _readHeader() + function _readHeader($v_binary_data, &$v_header) + { + if (strlen($v_binary_data)==0) { + $v_header[filename] = ""; + return true; + } + + if (strlen($v_binary_data) != 512) { + $v_header[filename] = ""; + $this->_error("Invalid block size : ".strlen($v_binary_data)); + return false; + } + + // ----- Calculate the checksum + $v_checksum = 0; + // ..... First part of the header + for ($i=0; $i<148; $i++) + $v_checksum+=ord(substr($v_binary_data,$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; $i<512; $i++) + $v_checksum+=ord(substr($v_binary_data,$i,1)); + + $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data); + + // ----- Extract the checksum + $v_header[checksum] = OctDec(trim($v_data[checksum])); + if ($v_header[checksum] != $v_checksum) { + $v_header[filename] = ""; + + // ----- Look for last block (empty block) + if (($v_checksum == 256) && ($v_header[checksum] == 0)) + return true; + + $this->_error("Invalid checksum : $v_checksum calculated, ".$v_header[checksum]." expected"); + return false; + } + + // ----- Extract the properties + $v_header[filename] = trim($v_data[filename]); + $v_header[mode] = OctDec(trim($v_data[mode])); + $v_header[uid] = OctDec(trim($v_data[uid])); + $v_header[gid] = OctDec(trim($v_data[gid])); + $v_header[size] = OctDec(trim($v_data[size])); + $v_header[mtime] = OctDec(trim($v_data[mtime])); + $v_header[typeflag] = $v_data[typeflag]; + /* ----- All these fields are removed form the header because they do not carry interesting info + $v_header[link] = trim($v_data[link]); + $v_header[magic] = trim($v_data[magic]); + $v_header[version] = trim($v_data[version]); + $v_header[uname] = trim($v_data[uname]); + $v_header[gname] = trim($v_data[gname]); + $v_header[devmajor] = trim($v_data[devmajor]); + $v_header[devminor] = trim($v_data[devminor]); + */ + + return true; + } + // }}} + + // {{{ _extractList() + function _extractList($p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path) + { + $v_result=true; + $v_nb = 0; + $v_extract_all = true; + $v_listing = false; + + if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../"))) + $p_path = "./".$p_path; + + // ----- Look for path to remove format (should end by /) + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) + $p_remove_path .= '/'; + $p_remove_path_size = strlen($p_remove_path); + + switch ($p_mode) { + case "complete" : + $v_extract_all = TRUE; + $v_listing = FALSE; + break; + case "partial" : + $v_extract_all = FALSE; + $v_listing = FALSE; + break; + case "list" : + $v_extract_all = FALSE; + $v_listing = TRUE; + break; + default : + $this->_error("Invalid extract mode ($p_mode)"); + return false; + } + + clearstatcache(); + + While (!($v_end_of_file = ($this->_compress?@gzeof($this->_file):@feof($this->_file)))) + { + $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; + + if ($v_header[filename] == "") + continue; + + if ((!$v_extract_all) && (is_array($p_file_list))) { + // ----- By default no unzip if the file is not found + $v_extract_file = false; + + for ($i=0; $i<sizeof($p_file_list); $i++) { + // ----- Look if it is a directory + if (substr($p_file_list[$i], -1) == "/") { + // ----- Look if the directory is in the filename path + if ((strlen($v_header[filename]) > strlen($p_file_list[$i])) && (substr($v_header[filename], 0, strlen($p_file_list[$i])) == $p_file_list[$i])) { + $v_extract_file = TRUE; + break; + } + } + + // ----- It is a file, so compare the file names + elseif ($p_file_list[$i] == $v_header[filename]) { + $v_extract_file = TRUE; + break; + } + } + } else { + $v_extract_file = TRUE; + } + + // ----- Look if this file need to be extracted + if (($v_extract_file) && (!$v_listing)) + { + if (($p_remove_path != "") + && (substr($v_header[filename], 0, $p_remove_path_size) == $p_remove_path)) + $v_header[filename] = substr($v_header[filename], $p_remove_path_size); + + if (($p_path != "./") && ($p_path != "/")) { + while (substr($p_path, -1) == "/") + $p_path = substr($p_path, 0, strlen($p_path)-1); + + if (substr($v_header[filename], 0, 1) == "/") + $v_header[filename] = $p_path.$v_header[filename]; + else + $v_header[filename] = $p_path."/".$v_header[filename]; + } + + if (file_exists($v_header[filename])) { + if ((is_dir($v_header[filename])) && ($v_header[typeflag] == "")) { + $this->_error("File '$v_header[filename]' already exists as a directory"); + return false; + } + if ((is_file($v_header[filename])) && ($v_header[typeflag] == "5")) { + $this->_error("Directory '$v_header[filename]' already exists as a file"); + return false; + } + if (!is_writeable($v_header[filename])) { + $this->_error("File '$v_header[filename]' already exists and is write protected"); + return false; + } + if (filemtime($v_header[filename]) > $v_header[mtime]) { + // To be completed : An error or silent no replace ? + } + } + + // ----- Check the directory availability and create it if necessary + elseif (($v_result = $this->_dirCheck(($v_header[typeflag] == "5"?$v_header[filename]:dirname($v_header[filename])))) != 1) { + $this->_error("Unable to create path for '$v_header[filename]'"); + return false; + } + + if ($v_extract_file) { + if ($v_header[typeflag] == "5") { + if (!@file_exists($v_header[filename])) { + if (!@mkdir($v_header[filename], 0777)) { + $this->_error("Unable to create directory '".$v_header[filename]."'"); + return false; + } + } + } else { + if (($v_dest_file = @fopen($v_header[filename], "wb")) == 0) { + $this->_error("Error while opening '$v_header[filename]' in write binary mode"); + return false; + } 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); + 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); + fwrite($v_dest_file, $v_content, ($v_header[size] % 512)); + } + + @fclose($v_dest_file); + + // ----- Change the file mode, mtime + @touch($v_header[filename], $v_header[mtime]); + // To be completed + //chmod($v_header[filename], DecOct($v_header[mode])); + } + + // ----- Check the file size + if (filesize($v_header[filename]) != $v_header[size]) { + $this->_error("Extracted file '$v_header[filename]' does not have the correct file size '".filesize($v_filename)."' ('$v_header[size]' expected). Archive may be corrupted."); + return false; + } + } + } 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)); + } + } 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)); + } + + 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 + if (($v_file_dir = dirname($v_header[filename])) == $v_header[filename]) + $v_file_dir = ""; + if ((substr($v_header[filename], 0, 1) == "/") && ($v_file_dir == "")) + $v_file_dir = "/"; + + $p_list_detail[$v_nb++] = $v_header; + } + } + + return true; + } + // }}} + + // {{{ _append() + function _append($p_filelist, $p_add_dir="", $p_remove_dir="") + { + if ($this->_compress) { + $this->_close(); + + if (!@rename($this->_tarname, $this->_tarname.".tmp")) { + $this->_error("Error while renaming '".$this->_tarname."' to temporary file '".$this->_tarname.".tmp'"); + return false; + } + + if (($v_temp_tar = @gzopen($this->_tarname.".tmp", "rb")) == 0) { + $this->_error("Unable to open file '".$this->_tarname.".tmp' in binary read mode"); + @rename($this->_tarname.".tmp", $this->_tarname); + return false; + } + + if (!$this->_openWrite()) { + @rename($this->_tarname.".tmp", $this->_tarname); + return false; + } + + $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); + + } while (!@gzeof($v_temp_tar)); + } + + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) + $this->_writeFooter(); + + $this->_close(); + @gzclose($v_temp_tar); + + if (!@unlink($this->_tarname.".tmp")) { + $this->_error("Error while deleting temporary file '".$this->_tarname.".tmp'"); + } + + return true; + } + + // ----- For not compressed tar, just add files before the last 512 bytes block + if (!$this->_openReadWrite()) + return false; + + $v_size = filesize($this->_tarname); + fseek($this->_file, $v_size-512); + + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) + $this->_writeFooter(); + + $this->_close(); + + return true; + } + // }}} + + // {{{ _dirCheck() + function _dirCheck($p_dir) + { + if ((is_dir($p_dir)) || ($p_dir == "")) + return true; + + $p_parent_dir = dirname($p_dir); + + if (($p_parent_dir != $p_dir) && + ($p_parent_dir != "") && + (!$this->_dirCheck($p_parent_dir))) + return false; + + if (!@mkdir($p_dir, 0777)) { + $this->_error("Unable to create directory '$p_dir'"); + return false; + } + + return true; + } + // }}} + + // {{{ _pathReduction() + function _pathReduction($p_dir) + { + $v_result = ""; + + // ----- Look for not empty path + if ($p_dir != "") { + // ----- Explode path by directory names + $v_list = explode("/", $p_dir); + + // ----- Study directories from last to first + for ($i=sizeof($v_list)-1; $i>=0; $i--) { + // ----- Look for current path + if ($v_list[$i] == ".") { + // ----- Ignore this directory + // Should be the first $i=0, but no check is done + } + else if ($v_list[$i] == "..") { + // ----- Ignore it and ignore the $i-1 + $i--; + } + else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0)) { + // ----- Ignore only the double '//' in path, + // but not the first and last '/' + } else { + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); + } + } + } + return $v_result; + } + // }}} + +} +?>
\ No newline at end of file diff --git a/pear/CODING_STANDARDS b/pear/CODING_STANDARDS index b9dd40f100..fc0b7dd064 100644 --- a/pear/CODING_STANDARDS +++ b/pear/CODING_STANDARDS @@ -4,251 +4,5 @@ $Id$ -------------- -[1] Indenting -============= - -Use an indent of 4 spaces, with no tabs. If you use Emacs to edit PEAR -code, you should set indent-tabs-mode to nil. Here is an example mode -hook that will set up Emacs according to these guidelines (you will -need to ensure that it is called when you are editing php files): - -(defun php-mode-hook () - (setq tab-width 4 - c-basic-offset 4 - c-hanging-comment-ender-p nil - indent-tabs-mode - (not - (and (string-match "/\\(PEAR\\|pear\\)/" (buffer-file-name)) - (string-match "\.php$" (buffer-file-name)))))) - -Here are vim rules for the same thing: - - set expandtab - set shiftwidth=4 - set tabstop=4 - - ----------------------- -[2] Control Structures -====================== - -These include if, for, while, switch, etc. Here is an example if statement, -since it is the most complicated of them: - - if ((condition1) || (condition2)) { - action1; - } elseif ((condition3) && (condition4)) { - action2; - } else { - defaultaction; - } - -Control statements should have one space between the control keyword -and opening parenthesis, to distinguish them from function calls. - -You are strongly encouraged to always use curly braces even in -situations where they are technically optional. Having them increases -readability and decreases the likelihood of logic errors being -introduced when new lines are added. - -For switch statements: - - switch (condition) { - case 1: - action1; - break; - - case 2: - action2; - break; - - default: - defaultaction; - break; - - } - - ------------------- -[3] Function Calls -================== - -Functions should be called with no spaces between the function name, -the opening parenthesis, and the first parameter; spaces between commas -and each parameter, and no space between the last parameter, the -closing parenthesis, and the semicolon. Here's an example: - - $var = foo($bar, $baz, $quux); - -As displayed above, there should be one space on either side of an -equals sign used to assign the return value of a function to a -variable. In the case of a block of related assignments, more space -may be inserted to promote readability: - - $short = foo($bar); - $long_variable = foo($baz); - - ------------------------- -[4] Function Definitions -======================== - -Function declaractions follow the "one true brace" convention: - -function fooFunction($arg1, $arg2 = '') -{ - if (condition) { - statement; - } - return $val; -} - -Arguments with default values go at the end of the argument list. -Always attempt to return a meaningful value from a function if one is -appropriate. Here is a slightly longer example: - -function connect(&$dsn, $persistent = false) -{ - if (is_array($dsn)) { - $dsninfo = &$dsn; - } else { - $dsninfo = DB::parseDSN($dsn); - } - - if (!$dsninfo || !$dsninfo['phptype']) { - return $this->raiseError(); - } - - return true; -} - -Functions should be named using the "studly caps" style (also referred to as -"bumpy case" or "camel caps"). The initial letter of the name is lowercase, -and each letter that starts a new "word" is capitalized. Some examples: - - connect() getData() buildSomeWidget() - -Private class members (meaning class members that an intented to be used -only from within the same class in which they are declared; PHP does not yet -support truly-enforceable private namespaces) are preceeded by a single -underscore. For example: - - _sort() _initTree() $_status - - ------------- -[5] Comments -============ - -Inline documentation for classes should follow the PHPDoc convention, similar -to Javadoc. More information about PHPDoc can be found here: - - http://www.phpdoc.de/ - -Non-documentation comments are strongly encouraged. A general rule of -thumb is that if you look at a section of code and think "Wow, I don't -want to try and describe that", you need to comment it before you -forget how it works. - -C++ style comments (/* */) and standard C comments (// ) are both -fine. Use of perl/shell style comments (# ) is discouraged. - - ------------------- -[6] Including Code -================== - -Anywhere you are unconditionally including a class file, use -require_once. Anywhere you are conditionally including a class file -(for example, factory methods), use include_once. Either of these will -ensure that class files are included only once. They share the same -file list, so you don't need to worry about mixing them - a file -included with require_once will not be included again by include_once. - -Note: include_once and require_once are statements, not functions. You -don't need parentheses around the filename to be included. - - ------------------ -[7] PHP Code Tags -================= - -ALWAYS use <?php ?> to delimit PHP code, not the <? ?> shorthand. -This is required for PEAR compliance and is also the most portable way -to include PHP code on differing operating systems and setups. - - -------------------------- -[8] Header Comment Blocks -========================= - -All source code files in the core PEAR distribution should contain the -following comment block as the header: - -/* vim: set expandtab tabstop=4 shiftwidth=4: */ -// +----------------------------------------------------------------------+ -// | PHP version 4.0 | -// +----------------------------------------------------------------------+ -// | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group | -// +----------------------------------------------------------------------+ -// | 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. | -// | 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: Original Author <author@example.com> | -// | Your Name <you@example.com> | -// +----------------------------------------------------------------------+ -// -// $Id$ - -There's no hard rule to determine when a new code contributer should be -added to the list of authors for a given source file. In general, their -changes should fall into the "substantial" category (meaning somewhere -around 10% to 20% of code changes). Exceptions could be made for rewriting -functions or contributing new logic. - -Simple code reorganization or bug fixes would not justify the addition of a -new individual to the list of authors. - -Files not in the core PEAR repository should have a similar block -stating the copyright, the license, and the authors. All files should -include the modeline comments to encourage consistency. - - ------------- -[9] CVS Tags -============ - -Include the <dollar>Id CVS vendor tag in each file. As each -file is edited, add this tag if it's not yet present (or replace existing -forms such as "Last Modified:", etc.). - -[NOTE: we have a custom $Horde tag in Horde cvs to track our versions -seperately; we could do the same and make a $PEAR tag, that would remain even -if PEAR files were put into another source control system, etc...] - - ------------------ -[10] Example URLs -================= - -Use "example.com" for all example URLs, per RFC 2606. - - ---------------------- -[11] Naming Constants -===================== - -Constants should always be uppercase, with underscores to seperate -words. Prefix constant names with the name of the class/package they -are used in. For example, the constants used by the DB:: package all -begin with "DB_". - -True and false are built in to the php language and behave like -constants, but should be written in lowercase to distinguish them from -user-defined constants. +This document is no longer maintained, see +http://php.net/manual/en/pear.standards.php instead. diff --git a/pear/Makefile.in b/pear/Makefile.in index 251831244b..3ef71a79c2 100644 --- a/pear/Makefile.in +++ b/pear/Makefile.in @@ -10,6 +10,7 @@ include $(top_srcdir)/build/rules.mk peardir=$(PEAR_INSTALLDIR) PEAR_SUBDIRS = \ + Archive \ Benchmark \ Cache \ Cache/Container \ @@ -32,6 +33,7 @@ PEAR_SUBDIRS = \ XML PEAR_FILES = \ + Archive/Tar.php \ Benchmark/Iterate.php \ Benchmark/Timer.php \ Cache.php \ @@ -138,7 +140,7 @@ BUILD_FILES = \ dynlib.m4 \ acinclude.m4 -bin_SCRIPTS = phpize php-config pear pearize +bin_SCRIPTS = phpize php-config pear pearize phptar install-build: $(mkinstalldirs) $(INSTALL_ROOT)$(phpbuilddir) $(INSTALL_ROOT)$(bindir) && \ @@ -183,6 +185,9 @@ scripts/pear: scripts/pear.in $(top_builddir)/config.status scripts/phpize: scripts/phpize.in $(top_builddir)/config.status (cd ..;CONFIG_FILES=pear/scripts/phpize CONFIG_HEADERS= $(top_builddir)/config.status) +scripts/phptar: scripts/phptar.in $(top_builddir)/config.status + (cd ..;CONFIG_FILES=pear/scripts/phptar CONFIG_HEADERS= $(top_builddir)/config.status) + scripts/pearize: scripts/pearize.in $(top_builddir)/config.status (cd ..;CONFIG_FILES=pear/scripts/pearize CONFIG_HEADERS= $(top_builddir)/config.status) diff --git a/pear/PEAR.php b/pear/PEAR.php index 16172f86c7..c1f8256f11 100644 --- a/pear/PEAR.php +++ b/pear/PEAR.php @@ -366,7 +366,7 @@ class PEAR $message = $message->getMessage(); } - if (sizeof($this->_expected_errors) > 0 && in_array($code, end($this->_expected_errors))) { + if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && in_array($code, end($this->_expected_errors))) { $mode = PEAR_ERROR_RETURN; } diff --git a/pear/PEAR/Common.php b/pear/PEAR/Common.php index 15ddf8fe80..584eb42d2b 100644 --- a/pear/PEAR/Common.php +++ b/pear/PEAR/Common.php @@ -14,6 +14,7 @@ // | license@php.net so we can mail you a copy immediately. | // +----------------------------------------------------------------------+ // | Authors: Stig Bakken <ssb@fast.no> | +// | Tomas V.V.Cox <cox@idecnet.com> | // | | // +----------------------------------------------------------------------+ // @@ -26,7 +27,7 @@ require_once 'PEAR.php'; * - check in inforFromDescFile that the minimal data needed is present * (pack name, version, files, others?) * - perhaps use parser folding to be less restrictive with the format - of the package.xml file +* of the package.xml file */ class PEAR_Common extends PEAR { @@ -47,6 +48,16 @@ class PEAR_Common extends PEAR /** assoc with information about a package */ var $pkginfo = array(); + /** + * Permitted maintainer roles + * @var array + */ + var $maintainer_roles = array('lead','developer','contributor','helper'); + /** + * Permitted release states + * @var array + */ + var $releases_states = array('alpha','beta','stable','snapshot'); // }}} // {{{ constructor @@ -119,25 +130,50 @@ class PEAR_Common extends PEAR { array_push($this->element_stack, $name); $this->current_element = $name; + $this->prev_element = $this->element_stack[sizeof($this->element_stack)-2]; $this->current_attributes = $attribs; switch ($name) { - case 'Dir': + case 'DIR': if (isset($this->dir_names)) { - $this->dir_names[] = $attribs['Name']; + $this->dir_names[] = $attribs['NAME']; } else { // Don't add the root dir $this->dir_names = array(); } - if (isset($attribs['BaseInstallDir'])) { - $this->dir_install = $attribs['BaseInstallDir']; + if (isset($attribs['BASEINSTALLDIR'])) { + $this->dir_install = $attribs['BASEINSTALLDIR']; } - if (isset($attribs['Role'])) { - $this->dir_role = $attribs['Role']; + if (isset($attribs['ROLE'])) { + $this->dir_role = $attribs['ROLE']; } break; - case 'LibFile': + case 'LIBFILE': $this->lib_atts = $attribs; - $this->lib_atts['Role'] = 'extension'; + $this->lib_atts['ROLE'] = 'extension'; + break; + case 'MAINTAINERS': + $this->pkginfo['maintainers'] = array(); + $this->m_i = 0; // maintainers array index + break; + case 'MAINTAINER': + // compatibility check + if (!isset($this->pkginfo['maintainers'])) { + $this->pkginfo['maintainers'] = array(); + $this->m_i = 0; + } + $this->pkginfo['maintainers'][$this->m_i] = array(); + $this->current_maintainer =& $this->pkginfo['maintainers'][$this->m_i]; + break; + case 'CHANGELOG': + $this->pkginfo['changelog'] = array(); + $this->c_i = 0; // changelog array index + $this->in_changelog = true; + break; + case 'RELEASE': + if ($this->in_changelog) { + $this->pkginfo['changelog'][$this->c_i] = array(); + $this->current_release =& $this->pkginfo['changelog'][$this->c_i]; + } break; } } @@ -148,12 +184,12 @@ class PEAR_Common extends PEAR function _element_end($xp, $name) { switch ($name) { - case 'Dir': + case 'DIR': array_pop($this->dir_names); unset($this->dir_install); unset($this->dir_role); break; - case 'File': + case 'FILE': $path = ''; foreach ($this->dir_names as $dir) { $path .= $dir . DIRECTORY_SEPARATOR; @@ -161,17 +197,17 @@ class PEAR_Common extends PEAR $path .= $this->current_file; $this->filelist[$path] = $this->current_attributes; // Set the baseinstalldir only if the file don't have this attrib - if (!isset($this->filelist[$path]['BaseInstallDir']) && + if (!isset($this->filelist[$path]['BASEINSTALLDIR']) && isset($this->dir_install)) { - $this->filelist[$path]['BaseInstallDir'] = $this->dir_install; + $this->filelist[$path]['BASEINSTALLDIR'] = $this->dir_install; } // Set the Role - if (!isset($this->filelist[$path]['Role']) && isset($this->dir_role)) { - $this->filelist[$path]['Role'] = $this->dir_role; + if (!isset($this->filelist[$path]['ROLE']) && isset($this->dir_role)) { + $this->filelist[$path]['ROLE'] = $this->dir_role; } break; - case 'LibFile': + case 'LIBFILE': $path = ''; foreach ($this->dir_names as $dir) { $path .= $dir . DIRECTORY_SEPARATOR; @@ -179,10 +215,10 @@ class PEAR_Common extends PEAR $path .= $this->lib_name; $this->filelist[$path] = $this->lib_atts; // Set the baseinstalldir only if the file don't have this attrib - if (!isset($this->filelist[$path]['BaseInstallDir']) && + if (!isset($this->filelist[$path]['BASEINSTALLDIR']) && isset($this->dir_install)) { - $this->filelist[$path]['BaseInstallDir'] = $this->dir_install; + $this->filelist[$path]['BASEINSTALLDIR'] = $this->dir_install; } if (isset($this->lib_sources)) { $this->filelist[$path]['sources'] = $this->lib_sources; @@ -190,6 +226,16 @@ class PEAR_Common extends PEAR unset($this->lib_atts); unset($this->lib_sources); break; + case 'MAINTAINER': + $this->m_i++; + break; + case 'RELEASE': + if ($this->in_changelog) { + $this->c_i++; + } + break; + case 'CHANGELOG': + $this->in_changelog = false; } array_pop($this->element_stack); $this->current_element = $this->element_stack[sizeof($this->element_stack)-1]; @@ -200,51 +246,73 @@ class PEAR_Common extends PEAR function _pkginfo_cdata($xp, $data) { - $prev = $this->element_stack[sizeof($this->element_stack)-2]; switch ($this->current_element) { - case 'Name': - switch ($prev) { - case 'Package': + case 'NAME': + switch ($this->prev_element) { + case 'PACKAGE': $this->pkginfo['package'] .= $data; break; - case 'Maintainer': - $this->pkginfo['maintainer_name'] .= $data; + case 'MAINTAINER': + $this->current_maintainer['name'] .= $data; break; } break; - case 'Summary': + case 'SUMMARY': $this->pkginfo['summary'] .= $data; break; - case 'Initials': - $this->pkginfo['maintainer_handle'] .= $data; + case 'INITIALS': + $this->current_maintainer['handle'] .= $data; break; - case 'Email': - $this->pkginfo['maintainer_email'] .= $data; + case 'EMAIL': + $this->current_maintainer['email'] .= $data; break; - case 'Version': - $this->pkginfo['version'] .= $data; + case 'ROLE': + if (!in_array($data, $this->maintainer_roles)) { + trigger_error("The maintainer role: '$data' is not valid", E_USER_WARNING); + } else { + $this->current_maintainer['role'] .= $data; + } break; - case 'Date': - $this->pkginfo['release_date'] .= $data; + case 'VERSION': + if ($this->in_changelog) { + $this->current_release['version'] .= $data; + } else { + $this->pkginfo['version'] .= $data; + } break; - case 'Notes': - $this->pkginfo['release_notes'] .= $data; + case 'DATE': + if ($this->in_changelog) { + $this->current_release['release_date'] .= $data; + } else { + $this->pkginfo['release_date'] .= $data; + } + break; + case 'NOTES': + if ($this->in_changelog) { + $this->current_release['release_notes'] .= $data; + } else { + $this->pkginfo['release_notes'] .= $data; + } break; - case 'Dir': - if (!$this->phpdir) { - break; + case 'STATE': + if (!in_array($data, $this->releases_states)) { + trigger_error("The release state: '$data' is not valid", E_USER_WARNING); + } elseif ($this->in_changelog) { + $this->current_release['release_state'] = $data; + } else { + $this->pkginfo['release_state'] .= $data; } - $dir = trim($data); - // XXX add to file list break; - case 'File': - $role = strtolower($this->current_attributes['Role']); + case 'DIR': + break; + case 'FILE': + $role = strtolower($this->current_attributes['ROLE']); $this->current_file = trim($data); break; - case 'LibName': + case 'LIBNAME': $this->lib_name = trim($data); break; - case 'Sources': + case 'SOURCES': $this->lib_sources[] = trim($data); break; } @@ -266,18 +334,20 @@ class PEAR_Common extends PEAR xml_set_object($xp, $this); xml_set_element_handler($xp, '_element_start', '_element_end'); xml_set_character_data_handler($xp, '_pkginfo_cdata'); - xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, true); $this->element_stack = array(); $this->pkginfo = array(); $this->current_element = false; $this->destdir = ''; - $this->filelist = array(); + $this->pkginfo['filelist'] = array(); + $this->filelist =& $this->pkginfo['filelist']; + $this->in_changelog = false; // read the whole thing so we only get one cdata callback // for each block of cdata $data = fread($fp, filesize($descfile)); - if (!@xml_parse($xp, $data, 1)) { + if (!xml_parse($xp, $data, 1)) { $msg = sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($xp)), xml_get_current_line_number($xp)); @@ -288,12 +358,24 @@ class PEAR_Common extends PEAR xml_parser_free($xp); foreach ($this->pkginfo as $k => $v) { - $this->pkginfo[$k] = trim($v); + if (!is_array($v)) { + $this->pkginfo[$k] = trim($v); + } } - $this->pkginfo['filelist'] = &$this->filelist; return $this->pkginfo; } - // }}} + + /** + * Returns info from a tgz pear package + * (experimental) + */ + function infoFromTgzFile($file) + { + // untar in temp + // chdir($tmp); + //return $this->infoFromDescriptionFile('package.xml'); + // clean temp + } } ?>
\ No newline at end of file diff --git a/pear/PEAR/Installer.php b/pear/PEAR/Installer.php index a4c595691a..01ff470cd3 100644 --- a/pear/PEAR/Installer.php +++ b/pear/PEAR/Installer.php @@ -193,8 +193,8 @@ class PEAR_Installer extends PEAR_Common $tmp_path = dirname($descfile); foreach ($pkginfo['filelist'] as $fname => $atts) { $dest_dir = $this->phpdir . DIRECTORY_SEPARATOR; - if (isset($atts['BaseInstallDir'])) { - $dest_dir .= $atts['BaseInstallDir'] . DIRECTORY_SEPARATOR; + if (isset($atts['BASEINSTALLDIR'])) { + $dest_dir .= $atts['BASEINSTALLDIR'] . DIRECTORY_SEPARATOR; } if (dirname($fname) != '.') { $dest_dir .= dirname($fname) . DIRECTORY_SEPARATOR; @@ -205,9 +205,13 @@ class PEAR_Installer extends PEAR_Common return true; } + // }}} + + // {{{ _installFile() + function _installFile($file, $dest_dir, $atts) { - $type = strtolower($atts['Role']); + $type = strtolower($atts['ROLE']); switch ($type) { case "test": // don't install test files for now @@ -227,10 +231,12 @@ class PEAR_Installer extends PEAR_Common } $this->log(2, "+ created dir $dest_dir"); } + $orig_perms = fileperms($file); if (!@copy($file, $dest_file)) { $this->log(0, "failed to copy $file to $dest_file"); return false; } + chmod($dest_file, $orig_perms); $this->log(2, "+ copy $file to $dest_file"); // FIXME Update Package database here //$this->updatePackageListFrom("$d/$file"); diff --git a/pear/PEAR/Packager.php b/pear/PEAR/Packager.php index b790ac956f..72591e1a99 100644 --- a/pear/PEAR/Packager.php +++ b/pear/PEAR/Packager.php @@ -15,6 +15,7 @@ // +----------------------------------------------------------------------+ // | Authors: Stig Bakken <ssb@fast.no> | // | Tomas V.V.Cox <cox@idecnet.com> | +// | | // +----------------------------------------------------------------------+ // // $Id$ @@ -114,8 +115,11 @@ class PEAR_Packager extends PEAR_Common // {{{ package() - function package($pkgfile = 'package.xml') + function package($pkgfile = null) { + if (empty($pkgfile)) { + $pkgfile = 'package.xml'; + } $pkginfo = $this->infoFromDescriptionFile($pkgfile); if (PEAR::isError($pkginfo)) { return $pkginfo; @@ -154,19 +158,24 @@ class PEAR_Packager extends PEAR_Common return $this->raiseError("could not mkdir $dir"); } } + //Maintain original file perms + $orig_perms = @fileperms($fname); if (!@copy($fname, $file)) { $this->log(0, "could not copy $fname to $file"); } else { $this->log(2, "+ copying from $fname to $file"); + @chmod($file, $orig_perms); } } // XXX TODO: Rebuild the package file as the old method did? // This allows build packages from different pear pack def files - if (!@copy($pkgfile, $this->tmpdir . DIRECTORY_SEPARATOR . 'package.xml')) { - return $this->raiseError("could not copy $pkgfile to " . $this->tmpdir); + $dest_pkgfile = $this->tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; + $this->log(2, "+ copying package $pkgfile to $dest_pkgfile"); + if (!@copy($pkgfile, $dest_pkgfile)) { + return $this->raiseError("could not copy $pkgfile to $dest_pkgfile"); } - $this->log(2, "+ copying package $pkgfile to " . $this->tmpdir); + chmod($dest_pkgfile, 0644); // TAR the Package ------------------------------------------- chdir(dirname($this->tmpdir)); diff --git a/pear/PEAR/WebInstaller.php b/pear/PEAR/WebInstaller.php index b566592d61..df99eb0f14 100644 --- a/pear/PEAR/WebInstaller.php +++ b/pear/PEAR/WebInstaller.php @@ -429,7 +429,7 @@ class PEAR_WebInstaller extends PEAR function _element_end($xp, $name) { array_pop($this->element_stack); - if ($name == "Package") + if ($name == "PACKAGE") { $this->AllPackages[$this->pkginfo["name"]] = $this->pkginfo; $this->pkginfo = array(); @@ -446,36 +446,36 @@ class PEAR_WebInstaller extends PEAR { $next = $this->element_stack[sizeof($this->element_stack)-1]; switch ($this->current_element) { - case "Name": + case "NAME": $this->pkginfo["name"] .= $data; break; - case "Summary": + case "SUMMARY": $this->pkginfo["summary"] .= $data; break; - case "Initials": + case "INITIALS": $this->pkginfo["maintainer_handle"] .= $data; break; - case "Email": + case "EMAIL": $this->pkginfo["maintainer_email"] .= $data; break; - case "Version": + case "VERSION": $this->pkginfo["version"] .= $data; break; - case "Date": + case "DATE": $this->pkginfo["release_date"] .= $data; break; - case "Notes": + case "NOTES": $this->pkginfo["release_notes"] .= $data; break; - case "Dir": + case "DIR": if (!$this->installdir) { break; } $dir = trim($data); // XXX add to file list break; - case "File": - $role = strtolower($this->current_attributes["Role"]); + case "FILE": + $role = strtolower($this->current_attributes["ROLE"]); $file = trim($data); // XXX add to file list break; @@ -501,7 +501,7 @@ class PEAR_WebInstaller extends PEAR xml_set_element_handler($xp, "_element_start", "_element_end"); xml_set_character_data_handler($xp, "_pkginfo_cdata"); - xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, true); $this->element_stack = array(); $this->pkginfo = array(); @@ -597,7 +597,7 @@ class PEAR_WebInstaller extends PEAR } } function help ($Full = False) { -global $PHP_SELF; + global $PHP_SELF; $this->loggerEnd(); print "From the WebInstaller.php introduction: <p>"; diff --git a/pear/package.dtd b/pear/package.dtd index e45c436dea..56cd1fbb8e 100644 --- a/pear/package.dtd +++ b/pear/package.dtd @@ -1,5 +1,5 @@ <!-- - $Id: package.dtd,v 1.6 2001-05-28 11:14:47 ssb Exp $ + $Id: package.dtd,v 1.6.2.1 2001-08-28 11:40:56 ssb Exp $ This is the PEAR package description, version 1.1b1. It should be used with the informal public identifier: @@ -28,98 +28,99 @@ ThreadSafe (on|off) 'off'"> <!ENTITY % format.atts "Format CDATA #IMPLIED"> <!--=============== ELEMENT: Package =======================================--> -<!ELEMENT Package (Name, Summary, Maintainer, Release, FileList)> -<!ATTLIST Package +<!ELEMENT package (name, summary, maintainer, release, filelist)> +<!ATTLIST package %global.atts; - Type (Source | Binary | Empty) "Empty" + type (source | binary | empty) "empty" > -<!--=============== ELEMENT: Name ==========================================--> -<!ELEMENT Name (#PCDATA)> -<!ATTLIST Name +<!--=============== ELEMENT: name ==========================================--> +<!ELEMENT name (#PCDATA)> +<!ATTLIST name %global.atts; > -<!--=============== ELEMENT: Summary =======================================--> -<!ELEMENT Summary (#PCDATA)> -<!ATTLIST Summary +<!--=============== ELEMENT: summary =======================================--> +<!ELEMENT summary (#PCDATA)> +<!ATTLIST summary %global.atts; > -<!--=============== ELEMENT: Maintainer ====================================--> -<!ELEMENT Maintainer (Initials, Name, Email)> -<!ATTLIST Maintainer +<!--=============== ELEMENT: maintainer ====================================--> +<!ELEMENT maintainer (initials, name, email)> +<!ATTLIST maintainer %global.atts; > -<!--=============== ELEMENT: Initials ======================================--> -<!ELEMENT Initials (#PCDATA)> -<!ATTLIST Initials +<!--=============== ELEMENT: initials ======================================--> +<!ELEMENT initials (#PCDATA)> +<!ATTLIST initials %global.atts; > -<!--=============== ELEMENT: Email =========================================--> -<!ELEMENT Email (#PCDATA)> -<!ATTLIST Email +<!--=============== ELEMENT: email =========================================--> +<!ELEMENT email (#PCDATA)> +<!ATTLIST email %global.atts; > -<!--=============== ELEMENT: Release =======================================--> -<!ELEMENT Release (Version, Date, Notes?)> -<!ATTLIST Release +<!--=============== ELEMENT: release =======================================--> +<!ELEMENT release (version, date, notes?)> +<!ATTLIST release %global.atts; > -<!--=============== ELEMENT: Version =======================================--> -<!ELEMENT Version (#PCDATA)> -<!ATTLIST Version +<!--=============== ELEMENT: version =======================================--> +<!ELEMENT version (#PCDATA)> +<!ATTLIST version %global.atts; > -<!--=============== ELEMENT: Date =========================================--> -<!ELEMENT Date (#PCDATA)> -<!ATTLIST Date +<!--=============== ELEMENT: date =========================================--> +<!ELEMENT date (#PCDATA)> +<!ATTLIST date %global.atts; > -<!--=============== ELEMENT: Notes =========================================--> -<!ELEMENT Notes (#PCDATA)> -<!ATTLIST Notes +<!--=============== ELEMENT: notes =========================================--> +<!ELEMENT notes (#PCDATA)> +<!ATTLIST notes %global.atts; > -<!--=============== ELEMENT: FileList ======================================--> -<!ELEMENT FileList (Dir | File | LibFile)*> -<!ATTLIST FileList +<!--=============== ELEMENT: filelist ======================================--> +<!ELEMENT filelist (dir | file | libfile)*> +<!ATTLIST filelist %global.atts; > -<!--=============== ELEMENT: Dir ===========================================--> -<!ELEMENT Dir (#PCDATA)> -<!ATTLIST Dir +<!--=============== ELEMENT: dir ===========================================--> +<!ELEMENT dir (#PCDATA)> +<!ATTLIST dir + baseinstalldir CDATA #IMPLIED %global.atts; > -<!--=============== ELEMENT: File ==========================================--> -<!ELEMENT File (#PCDATA)> -<!ATTLIST File +<!--=============== ELEMENT: file ==========================================--> +<!ELEMENT file (#PCDATA)> +<!ATTLIST file %global.atts; %role.atts; %extension.atts; %format.atts; > -<!--=============== ELEMENT: LibFile =======================================--> -<!ELEMENT LibFile (LibName,Sources,Includes?,LibAdd?)> -<!ATTLIST LibFile +<!--=============== ELEMENT: libfile =======================================--> +<!ELEMENT libfile (libname,sources,includes?,libadd?)> +<!ATTLIST libfile %global.atts; %role.atts; > -<!--=============== ELEMENT: LibFile =======================================--> -<!ELEMENT LibFile (LibName,Sources,Includes?,LibAdd?)> -<!ATTLIST LibFile +<!--=============== ELEMENT: libfile =======================================--> +<!ELEMENT libfile (libname,sources,includes?,libadd?)> +<!ATTLIST libfile %global.atts; %role.atts; > -<!--=============== ELEMENT: LibName =======================================--> -<!ELEMENT LibName (#PCDATA)> -<!ATTLIST LibName +<!--=============== ELEMENT: libname =======================================--> +<!ELEMENT libname (#PCDATA)> +<!ATTLIST libname %global.atts; > -<!--=============== ELEMENT: Sources =======================================--> -<!ELEMENT Sources (#PCDATA)> -<!ATTLIST Sources +<!--=============== ELEMENT: sources =======================================--> +<!ELEMENT sources (#PCDATA)> +<!ATTLIST sources %global.atts; > -<!--=============== ELEMENT: LibAdd ========================================--> -<!ELEMENT LibAdd (#PCDATA)> -<!ATTLIST LibAdd +<!--=============== ELEMENT: libadd ========================================--> +<!ELEMENT libadd (#PCDATA)> +<!ATTLIST libadd %global.atts; > diff --git a/pear/scripts/pearize.in b/pear/scripts/pearize.in index 332f3333aa..5c971a985e 100644 --- a/pear/scripts/pearize.in +++ b/pear/scripts/pearize.in @@ -1,12 +1,14 @@ #!@prefix@/bin/php -Cq <?php // -*- PHP -*- -main($argc, $argv, $HTTP_ENV_VARS); +main($argc, $argv, $_ENV); // {{{ main() function main(&$argc, &$argv, &$env) { + global $debug; + $debug = false; $file = check_options($argc, $argv, $env); parse_package_file($file); make_makefile_in($env); @@ -15,11 +17,30 @@ function main(&$argc, &$argv, &$env) // }}} // {{{ check_options() -function check_options(&$argc, &$argv, &$env) +function check_options($argc, $argv, $env) { - $file = $argv[1]; + global $debug; + array_shift($argv); + while ($argv[0]{0} == '-' && $argv[0] != '-') { + $opt = array_shift($argv); + switch ($opt) { + case '--': { + break 2; + } + case '-d': { + $debug = true; + break; + } + default: { + die("pearize: unrecognized option `$opt'\n"); + } + } + } + $file = array_shift($argv); if (empty($file)) { $file = "package.xml"; + } elseif ($file == '-') { + $file = "php://stdin"; } return $file; } @@ -29,14 +50,16 @@ function check_options(&$argc, &$argv, &$env) function make_makefile_in(&$env) { - global $libdata; - if (sizeof($libdata) == 0) { - exit; - } elseif (sizeof($libdata) > 1) { + global $libdata, $debug; + if (sizeof($libdata) > 1) { die("No support yet for multiple libraries in one package.\n"); } - $wp = @fopen("Makefile.in", "w"); + if ($debug) { + $wp = fopen("php://stdout", "w"); + } else { + $wp = @fopen("Makefile.in", "w"); + } if (is_resource($wp)) { print "Creating Makefile.in..."; flush(); @@ -44,21 +67,24 @@ function make_makefile_in(&$env) die("Could not create Makefile.in in current directory.\n"); } + $who = $env["USER"]; + $when = gmdate('Y-m-d h:i'); + fwrite($wp, "# This file was generated by `pearize' by $who at $when GMT\n\n"); + foreach ($libdata as $lib => $info) { extract($info); - $_who = $env["USER"]; - $_when = gmdate('Y-m-d h:i'); fwrite($wp, "\ -# This file was generated by `pearize' by $_who at $_when GMT INCLUDES = $includes LTLIBRARY_NAME = lib{$lib}.la LTLIBRARY_SOURCES = $sources LTLIBRARY_SHARED_NAME = {$lib}.la LTLIBRARY_SHARED_LIBADD = $libadd - -include \$(top_srcdir)/build/dynlib.mk "); } + + if (sizeof($libdata) > 0) { + fwrite($wp, "include \$(top_srcdir)/build/dynlib.mk\n"); + } fclose($wp); print "done.\n"; } @@ -69,17 +95,20 @@ include \$(top_srcdir)/build/dynlib.mk function parse_package_file($file) { global $in_file, $curlib, $curelem, $libdata, $cdata; + global $currinstalldir, $baseinstalldir; $in_file = false; $curlib = ''; $curelem = ''; $libdata = array(); $cdata = array(); + $baseinstalldir = array(); + $currinstalldir = array(); $xp = xml_parser_create(); xml_set_element_handler($xp, "start_handler", "end_handler"); xml_set_character_data_handler($xp, "cdata_handler"); - xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, true); $fp = @fopen($file, "r"); if (!is_resource($fp)) { @@ -96,10 +125,13 @@ function parse_package_file($file) function start_handler($xp, $elem, $attrs) { - global $cdata, $in_file, $curelem; + global $cdata, $in_file, $curelem, $curfile, $filerole; + global $baseinstalldir, $currinstalldir; switch ($elem) { - case "File": { - switch ($attrs['Role']) { + case "FILE": { + $curfile = ''; + $filerole = $attrs['ROLE']; + switch ($filerole) { case "ext": { $in_file = true; $cdata = array(); @@ -111,10 +143,21 @@ function start_handler($xp, $elem, $attrs) } break; } - case "Includes": - case "LibName": - case "LibAdd": - case "Sources": { + case "DIR": { + $cdir = $currinstalldir[sizeof($currinstalldir)-1]; + $bdir = $baseinstalldir[sizeof($baseinstalldir)-1]; + array_push($currinstalldir, "$cdir/{$attrs[NAME]}"); + if (isset($attrs["BASEINSTALLDIR"])) { + array_push($baseinstalldir, "$bdir/{$attrs[BASEINSTALLDIR]}"); + } else { + array_push($baseinstalldir, $bdir); + } + break; + } + case "INCLUDES": + case "LIBNAME": + case "LIBADD": + case "SOURCES": { $curelem = $elem; break; } @@ -127,19 +170,25 @@ function start_handler($xp, $elem, $attrs) function end_handler($xp, $elem) { global $in_file, $curlib, $curelem, $libdata, $cdata; + global $baseinstalldir, $currinstalldir; switch ($elem) { - case "File": { + case "FILE": { if ($in_file === true) { - $libname = trim($cdata['LibName']); + $libname = trim($cdata['LIBNAME']); $libdata[$libname] = array( - "sources" => trim($cdata['Sources']), - "includes" => trim($cdata['Includes']), - "libadd" => trim($cdata['LibAdd']), + "sources" => trim($cdata['SOURCES']), + "includes" => trim($cdata['INCLUDES']), + "libadd" => trim($cdata['LIBADD']), ); $in_file = false; } break; } + case "DIR": { + array_pop($currinstalldir); + array_pop($baseinstalldir); + break; + } } } @@ -148,12 +197,16 @@ function end_handler($xp, $elem) function cdata_handler($xp, $data) { - global $curelem, $cdata; + global $curelem, $cdata, $curfile; switch ($curelem) { - case "Includes": - case "LibAdd": - case "LibName": - case "Sources": { + case "FILE": { + $curfile .= $data; + break; + } + case "INCLUDES": + case "LIBADD": + case "LIBNAME": + case "SOURCES": { $cdata[$curelem] .= $data; break; } |