summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStig Bakken <ssb@php.net>2001-08-28 11:41:13 +0000
committerStig Bakken <ssb@php.net>2001-08-28 11:41:13 +0000
commit28caf732a7a29f97f41905e59cfec9014864b178 (patch)
tree3f9ce6e9b1587350b09de5aa2c1e15096aaf3f28
parent513874acc7d0c4841d4b2d279b8d81f56248798f (diff)
downloadphp-git-28caf732a7a29f97f41905e59cfec9014864b178.tar.gz
* MFH PEAR stuff
* copied in Archive_Tar class from pear/Archive_Tar
-rw-r--r--pear/Archive/Tar.php880
-rw-r--r--pear/CODING_STANDARDS250
-rw-r--r--pear/Makefile.in7
-rw-r--r--pear/PEAR.php2
-rw-r--r--pear/PEAR/Common.php182
-rw-r--r--pear/PEAR/Installer.php12
-rw-r--r--pear/PEAR/Packager.php17
-rw-r--r--pear/PEAR/WebInstaller.php26
-rw-r--r--pear/package.dtd111
-rw-r--r--pear/scripts/pearize.in115
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;
}