diff options
Diffstat (limited to '3dparty/PEAR/Command')
-rw-r--r-- | 3dparty/PEAR/Command/Auth.php | 155 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Build.php | 89 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Common.php | 249 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Config.php | 225 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Install.php | 470 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Mirror.php | 101 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Package.php | 819 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Registry.php | 351 | ||||
-rw-r--r-- | 3dparty/PEAR/Command/Remote.php | 435 |
9 files changed, 2894 insertions, 0 deletions
diff --git a/3dparty/PEAR/Command/Auth.php b/3dparty/PEAR/Command/Auth.php new file mode 100644 index 00000000000..0b9d3d3965d --- /dev/null +++ b/3dparty/PEAR/Command/Auth.php @@ -0,0 +1,155 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Bakken <ssb@php.net> | +// +----------------------------------------------------------------------+ +// +// $Id: Auth.php,v 1.15 2004/01/08 17:33:13 sniper Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Remote.php"; +require_once "PEAR/Config.php"; + +/** + * PEAR commands for managing configuration data. + * + */ +class PEAR_Command_Auth extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'login' => array( + 'summary' => 'Connects and authenticates to remote server', + 'shortcut' => 'li', + 'function' => 'doLogin', + 'options' => array(), + 'doc' => ' +Log in to the remote server. To use remote functions in the installer +that require any kind of privileges, you need to log in first. The +username and password you enter here will be stored in your per-user +PEAR configuration (~/.pearrc on Unix-like systems). After logging +in, your username and password will be sent along in subsequent +operations on the remote server.', + ), + 'logout' => array( + 'summary' => 'Logs out from the remote server', + 'shortcut' => 'lo', + 'function' => 'doLogout', + 'options' => array(), + 'doc' => ' +Logs out from the remote server. This command does not actually +connect to the remote server, it only deletes the stored username and +password from your user configuration.', + ) + + ); + + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Auth constructor. + * + * @access public + */ + function PEAR_Command_Auth(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doLogin() + + /** + * Execute the 'login' command. + * + * @param string $command command name + * + * @param array $options option_name => value + * + * @param array $params list of additional parameters + * + * @return bool TRUE on success, FALSE for unknown commands, or + * a PEAR error on failure + * + * @access public + */ + function doLogin($command, $options, $params) + { + $server = $this->config->get('master_server'); + $remote = new PEAR_Remote($this->config); + $username = $this->config->get('username'); + if (empty($username)) { + $username = @$_ENV['USER']; + } + $this->ui->outputData("Logging in to $server.", $command); + + list($username, $password) = $this->ui->userDialog( + $command, + array('Username', 'Password'), + array('text', 'password'), + array($username, '') + ); + $username = trim($username); + $password = trim($password); + + $this->config->set('username', $username); + $this->config->set('password', $password); + + $remote->expectError(401); + $ok = $remote->call('logintest'); + $remote->popExpect(); + if ($ok === true) { + $this->ui->outputData("Logged in.", $command); + $this->config->store(); + } else { + return $this->raiseError("Login failed!"); + } + + } + + // }}} + // {{{ doLogout() + + /** + * Execute the 'logout' command. + * + * @param string $command command name + * + * @param array $options option_name => value + * + * @param array $params list of additional parameters + * + * @return bool TRUE on success, FALSE for unknown commands, or + * a PEAR error on failure + * + * @access public + */ + function doLogout($command, $options, $params) + { + $server = $this->config->get('master_server'); + $this->ui->outputData("Logging out from $server.", $command); + $this->config->remove('username'); + $this->config->remove('password'); + $this->config->store(); + } + + // }}} +} + +?>
\ No newline at end of file diff --git a/3dparty/PEAR/Command/Build.php b/3dparty/PEAR/Command/Build.php new file mode 100644 index 00000000000..2ecbbc92f5f --- /dev/null +++ b/3dparty/PEAR/Command/Build.php @@ -0,0 +1,89 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Bakken <ssb@php.net> | +// | Tomas V.V.Cox <cox@idecnet.com> | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Build.php,v 1.9 2004/01/08 17:33:13 sniper Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Builder.php"; + +/** + * PEAR commands for building extensions. + * + */ +class PEAR_Command_Build extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'build' => array( + 'summary' => 'Build an Extension From C Source', + 'function' => 'doBuild', + 'shortcut' => 'b', + 'options' => array(), + 'doc' => '[package.xml] +Builds one or more extensions contained in a package.' + ), + ); + + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Build constructor. + * + * @access public + */ + function PEAR_Command_Build(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doBuild() + + function doBuild($command, $options, $params) + { + if (sizeof($params) < 1) { + $params[0] = 'package.xml'; + } + $builder = &new PEAR_Builder($this->ui); + $this->debug = $this->config->get('verbose'); + $err = $builder->build($params[0], array(&$this, 'buildCallback')); + if (PEAR::isError($err)) { + return $err; + } + return true; + } + + // }}} + // {{{ buildCallback() + + function buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } + + // }}} +} diff --git a/3dparty/PEAR/Command/Common.php b/3dparty/PEAR/Command/Common.php new file mode 100644 index 00000000000..c6ace694caf --- /dev/null +++ b/3dparty/PEAR/Command/Common.php @@ -0,0 +1,249 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Sæther Bakken <ssb@php.net> | +// +----------------------------------------------------------------------+ +// +// $Id: Common.php,v 1.24 2004/01/08 17:33:13 sniper Exp $ + +require_once "PEAR.php"; + +class PEAR_Command_Common extends PEAR +{ + // {{{ properties + + /** + * PEAR_Config object used to pass user system and configuration + * on when executing commands + * + * @var object + */ + var $config; + + /** + * User Interface object, for all interaction with the user. + * @var object + */ + var $ui; + + var $_deps_rel_trans = array( + 'lt' => '<', + 'le' => '<=', + 'eq' => '=', + 'ne' => '!=', + 'gt' => '>', + 'ge' => '>=', + 'has' => '==' + ); + + var $_deps_type_trans = array( + 'pkg' => 'package', + 'extension' => 'extension', + 'php' => 'PHP', + 'prog' => 'external program', + 'ldlib' => 'external library for linking', + 'rtlib' => 'external runtime library', + 'os' => 'operating system', + 'websrv' => 'web server', + 'sapi' => 'SAPI backend' + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Common constructor. + * + * @access public + */ + function PEAR_Command_Common(&$ui, &$config) + { + parent::PEAR(); + $this->config = &$config; + $this->ui = &$ui; + } + + // }}} + + // {{{ getCommands() + + /** + * Return a list of all the commands defined by this class. + * @return array list of commands + * @access public + */ + function getCommands() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + $ret[$command] = $this->commands[$command]['summary']; + } + return $ret; + } + + // }}} + // {{{ getShortcuts() + + /** + * Return a list of all the command shortcuts defined by this class. + * @return array shortcut => command + * @access public + */ + function getShortcuts() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + if (isset($this->commands[$command]['shortcut'])) { + $ret[$this->commands[$command]['shortcut']] = $command; + } + } + return $ret; + } + + // }}} + // {{{ getOptions() + + function getOptions($command) + { + return @$this->commands[$command]['options']; + } + + // }}} + // {{{ getGetoptArgs() + + function getGetoptArgs($command, &$short_args, &$long_args) + { + $short_args = ""; + $long_args = array(); + if (empty($this->commands[$command])) { + return; + } + reset($this->commands[$command]); + while (list($option, $info) = each($this->commands[$command]['options'])) { + $larg = $sarg = ''; + if (isset($info['arg'])) { + if ($info['arg']{0} == '(') { + $larg = '=='; + $sarg = '::'; + $arg = substr($info['arg'], 1, -1); + } else { + $larg = '='; + $sarg = ':'; + $arg = $info['arg']; + } + } + if (isset($info['shortopt'])) { + $short_args .= $info['shortopt'] . $sarg; + } + $long_args[] = $option . $larg; + } + } + + // }}} + // {{{ getHelp() + /** + * Returns the help message for the given command + * + * @param string $command The command + * @return mixed A fail string if the command does not have help or + * a two elements array containing [0]=>help string, + * [1]=> help string for the accepted cmd args + */ + function getHelp($command) + { + $config = &PEAR_Config::singleton(); + $help = @$this->commands[$command]['doc']; + if (empty($help)) { + // XXX (cox) Fallback to summary if there is no doc (show both?) + if (!$help = @$this->commands[$command]['summary']) { + return "No help for command \"$command\""; + } + } + if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) { + foreach($matches[0] as $k => $v) { + $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help); + } + } + return array($help, $this->getHelpArgs($command)); + } + + // }}} + // {{{ getHelpArgs() + /** + * Returns the help for the accepted arguments of a command + * + * @param string $command + * @return string The help string + */ + function getHelpArgs($command) + { + if (isset($this->commands[$command]['options']) && + count($this->commands[$command]['options'])) + { + $help = "Options:\n"; + foreach ($this->commands[$command]['options'] as $k => $v) { + if (isset($v['arg'])) { + if ($v['arg']{0} == '(') { + $arg = substr($v['arg'], 1, -1); + $sapp = " [$arg]"; + $lapp = "[=$arg]"; + } else { + $sapp = " $v[arg]"; + $lapp = "=$v[arg]"; + } + } else { + $sapp = $lapp = ""; + } + if (isset($v['shortopt'])) { + $s = $v['shortopt']; + @$help .= " -$s$sapp, --$k$lapp\n"; + } else { + @$help .= " --$k$lapp\n"; + } + $p = " "; + $doc = rtrim(str_replace("\n", "\n$p", $v['doc'])); + $help .= " $doc\n"; + } + return $help; + } + return null; + } + + // }}} + // {{{ run() + + function run($command, $options, $params) + { + $func = @$this->commands[$command]['function']; + if (empty($func)) { + // look for shortcuts + foreach (array_keys($this->commands) as $cmd) { + if (@$this->commands[$cmd]['shortcut'] == $command) { + $command = $cmd; + $func = @$this->commands[$command]['function']; + if (empty($func)) { + return $this->raiseError("unknown command `$command'"); + } + break; + } + } + } + return $this->$func($command, $options, $params); + } + + // }}} +} + +?>
\ No newline at end of file diff --git a/3dparty/PEAR/Command/Config.php b/3dparty/PEAR/Command/Config.php new file mode 100644 index 00000000000..474a2345170 --- /dev/null +++ b/3dparty/PEAR/Command/Config.php @@ -0,0 +1,225 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Bakken <ssb@php.net> | +// | Tomas V.V.Cox <cox@idecnet.com> | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Config.php,v 1.27 2004/06/15 16:48:49 pajoye Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Config.php"; + +/** + * PEAR commands for managing configuration data. + * + */ +class PEAR_Command_Config extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'config-show' => array( + 'summary' => 'Show All Settings', + 'function' => 'doConfigShow', + 'shortcut' => 'csh', + 'options' => array(), + 'doc' => ' +Displays all configuration values. An optional argument +may be used to tell which configuration layer to display. Valid +configuration layers are "user", "system" and "default". +', + ), + 'config-get' => array( + 'summary' => 'Show One Setting', + 'function' => 'doConfigGet', + 'shortcut' => 'cg', + 'options' => array(), + 'doc' => '<parameter> [layer] +Displays the value of one configuration parameter. The +first argument is the name of the parameter, an optional second argument +may be used to tell which configuration layer to look in. Valid configuration +layers are "user", "system" and "default". If no layer is specified, a value +will be picked from the first layer that defines the parameter, in the order +just specified. +', + ), + 'config-set' => array( + 'summary' => 'Change Setting', + 'function' => 'doConfigSet', + 'shortcut' => 'cs', + 'options' => array(), + 'doc' => '<parameter> <value> [layer] +Sets the value of one configuration parameter. The first argument is +the name of the parameter, the second argument is the new value. Some +parameters are subject to validation, and the command will fail with +an error message if the new value does not make sense. An optional +third argument may be used to specify in which layer to set the +configuration parameter. The default layer is "user". +', + ), + 'config-help' => array( + 'summary' => 'Show Information About Setting', + 'function' => 'doConfigHelp', + 'shortcut' => 'ch', + 'options' => array(), + 'doc' => '[parameter] +Displays help for a configuration parameter. Without arguments it +displays help for all configuration parameters. +', + ), + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Config constructor. + * + * @access public + */ + function PEAR_Command_Config(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doConfigShow() + + function doConfigShow($command, $options, $params) + { + // $params[0] -> the layer + if ($error = $this->_checkLayer(@$params[0])) { + return $this->raiseError($error); + } + $keys = $this->config->getKeys(); + sort($keys); + $data = array('caption' => 'Configuration:'); + foreach ($keys as $key) { + $type = $this->config->getType($key); + $value = $this->config->get($key, @$params[0]); + if ($type == 'password' && $value) { + $value = '********'; + } + if ($value === false) { + $value = 'false'; + } elseif ($value === true) { + $value = 'true'; + } + $data['data'][$this->config->getGroup($key)][] = array($this->config->getPrompt($key) , $key, $value); + } + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doConfigGet() + + function doConfigGet($command, $options, $params) + { + // $params[0] -> the parameter + // $params[1] -> the layer + if ($error = $this->_checkLayer(@$params[1])) { + return $this->raiseError($error); + } + if (sizeof($params) < 1 || sizeof($params) > 2) { + return $this->raiseError("config-get expects 1 or 2 parameters"); + } elseif (sizeof($params) == 1) { + $this->ui->outputData($this->config->get($params[0]), $command); + } else { + $data = $this->config->get($params[0], $params[1]); + $this->ui->outputData($data, $command); + } + return true; + } + + // }}} + // {{{ doConfigSet() + + function doConfigSet($command, $options, $params) + { + // $param[0] -> a parameter to set + // $param[1] -> the value for the parameter + // $param[2] -> the layer + $failmsg = ''; + if (sizeof($params) < 2 || sizeof($params) > 3) { + $failmsg .= "config-set expects 2 or 3 parameters"; + return PEAR::raiseError($failmsg); + } + if ($error = $this->_checkLayer(@$params[2])) { + $failmsg .= $error; + return PEAR::raiseError($failmsg); + } + if (!call_user_func_array(array(&$this->config, 'set'), $params)) + { + $failmsg = "config-set (" . implode(", ", $params) . ") failed"; + } else { + $this->config->store(); + } + if ($failmsg) { + return $this->raiseError($failmsg); + } + return true; + } + + // }}} + // {{{ doConfigHelp() + + function doConfigHelp($command, $options, $params) + { + if (empty($params)) { + $params = $this->config->getKeys(); + } + $data['caption'] = "Config help" . ((count($params) == 1) ? " for $params[0]" : ''); + $data['headline'] = array('Name', 'Type', 'Description'); + $data['border'] = true; + foreach ($params as $name) { + $type = $this->config->getType($name); + $docs = $this->config->getDocs($name); + if ($type == 'set') { + $docs = rtrim($docs) . "\nValid set: " . + implode(' ', $this->config->getSetValues($name)); + } + $data['data'][] = array($name, $type, $docs); + } + $this->ui->outputData($data, $command); + } + + // }}} + // {{{ _checkLayer() + + /** + * Checks if a layer is defined or not + * + * @param string $layer The layer to search for + * @return mixed False on no error or the error message + */ + function _checkLayer($layer = null) + { + if (!empty($layer) && $layer != 'default') { + $layers = $this->config->getLayers(); + if (!in_array($layer, $layers)) { + return " only the layers: \"" . implode('" or "', $layers) . "\" are supported"; + } + } + return false; + } + + // }}} +} + +?> diff --git a/3dparty/PEAR/Command/Install.php b/3dparty/PEAR/Command/Install.php new file mode 100644 index 00000000000..dce52f017e2 --- /dev/null +++ b/3dparty/PEAR/Command/Install.php @@ -0,0 +1,470 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Sæther Bakken <ssb@php.net> | +// +----------------------------------------------------------------------+ +// +// $Id: Install.php,v 1.53.2.1 2004/10/19 04:08:42 cellog Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Installer.php"; + +/** + * PEAR commands for installation or deinstallation/upgrading of + * packages. + * + */ +class PEAR_Command_Install extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'install' => array( + 'summary' => 'Install Package', + 'function' => 'doInstall', + 'shortcut' => 'i', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'will overwrite newer installed packages', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, install anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as installed', + ), + 'soft' => array( + 'shortopt' => 's', + 'doc' => 'soft install, fail silently, or upgrade if already installed', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'alldeps' => array( + 'shortopt' => 'a', + 'doc' => 'install all required and optional dependencies', + ), + 'onlyreqdeps' => array( + 'shortopt' => 'o', + 'doc' => 'install all required dependencies', + ), + ), + 'doc' => '<package> ... +Installs one or more PEAR packages. You can specify a package to +install in four ways: + +"Package-1.0.tgz" : installs from a local file + +"http://example.com/Package-1.0.tgz" : installs from +anywhere on the net. + +"package.xml" : installs the package described in +package.xml. Useful for testing, or for wrapping a PEAR package in +another package manager such as RPM. + +"Package" : queries your configured server +({config master_server}) and downloads the newest package with +the preferred quality/state ({config preferred_state}). + +More than one package may be specified at once. It is ok to mix these +four ways of specifying packages. +'), + 'upgrade' => array( + 'summary' => 'Upgrade Package', + 'function' => 'doInstall', + 'shortcut' => 'up', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'overwrite newer installed packages', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'alldeps' => array( + 'shortopt' => 'a', + 'doc' => 'install all required and optional dependencies', + ), + 'onlyreqdeps' => array( + 'shortopt' => 'o', + 'doc' => 'install all required dependencies', + ), + ), + 'doc' => '<package> ... +Upgrades one or more PEAR packages. See documentation for the +"install" command for ways to specify a package. + +When upgrading, your package will be updated if the provided new +package has a higher version number (use the -f option if you need to +upgrade anyway). + +More than one package may be specified at once. +'), + 'upgrade-all' => array( + 'summary' => 'Upgrade All Packages', + 'function' => 'doInstall', + 'shortcut' => 'ua', + 'options' => array( + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + ), + 'doc' => ' +Upgrades all packages that have a newer release available. Upgrades are +done only if there is a release available of the state specified in +"preferred_state" (currently {config preferred_state}), or a state considered +more stable. +'), + 'uninstall' => array( + 'summary' => 'Un-install Package', + 'function' => 'doUninstall', + 'shortcut' => 'un', + 'options' => array( + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, uninstall anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not remove files, only register the packages as not installed', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + ), + 'doc' => '<package> ... +Uninstalls one or more PEAR packages. More than one package may be +specified at once. +'), + 'bundle' => array( + 'summary' => 'Unpacks a Pecl Package', + 'function' => 'doBundle', + 'shortcut' => 'bun', + 'options' => array( + 'destination' => array( + 'shortopt' => 'd', + 'arg' => 'DIR', + 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', + ), + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'Force the unpacking even if there were errors in the package', + ), + ), + 'doc' => '<package> +Unpacks a Pecl Package into the selected location. It will download the +package if needed. +'), + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Install constructor. + * + * @access public + */ + function PEAR_Command_Install(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doInstall() + + function doInstall($command, $options, $params) + { + require_once 'PEAR/Downloader.php'; + if (empty($this->installer)) { + $this->installer = &new PEAR_Installer($this->ui); + } + if ($command == 'upgrade') { + $options['upgrade'] = true; + } + if ($command == 'upgrade-all') { + include_once "PEAR/Remote.php"; + $options['upgrade'] = true; + $remote = &new PEAR_Remote($this->config); + $state = $this->config->get('preferred_state'); + if (empty($state) || $state == 'any') { + $latest = $remote->call("package.listLatestReleases"); + } else { + $latest = $remote->call("package.listLatestReleases", $state); + } + if (PEAR::isError($latest)) { + return $latest; + } + $reg = new PEAR_Registry($this->config->get('php_dir')); + $installed = array_flip($reg->listPackages()); + $params = array(); + foreach ($latest as $package => $info) { + $package = strtolower($package); + if (!isset($installed[$package])) { + // skip packages we don't have installed + continue; + } + $inst_version = $reg->packageInfo($package, 'version'); + if (version_compare("$info[version]", "$inst_version", "le")) { + // installed version is up-to-date + continue; + } + $params[] = $package; + $this->ui->outputData(array('data' => "Will upgrade $package"), $command); + } + } + $this->downloader = &new PEAR_Downloader($this->ui, $options, $this->config); + $errors = array(); + $downloaded = array(); + $this->downloader->download($params); + $errors = $this->downloader->getErrorMsgs(); + if (count($errors)) { + $err['data'] = array($errors); + $err['headline'] = 'Install Errors'; + $this->ui->outputData($err); + return $this->raiseError("$command failed"); + } + $downloaded = $this->downloader->getDownloadedPackages(); + $this->installer->sortPkgDeps($downloaded); + foreach ($downloaded as $pkg) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->install($pkg['file'], $options, $this->config); + PEAR::popErrorHandling(); + if (PEAR::isError($info)) { + $this->ui->outputData('ERROR: ' .$info->getMessage()); + continue; + } + if (is_array($info)) { + if ($this->config->get('verbose') > 0) { + $label = "$info[package] $info[version]"; + $out = array('data' => "$command ok: $label"); + if (isset($info['release_warnings'])) { + $out['release_warnings'] = $info['release_warnings']; + } + $this->ui->outputData($out, $command); + } + } else { + return $this->raiseError("$command failed"); + } + } + return true; + } + + // }}} + // {{{ doUninstall() + + function doUninstall($command, $options, $params) + { + if (empty($this->installer)) { + $this->installer = &new PEAR_Installer($this->ui); + } + if (sizeof($params) < 1) { + return $this->raiseError("Please supply the package(s) you want to uninstall"); + } + include_once 'PEAR/Registry.php'; + $reg = new PEAR_Registry($this->config->get('php_dir')); + $newparams = array(); + $badparams = array(); + foreach ($params as $pkg) { + $info = $reg->packageInfo($pkg); + if ($info === null) { + $badparams[] = $pkg; + } else { + $newparams[] = $info; + } + } + $this->installer->sortPkgDeps($newparams, true); + $params = array(); + foreach($newparams as $info) { + $params[] = $info['info']['package']; + } + $params = array_merge($params, $badparams); + foreach ($params as $pkg) { + if ($this->installer->uninstall($pkg, $options)) { + if ($this->config->get('verbose') > 0) { + $this->ui->outputData("uninstall ok: $pkg", $command); + } + } else { + return $this->raiseError("uninstall failed: $pkg"); + } + } + return true; + } + + // }}} + + + // }}} + // {{{ doBundle() + /* + (cox) It just downloads and untars the package, does not do + any check that the PEAR_Installer::_installFile() does. + */ + + function doBundle($command, $options, $params) + { + if (empty($this->installer)) { + $this->installer = &new PEAR_Downloader($this->ui); + } + $installer = &$this->installer; + if (sizeof($params) < 1) { + return $this->raiseError("Please supply the package you want to bundle"); + } + $pkgfile = $params[0]; + $need_download = false; + if (preg_match('#^(http|ftp)://#', $pkgfile)) { + $need_download = true; + } elseif (!@is_file($pkgfile)) { + if ($installer->validPackageName($pkgfile)) { + $pkgfile = $installer->getPackageDownloadUrl($pkgfile); + $need_download = true; + } else { + if (strlen($pkgfile)) { + return $this->raiseError("Could not open the package file: $pkgfile"); + } else { + return $this->raiseError("No package file given"); + } + } + } + + // Download package ----------------------------------------------- + if ($need_download) { + $downloaddir = $installer->config->get('download_dir'); + if (empty($downloaddir)) { + if (PEAR::isError($downloaddir = System::mktemp('-d'))) { + return $downloaddir; + } + $installer->log(2, '+ tmp dir created at ' . $downloaddir); + } + $callback = $this->ui ? array(&$installer, '_downloadCallback') : null; + $file = $installer->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback); + if (PEAR::isError($file)) { + return $this->raiseError($file); + } + $pkgfile = $file; + } + + // Parse xml file ----------------------------------------------- + $pkginfo = $installer->infoFromTgzFile($pkgfile); + if (PEAR::isError($pkginfo)) { + return $this->raiseError($pkginfo); + } + $installer->validatePackageInfo($pkginfo, $errors, $warnings); + // XXX We allow warnings, do we have to do it? + if (count($errors)) { + if (empty($options['force'])) { + return $this->raiseError("The following errors where found:\n". + implode("\n", $errors)); + } else { + $this->log(0, "warning : the following errors were found:\n". + implode("\n", $errors)); + } + } + $pkgname = $pkginfo['package']; + + // Unpacking ------------------------------------------------- + + if (isset($options['destination'])) { + if (!is_dir($options['destination'])) { + System::mkdir('-p ' . $options['destination']); + } + $dest = realpath($options['destination']); + } else { + $pwd = getcwd(); + if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) { + $dest = $pwd . DIRECTORY_SEPARATOR . 'ext'; + } else { + $dest = $pwd; + } + } + $dest .= DIRECTORY_SEPARATOR . $pkgname; + $orig = $pkgname . '-' . $pkginfo['version']; + + $tar = new Archive_Tar($pkgfile); + if (!@$tar->extractModify($dest, $orig)) { + return $this->raiseError("unable to unpack $pkgfile"); + } + $this->ui->outputData("Package ready at '$dest'"); + // }}} + } + + // }}} + +} +?> diff --git a/3dparty/PEAR/Command/Mirror.php b/3dparty/PEAR/Command/Mirror.php new file mode 100644 index 00000000000..bf56c3db640 --- /dev/null +++ b/3dparty/PEAR/Command/Mirror.php @@ -0,0 +1,101 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Alexander Merz <alexmerz@php.net> | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Mirror.php,v 1.5 2004/03/18 12:23:57 mj Exp $ + +require_once "PEAR/Command/Common.php"; +require_once "PEAR/Command.php"; +require_once "PEAR/Remote.php"; +require_once "PEAR.php"; + +/** + * PEAR commands for providing file mirrors + * + */ +class PEAR_Command_Mirror extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'download-all' => array( + 'summary' => 'Downloads each available package from master_server', + 'function' => 'doDownloadAll', + 'shortcut' => 'da', + 'options' => array(), + 'doc' => ' + Requests a list of available packages from the package server + (master_server) and downloads them to current working directory' + ), + ); + + // }}} + + // {{{ constructor + + /** + * PEAR_Command_Mirror constructor. + * + * @access public + * @param object PEAR_Frontend a reference to an frontend + * @param object PEAR_Config a reference to the configuration data + */ + function PEAR_Command_Mirror(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doDownloadAll() + /** + * retrieves a list of avaible Packages from master server + * and downloads them + * + * @access public + * @param string $command the command + * @param array $options the command options before the command + * @param array $params the stuff after the command name + * @return bool true if succesful + * @throw PEAR_Error + */ + function doDownloadAll($command, $options, $params) + { + $this->config->set("php_dir", "."); + $remote = &new PEAR_Remote($this->config); + $remoteInfo = $remote->call("package.listAll"); + if (PEAR::isError($remoteInfo)) { + return $remoteInfo; + } + $cmd = &PEAR_Command::factory("download", $this->config); + if (PEAR::isError($cmd)) { + return $cmd; + } + foreach ($remoteInfo as $pkgn => $pkg) { + /** + * Error handling not neccesary, because already done by + * the download command + */ + $cmd->run("download", array(), array($pkgn)); + } + + return true; + } + + // }}} +} diff --git a/3dparty/PEAR/Command/Package.php b/3dparty/PEAR/Command/Package.php new file mode 100644 index 00000000000..aca87111118 --- /dev/null +++ b/3dparty/PEAR/Command/Package.php @@ -0,0 +1,819 @@ +<?php +// +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Authors: Stig Bakken <ssb@php.net> | +// | Martin Jansen <mj@php.net> | +// | Greg Beaver <cellog@php.net> | +// +----------------------------------------------------------------------+ +// +// $Id: Package.php,v 1.61.2.7 2005/02/17 17:47:55 cellog Exp $ + +require_once 'PEAR/Common.php'; +require_once 'PEAR/Command/Common.php'; + +class PEAR_Command_Package extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'package' => array( + 'summary' => 'Build Package', + 'function' => 'doPackage', + 'shortcut' => 'p', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'Do not gzip the package file' + ), + 'showname' => array( + 'shortopt' => 'n', + 'doc' => 'Print the name of the packaged file.', + ), + ), + 'doc' => '[descfile] +Creates a PEAR package from its description file (usually called +package.xml). +' + ), + 'package-validate' => array( + 'summary' => 'Validate Package Consistency', + 'function' => 'doPackageValidate', + 'shortcut' => 'pv', + 'options' => array(), + 'doc' => ' +', + ), + 'cvsdiff' => array( + 'summary' => 'Run a "cvs diff" for all files in a package', + 'function' => 'doCvsDiff', + 'shortcut' => 'cd', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'date' => array( + 'shortopt' => 'D', + 'doc' => 'Diff against revision of DATE', + 'arg' => 'DATE', + ), + 'release' => array( + 'shortopt' => 'R', + 'doc' => 'Diff against tag for package release REL', + 'arg' => 'REL', + ), + 'revision' => array( + 'shortopt' => 'r', + 'doc' => 'Diff against revision REV', + 'arg' => 'REV', + ), + 'context' => array( + 'shortopt' => 'c', + 'doc' => 'Generate context diff', + ), + 'unified' => array( + 'shortopt' => 'u', + 'doc' => 'Generate unified diff', + ), + 'ignore-case' => array( + 'shortopt' => 'i', + 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', + ), + 'ignore-whitespace' => array( + 'shortopt' => 'b', + 'doc' => 'Ignore changes in amount of white space', + ), + 'ignore-blank-lines' => array( + 'shortopt' => 'B', + 'doc' => 'Ignore changes that insert or delete blank lines', + ), + 'brief' => array( + 'doc' => 'Report only whether the files differ, no details', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => '<package.xml> +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. +', + ), + 'cvstag' => array( + 'summary' => 'Set CVS Release Tag', + 'function' => 'doCvsTag', + 'shortcut' => 'ct', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => '<package.xml> +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. +', + ), + 'run-tests' => array( + 'summary' => 'Run Regression Tests', + 'function' => 'doRunTests', + 'shortcut' => 'rt', + 'options' => array( + 'recur' => array( + 'shortopt' => 'r', + 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', + ), + 'ini' => array( + 'shortopt' => 'i', + 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', + 'arg' => 'SETTINGS' + ), + 'realtimelog' => array( + 'shortopt' => 'l', + 'doc' => 'Log test runs/results as they are run', + ), + ), + 'doc' => '[testfile|dir ...] +Run regression tests with PHP\'s regression testing script (run-tests.php).', + ), + 'package-dependencies' => array( + 'summary' => 'Show package dependencies', + 'function' => 'doPackageDependencies', + 'shortcut' => 'pd', + 'options' => array(), + 'doc' => ' +List all depencies the package has.' + ), + 'sign' => array( + 'summary' => 'Sign a package distribution file', + 'function' => 'doSign', + 'shortcut' => 'si', + 'options' => array(), + 'doc' => '<package-file> +Signs a package distribution (.tar or .tgz) file with GnuPG.', + ), + 'makerpm' => array( + 'summary' => 'Builds an RPM spec file from a PEAR package', + 'function' => 'doMakeRPM', + 'shortcut' => 'rpm', + 'options' => array( + 'spec-template' => array( + 'shortopt' => 't', + 'arg' => 'FILE', + 'doc' => 'Use FILE as RPM spec file template' + ), + 'rpm-pkgname' => array( + 'shortopt' => 'p', + 'arg' => 'FORMAT', + 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced +by the PEAR package name, defaults to "PEAR::%s".', + ), + ), + 'doc' => '<package-file> + +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: + +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm +', + ), + ); + + var $output; + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Package constructor. + * + * @access public + */ + function PEAR_Command_Package(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ _displayValidationResults() + + function _displayValidationResults($err, $warn, $strict = false) + { + foreach ($err as $e) { + $this->output .= "Error: $e\n"; + } + foreach ($warn as $w) { + $this->output .= "Warning: $w\n"; + } + $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", + sizeof($err), sizeof($warn)); + if ($strict && sizeof($err) > 0) { + $this->output .= "Fix these errors and try again."; + return false; + } + return true; + } + + // }}} + // {{{ doPackage() + + function doPackage($command, $options, $params) + { + $this->output = ''; + include_once 'PEAR/Packager.php'; + if (sizeof($params) < 1) { + $params[0] = "package.xml"; + } + $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; + $packager =& new PEAR_Packager(); + $err = $warn = array(); + $dir = dirname($pkginfofile); + $compress = empty($options['nocompress']) ? true : false; + $result = $packager->package($pkginfofile, $compress); + if (PEAR::isError($result)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError($result); + } + // Don't want output, only the package file name just created + if (isset($options['showname'])) { + $this->output = $result; + } + if (PEAR::isError($result)) { + $this->output .= "Package failed: ".$result->getMessage(); + } + $this->ui->outputData($this->output, $command); + return true; + } + + // }}} + // {{{ doPackageValidate() + + function doPackageValidate($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $params[0] = "package.xml"; + } + $obj = new PEAR_Common; + $info = null; + if ($fp = @fopen($params[0], "r")) { + $test = fread($fp, 5); + fclose($fp); + if ($test == "<?xml") { + $info = $obj->infoFromDescriptionFile($params[0]); + } + } + if (empty($info)) { + $info = $obj->infoFromTgzFile($params[0]); + } + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + $obj->validatePackageInfo($info, $err, $warn); + $this->_displayValidationResults($err, $warn); + $this->ui->outputData($this->output, $command); + return true; + } + + // }}} + // {{{ doCvsTag() + + function doCvsTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + $obj = new PEAR_Common; + $info = $obj->infoFromDescriptionFile($params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + $err = $warn = array(); + $obj->validatePackageInfo($info, $err, $warn); + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + break; + } + $version = $info['version']; + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); + $cvstag = "RELEASE_$cvsversion"; + $files = array_keys($info['filelist']); + $command = "cvs"; + if (isset($options['quiet'])) { + $command .= ' -q'; + } + if (isset($options['reallyquiet'])) { + $command .= ' -Q'; + } + $command .= ' tag'; + if (isset($options['slide'])) { + $command .= ' -F'; + } + if (isset($options['delete'])) { + $command .= ' -d'; + } + $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); + foreach ($files as $file) { + $command .= ' ' . escapeshellarg($file); + } + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + $this->ui->outputData($this->output, $_cmd); + return true; + } + + // }}} + // {{{ doCvsDiff() + + function doCvsDiff($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + $obj = new PEAR_Common; + $info = $obj->infoFromDescriptionFile($params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + $files = array_keys($info['filelist']); + $cmd = "cvs"; + if (isset($options['quiet'])) { + $cmd .= ' -q'; + unset($options['quiet']); + } + if (isset($options['reallyquiet'])) { + $cmd .= ' -Q'; + unset($options['reallyquiet']); + } + if (isset($options['release'])) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); + $cvstag = "RELEASE_$cvsversion"; + $options['revision'] = $cvstag; + unset($options['release']); + } + $execute = true; + if (isset($options['dry-run'])) { + $execute = false; + unset($options['dry-run']); + } + $cmd .= ' diff'; + // the rest of the options are passed right on to "cvs diff" + foreach ($options as $option => $optarg) { + $arg = @$this->commands[$command]['options'][$option]['arg']; + $short = @$this->commands[$command]['options'][$option]['shortopt']; + $cmd .= $short ? " -$short" : " --$option"; + if ($arg && $optarg) { + $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); + } + } + foreach ($files as $file) { + $cmd .= ' ' . escapeshellarg($file); + } + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $cmd\n"; + } + if ($execute) { + $fp = popen($cmd, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + $this->ui->outputData($this->output, $command); + return true; + } + + // }}} + // {{{ doRunTests() + + function doRunTests($command, $options, $params) + { + include_once 'PEAR/RunTest.php'; + $log = new PEAR_Common; + $log->ui = &$this->ui; // slightly hacky, but it will work + $run = new PEAR_RunTest($log); + $tests = array(); + if (isset($options['recur'])) { + $depth = 4; + } else { + $depth = 1; + } + if (!count($params)) { + $params[] = '.'; + } + foreach ($params as $p) { + if (is_dir($p)) { + $dir = System::find(array($p, '-type', 'f', + '-maxdepth', $depth, + '-name', '*.phpt')); + $tests = array_merge($tests, $dir); + } else { + if (!@file_exists($p)) { + if (!preg_match('/\.phpt$/', $p)) { + $p .= '.phpt'; + } + $dir = System::find(array(dirname($p), '-type', 'f', + '-maxdepth', $depth, + '-name', $p)); + $tests = array_merge($tests, $dir); + } else { + $tests[] = $p; + } + } + } + $ini_settings = ''; + if (isset($options['ini'])) { + $ini_settings .= $options['ini']; + } + if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { + $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; + } + if ($ini_settings) { + $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); + } + $skipped = $passed = $failed = array(); + $this->ui->outputData('Running ' . count($tests) . ' tests', $command); + $start = time(); + if (isset($options['realtimelog'])) { + @unlink('run-tests.log'); + } + foreach ($tests as $t) { + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "Running test $t..."); + fclose($fp); + } + } + $result = $run->run($t, $ini_settings); + if (OS_WINDOWS) { + for($i=0;$i<2000;$i++) { + $i = $i; // delay - race conditions on windows + } + } + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "$result\n"); + fclose($fp); + } + } + if ($result == 'FAILED') { + $failed[] = $t; + } + if ($result == 'PASSED') { + $passed[] = $t; + } + if ($result == 'SKIPPED') { + $skipped[] = $t; + } + } + $total = date('i:s', time() - $start); + if (count($failed)) { + $output = "TOTAL TIME: $total\n"; + $output .= count($passed) . " PASSED TESTS\n"; + $output .= count($skipped) . " SKIPPED TESTS\n"; + $output .= count($failed) . " FAILED TESTS:\n"; + foreach ($failed as $failure) { + $output .= $failure . "\n"; + } + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + } else { + $fp = @fopen('run-tests.log', 'w'); + } + if ($fp) { + fwrite($fp, $output, strlen($output)); + fclose($fp); + $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); + } + } elseif (@file_exists('run-tests.log') && !@is_dir('run-tests.log')) { + @unlink('run-tests.log'); + } + $this->ui->outputData('TOTAL TIME: ' . $total); + $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); + $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); + if (count($failed)) { + $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); + foreach ($failed as $failure) { + $this->ui->outputData($failure, $command); + } + } + + return true; + } + + // }}} + // {{{ doPackageDependencies() + + function doPackageDependencies($command, $options, $params) + { + // $params[0] -> the PEAR package to list its information + if (sizeof($params) != 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + $obj = new PEAR_Common(); + if (PEAR::isError($info = $obj->infoFromAny($params[0]))) { + return $this->raiseError($info); + } + + if (is_array($info['release_deps'])) { + $data = array( + 'caption' => 'Dependencies for ' . $info['package'], + 'border' => true, + 'headline' => array("Type", "Name", "Relation", "Version"), + ); + + foreach ($info['release_deps'] as $d) { + + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + + if (isset($d['name'])) { + $name = $d['name']; + } else { + $name = ''; + } + + if (isset($d['version'])) { + $version = $d['version']; + } else { + $version = ''; + } + + $data['data'][] = array($type, $name, $rel, $version); + } + + $this->ui->outputData($data, $command); + return true; + } + + // Fallback + $this->ui->outputData("This package does not have any dependencies.", $command); + } + + // }}} + // {{{ doSign() + + function doSign($command, $options, $params) + { + // should move most of this code into PEAR_Packager + // so it'll be easy to implement "pear package --sign" + if (sizeof($params) != 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + $obj = new PEAR_Common; + $info = $obj->infoFromTgzFile($params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + include_once "Archive/Tar.php"; + include_once "System.php"; + $tar = new Archive_Tar($params[0]); + $tmpdir = System::mktemp('-d pearsign'); + if (!$tar->extractList('package.xml package.sig', $tmpdir)) { + return $this->raiseError("failed to extract tar file"); + } + if (file_exists("$tmpdir/package.sig")) { + return $this->raiseError("package already signed"); + } + @unlink("$tmpdir/package.sig"); + $input = $this->ui->userDialog($command, + array('GnuPG Passphrase'), + array('password')); + $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/package.xml 2>/dev/null", "w"); + if (!$gpg) { + return $this->raiseError("gpg command failed"); + } + fwrite($gpg, "$input[0]\r"); + if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { + return $this->raiseError("gpg sign failed"); + } + $tar->addModify("$tmpdir/package.sig", '', $tmpdir); + return true; + } + + // }}} + // {{{ doMakeRPM() + + /* + + (cox) + + TODO: + + - Fill the rpm dependencies in the template file. + + IDEAS: + + - Instead of mapping the role to rpm vars, perhaps it's better + + to use directly the pear cmd to install the files by itself + + in %postrun so: + + pear -d php_dir=%{_libdir}/php/pear -d test_dir=.. <package> + + */ + + function doMakeRPM($command, $options, $params) + { + if (sizeof($params) != 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + include_once "Archive/Tar.php"; + include_once "PEAR/Installer.php"; + include_once "System.php"; + $tar = new Archive_Tar($params[0]); + $tmpdir = System::mktemp('-d pear2rpm'); + $instroot = System::mktemp('-d pear2rpm'); + $tmp = $this->config->get('verbose'); + $this->config->set('verbose', 0); + $installer = new PEAR_Installer($this->ui); + $info = $installer->install($params[0], + array('installroot' => $instroot, + 'nodeps' => true)); + $pkgdir = "$info[package]-$info[version]"; + $info['rpm_xml_dir'] = '/var/lib/pear'; + $this->config->set('verbose', $tmp); + if (!$tar->extractList("package.xml", $tmpdir, $pkgdir)) { + return $this->raiseError("failed to extract $params[0]"); + } + if (!file_exists("$tmpdir/package.xml")) { + return $this->raiseError("no package.xml found in $params[0]"); + } + if (isset($options['spec-template'])) { + $spec_template = $options['spec-template']; + } else { + $spec_template = $this->config->get('data_dir') . + '/PEAR/template.spec'; + } + if (isset($options['rpm-pkgname'])) { + $rpm_pkgname_format = $options['rpm-pkgname']; + } else { + $rpm_pkgname_format = "PEAR::%s"; + } + + $info['extra_headers'] = ''; + $info['doc_files'] = ''; + $info['files'] = ''; + $info['rpm_package'] = sprintf($rpm_pkgname_format, $info['package']); + $srcfiles = 0; + foreach ($info['filelist'] as $name => $attr) { + + if (!isset($attr['role'])) { + continue; + } + $name = preg_replace('![/:\\\\]!', '/', $name); + if ($attr['role'] == 'doc') { + $info['doc_files'] .= " $name"; + + // Map role to the rpm vars + } else { + + $c_prefix = '%{_libdir}/php/pear'; + + switch ($attr['role']) { + + case 'php': + + $prefix = $c_prefix; break; + + case 'ext': + + $prefix = '%{_libdir}/php'; break; // XXX good place? + + case 'src': + + $srcfiles++; + + $prefix = '%{_includedir}/php'; break; // XXX good place? + + case 'test': + + $prefix = "$c_prefix/tests/" . $info['package']; break; + + case 'data': + + $prefix = "$c_prefix/data/" . $info['package']; break; + + case 'script': + + $prefix = '%{_bindir}'; break; + + } + + $name = str_replace('\\', '/', $name); + $info['files'] .= "$prefix/$name\n"; + + } + } + if ($srcfiles > 0) { + include_once "OS/Guess.php"; + $os = new OS_Guess; + $arch = $os->getCpu(); + } else { + $arch = 'noarch'; + } + $cfg = array('master_server', 'php_dir', 'ext_dir', 'doc_dir', + 'bin_dir', 'data_dir', 'test_dir'); + foreach ($cfg as $k) { + $info[$k] = $this->config->get($k); + } + $info['arch'] = $arch; + $fp = @fopen($spec_template, "r"); + if (!$fp) { + return $this->raiseError("could not open RPM spec file template $spec_template: $php_errormsg"); + } + $spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\1"]', fread($fp, filesize($spec_template))); + fclose($fp); + $spec_file = "$info[rpm_package]-$info[version].spec"; + $wp = fopen($spec_file, "wb"); + if (!$wp) { + return $this->raiseError("could not write RPM spec file $spec_file: $php_errormsg"); + } + fwrite($wp, $spec_contents); + fclose($wp); + $this->ui->outputData("Wrote RPM spec file $spec_file", $command); + + return true; + } + + // }}} +} + +?> diff --git a/3dparty/PEAR/Command/Registry.php b/3dparty/PEAR/Command/Registry.php new file mode 100644 index 00000000000..62cb4b00e28 --- /dev/null +++ b/3dparty/PEAR/Command/Registry.php @@ -0,0 +1,351 @@ +<?php +// /* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Bakken <ssb@php.net> | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Registry.php,v 1.36 2004/01/08 17:33:13 sniper Exp $ + +require_once 'PEAR/Command/Common.php'; +require_once 'PEAR/Registry.php'; +require_once 'PEAR/Config.php'; + +class PEAR_Command_Registry extends PEAR_Command_Common +{ + // {{{ properties + + var $commands = array( + 'list' => array( + 'summary' => 'List Installed Packages', + 'function' => 'doList', + 'shortcut' => 'l', + 'options' => array(), + 'doc' => '[package] +If invoked without parameters, this command lists the PEAR packages +installed in your php_dir ({config php_dir)). With a parameter, it +lists the files in that package. +', + ), + 'shell-test' => array( + 'summary' => 'Shell Script Test', + 'function' => 'doShellTest', + 'shortcut' => 'st', + 'options' => array(), + 'doc' => '<package> [[relation] version] +Tests if a package is installed in the system. Will exit(1) if it is not. + <relation> The version comparison operator. One of: + <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne + <version> The version to compare with +'), + 'info' => array( + 'summary' => 'Display information about a package', + 'function' => 'doInfo', + 'shortcut' => 'in', + 'options' => array(), + 'doc' => '<package> +Displays information about a package. The package argument may be a +local package file, an URL to a package file, or the name of an +installed package.' + ) + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Registry constructor. + * + * @access public + */ + function PEAR_Command_Registry(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doList() + + function _sortinfo($a, $b) + { + return strcmp($a['package'], $b['package']); + } + + function doList($command, $options, $params) + { + $reg = new PEAR_Registry($this->config->get('php_dir')); + if (sizeof($params) == 0) { + $installed = $reg->packageInfo(); + usort($installed, array(&$this, '_sortinfo')); + $i = $j = 0; + $data = array( + 'caption' => 'Installed packages:', + 'border' => true, + 'headline' => array('Package', 'Version', 'State') + ); + foreach ($installed as $package) { + $data['data'][] = array($package['package'], + $package['version'], + @$package['release_state']); + } + if (count($installed)==0) { + $data = '(no packages installed)'; + } + $this->ui->outputData($data, $command); + } else { + if (file_exists($params[0]) && !is_dir($params[0])) { + include_once "PEAR/Common.php"; + $obj = &new PEAR_Common; + $info = $obj->infoFromAny($params[0]); + $headings = array('Package File', 'Install Path'); + $installed = false; + } else { + $info = $reg->packageInfo($params[0]); + $headings = array('Type', 'Install Path'); + $installed = true; + } + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + if ($info === null) { + return $this->raiseError("`$params[0]' not installed"); + } + $list = $info['filelist']; + if ($installed) { + $caption = 'Installed Files For ' . $params[0]; + } else { + $caption = 'Contents of ' . basename($params[0]); + } + $data = array( + 'caption' => $caption, + 'border' => true, + 'headline' => $headings); + foreach ($list as $file => $att) { + if ($installed) { + if (empty($att['installed_as'])) { + continue; + } + $data['data'][] = array($att['role'], $att['installed_as']); + } else { + if (isset($att['baseinstalldir'])) { + $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR . + $file; + } else { + $dest = $file; + } + switch ($att['role']) { + case 'test': + case 'data': + if ($installed) { + break 2; + } + $dest = '-- will not be installed --'; + break; + case 'doc': + $dest = $this->config->get('doc_dir') . DIRECTORY_SEPARATOR . + $dest; + break; + case 'php': + default: + $dest = $this->config->get('php_dir') . DIRECTORY_SEPARATOR . + $dest; + } + $dest = preg_replace('!/+!', '/', $dest); + $file = preg_replace('!/+!', '/', $file); + $data['data'][] = array($file, $dest); + } + } + $this->ui->outputData($data, $command); + + + } + return true; + } + + // }}} + // {{{ doShellTest() + + function doShellTest($command, $options, $params) + { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $reg = &new PEAR_Registry($this->config->get('php_dir')); + // "pear shell-test Foo" + if (sizeof($params) == 1) { + if (!$reg->packageExists($params[0])) { + exit(1); + } + // "pear shell-test Foo 1.0" + } elseif (sizeof($params) == 2) { + $v = $reg->packageInfo($params[0], 'version'); + if (!$v || !version_compare("$v", "{$params[1]}", "ge")) { + exit(1); + } + // "pear shell-test Foo ge 1.0" + } elseif (sizeof($params) == 3) { + $v = $reg->packageInfo($params[0], 'version'); + if (!$v || !version_compare("$v", "{$params[2]}", $params[1])) { + exit(1); + } + } else { + $this->popErrorHandling(); + $this->raiseError("$command: expects 1 to 3 parameters"); + exit(1); + } + } + + // }}} + // {{{ doInfo + + function doInfo($command, $options, $params) + { + // $params[0] The package for showing info + if (sizeof($params) != 1) { + return $this->raiseError("This command only accepts one param: ". + "the package you want information"); + } + if (@is_file($params[0])) { + $obj = &new PEAR_Common(); + $info = $obj->infoFromAny($params[0]); + } else { + $reg = &new PEAR_Registry($this->config->get('php_dir')); + $info = $reg->packageInfo($params[0]); + } + if (PEAR::isError($info)) { + return $info; + } + if (empty($info)) { + $this->raiseError("Nothing found for `$params[0]'"); + return; + } + unset($info['filelist']); + unset($info['changelog']); + $keys = array_keys($info); + $longtext = array('description', 'summary'); + foreach ($keys as $key) { + if (is_array($info[$key])) { + switch ($key) { + case 'maintainers': { + $i = 0; + $mstr = ''; + foreach ($info[$key] as $m) { + if ($i++ > 0) { + $mstr .= "\n"; + } + $mstr .= $m['name'] . " <"; + if (isset($m['email'])) { + $mstr .= $m['email']; + } else { + $mstr .= $m['handle'] . '@php.net'; + } + $mstr .= "> ($m[role])"; + } + $info[$key] = $mstr; + break; + } + case 'release_deps': { + $i = 0; + $dstr = ''; + foreach ($info[$key] as $d) { + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + if (isset($d['name'])) { + $name = $d['name'] . ' '; + } else { + $name = ''; + } + if (isset($d['version'])) { + $version = $d['version'] . ' '; + } else { + $version = ''; + } + $dstr .= "$type $name$rel $version\n"; + } + $info[$key] = $dstr; + break; + } + case 'provides' : { + $debug = $this->config->get('verbose'); + if ($debug < 2) { + $pstr = 'Classes: '; + } else { + $pstr = ''; + } + $i = 0; + foreach ($info[$key] as $p) { + if ($debug < 2 && $p['type'] != "class") { + continue; + } + // Only print classes when verbosity mode is < 2 + if ($debug < 2) { + if ($i++ > 0) { + $pstr .= ", "; + } + $pstr .= $p['name']; + } else { + if ($i++ > 0) { + $pstr .= "\n"; + } + $pstr .= ucfirst($p['type']) . " " . $p['name']; + if (isset($p['explicit']) && $p['explicit'] == 1) { + $pstr .= " (explicit)"; + } + } + } + $info[$key] = $pstr; + break; + } + default: { + $info[$key] = implode(", ", $info[$key]); + break; + } + } + } + if ($key == '_lastmodified') { + $hdate = date('Y-m-d', $info[$key]); + unset($info[$key]); + $info['Last Modified'] = $hdate; + } else { + $info[$key] = trim($info[$key]); + if (in_array($key, $longtext)) { + $info[$key] = preg_replace('/ +/', ' ', $info[$key]); + } + } + } + $caption = 'About ' . $info['package'] . '-' . $info['version']; + $data = array( + 'caption' => $caption, + 'border' => true); + foreach ($info as $key => $value) { + $key = ucwords(trim(str_replace('_', ' ', $key))); + $data['data'][] = array($key, $value); + } + $data['raw'] = $info; + + $this->ui->outputData($data, 'package-info'); + } + + // }}} +} + +?> diff --git a/3dparty/PEAR/Command/Remote.php b/3dparty/PEAR/Command/Remote.php new file mode 100644 index 00000000000..bbd16093f5d --- /dev/null +++ b/3dparty/PEAR/Command/Remote.php @@ -0,0 +1,435 @@ +<?php +// /* vim: set expandtab tabstop=4 shiftwidth=4: */ +// +----------------------------------------------------------------------+ +// | PHP Version 5 | +// +----------------------------------------------------------------------+ +// | Copyright (c) 1997-2004 The PHP Group | +// +----------------------------------------------------------------------+ +// | This source file is subject to version 3.0 of the PHP license, | +// | that is bundled with this package in the file LICENSE, and is | +// | available through the world-wide-web at the following url: | +// | http://www.php.net/license/3_0.txt. | +// | If you did not receive a copy of the PHP license and are unable to | +// | obtain it through the world-wide-web, please send a note to | +// | license@php.net so we can mail you a copy immediately. | +// +----------------------------------------------------------------------+ +// | Author: Stig Bakken <ssb@php.net> | +// | | +// +----------------------------------------------------------------------+ +// +// $Id: Remote.php,v 1.39 2004/04/03 15:56:00 cellog Exp $ + +require_once 'PEAR/Command/Common.php'; +require_once 'PEAR/Common.php'; +require_once 'PEAR/Remote.php'; +require_once 'PEAR/Registry.php'; + +class PEAR_Command_Remote extends PEAR_Command_Common +{ + // {{{ command definitions + + var $commands = array( + 'remote-info' => array( + 'summary' => 'Information About Remote Packages', + 'function' => 'doRemoteInfo', + 'shortcut' => 'ri', + 'options' => array(), + 'doc' => '<package> +Get details on a package from the server.', + ), + 'list-upgrades' => array( + 'summary' => 'List Available Upgrades', + 'function' => 'doListUpgrades', + 'shortcut' => 'lu', + 'options' => array(), + 'doc' => ' +List releases on the server of packages you have installed where +a newer version is available with the same release state (stable etc.).' + ), + 'remote-list' => array( + 'summary' => 'List Remote Packages', + 'function' => 'doRemoteList', + 'shortcut' => 'rl', + 'options' => array(), + 'doc' => ' +Lists the packages available on the configured server along with the +latest stable release of each package.', + ), + 'search' => array( + 'summary' => 'Search remote package database', + 'function' => 'doSearch', + 'shortcut' => 'sp', + 'options' => array(), + 'doc' => ' +Lists all packages which match the search parameters (first param +is package name, second package info)', + ), + 'list-all' => array( + 'summary' => 'List All Packages', + 'function' => 'doListAll', + 'shortcut' => 'la', + 'options' => array(), + 'doc' => ' +Lists the packages available on the configured server along with the +latest stable release of each package.', + ), + 'download' => array( + 'summary' => 'Download Package', + 'function' => 'doDownload', + 'shortcut' => 'd', + 'options' => array( + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'download an uncompressed (.tar) file', + ), + ), + 'doc' => '{package|package-version} +Download a package tarball. The file will be named as suggested by the +server, for example if you download the DB package and the latest stable +version of DB is 1.2, the downloaded file will be DB-1.2.tgz.', + ), + 'clear-cache' => array( + 'summary' => 'Clear XML-RPC Cache', + 'function' => 'doClearCache', + 'shortcut' => 'cc', + 'options' => array(), + 'doc' => ' +Clear the XML-RPC cache. See also the cache_ttl configuration +parameter. +', + ), + ); + + // }}} + // {{{ constructor + + /** + * PEAR_Command_Remote constructor. + * + * @access public + */ + function PEAR_Command_Remote(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} + + // {{{ doRemoteInfo() + + function doRemoteInfo($command, $options, $params) + { + if (sizeof($params) != 1) { + return $this->raiseError("$command expects one param: the remote package name"); + } + $r = new PEAR_Remote($this->config); + $info = $r->call('package.info', $params[0]); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $reg = new PEAR_Registry($this->config->get('php_dir')); + $installed = $reg->packageInfo($info['name']); + $info['installed'] = $installed['version'] ? $installed['version'] : '- no -'; + + $this->ui->outputData($info, $command); + + return true; + } + + // }}} + // {{{ doRemoteList() + + function doRemoteList($command, $options, $params) + { + $r = new PEAR_Remote($this->config); + $list_options = false; + if ($this->config->get('preferred_state') == 'stable') + $list_options = true; + $available = $r->call('package.listAll', $list_options); + if (PEAR::isError($available)) { + return $this->raiseError($available); + } + $i = $j = 0; + $data = array( + 'caption' => 'Available packages:', + 'border' => true, + 'headline' => array('Package', 'Version'), + ); + foreach ($available as $name => $info) { + $data['data'][] = array($name, isset($info['stable']) ? $info['stable'] : '-n/a-'); + } + if (count($available)==0) { + $data = '(no packages installed yet)'; + } + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doListAll() + + function doListAll($command, $options, $params) + { + $r = new PEAR_Remote($this->config); + $reg = new PEAR_Registry($this->config->get('php_dir')); + $list_options = false; + if ($this->config->get('preferred_state') == 'stable') + $list_options = true; + $available = $r->call('package.listAll', $list_options); + if (PEAR::isError($available)) { + return $this->raiseError($available); + } + if (!is_array($available)) { + return $this->raiseError('The package list could not be fetched from the remote server. Please try again. (Debug info: "'.$available.'")'); + } + $data = array( + 'caption' => 'All packages:', + 'border' => true, + 'headline' => array('Package', 'Latest', 'Local'), + ); + $local_pkgs = $reg->listPackages(); + + foreach ($available as $name => $info) { + $installed = $reg->packageInfo($name); + $desc = $info['summary']; + if (isset($params[$name])) + $desc .= "\n\n".$info['description']; + + if (isset($options['mode'])) + { + if ($options['mode'] == 'installed' && !isset($installed['version'])) + continue; + if ($options['mode'] == 'notinstalled' && isset($installed['version'])) + continue; + if ($options['mode'] == 'upgrades' + && (!isset($installed['version']) || $installed['version'] == $info['stable'])) + { + continue; + } + } + $pos = array_search(strtolower($name), $local_pkgs); + if ($pos !== false) { + unset($local_pkgs[$pos]); + } + + $data['data'][$info['category']][] = array( + $name, + @$info['stable'], + @$installed['version'], + @$desc, + @$info['deps'], + ); + } + + foreach ($local_pkgs as $name) { + $info = $reg->packageInfo($name); + $data['data']['Local'][] = array( + $info['package'], + '', + $info['version'], + $info['summary'], + @$info['release_deps'] + ); + } + + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doSearch() + + function doSearch($command, $options, $params) + { + if ((!isset($params[0]) || empty($params[0])) + && (!isset($params[1]) || empty($params[1]))) + { + return $this->raiseError('no valid search string supplied'); + }; + + $r = new PEAR_Remote($this->config); + $reg = new PEAR_Registry($this->config->get('php_dir')); + $available = $r->call('package.listAll', true, false); + if (PEAR::isError($available)) { + return $this->raiseError($available); + } + $data = array( + 'caption' => 'Matched packages:', + 'border' => true, + 'headline' => array('Package', 'Stable/(Latest)', 'Local'), + ); + + foreach ($available as $name => $info) { + $found = (!empty($params[0]) && stristr($name, $params[0]) !== false); + if (!$found && !(isset($params[1]) && !empty($params[1]) + && (stristr($info['summary'], $params[1]) !== false + || stristr($info['description'], $params[1]) !== false))) + { + continue; + }; + + $installed = $reg->packageInfo($name); + $desc = $info['summary']; + if (isset($params[$name])) + $desc .= "\n\n".$info['description']; + + $unstable = ''; + if ($info['unstable']) { + $unstable = '/(' . $info['unstable'] . $info['state'] . ')'; + } + if (!isset($info['stable']) || !$info['stable']) { + $info['stable'] = 'none'; + } + $data['data'][$info['category']][] = array( + $name, + $info['stable'] . $unstable, + $installed['version'], + $desc, + ); + } + if (!isset($data['data'])) { + return $this->raiseError('no packages found'); + } + $this->ui->outputData($data, $command); + return true; + } + + // }}} + // {{{ doDownload() + + function doDownload($command, $options, $params) + { + //$params[0] -> The package to download + if (count($params) != 1) { + return PEAR::raiseError("download expects one argument: the package to download"); + } + $server = $this->config->get('master_server'); + if (!ereg('^http://', $params[0])) { + $getoption = isset($options['nocompress'])&&$options['nocompress']==1?'?uncompress=on':''; + $pkgfile = "http://$server/get/$params[0]".$getoption; + } else { + $pkgfile = $params[0]; + } + $this->bytes_downloaded = 0; + $saved = PEAR_Common::downloadHttp($pkgfile, $this->ui, '.', + array(&$this, 'downloadCallback')); + if (PEAR::isError($saved)) { + return $this->raiseError($saved); + } + $fname = basename($saved); + $this->ui->outputData("File $fname downloaded ($this->bytes_downloaded bytes)", $command); + return true; + } + + function downloadCallback($msg, $params = null) + { + if ($msg == 'done') { + $this->bytes_downloaded = $params; + } + } + + // }}} + // {{{ doListUpgrades() + + function doListUpgrades($command, $options, $params) + { + include_once "PEAR/Registry.php"; + $remote = new PEAR_Remote($this->config); + if (empty($params[0])) { + $state = $this->config->get('preferred_state'); + } else { + $state = $params[0]; + } + $caption = 'Available Upgrades'; + if (empty($state) || $state == 'any') { + $latest = $remote->call("package.listLatestReleases"); + } else { + $latest = $remote->call("package.listLatestReleases", $state); + $caption .= ' (' . implode(', ', PEAR_Common::betterStates($state, true)) . ')'; + } + $caption .= ':'; + if (PEAR::isError($latest)) { + return $latest; + } + $reg = new PEAR_Registry($this->config->get('php_dir')); + $inst = array_flip($reg->listPackages()); + $data = array( + 'caption' => $caption, + 'border' => 1, + 'headline' => array('Package', 'Local', 'Remote', 'Size'), + ); + foreach ((array)$latest as $pkg => $info) { + $package = strtolower($pkg); + if (!isset($inst[$package])) { + // skip packages we don't have installed + continue; + } + extract($info); + $pkginfo = $reg->packageInfo($package); + $inst_version = $pkginfo['version']; + $inst_state = $pkginfo['release_state']; + if (version_compare("$version", "$inst_version", "le")) { + // installed version is up-to-date + continue; + } + if ($filesize >= 20480) { + $filesize += 1024 - ($filesize % 1024); + $fs = sprintf("%dkB", $filesize / 1024); + } elseif ($filesize > 0) { + $filesize += 103 - ($filesize % 103); + $fs = sprintf("%.1fkB", $filesize / 1024.0); + } else { + $fs = " -"; // XXX center instead + } + $data['data'][] = array($pkg, "$inst_version ($inst_state)", "$version ($state)", $fs); + } + if (empty($data['data'])) { + $this->ui->outputData('No upgrades available'); + } else { + $this->ui->outputData($data, $command); + } + return true; + } + + // }}} + // {{{ doClearCache() + + function doClearCache($command, $options, $params) + { + $cache_dir = $this->config->get('cache_dir'); + $verbose = $this->config->get('verbose'); + $output = ''; + if (!($dp = @opendir($cache_dir))) { + return $this->raiseError("opendir($cache_dir) failed: $php_errormsg"); + } + if ($verbose >= 1) { + $output .= "reading directory $cache_dir\n"; + } + $num = 0; + while ($ent = readdir($dp)) { + if (preg_match('/^xmlrpc_cache_[a-z0-9]{32}$/', $ent)) { + $path = $cache_dir . DIRECTORY_SEPARATOR . $ent; + $ok = @unlink($path); + if ($ok) { + if ($verbose >= 2) { + $output .= "deleted $path\n"; + } + $num++; + } elseif ($verbose >= 1) { + $output .= "failed to delete $path\n"; + } + } + } + closedir($dp); + if ($verbose >= 1) { + $output .= "$num cache entries cleared\n"; + } + $this->ui->outputData(rtrim($output), $command); + return $num; + } + + // }}} +} + +?> |