Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'inc/PEAR/Command')
-rwxr-xr-xinc/PEAR/Command/Auth.php155
-rwxr-xr-xinc/PEAR/Command/Build.php89
-rwxr-xr-xinc/PEAR/Command/Common.php249
-rwxr-xr-xinc/PEAR/Command/Config.php225
-rwxr-xr-xinc/PEAR/Command/Install.php470
-rwxr-xr-xinc/PEAR/Command/Mirror.php101
-rwxr-xr-xinc/PEAR/Command/Package.php819
-rwxr-xr-xinc/PEAR/Command/Registry.php351
-rwxr-xr-xinc/PEAR/Command/Remote.php435
9 files changed, 2894 insertions, 0 deletions
diff --git a/inc/PEAR/Command/Auth.php b/inc/PEAR/Command/Auth.php
new file mode 100755
index 00000000000..0b9d3d3965d
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Build.php b/inc/PEAR/Command/Build.php
new file mode 100755
index 00000000000..2ecbbc92f5f
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Common.php b/inc/PEAR/Command/Common.php
new file mode 100755
index 00000000000..c6ace694caf
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Config.php b/inc/PEAR/Command/Config.php
new file mode 100755
index 00000000000..474a2345170
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Install.php b/inc/PEAR/Command/Install.php
new file mode 100755
index 00000000000..dce52f017e2
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Mirror.php b/inc/PEAR/Command/Mirror.php
new file mode 100755
index 00000000000..bf56c3db640
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Package.php b/inc/PEAR/Command/Package.php
new file mode 100755
index 00000000000..aca87111118
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Registry.php b/inc/PEAR/Command/Registry.php
new file mode 100755
index 00000000000..62cb4b00e28
--- /dev/null
+++ b/inc/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/inc/PEAR/Command/Remote.php b/inc/PEAR/Command/Remote.php
new file mode 100755
index 00000000000..bbd16093f5d
--- /dev/null
+++ b/inc/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;
+ }
+
+ // }}}
+}
+
+?>