]> granicus.if.org Git - php/commitdiff
* Refactoring of "pear" command internals. Highlights:
authorStig Bakken <ssb@php.net>
Mon, 18 Mar 2002 17:39:52 +0000 (17:39 +0000)
committerStig Bakken <ssb@php.net>
Mon, 18 Mar 2002 17:39:52 +0000 (17:39 +0000)
 - user interface abstraction, making a Gtk installer should only be
   a matter of implementing PEAR_CommandUI_Gtk plus a "pear-gtk" executable
 - separated code into command classes, able to specify one or more
   commands
 - no more "pear-get" :-)
* fixed use of PEAR_Config::singleton to avoid object copying

12 files changed:
pear/DB.php
pear/Makefile.frag
pear/PEAR/Command.php
pear/PEAR/Command/Common.php
pear/PEAR/Command/Config.php [new file with mode: 0644]
pear/PEAR/Command/Install.php
pear/PEAR/Command/Login.php [new file with mode: 0644]
pear/PEAR/CommandUI/CLI.php [new file with mode: 0644]
pear/PEAR/Config.php
pear/PEAR/Remote.php
pear/scripts/pear.in
pear/tests/pear_config.phpt

index 86125a2b60b253a72223fa52be4abbf3a7d10c01..22cff1f81cbfaeccde3a6b475fb939d855a9b4eb 100644 (file)
@@ -261,6 +261,9 @@ class DB
 
         @$obj =& new $classname;
 
+        if (isset($options['connect_ondemand']) && !extension_loaded("overload")) {
+            unset($options['connect_ondemand']);
+        }
         if (is_array($options)) {
             foreach ($options as $option => $value) {
                 $test = $obj->setOption($option, $value);
@@ -271,11 +274,14 @@ class DB
         } else {
             $obj->setOption('persistent', $options);
         }
-        $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
-
-        if (DB::isError($err)) {
-            $err->addUserInfo($dsn);
-            return $err;
+        if (!$obj->getOption('connect_ondemand')) {
+            $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
+            if (DB::isError($err)) {
+                $err->addUserInfo($dsn);
+                return $err;
+            }
+        } else {
+            $obj->dsn = $dsninfo;
         }
 
         return $obj;
index 11362207d47ff808780b3979a0dfad308a31d78c..5ae5c5525739e46af6c1e3b399ba4e2096a4b213 100644 (file)
@@ -20,6 +20,8 @@ PEAR_SUBDIRS = \
        Mail \
        Net \
        PEAR \
+       PEAR/Command \
+       PEAR/CommandUI \
        Schedule \
        XML 
 
@@ -67,6 +69,13 @@ PEAR_FILES = \
        Net/Socket.php \
        PEAR.php \
        PEAR/Autoloader.php \
+       PEAR/Command.php \
+       PEAR/Command/Common.php \
+       PEAR/Command/Config.php \
+       PEAR/Command/Install.php \
+       PEAR/Command/Login.php \
+       PEAR/CommandResponse.php \
+       PEAR/CommandUI/CLI.php \
        PEAR/Common.php \
        PEAR/Config.php \
        PEAR/Dependency.php \
@@ -79,17 +88,6 @@ PEAR_FILES = \
        System.php \
        XML/Parser.php 
 
-PEAR_COMMAND_LIBS = \
-       pearcmd-common.php \
-       pearcmd-help.php \
-       pearcmd-info.php \
-       pearcmd-install.php \
-       pearcmd-list.php \
-       pearcmd-package.php \
-       pearcmd-remote-list.php \
-       pearcmd-show-config.php \
-       pearcmd-uninstall.php
-
 install-pear:
        @if $(mkinstalldirs) $(INSTALL_ROOT)$(peardir); then \
                for i in $(PEAR_SUBDIRS); do \
@@ -131,10 +129,6 @@ install-programs:
        for prog in phpextdist; do \
                echo "Installing program: $$prog"; \
                $(INSTALL) -m 755 $(srcdir)/scripts/$$prog $(INSTALL_ROOT)$(bindir)/$$prog; \
-       done; \
-       for lib in $(PEAR_COMMAND_LIBS); do \
-               echo "Installing program library: $$lib"; \
-               $(INSTALL) -m 644 $(srcdir)/scripts/$$lib $(INSTALL_ROOT)$(bindir)/$$lib; \
        done
 
 HEADER_DIRS = \
index 49807d0339bfc0ed0e95236407dd45febbc9c05b..d7944c677708421ad0f4a6bad1352b19dbce1109 100644 (file)
@@ -27,6 +27,12 @@ require_once "PEAR.php";
  */
 $GLOBALS['_PEAR_Command_commandlist'] = array();
 
+/**
+ * Which user interface class is being used.
+ * @var string class name
+ */
+$GLOBALS['_PEAR_Command_uiclass'] = 'PEAR_CommandUI_CLI';
+
 /**
  * PEAR command class, a simple factory class for administrative
  * commands.
@@ -82,17 +88,40 @@ class PEAR_Command
      *
      * @access public
      */
-    function factory(&$config, $command)
+    function factory($command)
     {
         if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
             PEAR_Command::registerCommands();
         }
         if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) {
             $class = $GLOBALS['_PEAR_Command_commandlist'][$command];
-            $obj =& new $class($config);
+            $obj = &new $class(PEAR_Command::getUIObject());
             return $obj;
         }
-        return PEAR::raiseError("unknown command: $command");
+        return PEAR::raiseError("unknown command `$command'");
+    }
+
+    function &getUIObject()
+    {
+        global $_PEAR_Command_uiclass, $_PEAR_Command_uiobject;
+        if (empty($_PEAR_Command_uiobject)) {
+            $_PEAR_Command_uiobject = &new $_PEAR_Command_uiclass;
+        }
+        return $_PEAR_Command_uiobject;
+    }
+
+    function setUIClass($uiclass)
+    {
+        $GLOBALS['_PEAR_Command_uiclass'] = $uiclass;
+        $file = str_replace("_", "/", $uiclass) . '.php';
+        include_once $file;
+        return class_exists(strtolower($uiclass));
+    }
+
+    function setUIType($uitype)
+    {
+        $uiclass = 'PEAR_CommandUI_' . $uitype;
+        return PEAR_Command::setUIClass($uiclass);
     }
 
     /**
@@ -119,13 +148,16 @@ class PEAR_Command
         }
         $dp = @opendir($dir);
         if (empty($dp)) {
-            return PEAR::raiseError("PEAR_Command::registerCommands: opendir($dir) failed");
+            return PEAR::raiseError("PEAR_Command::registerCommands: ".
+                                    "opendir($dir) failed");
         }
         if (!$merge) {
             $GLOBALS['_PEAR_Command_commandlist'] = array();
         }
         while ($entry = readdir($dp)) {
-            if ($entry{0} == '.' || substr($entry, -4) != '.php' || $entry == 'Common.php') {
+            if ($entry{0} == '.' || substr($entry, -4) != '.php' ||
+                $entry == 'Common.php')
+            {
                 continue;
             }
             $class = "PEAR_Command_".substr($entry, 0, -4);
@@ -149,6 +181,9 @@ class PEAR_Command
      */
     function getCommands()
     {
+        if (empty($GLOBALS['_PEAR_Command_commandlist'])) {
+            PEAR_Command::registerCommands();
+        }
         return $GLOBALS['_PEAR_Command_commandlist'];
     }
 }
index e54c1694f13cc21f01720b8ca9e38a1b0da3bb17..0fc50f4aaf6da3ae04b23eb735767fb5d6c58de6 100644 (file)
@@ -19,7 +19,7 @@
 // $Id$
 
 require_once "PEAR.php";
-require_once "PEAR/CommandResponse.php";
+//require_once "PEAR/CommandResponse.php";
 
 class PEAR_Command_Common extends PEAR
 {
@@ -31,15 +31,22 @@ class PEAR_Command_Common extends PEAR
      */
     var $config;
 
+    /**
+     * User Interface object, for all interaction with the user.
+     * @var object
+     */
+    var $ui;
+
     /**
      * PEAR_Command_Common constructor.
      *
      * @access public
      */
-    function PEAR_Command_Common()
+    function PEAR_Command_Common(&$ui)
     {
         parent::PEAR();
-        $this->config = PEAR_Config::singleton();
+        $this->config = &PEAR_Config::singleton();
+        $this->ui = $ui;
     }
 
     /**
@@ -56,13 +63,13 @@ class PEAR_Command_Common extends PEAR
      *
      * @see PEAR_CommandResponse
      */
+/*
     function &makeResponse($status, $message, $encoding = null)
     {
-        $obj =new PEAR_CommandResponse($status, $message, $encoding);
+        $obj = &new PEAR_CommandResponse($status, $message, $encoding);
         return $obj;
     }
-
-    
+*/
 }
 
 ?>
\ No newline at end of file
diff --git a/pear/PEAR/Command/Config.php b/pear/PEAR/Command/Config.php
new file mode 100644 (file)
index 0000000..9664f57
--- /dev/null
@@ -0,0 +1,127 @@
+<?php
+//
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Author: Stig Bakken <ssb@fast.no>                                    |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+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
+    // }}}
+
+    // {{{ constructor
+
+    /**
+     * PEAR_Command_Config constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Config($ui)
+    {
+        parent::PEAR_Command_Common($ui);
+    }
+
+    // }}}
+
+    // {{{ getCommands()
+
+    /**
+     * Return a list of all the commands defined by this class.
+     * @return array list of commands
+     * @access public
+     */
+    function getCommands()
+    {
+        return array('config-show', 'config-get', 'config-set');
+    }
+
+    // }}}
+    // {{{ run()
+
+    function run($command, $options, $params)
+    {
+        $cf = $this->config;
+        $failmsg = '';
+        switch ($command) {
+            case 'config-show': {
+                $keys = $cf->getKeys();
+                if (isset($params[0]) && $cf->isDefined($params[0])) {
+                    foreach ($keys as $key) {
+                        $type = $cf->getType($key);
+                        if ($type == 'password') {
+                            $this->ui->displayLine("$key = ********");
+                        } else {
+                            $this->ui->displayLine("$key = " . $cf->get($key, $params[0]));
+                        }
+                    }
+                } else {
+                    foreach ($keys as $key) {
+                        $type = $cf->getType($key);
+                        if ($type == 'password') {
+                            $this->ui->displayLine("$key = ********");
+                        } else {
+                            $this->ui->displayLine("$key = " . $cf->get($key));
+                        }
+                    }
+                }
+                break;
+            }
+            case 'config-get': {
+                if (sizeof($params) < 1 || sizeof($params) > 2) {
+                    $failmsg .= "config-get expects 1 or 2 parameters";
+                } elseif (sizeof($params) == 1) {
+                    $this->ui->displayLine("$params[0] = " . $cf->get($params[0]));
+                } else {
+                    $this->ui->displayLine("($params[1])$params[0] = " .
+                                           $cf->get($params[0], $params[1]));
+                }
+                break;
+            }
+            case 'config-set': {
+                if (sizeof($params) < 2 || sizeof($params) > 3) {
+                    $failmsg .= "config-set expects 2 or 3 parameters";
+                    break;
+                } else {
+                    if (!call_user_func_array(array($cf, 'set'), $params))
+                    {
+                        $failmsg = "config-set (" .
+                             implode(", ", $params) . ") failed";
+                    }
+                }
+                break;
+            }
+            default: {
+                return false;
+            }
+        }
+        if ($failmsg) {
+            return $this->raiseError($failmsg);
+        }
+        return true;
+    }
+
+    // }}}
+}
+
+?>
\ No newline at end of file
index 0d99f85b1afbf64cabbdc32cf20f5d642026a1c1..658f4a7b29838ec83935426d810b34db712c70d9 100644 (file)
@@ -28,6 +28,8 @@ require_once "PEAR/Installer.php";
  */
 class PEAR_Command_Install extends PEAR_Command_Common
 {
+    // {{{ properties
+
     /** Stack of executing commands, to make run() re-entrant
      * @var array
      */
@@ -38,16 +40,24 @@ class PEAR_Command_Install extends PEAR_Command_Common
      */
     var $command; // XXX UNUSED
 
+    // }}}
+
+    // {{{ constructor
+
     /**
      * PEAR_Command_Install constructor.
      *
      * @access public
      */
-    function PEAR_Command_Install()
+    function PEAR_Command_Install($ui)
     {
-        parent::PEAR_Command_Common();
+        parent::PEAR_Command_Common($ui);
     }
 
+    // }}}
+
+    // {{{ getCommands()
+
     /**
      * Return a list of all the commands defined by this class.
      * @return array list of commands
@@ -58,14 +68,16 @@ class PEAR_Command_Install extends PEAR_Command_Common
         return array('install', 'uninstall', 'upgrade');
     }
 
+    // }}}
+    // {{{ run()
+
     function run($command, $options, $params)
     {
         $installer =& new PEAR_Installer($options['php_dir'],
                                          $options['ext_dir'],
                                          $options['doc_dir']);
         $installer->debug = @$options['verbose'];
-        $status = PEAR_COMMAND_SUCCESS;
-        ob_start();
+        $failmsg = '';
         switch ($command) {
             case 'install':
             case 'upgrade': {
@@ -73,27 +85,31 @@ class PEAR_Command_Install extends PEAR_Command_Common
                     $options['upgrade'] = true;
                 }
                 if ($installer->install($params[0], $options, $this->config)) {
-                    print "install ok\n";
+                    $this->ui->displayLine("install ok");
                 } else {
-                    print "install failed\n";
-                    $status = PEAR_COMMAND_FAILURE;
+                    $failmsg = "install failed";
                 }
                 break;
             }
             case 'uninstall': {
                 if ($installer->uninstall($params[0], $uninstall_options)) {
-                    print "uninstall ok\n";
+                    $this->ui->displayLine("uninstall ok");
                 } else {
-                    print "uninstall failed\n";
-                    $status = PEAR_COMMAND_FAILURE;
+                    $failmsg = "uninstall failed";
                 }
                 break;
             }                
+            default: {
+                return false;
+            }
         }
-        $output = ob_get_contents();
-        ob_end_clean();
-        return $this->makeResponse($status, $output);
+        if ($failmsg) {
+            return $this->raiseError($failmsg);
+        }
+        return true;
     }
+
+    // }}}
 }
 
 ?>
\ No newline at end of file
diff --git a/pear/PEAR/Command/Login.php b/pear/PEAR/Command/Login.php
new file mode 100644 (file)
index 0000000..e01da96
--- /dev/null
@@ -0,0 +1,107 @@
+<?php
+//
+// +----------------------------------------------------------------------+
+// | PHP Version 4                                                        |
+// +----------------------------------------------------------------------+
+// | Copyright (c) 1997-2002 The PHP Group                                |
+// +----------------------------------------------------------------------+
+// | This source file is subject to version 2.02 of the PHP license,      |
+// | that is bundled with this package in the file LICENSE, and is        |
+// | available at through the world-wide-web at                           |
+// | http://www.php.net/license/2_02.txt.                                 |
+// | If you did not receive a copy of the PHP license and are unable to   |
+// | obtain it through the world-wide-web, please send a note to          |
+// | license@php.net so we can mail you a copy immediately.               |
+// +----------------------------------------------------------------------+
+// | Author: Stig Bakken <ssb@fast.no>                                    |
+// +----------------------------------------------------------------------+
+//
+// $Id$
+
+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_Login extends PEAR_Command_Common
+{
+    // {{{ properties
+    // }}}
+
+    // {{{ constructor
+
+    /**
+     * PEAR_Command_Login constructor.
+     *
+     * @access public
+     */
+    function PEAR_Command_Login($ui)
+    {
+        parent::PEAR_Command_Common($ui);
+    }
+
+    // }}}
+
+    // {{{ getCommands()
+
+    /**
+     * Return a list of all the commands defined by this class.
+     * @return array list of commands
+     * @access public
+     */
+    function getCommands()
+    {
+        return array('login', 'logout');
+    }
+
+    // }}}
+    // {{{ run()
+
+    function run($command, $options, $params)
+    {
+        $cf = $this->config;
+        $failmsg = '';
+        $server = $cf->get('master_server');
+        switch ($command) {
+            case 'login': {
+                $username = $cf->get('username');
+                if (empty($username)) {
+                    $this->ui->displayLine("Logging in to $server.");
+                    $username = trim($this->ui->userDialog('Username'));
+                    $cf->set('username', $username);
+                } else {
+                    $this->ui->displayLine("Logging in as `$username' to $server.");
+                }
+                $password = trim($this->ui->userDialog('Password', 'password'));
+                $cf->set('password', $password);
+                $cf->store();
+                $remote = new PEAR_Remote;
+                $ok = $remote->call('logintest');
+                print "logintest=";var_dump($ok);
+                break;
+            }
+            case 'logout': {
+                $this->ui->displayLine("Logging out from $server.");
+                $cf->remove('username');
+                $cf->remove('password');
+                $cf->store();
+                break;
+            }
+            default: {
+                $failmsg = "unknown command: $command";
+                break;
+            }
+        }
+        if ($failmsg) {
+            return $this->raiseError($failmsg);
+        }
+        return true;
+    }
+
+    // }}}
+}
+
+?>
\ No newline at end of file
diff --git a/pear/PEAR/CommandUI/CLI.php b/pear/PEAR/CommandUI/CLI.php
new file mode 100644 (file)
index 0000000..816abde
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+
+require_once "PEAR.php";
+
+class PEAR_CommandUI_CLI extends PEAR
+{
+    var $output_mode = 'plain';
+    var $output_mode_params = array();
+
+    function PEAR_CommandUI_CLI()
+    {
+        parent::PEAR();
+    }
+
+    function _PEAR_CommandUI_CLI()
+    {
+        parent::_PEAR();
+        if ($this->output_mode) {
+            $this->endOutput();
+        }
+    }
+
+    function displayLine($text)
+    {
+        print "$text\n";
+    }
+
+    function userDialog($prompt, $type = 'text')
+    {
+        if ($type == 'password') {
+            system('stty -echo');
+        }
+        print "$prompt : ";
+        $fp = fopen("php://stdin", "r");
+        $line = fgets($fp, 2048);
+        fclose($fp);
+        if ($type == 'password') {
+            system('stty echo');
+            print "\n";
+        }
+        return $line;
+    }
+
+    function userConfirm($prompt, $default = 'yes')
+    {
+        static $positives = array('y', 'yes', 'on', '1');
+        static $negatives = array('n', 'no', 'off', '0');
+        print "$prompt [$default] : ";
+        $fp = fopen("php://stdin", "r");
+        $line = fgets($fp, 2048);
+        fclose($fp);
+        $answer = strtolower(trim($line));
+        if (empty($answer)) {
+            $answer = $default;
+        }
+        if (in_array($answer, $positives)) {
+            return true;
+        }
+        if (in_array($answer, $negatives)) {
+            return false;
+        }
+        if (in_array($default, $positives)) {
+            return true;
+        }
+        return false;
+    }
+
+    function setOutputMode($mode, $params = array())
+    {
+        $this->output_mode = $mode;
+        $this->output_mode_params = $params;
+    }
+
+    function startOutput($mode)
+    {
+        if ($this->output_mode) {
+            $this->endOutput();
+        }
+        switch ($mode) {
+        }
+    }
+
+    function endOutput($mode = null)
+    {
+        if ($mode === null) {
+            $mode = $this->output_mode;
+        }
+        $this->output_mode = '';
+        switch ($mode) {
+        }
+    }
+}
+
+?>
\ No newline at end of file
index 1cb4c8eb59ba6457a2604e0c945a5b74241b25e0..75d38a2dddfbd9d101beb252cfc38eb442562eab 100644 (file)
@@ -24,7 +24,7 @@ require_once 'PEAR.php';
  * Last created PEAR_Config instance.
  * @var object
  */
-$GLOBALS['_PEAR_Config_last_instance'] = null;
+$GLOBALS['_PEAR_Config_instance'] = null;
 
 define('PEAR_CONFIG_DEFAULT_DOCDIR',
        PHP_DATADIR.DIRECTORY_SEPARATOR.'pear'.DIRECTORY_SEPARATOR.'doc');
@@ -165,7 +165,6 @@ class PEAR_Config extends PEAR
         $this->layers = array_keys($this->configuration);
         $this->files['user'] = $user_file;
         $this->files['system'] = $system_file;
-        $GLOBALS['_PEAR_Config_last_instance'] = &$this;
         if ($user_file && file_exists($user_file)) {
             $this->readConfigFile($user_file);
         }
@@ -175,6 +174,7 @@ class PEAR_Config extends PEAR
         foreach ($this->configuration_info as $key => $info) {
             $this->configuration['default'][$key] = $info['default'];
         }
+        //$GLOBALS['_PEAR_Config_instance'] = &$this;
     }
 
     // }}}
@@ -197,11 +197,12 @@ class PEAR_Config extends PEAR
      */
     function &singleton($user_file = '', $system_file = '')
     {
-        if (empty($GLOBALS['_PEAR_Config_last_instance'])) {
-            $obj =& new PEAR_Config($user_file, $system_file);
-            $GLOBALS['_PEAR_Config_last_instance'] = &$obj;
+        if (is_object($GLOBALS['_PEAR_Config_instance'])) {
+            return $GLOBALS['_PEAR_Config_instance'];
         }
-        return $GLOBALS['_PEAR_Config_last_instance'];
+        $GLOBALS['_PEAR_Config_instance'] =
+             &new PEAR_Config($user_file, $system_file);
+        return $GLOBALS['_PEAR_Config_instance'];
     }
 
     // }}}
@@ -318,7 +319,7 @@ class PEAR_Config extends PEAR
         }
         $data = $this->configuration[$layer];
         $this->_encodeOutput($data);
-        if (!@is_writeable($file)) {
+        if (@file_exists($file) && !@is_writeable($file)) {
             return $this->raiseError("no write access to $file!");
         }
         $fp = @fopen($file, "w");
@@ -637,6 +638,23 @@ class PEAR_Config extends PEAR
         return false;
     }
 
+    // }}}
+    // {{{ store([layer])
+
+    /**
+     * Stores configuration data in a layer.
+     *
+     * @param string config layer to store
+     *
+     * @return bool TRUE on success, or PEAR error on failure
+     *
+     * @access public
+     */
+    function store($layer = 'user')
+    {
+        return $this->writeConfigFile(null, $layer);
+    }
+
     // }}}
     // {{{ toDefault(key)
 
index 7f397b72210158fa8635efd1d23350b9d443d9cf..2b12c3b73a0b4eb0ee907811a73146d194b83974 100644 (file)
@@ -19,6 +19,7 @@
 // $Id$
 
 require_once 'PEAR.php';
+require_once 'PEAR/Config.php';
 
 /**
  * This is a class for doing remote operations against the central
@@ -28,16 +29,19 @@ class PEAR_Remote extends PEAR
 {
     // {{{ properties
 
-    var $config_object = null;
+    var $config = null;
 
     // }}}
 
     // {{{ PEAR_Remote(config_object)
 
-    function PEAR_Remote($config_object)
+    function PEAR_Remote($config = null)
     {
         $this->PEAR();
-        $this->config_object = $config_object;
+        if ($config === null) {
+            $config = &PEAR_Config::singleton();
+        }
+        $this->config = $config;
     }
 
     // }}}
@@ -51,7 +55,7 @@ class PEAR_Remote extends PEAR
         }
         $method = str_replace("_", ".", $method);
         $request = xmlrpc_encode_request($method, $params);
-        $server_host = $this->config_object->get("master_server");
+        $server_host = $this->config->get("master_server");
         if (empty($server_host)) {
             return $this->raiseError("PEAR_Remote::call: no master_server configured");
         }
@@ -61,13 +65,30 @@ class PEAR_Remote extends PEAR
             return $this->raiseError("PEAR_Remote::call: fsockopen(`$server_host', $server_port) failed");
         }
         $len = strlen($request);
-        fwrite($fp, ("POST /xmlrpc.php HTTP/1.0\r\n".
-                     "Host: $server_host:$server_port\r\n".
-                     "Content-type: text/xml\r\n".
-                     "Content-length: $len\r\n".
-                     "\r\n$request"));
+        $req_headers = "Host: $server_host:$server_port\r\n" .
+             "Content-type: text/xml\r\n" .
+             "Content-length: $len\r\n";
+        $username = $this->config->get('username');
+        $password = $this->config->get('password');
+        if ($username && $password) {
+            $tmp = base64_encode("$username:$password");
+            $req_headers .= "Authorization: Basic $auth\r\n";
+        }
+        fwrite($fp, ("POST /xmlrpc.php HTTP/1.0\r\n$req_headers\r\n$request"));
         $response = '';
-        while (trim(fgets($fp, 2048)) != ''); // skip headers
+        $line1 = fgets($fp, 2048);
+        if (!preg_match('!^HTTP/[0-9\.]+ (\d+) (.*)!', $line1, &$matches)) {
+            return $this->raiseError("PEAR_Remote: invalid HTTP response from XML-RPC server");
+        }
+        switch ($matches[1]) {
+            case "200":
+                break;
+            case "401":
+                return $this->raiseError("PEAR_Remote: authorization required, please log in first");
+            default:
+                return $this->raiseError("PEAR_Remote: unexpected HTTP response: $matches[1] $matches[2]");
+        }
+        while (trim(fgets($fp, 2048)) != ''); // skip rest of headers
         while ($chunk = fread($fp, 10240)) {
             $response .= $chunk;
         }
index d7bb854b53bb2cc4e4bb2e7cc4973665ae1d25fc..8afc9c8b84feecbf329b504c63e420485b589af5 100644 (file)
 //
 
 require_once 'PEAR.php';
-require_once 'PEAR/Common.php';
-require_once 'PEAR/Registry.php';
+require_once "PEAR/Config.php";
+require_once "PEAR/Command.php";
+require_once "Console/Getopt.php";
 
 error_reporting(E_ALL & ~E_NOTICE);
 
-$subcommands = array(
-    'help'        => 'help [command]',
-    'uninstall'   => 'uninstall [-r] <package name>',
-    'package'     => 'package [package info file]',
-    'info'        => 'info',
-    'list'        => 'list',
-    'show-config' => 'show-config',
-);
+PEAR_Command::setUIType('CLI');
+$all_commands = PEAR_Command::getCommands();
 
-$command_options = array(
-    "list"      => "v",
-    "uninstall" => "fr",
-);
+$progname = basename($argv[0]);
 
-include "pearcmd-common.php";
+PEAR::setErrorHandling(PEAR_ERROR_DIE, "$progname: %s\n");
+$argv = Console_Getopt::readPHPArgv();
 
-if (isset($subcommands[$command])) {
-    include "pearcmd-$command.php";
-} elseif (!$store_default_config && !$store_user_config) {
-    usage();
+PEAR::pushErrorHandling(PEAR_ERROR_CALLBACK, 'usage');
+$options = Console_Getopt::getopt($argv, "c:C:d:D:h?sSqu:v");
+PEAR::popErrorHandling();
+
+$opts = $options[0];
+
+$pear_user_config = '';
+$pear_system_config = '';
+$store_user_config = false;
+$store_system_config = false;
+$verbose = 1;
+
+foreach ($opts as $opt) {
+    switch ($opt[0]) {
+        case 'c':
+            $pear_user_config = $opt[1];
+            break;
+        case 'C':
+            $pear_system_config = $opt[1];
+            break;
+    }
+}
+
+$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config);
+$verbose = $config->get("verbose");
+
+foreach ($opts as $opt) {
+    $param = $opt[1];
+    switch ($opt[0]) {
+        case 'd':
+            list($key, $value) = explode('=', $param);
+            $config->set($key, $value, 'user');
+            break;
+        case 'D':
+            list($key, $value) = explode('=', $param);
+            $config->set($key, $value, 'system');
+            break;
+        case 's':
+            $store_user_config = true;
+            break;
+        case 'S':
+            $store_system_config = true;
+            break;
+        case 'u':
+            $config->remove($param, 'user');
+            break;
+        case 'v':
+            $verbose++;
+            break;
+        case 'q':
+            $verbose--;
+            break;
+    }
+}
+
+if ($store_system_config) {
+    $config->store('system');
+}
+
+if ($store_user_config) {
+    $config->store('user');
+}
+
+$command = (isset($options[1][1])) ? $options[1][1] : null;
+
+if (empty($command) && ($store_user_config || $store_system_config)) {
+    exit;
+}
+
+if (empty($all_commands[$command]) || $command == 'help') {
+    usage(null, @$options[1][2]);
 }
 
+$cmd = PEAR_Command::factory($command);
+if (PEAR::isError($cmd)) {
+    die($cmd->getMessage());
+}
+$ok = $cmd->run($command, $cmdopts, $cmdargs);
+if ($ok === false) {
+    PEAR::raiseError("unknown command `$command'");
+}
+
+exit;
+
+// {{{ usage()
+
+function usage($error = null, $helpsubject = null)
+{
+    global $progname, $all_commands;
+    $stderr = fopen('php://stderr', 'w');
+    if (PEAR::isError($error)) {
+        fputs($stderr, $error->getMessage());
+    } elseif ($error !== null) {
+        fputs($stderr, $error);
+    }
+    fputs($stderr,
+        "Usage: $progname [options] command [command-options] <parameters>\n");
+    if ($helpsubject == "options") {
+        fputs($stderr,
+        "Options:\n".
+        "     -v         increase verbosity level (default 1)\n".
+        "     -q         be quiet, decrease verbosity level\n".
+        "     -c file    find user configuration in `file'\n".
+        "     -C file    find system configuration in `file'\n".
+        "     -d foo=bar set user config variable `foo' to `bar'\n".
+        "     -D foo=bar set system config variable `foo' to `bar'\n".
+        "     -s         store user configuration\n".
+        "     -S         store system configuration\n".
+        "     -u foo     unset `foo' in the user configuration\n".
+        "     -h, -?     display help/usage (this message)\n");
+    } else {
+        fputs($stderr,
+              "Type \"$progname help options\" to list all options.\n");
+    }        
+    fputs($stderr,
+          "Commands:\n   " . implode("\n   ", array_keys($all_commands)) .
+          "\n");
+    fclose($stderr);
+    exit;
+}
+
+// }}}
+// {{{ present_array()
+
+function present_array(&$arr, $keys = null)
+{
+    if ($keys === null) {
+        $keys = array_keys($arr);
+    }
+    $longest_key = max(array_map("strlen", array_keys($arr))) + 2;
+    $format_string = "%{$longest_key}s : %s\n";
+    foreach ($keys as $k) {
+        if (is_array($arr[$k])) {
+            foreach ($arr[$k] as $i => $value) {
+                $x = "$k #$i";
+                $cont = array();
+                foreach(array_keys($value) as $val) {
+                    $cont[] = "$val=" . $value[$val];
+                }
+                $v = implode(", ", $cont);
+                printf($format_string, $x, $v);
+            }
+            continue;
+        } else {
+            $v = $arr[$k];
+            printf($format_string, $k, $v);
+        }
+    }
+}
+
+// }}}
+// {{{ heading()
+
+function heading($text)
+{
+    $l = strlen(trim($text));
+    print rtrim($text) . "\n" . str_repeat("=", $l) . "\n";
+}
+
+// }}}
+
 /*
  * Local variables:
  * tab-width: 4
index 08163b331d02cfe38f97cec19f945d496bbaa1aa..162d64c981ee355100c5edd7853e1a61f9a3ecb2 100644 (file)
@@ -20,8 +20,11 @@ $config = new PEAR_Config("user.conf", "system.conf");
 dump_array("files", $config->files);
 
 print "#2 testing: singleton\n";
-$cf2 = PEAR_Config::singleton();
-dump_array("files", $cf2->files);
+$o1 = &PEAR_Config::singleton();
+$o1->blah = 'blah';
+$o2 = &PEAR_Config::singleton();
+var_dump($o1->blah);
+@var_dump($o2->blah);
 
 print "#3 testing: readConfigFile\n";
 $config->readConfigFile("user2.conf", "user");
@@ -167,7 +170,8 @@ function dump_config(&$obj, $layer = null) {
 #1 testing: constructor
 files: system="system.conf" user="user.conf"
 #2 testing: singleton
-files: system="system.conf" user="user.conf"
+string(4) "blah"
+string(4) "blah"
 #3 testing: readConfigFile
 user: verbose="2"
 system: master_server="pear.php.net"