Subversion Repositories Applications.gtt

Compare Revisions

Ignore whitespace Rev 94 → Rev 187

/trunk/bibliotheque/pear/PEAR/Installer.php
4,12 → 4,6
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.0 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_0.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category pear
* @package PEAR
* @author Stig Bakken <ssb@php.net>
16,9 → 10,8
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version CVS: $Id: Installer.php,v 1.243 2007/02/16 04:00:37 cellog Exp $
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @link http://pear.php.net/package/PEAR
* @since File available since Release 0.1
*/
40,9 → 33,9
* @author Tomas V.V. Cox <cox@idecnet.com>
* @author Martin Jansen <mj@php.net>
* @author Greg Beaver <cellog@php.net>
* @copyright 1997-2006 The PHP Group
* @license http://www.php.net/license/3_0.txt PHP License 3.0
* @version Release: 1.5.1
* @copyright 1997-2009 The Authors
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* @version Release: 1.10.1
* @link http://pear.php.net/package/PEAR
* @since Class available since Release 0.1
*/
122,9 → 115,9
*
* @access public
*/
function PEAR_Installer(&$ui)
function __construct(&$ui)
{
parent::PEAR_Common();
parent::__construct($ui, array(), null);
$this->setFrontendObject($ui);
$this->debug = $this->config->get('verbose');
}
136,7 → 129,7
 
function setConfig(&$config)
{
$this->config = &$config;
$this->config = &$config;
$this->_registry = &$config->getRegistry();
}
 
165,9 → 158,11
if (!$channel) {
$channel = 'pear.php.net';
}
 
if (!strlen($package)) {
return $this->raiseError("No package to uninstall given");
}
 
if (strtolower($package) == 'pear' && $channel == 'pear.php.net') {
// to avoid race conditions, include all possible needed files
require_once 'PEAR/Task/Common.php';
179,25 → 174,31
require_once 'PEAR/PackageFile/Generator/v1.php';
require_once 'PEAR/PackageFile/Generator/v2.php';
}
 
$filelist = $this->_registry->packageInfo($package, 'filelist', $channel);
if ($filelist == null) {
return $this->raiseError("$channel/$package not installed");
}
 
$ret = array();
foreach ($filelist as $file => $props) {
if (empty($props['installed_as'])) {
continue;
}
 
$path = $props['installed_as'];
if ($backup) {
$this->addFileOperation('backup', array($path));
$ret[] = $path;
}
 
$this->addFileOperation('delete', array($path));
}
 
if ($backup) {
return $ret;
}
 
return true;
}
 
218,17 → 219,20
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
 
if (isset($atts['platform'])) {
if (empty($os)) {
$os = new OS_Guess();
}
 
if (strlen($atts['platform']) && $atts['platform']{0} == '!') {
$negate = true;
$negate = true;
$platform = substr($atts['platform'], 1);
} else {
$negate = false;
$negate = false;
$platform = $atts['platform'];
}
 
if ((bool) $os->matchSignature($platform) === $negate) {
$this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")");
return PEAR_INSTALLER_SKIPPED;
239,6 → 243,10
$channel = $this->pkginfo->getChannel();
// {{{ assemble the destination paths
switch ($atts['role']) {
case 'src':
case 'extsrc':
$this->source_files++;
return;
case 'doc':
case 'data':
case 'test':
253,20 → 261,19
case 'script':
$dest_dir = $this->config->get('bin_dir', null, $channel);
break;
case 'src':
case 'extsrc':
$this->source_files++;
return;
default:
return $this->raiseError("Invalid role `$atts[role]' for file $file");
}
 
$save_destdir = $dest_dir;
if (!empty($atts['baseinstalldir'])) {
$dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
}
 
if (dirname($file) != '.' && empty($atts['install-as'])) {
$dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
}
 
if (empty($atts['install-as'])) {
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
} else {
283,16 → 290,19
array($dest_file, $orig_file));
$final_dest_file = $installed_as = $dest_file;
if (isset($this->_options['packagingroot'])) {
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
$final_dest_file = $this->_prependPath($final_dest_file,
$this->_options['packagingroot']);
$final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']);
} else {
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_dir = dirname($final_dest_file);
$installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
}
$dest_dir = dirname($final_dest_file);
 
$dest_dir = dirname($final_dest_file);
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
}
// }}}
 
if (empty($this->_options['register-only']) &&
303,6 → 313,7
}
$this->log(3, "+ mkdir $dest_dir");
}
 
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
if (empty($atts['replacements'])) {
310,10 → 321,12
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
 
if (!@copy($orig_file, $dest_file)) {
return $this->raiseError("failed to write $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ cp $orig_file $dest_file");
if (isset($atts['md5sum'])) {
$md5sum = md5_file($dest_file);
324,18 → 337,21
return $this->raiseError("file does not exist",
PEAR_INSTALLER_FAILED);
}
 
$contents = file_get_contents($orig_file);
if ($contents === false) {
$contents = '';
}
 
if (isset($atts['md5sum'])) {
$md5sum = md5($contents);
}
 
$subst_from = $subst_to = array();
foreach ($atts['replacements'] as $a) {
$to = '';
if ($a['type'] == 'php-const') {
if (preg_match('/^[a-z0-9_]+$/i', $a['to'])) {
if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) {
eval("\$to = $a[to];");
} else {
if (!isset($options['soft'])) {
375,25 → 391,30
$subst_to[] = $to;
}
}
 
$this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file");
if (sizeof($subst_from)) {
$contents = str_replace($subst_from, $subst_to, $contents);
}
 
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
return $this->raiseError("failed to create $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
if (@fwrite($wp, $contents) === false) {
return $this->raiseError("failed writing to $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
fclose($wp);
// }}}
}
 
// {{{ check the md5
if (isset($md5sum)) {
if (strtolower($md5sum) == strtolower($atts['md5sum'])) {
if (strtolower($md5sum) === strtolower($atts['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
} else {
if (empty($options['force'])) {
401,14 → 422,15
if (file_exists($dest_file)) {
unlink($dest_file);
}
 
if (!isset($options['ignore-errors'])) {
return $this->raiseError("bad md5sum for file $final_dest_file",
PEAR_INSTALLER_FAILED);
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
425,21 → 447,40
} else {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
}
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
 
if ($atts['role'] != 'src') {
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
}
}
}
// }}}
$this->addFileOperation("rename", array($dest_file, $final_dest_file,
$atts['role'] == 'ext'));
 
if ($atts['role'] == 'src') {
rename($dest_file, $final_dest_file);
$this->log(2, "renamed source file $dest_file to $final_dest_file");
} else {
$this->addFileOperation("rename", array($dest_file, $final_dest_file,
$atts['role'] == 'ext'));
}
}
 
// Store the full path where the file was installed for easy unistall
$this->addFileOperation("installed_as", array($file, $installed_as,
$save_destdir, dirname(substr($installedas_dest_file, strlen($save_destdir)))));
if ($atts['role'] != 'script') {
$loc = $this->config->get($atts['role'] . '_dir');
} else {
$loc = $this->config->get('bin_dir');
}
 
if ($atts['role'] != 'src') {
$this->addFileOperation("installed_as", array($file, $installed_as,
$loc,
dirname(substr($installedas_dest_file, strlen($loc)))));
}
 
//$this->log(2, "installed: $dest_file");
return PEAR_INSTALLER_OK;
}
455,8 → 496,9
* @param array options from command-line
* @access private
*/
function _installFile2(&$pkg, $file, $atts, $tmp_path, $options)
function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options)
{
$atts = $real_atts;
if (!isset($this->_registry)) {
$this->_registry = &$this->config->getRegistry();
}
468,26 → 510,34
return $this->raiseError('Invalid role `' . $atts['attribs']['role'] .
"' for file $file");
}
 
$role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config);
$err = $role->setup($this, $pkg, $atts['attribs'], $file);
$err = $role->setup($this, $pkg, $atts['attribs'], $file);
if (PEAR::isError($err)) {
return $err;
}
 
if (!$role->isInstallable()) {
return;
}
 
$info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path);
if (PEAR::isError($info)) {
return $info;
} else {
list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
}
 
list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info;
if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) {
return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED);
}
 
$final_dest_file = $installed_as = $dest_file;
if (isset($this->_options['packagingroot'])) {
$final_dest_file = $this->_prependPath($final_dest_file,
$this->_options['packagingroot']);
}
$dest_dir = dirname($final_dest_file);
 
$dest_dir = dirname($final_dest_file);
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file);
// }}}
 
500,6 → 550,7
$this->log(3, "+ mkdir $dest_dir");
}
}
 
$attribs = $atts['attribs'];
unset($atts['attribs']);
// pretty much nothing happens if we are only registering the install
509,10 → 560,12
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
 
if (!@copy($orig_file, $dest_file)) {
return $this->raiseError("failed to write $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ cp $orig_file $dest_file");
if (isset($attribs['md5sum'])) {
$md5sum = md5_file($dest_file);
522,18 → 575,20
return $this->raiseError("file $orig_file does not exist",
PEAR_INSTALLER_FAILED);
}
 
$contents = file_get_contents($orig_file);
if ($contents === false) {
$contents = '';
}
 
if (isset($attribs['md5sum'])) {
$md5sum = md5($contents);
}
 
foreach ($atts as $tag => $raw) {
$tag = str_replace(array($pkg->getTasksNs() . ':', '-'),
array('', '_'), $tag);
$tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag);
$task = "PEAR_Task_$tag";
$task = &new $task($this->config, $this, PEAR_TASK_INSTALL);
$task = new $task($this->config, $this, PEAR_TASK_INSTALL);
if (!$task->isScript()) { // scripts are only handled after installation
$task->init($raw, $attribs, $pkg->getLastInstalledVersion());
$res = $task->startSession($pkg, $contents, $final_dest_file);
540,27 → 595,39
if ($res === false) {
continue; // skip this file
}
 
if (PEAR::isError($res)) {
return $res;
}
 
$contents = $res; // save changes
}
 
$wp = @fopen($dest_file, "wb");
if (!is_resource($wp)) {
return $this->raiseError("failed to create $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
if (fwrite($wp, $contents) === false) {
return $this->raiseError("failed writing to $dest_file: $php_errormsg",
PEAR_INSTALLER_FAILED);
}
 
fclose($wp);
}
}
 
// {{{ check the md5
if (isset($md5sum)) {
if (strtolower($md5sum) == strtolower($attribs['md5sum'])) {
// Make sure the original md5 sum matches with expected
if (strtolower($md5sum) === strtolower($attribs['md5sum'])) {
$this->log(2, "md5sum ok: $final_dest_file");
 
if (isset($contents)) {
// set md5 sum based on $content in case any tasks were run.
$real_atts['attribs']['md5sum'] = md5($contents);
}
} else {
if (empty($options['force'])) {
// delete the file
567,14 → 634,15
if (file_exists($dest_file)) {
unlink($dest_file);
}
 
if (!isset($options['ignore-errors'])) {
return $this->raiseError("bad md5sum for file $final_dest_file",
PEAR_INSTALLER_FAILED);
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
}
} else {
if (!isset($options['soft'])) {
$this->log(0, "warning : bad md5sum for file $final_dest_file");
581,7 → 649,10
}
}
}
} else {
$real_atts['attribs']['md5sum'] = md5_file($dest_file);
}
 
// }}}
// {{{ set file permissions
if (!OS_WINDOWS) {
591,19 → 662,33
} else {
$mode = 0666 & ~(int)octdec($this->config->get('umask'));
}
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
 
if ($attribs['role'] != 'src') {
$this->addFileOperation("chmod", array($mode, $dest_file));
if (!@chmod($dest_file, $mode)) {
if (!isset($options['soft'])) {
$this->log(0, "failed to change mode of $dest_file: $php_errormsg");
}
}
}
}
// }}}
$this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
 
if ($attribs['role'] == 'src') {
rename($dest_file, $final_dest_file);
$this->log(2, "renamed source file $dest_file to $final_dest_file");
} else {
$this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension()));
}
}
 
// Store the full path where the file was installed for easy uninstall
$this->addFileOperation("installed_as", array($file, $installed_as,
$save_destdir, dirname(substr($dest_file, strlen($save_destdir)))));
if ($attribs['role'] != 'src') {
$loc = $this->config->get($role->getLocationConfig(), null, $channel);
$this->addFileOperation('installed_as', array($file, $installed_as,
$loc,
dirname(substr($installed_as, strlen($loc)))));
}
 
//$this->log(2, "installed: $dest_file");
return PEAR_INSTALLER_OK;
642,6 → 727,7
return $this->raiseError('Internal Error: $data in addFileOperation'
. ' must be an array, was ' . gettype($data));
}
 
if ($type == 'chmod') {
$octmode = decoct($data[0]);
$this->log(3, "adding to transaction: $type $octmode $data[1]");
667,11 → 753,9
 
function commitFileTransaction()
{
$n = count($this->file_operations);
$this->log(2, "about to commit $n file operations");
// {{{ first, check permissions and such manually
$errors = array();
foreach ($this->file_operations as $tr) {
foreach ($this->file_operations as $key => $tr) {
list($type, $data) = $tr;
switch ($type) {
case 'rename':
678,6 → 762,7
if (!file_exists($data[0])) {
$errors[] = "cannot rename file $data[0], doesn't exist";
}
 
// check that dest dir. is writable
if (!is_writable(dirname($data[1]))) {
$errors[] = "permission denied ($type): $data[1]";
707,6 → 792,27
fclose($fp);
}
}
 
/* Verify we are not deleting a file owned by another package
* This can happen when a file moves from package A to B in
* an upgrade ala http://pear.php.net/17986
*/
$info = array(
'package' => strtolower($this->pkginfo->getName()),
'channel' => strtolower($this->pkginfo->getChannel()),
);
$result = $this->_registry->checkFileMap($data[0], $info, '1.1');
if (is_array($result)) {
$res = array_diff($result, $info);
if (!empty($res)) {
$new = $this->_registry->getPackage($result[1], $result[0]);
$this->file_operations[$key] = false;
$pkginfoName = $this->pkginfo->getName();
$newChannel = $new->getChannel();
$newPackage = $new->getName();
$this->log(3, "file $data[0] was scheduled for removal from $pkginfoName but is owned by $newChannel/$newPackage, removal has been cancelled.");
}
}
}
break;
}
713,7 → 819,11
 
}
// }}}
$m = sizeof($errors);
 
$n = count($this->file_operations);
$this->log(2, "about to commit $n file operations for " . $this->pkginfo->getName());
 
$m = count($errors);
if ($m > 0) {
foreach ($errors as $error) {
if (!isset($this->_options['soft'])) {
720,10 → 830,12
$this->log(1, $error);
}
}
 
if (!isset($this->_options['ignore-errors'])) {
return false;
}
}
 
$this->_dirtree = array();
// {{{ really commit the transaction
foreach ($this->file_operations as $i => $tr) {
731,6 → 843,7
// support removal of non-existing backups
continue;
}
 
list($type, $data) = $tr;
switch ($type) {
case 'backup':
738,6 → 851,7
$this->file_operations[$i] = false;
break;
}
 
if (!@copy($data[0], $data[0] . '.bak')) {
$this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] .
'.bak ' . $php_errormsg);
752,11 → 866,7
}
break;
case 'rename':
if (file_exists($data[1])) {
$test = @unlink($data[1]);
} else {
$test = null;
}
$test = file_exists($data[1]) ? @unlink($data[1]) : null;
if (!$test && file_exists($data[1])) {
if ($data[2]) {
$extra = ', this extension must be installed manually. Rename to "' .
764,14 → 874,17
} else {
$extra = '';
}
 
if (!isset($this->_options['soft'])) {
$this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' .
$data[0] . $extra);
}
 
if (!isset($this->_options['ignore-errors'])) {
return false;
}
}
 
// permissions issues with rename - copy() is far superior
$perms = @fileperms($data[0]);
if (!@copy($data[0], $data[1])) {
779,6 → 892,7
' ' . $php_errormsg);
return false;
}
 
// copy over permissions, otherwise they are lost
@chmod($data[1], $perms);
@unlink($data[0]);
790,6 → 904,7
decoct($data[0]) . ' ' . $php_errormsg);
return false;
}
 
$octmode = decoct($data[0]);
$this->log(3, "+ chmod $octmode $data[1]");
break;
815,6 → 930,7
break 2; // this directory is not empty and can't be
// deleted
}
 
closedir($testme);
if (!@rmdir($data[0])) {
$this->log(1, 'Could not rmdir ' . $data[0] . ' ' .
831,8 → 947,8
$this->_dirtree[dirname($data[1])] = true;
$this->pkginfo->setDirtree(dirname($data[1]));
 
while(!empty($data[3]) && $data[3] != '/' && $data[3] != '\\'
&& $data[3] != '.') {
while(!empty($data[3]) && dirname($data[3]) != $data[3] &&
$data[3] != '/' && $data[3] != '\\') {
$this->pkginfo->setDirtree($pp =
$this->_prependPath($data[3], $data[2]));
$this->_dirtree[$pp] = true;
904,62 → 1020,12
}
 
// }}}
// {{{ download()
 
/**
* Download any files and their dependencies, if necessary
*
* @param array a mixed list of package names, local files, or package.xml
* @param PEAR_Config
* @param array options from the command line
* @param array this is the array that will be populated with packages to
* install. Format of each entry:
*
* <code>
* array('pkg' => 'package_name', 'file' => '/path/to/local/file',
* 'info' => array() // parsed package.xml
* );
* </code>
* @param array this will be populated with any error messages
* @param false private recursion variable
* @param false private recursion variable
* @param false private recursion variable
* @deprecated in favor of PEAR_Downloader
*/
function download($packages, $options, &$config, &$installpackages,
&$errors, $installed = false, $willinstall = false, $state = false)
{
// trickiness: initialize here
parent::PEAR_Downloader($this->ui, $options, $config);
$ret = parent::download($packages);
$errors = $this->getErrorMsgs();
$installpackages = $this->getDownloadedPackages();
trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
"in favor of PEAR_Downloader class", E_USER_WARNING);
return $ret;
}
 
// }}}
// {{{ _parsePackageXml()
 
function _parsePackageXml(&$descfile, &$tmpdir)
function _parsePackageXml(&$descfile)
{
if (substr($descfile, -4) == '.xml') {
$tmpdir = false;
} else {
// {{{ Decompress pack in tmp dir -------------------------------------
 
// To allow relative package file names
$descfile = realpath($descfile);
 
if (PEAR::isError($tmpdir = System::mktemp('-d'))) {
return $tmpdir;
}
$this->log(3, '+ tmp dir created at ' . $tmpdir);
// }}}
}
// Parse xml file -----------------------------------------------
$pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir);
$pkg = new PEAR_PackageFile($this->config, $this->debug);
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
$p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING);
PEAR::staticPopErrorHandling();
973,9 → 1039,9
}
}
return $this->raiseError('Installation failed: invalid package file');
} else {
$descfile = $p->getPackageFile();
}
 
$descfile = $p->getPackageFile();
return $p;
}
 
1031,26 → 1097,29
*
* @return array|PEAR_Error package info if successful
*/
 
function install($pkgfile, $options = array())
{
$this->_options = $options;
$this->_registry = &$this->config->getRegistry();
if (is_object($pkgfile)) {
$dlpkg = &$pkgfile;
$pkg = $pkgfile->getPackageFile();
$pkgfile = $pkg->getArchiveFile();
$dlpkg = &$pkgfile;
$pkg = $pkgfile->getPackageFile();
$pkgfile = $pkg->getArchiveFile();
$descfile = $pkg->getPackageFile();
$tmpdir = dirname($descfile);
} else {
$descfile = $pkgfile;
$tmpdir = '';
if (PEAR::isError($pkg = &$this->_parsePackageXml($descfile, $tmpdir))) {
$pkg = $this->_parsePackageXml($descfile);
if (PEAR::isError($pkg)) {
return $pkg;
}
}
 
$tmpdir = dirname($descfile);
if (realpath($descfile) != realpath($pkgfile)) {
// Use the temp_dir since $descfile can contain the download dir path
$tmpdir = $this->config->get('temp_dir', null, 'pear.php.net');
$tmpdir = System::mktemp('-d -t "' . $tmpdir . '"');
 
$tar = new Archive_Tar($pkgfile);
if (!$tar->extract($tmpdir)) {
return $this->raiseError("unable to unpack $pkgfile");
1059,14 → 1128,6
 
$pkgname = $pkg->getName();
$channel = $pkg->getChannel();
if (isset($this->_options['packagingroot'])) {
$regdir = $this->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$this->_options['packagingroot']);
$packrootphp_dir = $this->_prependPath(
$this->config->get('php_dir', null, $channel),
$this->_options['packagingroot']);
}
 
if (isset($options['installroot'])) {
$this->config->setInstallRoot($options['installroot']);
1078,7 → 1139,21
$this->config->setInstallRoot(false);
$this->_registry = &$this->config->getRegistry();
if (isset($this->_options['packagingroot'])) {
$installregistry = &new PEAR_Registry($regdir);
$regdir = $this->_prependPath(
$this->config->get('php_dir', null, 'pear.php.net'),
$this->_options['packagingroot']);
 
$metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net');
if ($metadata_dir) {
$metadata_dir = $this->_prependPath(
$metadata_dir,
$this->_options['packagingroot']);
}
$packrootphp_dir = $this->_prependPath(
$this->config->get('php_dir', null, $channel),
$this->_options['packagingroot']);
 
$installregistry = new PEAR_Registry($regdir, false, false, $metadata_dir);
if (!$installregistry->channelExists($channel, true)) {
// we need to fake a channel-discover of this channel
$chanobj = $this->_registry->getChannel($channel, true);
1101,6 → 1176,7
if (PEAR::isError($instfilelist)) {
return $instfilelist;
}
 
// ensure we have the most accurate registry
$installregistry->flushFileMap();
$test = $installregistry->checkFileMap($instfilelist, $testp, '1.1');
1107,6 → 1183,7
if (PEAR::isError($test)) {
return $test;
}
 
if (sizeof($test)) {
$pkgs = $this->getInstallPackages();
$found = false;
1116,6 → 1193,7
break;
}
}
 
if ($found) {
// subpackages can conflict with earlier versions of parent packages
$parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel());
1123,24 → 1201,52
foreach ($tmp as $file => $info) {
if (is_array($info)) {
if (strtolower($info[1]) == strtolower($param->getPackage()) &&
strtolower($info[0]) == strtolower($param->getChannel())) {
strtolower($info[0]) == strtolower($param->getChannel())
) {
if (isset($parentreg['filelist'][$file])) {
unset($parentreg['filelist'][$file]);
} else{
$pos = strpos($file, '/');
$basedir = substr($file, 0, $pos);
$file2 = substr($file, $pos + 1);
if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
&& $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
) {
unset($parentreg['filelist'][$file2]);
}
}
 
unset($test[$file]);
unset($parentreg['filelist'][$file]);
}
} else {
if (strtolower($param->getChannel()) != 'pear.php.net') {
continue;
}
 
if (strtolower($info) == strtolower($param->getPackage())) {
if (isset($parentreg['filelist'][$file])) {
unset($parentreg['filelist'][$file]);
} else{
$pos = strpos($file, '/');
$basedir = substr($file, 0, $pos);
$file2 = substr($file, $pos + 1);
if (isset($parentreg['filelist'][$file2]['baseinstalldir'])
&& $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir
) {
unset($parentreg['filelist'][$file2]);
}
}
 
unset($test[$file]);
unset($parentreg['filelist'][$file]);
}
}
}
$pfk = &new PEAR_PackageFile($this->config);
 
$pfk = new PEAR_PackageFile($this->config);
$parentpkg = &$pfk->fromArray($parentreg);
$installregistry->updatePackage2($parentpkg);
}
 
if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) {
$tmp = $test;
foreach ($tmp as $file => $info) {
1153,7 → 1259,8
}
}
}
if (sizeof($test)) {
 
if (count($test)) {
$msg = "$channel/$pkgname: conflicting files found:\n";
$longest = max(array_map("strlen", array_keys($test)));
$fmt = "%${longest}s (%s)\n";
1164,13 → 1271,14
$info = $info[0] . '/' . $info[1];
$msg .= sprintf($fmt, $file, $info);
}
 
if (!isset($options['ignore-errors'])) {
return $this->raiseError($msg);
} else {
if (!isset($options['soft'])) {
$this->log(0, "WARNING: $msg");
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "WARNING: $msg");
}
}
}
}
1178,30 → 1286,24
 
$this->startFileTransaction();
 
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
 
if (empty($options['upgrade']) && empty($options['soft'])) {
// checks to do only when installing new packages
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
if (empty($options['force']) && $test) {
return $this->raiseError("$channel/$pkgname is already installed");
}
} else {
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
if (!$test) {
$test = $installregistry->packageExists($pkgname, 'pear.php.net');
$usechannel = 'pear.php.net';
}
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
// Upgrade
if ($test) {
$v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel);
$v2 = $pkg->getVersion();
1209,21 → 1311,23
if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) {
return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)");
}
if (empty($options['register-only'])) {
// when upgrading, remove old release's files first:
if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel,
true))) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
}
} else {
$backedup = $err;
}
}
}
 
// Do cleanups for upgrade and install, remove old release's files first
if ($test && empty($options['register-only'])) {
// when upgrading, remove old release's files first:
if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel,
true))) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
} else {
$backedup = $err;
}
}
 
1241,9 → 1345,8
}
}
 
$tmp_path = dirname($descfile);
if (substr($pkgfile, -4) != '.xml') {
$tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
$tmpdir .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion();
}
 
$this->configSet('default_channel', $channel);
1255,22 → 1358,26
} else {
$filelist = $pkg->getFileList();
}
 
if (PEAR::isError($filelist)) {
return $filelist;
}
 
$p = &$installregistry->getPackage($pkgname, $channel);
$dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false;
 
$pkg->resetFilelist();
$pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(),
'version', $pkg->getChannel()));
foreach ($filelist as $file => $atts) {
$this->expectError(PEAR_INSTALLER_FAILED);
if ($pkg->getPackagexmlVersion() == '1.0') {
$this->expectError(PEAR_INSTALLER_FAILED);
$res = $this->_installFile($file, $atts, $tmp_path, $options);
$this->popExpect();
$res = $this->_installFile($file, $atts, $tmpdir, $options);
} else {
$this->expectError(PEAR_INSTALLER_FAILED);
$res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options);
$this->popExpect();
$res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options);
}
$this->popExpect();
 
if (PEAR::isError($res)) {
if (empty($options['ignore-errors'])) {
$this->rollbackFileTransaction();
1277,14 → 1384,17
if ($res->getMessage() == "file does not exist") {
$this->raiseError("file $file in package.xml does not exist");
}
 
return $this->raiseError($res);
} else {
if (!isset($options['soft'])) {
$this->log(0, "Warning: " . $res->getMessage());
}
}
 
if (!isset($options['soft'])) {
$this->log(0, "Warning: " . $res->getMessage());
}
}
if ($res == PEAR_INSTALLER_OK) {
 
$real = isset($atts['attribs']) ? $atts['attribs'] : $atts;
if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') {
// Register files that were installed
$pkg->installedFile($file, $atts);
}
1303,6 → 1413,7
if (isset($backedup)) {
$this->_removeBackups($backedup);
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
$this->configSet('default_channel', $savechannel);
1310,9 → 1421,9
}
// }}}
 
$ret = false;
$ret = false;
$installphase = 'install';
$oldversion = false;
$oldversion = false;
// {{{ Register that the package is installed -----------------------
if (empty($options['upgrade'])) {
// if 'force' is used, replace the info in registry
1326,6 → 1437,7
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
 
if (!empty($options['force']) && $test) {
$oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel);
$installregistry->deletePackage($pkgname, $usechannel);
1332,6 → 1444,16
}
$ret = $installregistry->addPackage2($pkg);
} else {
if ($dirtree) {
$this->startFileTransaction();
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
$this->commitFileTransaction();
}
 
$usechannel = $channel;
if ($channel == 'pecl.php.net') {
$test = $installregistry->packageExists($pkgname, $channel);
1342,6 → 1464,7
} else {
$test = $installregistry->packageExists($pkgname, $channel);
}
 
// new: upgrade installs a package if it isn't installed
if (!$test) {
$ret = $installregistry->addPackage2($pkg);
1355,11 → 1478,13
$installphase = 'upgrade';
}
}
 
if (!$ret) {
$this->configSet('default_channel', $savechannel);
return $this->raiseError("Adding package $channel/$pkgname to registry failed");
}
// }}}
 
$this->configSet('default_channel', $savechannel);
if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist
if (PEAR_Task_Common::hasPostinstallTasks()) {
1366,6 → 1491,7
PEAR_Task_Common::runPostinstallTasks($installphase);
}
}
 
return $pkg->toArray(true);
}
 
1380,7 → 1506,7
{
require_once 'PEAR/Builder.php';
$this->log(1, "$this->source_files source files, building");
$bob = &new PEAR_Builder($this->ui);
$bob = new PEAR_Builder($this->ui);
$bob->debug = $this->debug;
$built = $bob->build($filelist, array(&$this, '_buildCallback'));
if (PEAR::isError($built)) {
1388,6 → 1514,7
$this->configSet('default_channel', $savechannel);
return $built;
}
 
$this->log(1, "\nBuild process completed successfully");
foreach ($built as $ext) {
$bn = basename($ext['file']);
1402,17 → 1529,17
} else {
$role = 'src';
}
 
$dest = $ext['dest'];
$packagingroot = '';
if (isset($this->_options['packagingroot'])) {
$packagingroot = $this->_options['packagingroot'];
}
 
$copyto = $this->_prependPath($dest, $packagingroot);
if ($copyto != $dest) {
$this->log(1, "Installing '$dest' as '$copyto'");
} else {
$this->log(1, "Installing '$dest'");
}
$extra = $copyto != $dest ? " as '$copyto'" : '';
$this->log(1, "Installing '$dest'$extra");
 
$copydir = dirname($copyto);
// pretty much nothing happens if we are only registering the install
if (empty($this->_options['register-only'])) {
1421,11 → 1548,14
return $this->raiseError("failed to mkdir $copydir",
PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ mkdir $copydir");
}
 
if (!@copy($ext['file'], $copyto)) {
return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED);
}
 
$this->log(3, "+ cp $ext[file] $copyto");
$this->addFileOperation('rename', array($ext['file'], $copyto));
if (!OS_WINDOWS) {
1437,24 → 1567,20
}
}
 
 
$data = array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
);
 
if ($filelist->getPackageXmlVersion() == '1.0') {
$filelist->installedFile($bn, array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
));
$filelist->installedFile($bn, $data);
} else {
$filelist->installedFile($bn, array('attribs' => array(
'role' => $role,
'name' => $bn,
'installed_as' => $dest,
'php_api' => $ext['php_api'],
'zend_mod_api' => $ext['zend_mod_api'],
'zend_ext_api' => $ext['zend_ext_api'],
)));
$filelist->installedFile($bn, array('attribs' => $data));
}
}
}
1481,17 → 1607,14
*/
function uninstall($package, $options = array())
{
if (isset($options['installroot'])) {
$this->config->setInstallRoot($options['installroot']);
$this->installroot = '';
} else {
$this->config->setInstallRoot('');
$this->installroot = '';
}
$installRoot = isset($options['installroot']) ? $options['installroot'] : '';
$this->config->setInstallRoot($installRoot);
 
$this->installroot = '';
$this->_registry = &$this->config->getRegistry();
if (is_object($package)) {
$channel = $package->getChannel();
$pkg = $package;
$pkg = $package;
$package = $pkg->getPackage();
} else {
$pkg = false;
1500,11 → 1623,13
$channel = $info['channel'];
$package = $info['package'];
}
 
$savechannel = $this->config->get('default_channel');
$this->configSet('default_channel', $channel);
if (!is_object($pkg)) {
$pkg = $this->_registry->getPackage($package, $channel);
}
 
if (!$pkg) {
$this->configSet('default_channel', $savechannel);
return $this->raiseError($this->_registry->parsedPackageNameToString(
1513,16 → 1638,19
'package' => $package
), true) . ' not installed');
}
 
if ($pkg->getInstalledBinary()) {
// this is just an alias for a binary package
return $this->_registry->deletePackage($package, $channel);
}
 
$filelist = $pkg->getFilelist();
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
if (!class_exists('PEAR_Dependency2')) {
require_once 'PEAR/Dependency2.php';
}
$depchecker = &new PEAR_Dependency2($this->config, $options,
 
$depchecker = new PEAR_Dependency2($this->config, $options,
array('channel' => $channel, 'package' => $package),
PEAR_VALIDATE_UNINSTALLING);
$e = $depchecker->validatePackageUninstall($this);
1530,16 → 1658,17
if (PEAR::isError($e)) {
if (!isset($options['ignore-errors'])) {
return $this->raiseError($e);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $e->getMessage());
}
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $e->getMessage());
}
} elseif (is_array($e)) {
if (!isset($options['soft'])) {
$this->log(0, $e[0]);
}
}
 
$this->pkginfo = &$pkg;
// pretty much nothing happens if we are only registering the uninstall
if (empty($options['register-only'])) {
1552,38 → 1681,45
$this->configSet('default_channel', $savechannel);
if (!isset($options['ignore-errors'])) {
return $this->raiseError($err);
} else {
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: ' . $err->getMessage());
}
} else {
PEAR::popErrorHandling();
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
} elseif (!isset($options['soft'])) {
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
} else {
$this->startFileTransaction();
if ($dirtree = $pkg->getDirTree()) {
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
} else {
$dirtree = $pkg->getDirTree();
if ($dirtree === false) {
$this->configSet('default_channel', $savechannel);
return $this->_registry->deletePackage($package, $channel);
}
 
// attempt to delete empty directories
uksort($dirtree, array($this, '_sortDirs'));
foreach($dirtree as $dir => $notused) {
$this->addFileOperation('rmdir', array($dir));
}
 
if (!$this->commitFileTransaction()) {
$this->rollbackFileTransaction();
if (!isset($options['ignore-errors'])) {
return $this->raiseError("uninstall failed");
} elseif (!isset($options['soft'])) {
}
 
if (!isset($options['soft'])) {
$this->log(0, 'WARNING: uninstall failed');
}
}
1656,17 → 1792,3
 
// }}}
}
 
// {{{ md5_file() utility function
if (!function_exists("md5_file")) {
function md5_file($filename) {
if (!$fd = @fopen($file, 'r')) {
return false;
}
fclose($fd);
return md5(file_get_contents($filename));
}
}
// }}}
 
?>