]> granicus.if.org Git - php/commitdiff
* PEAR MFH
authorStig Bakken <ssb@php.net>
Tue, 9 Apr 2002 19:04:25 +0000 (19:04 +0000)
committerStig Bakken <ssb@php.net>
Tue, 9 Apr 2002 19:04:25 +0000 (19:04 +0000)
# using rsync this time, does it work?

23 files changed:
pear/DB.php
pear/PEAR.php
pear/PEAR/Command.php
pear/PEAR/Command/Auth.php
pear/PEAR/Command/Common.php
pear/PEAR/Command/Config.php
pear/PEAR/Command/Install.php
pear/PEAR/Command/Package.php
pear/PEAR/Command/Registry.php
pear/PEAR/CommandResponse.php [deleted file]
pear/PEAR/Common.php
pear/PEAR/Config.php
pear/PEAR/Dependency.php
pear/PEAR/Frontend/CLI.php
pear/PEAR/Installer.php
pear/PEAR/Packager.php
pear/PEAR/Registry.php
pear/PEAR/Remote.php
pear/PEAR/Uploader.php [deleted file]
pear/package.dtd
pear/pear.m4
pear/scripts/pear.bat
pear/scripts/pear.in

index 22cff1f81cbfaeccde3a6b475fb939d855a9b4eb..75b12e79445372c6c625b7614309886e14acb10f 100644 (file)
@@ -127,8 +127,8 @@ define('DB_FETCHMODE_ORDERED', 1);
 define('DB_FETCHMODE_ASSOC', 2);
 
 /**
-* Column data as object properties
-*/
+ * Column data as object properties
+ */
 
 define('DB_FETCHMODE_OBJECT', 3);
 
@@ -180,7 +180,6 @@ define('DB_TABLEINFO_FULL', 3);
  *              class.
  *
  * @package  DB
- * @version  2
  * @author   Stig Bakken <ssb@fast.no>
  * @since    PHP 4.0
  */
@@ -261,9 +260,6 @@ 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);
@@ -274,14 +270,10 @@ class DB
         } else {
             $obj->setOption('persistent', $options);
         }
-        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;
+        $err = $obj->connect($dsninfo, $obj->getOption('persistent'));
+        if (DB::isError($err)) {
+            $err->addUserInfo($dsn);
+            return $err;
         }
 
         return $obj;
index 7c5198b6b18f6eefec9957c19beee1b6565ee5f9..4d013d76c2a195e65e7ff26a29e5e6dfc3540ccf 100644 (file)
@@ -39,8 +39,13 @@ if (substr(PHP_OS, 0, 3) == 'WIN') {
 
 $GLOBALS['_PEAR_default_error_mode']     = PEAR_ERROR_RETURN;
 $GLOBALS['_PEAR_default_error_options']  = E_USER_NOTICE;
+$GLOBALS['_PEAR_default_error_callback'] = '';
 $GLOBALS['_PEAR_destructor_object_list'] = array();
 
+//
+// Tests needed: - PEAR inheritance
+//
+
 /**
  * Base class for other PEAR classes.  Provides rudimentary
  * emulation of destructors.
@@ -55,12 +60,8 @@ $GLOBALS['_PEAR_destructor_object_list'] = array();
  * discarded.  If you need to get any debug information from your
  * destructor, use error_log(), syslog() or something similar.
  *
- * IMPORTANT! To use the emulated destructors you need to create the
- * objects by reference, ej: $obj =& new PEAR_child;
- *
  * @since PHP 4.0.2
  * @author Stig Bakken <ssb@fast.no>
- * @see http://pear.php.net/manual/
  */
 class PEAR
 {
@@ -125,8 +126,8 @@ class PEAR
      * $_PEAR_destructor_object_list for destructor emulation if a
      * destructor object exists.
      *
-     * @param string  $error_class (optional) which class to use for error
-     *                             objects, defaults to PEAR_Error.
+     * @param string      (optional) which class to use for error objects,
+     *                    defaults to PEAR_Error.
      * @access public
      * @return void
      */
@@ -177,7 +178,7 @@ class PEAR
     /**
      * Tell whether a value is a PEAR error.
      *
-     * @param   mixed   $data the value to test
+     * @param   mixed   the value to test
      * @access  public
      * @return  bool    true if parameter is an error
      */
@@ -233,9 +234,11 @@ class PEAR
         if (isset($this)) {
             $setmode     = &$this->_default_error_mode;
             $setoptions  = &$this->_default_error_options;
+            //$setcallback = &$this->_default_error_callback;
         } else {
             $setmode     = &$GLOBALS['_PEAR_default_error_mode'];
             $setoptions  = &$GLOBALS['_PEAR_default_error_options'];
+            //$setcallback = &$GLOBALS['_PEAR_default_error_callback'];
         }
 
         switch ($mode) {
@@ -276,15 +279,12 @@ class PEAR
      * expected errors are in effect until they are popped off the
      * stack with the popExpect() method.
      *
-     * Note that this method can not be called statically
-     *
-     * @param mixed  $code  a single error code or an array of error codes
-     *                      to expect
+     * @param mixed    a single error code or an array of error codes
+     *                 to expect
      *
      * @return int     the new depth of the "expected errors" stack
-     * @access public
      */
-    function expectError($code = '*')
+    function expectError($code = "*")
     {
         if (is_array($code)) {
             array_push($this->_expected_errors, $code);
@@ -371,19 +371,47 @@ class PEAR
                 $mode = PEAR_ERROR_RETURN;
             }
         }
-        // No mode given, try global ones
+
         if ($mode === null) {
-            // Class error handler
             if (isset($this) && isset($this->_default_error_mode)) {
-                $mode    = $this->_default_error_mode;
-                $options = $this->_default_error_options;
-            // Global error handler
-            } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) {
-                $mode    = $GLOBALS['_PEAR_default_error_mode'];
+                $mode = $this->_default_error_mode;
+            } else {
+                $mode = $GLOBALS['_PEAR_default_error_mode'];
+            }
+        }
+
+        if ($mode == PEAR_ERROR_TRIGGER && $options === null) {
+            if (isset($this)) {
+                if (isset($this->_default_error_options)) {
+                    $options = $this->_default_error_options;
+                }
+            } else {
                 $options = $GLOBALS['_PEAR_default_error_options'];
             }
         }
 
+        if ($mode == PEAR_ERROR_CALLBACK) {
+            if (!is_string($options) &&
+                !(is_array($options) && sizeof($options) == 2 &&
+                  is_object($options[0]) && is_string($options[1])))
+            {
+                if (isset($this) && isset($this->_default_error_options)) {
+                    $options = $this->_default_error_options;
+                } else {
+                    $options = $GLOBALS['_PEAR_default_error_options'];
+                }
+            }
+        } else {
+            if ($options === null) {
+                if (isset($this)) {
+                    if (isset($this->_default_error_options)) {
+                        $options = $this->_default_error_options;
+                    }
+                } else {
+                    $options = $GLOBALS['_PEAR_default_error_options'];
+                }
+            }
+        }
         if ($error_class !== null) {
             $ec = $error_class;
         } elseif (isset($this) && isset($this->_error_class)) {
@@ -406,7 +434,7 @@ class PEAR
     * you can easily override the actual error handler for some code and restore
     * it later with popErrorHandling.
     *
-    * @param $mode    mixed (same as setErrorHandling)
+    * @param $mode mixed (same as setErrorHandling)
     * @param $options mixed (same as setErrorHandling)
     *
     * @return bool Always true
@@ -420,9 +448,13 @@ class PEAR
             if (isset($this)) {
                 $def_mode = &$this->_default_error_mode;
                 $def_options = &$this->_default_error_options;
+                // XXX Used anywhere?
+                //$def_callback = &$this->_default_error_callback;
             } else {
                 $def_mode = &$GLOBALS['_PEAR_default_error_mode'];
                 $def_options = &$GLOBALS['_PEAR_default_error_options'];
+                // XXX Used anywhere?
+                //$def_callback = &$GLOBALS['_PEAR_default_error_callback'];
             }
             $stack = array();
             $stack[] = array($def_mode, $def_options);
@@ -622,7 +654,7 @@ class PEAR_Error
      * @return  string  full error message
      * @access public
      */
-    function getMessage()
+    function getMessage ()
     {
         return ($this->error_message_prefix . $this->message);
     }
@@ -651,7 +683,7 @@ class PEAR_Error
      * @return string error/exception name (type)
      * @access public
      */
-    function getType()
+    function getType ()
     {
         return get_class($this);
     }
@@ -665,7 +697,7 @@ class PEAR_Error
      * @return string user-supplied information
      * @access public
      */
-    function getUserInfo()
+    function getUserInfo ()
     {
         return $this->userinfo;
     }
@@ -679,7 +711,7 @@ class PEAR_Error
      * @return string debug information
      * @access public
      */
-    function getDebugInfo()
+    function getDebugInfo ()
     {
         return $this->getUserInfo();
     }
index 851099e66bffb0c22795fb9ec725e3653a54765f..50b8c7b42cb7b563625d7f20df68ac17adbf29fa 100644 (file)
@@ -33,6 +33,12 @@ $GLOBALS['_PEAR_Command_commandlist'] = array();
  */
 $GLOBALS['_PEAR_Command_uiclass'] = 'PEAR_Frontend_CLI';
 
+/**
+ * Instance of $_PEAR_Command_uiclass.
+ * @var object
+ */
+$GLOBALS['_PEAR_Command_uiobject'] = null;
+
 /**
 * The options accepted by the commands
 * @var string the options
@@ -205,6 +211,15 @@ class PEAR_Command
         }
         return $GLOBALS['_PEAR_Command_commandopts'];
     }
+
+    function getHelp($command)
+    {
+        $cmds = PEAR_Command::getCommands();
+        if (isset($cmds[$command])) {
+            return call_user_func(array($cmds[$command], 'getHelp'), $command);
+        }
+        return false;
+    }
 }
 
 ?>
\ No newline at end of file
index 81c393e8d6c28aa37e2d9796738df65411d8955f..f59f730b83c243fbe8d739a1ff03e6c2aedf6fcf 100644 (file)
@@ -55,6 +55,16 @@ class PEAR_Command_Auth extends PEAR_Command_Common
     }
 
     // }}}
+
+    function getHelp($command)
+    {
+        switch ($command) {
+            case 'login':
+                return array(null, 'Connects to the remote server');
+            case 'logout':
+                return array(null, 'Disconnects from the remote server');
+        }
+    }
     // {{{ run()
 
     /**
@@ -73,28 +83,27 @@ class PEAR_Command_Auth extends PEAR_Command_Common
      */
     function run($command, $options, $params)
     {
-        $cf = $this->config;
         $failmsg = '';
-        $server = $cf->get('master_server');
+        $server = $this->config->get('master_server');
         switch ($command) {
             case 'login': {
-                $remote = new PEAR_Remote($cf);
-                $username = $cf->get('username');
+                $remote = new PEAR_Remote($this->config);
+                $username = $this->config->get('username');
                 if (empty($username)) {
                     $username = @$_ENV['USER'];
                 }
                 $this->ui->displayLine("Logging in to $server.");
                 $username = trim($this->ui->userDialog('Username', 'text', $username));
 
-                $cf->set('username', $username);
+                $this->config->set('username', $username);
                 $password = trim($this->ui->userDialog('Password', 'password'));
-                $cf->set('password', $password);
+                $this->config->set('password', $password);
                 $remote->expectError(401);
                 $ok = $remote->call('logintest');
                 $remote->popExpect();
                 if ($ok === true) {
                     $this->ui->displayLine("Logged in.");
-                    $cf->store();
+                    $this->config->store();
                 } else {
                     $this->ui->displayLine("Login failed!");
                 }
@@ -102,9 +111,9 @@ class PEAR_Command_Auth extends PEAR_Command_Common
             }
             case 'logout': {
                 $this->ui->displayLine("Logging out from $server.");
-                $cf->remove('username');
-                $cf->remove('password');
-                $cf->store();
+                $this->config->remove('username');
+                $this->config->remove('password');
+                $this->config->store();
                 break;
             }
             default: {
index 7ea724a999e202550c1f3845979fb6762085aac4..c31c23680da91e6049dd35a17345d96a4ccb60a7 100644 (file)
@@ -19,7 +19,6 @@
 // $Id$
 
 require_once "PEAR.php";
-//require_once "PEAR/CommandResponse.php";
 
 class PEAR_Command_Common extends PEAR
 {
@@ -54,27 +53,10 @@ class PEAR_Command_Common extends PEAR
         return array();
     }
 
-    /**
-     * Return a PEAR_CommandResponse object with parameters
-     * filled in.
-     *
-     * @param int     status code
-     * @param string  message text
-     * @param string  (optional) message character encoding
-     *
-     * @return object a PEAR_CommandResponse object
-     *
-     * @access public
-     *
-     * @see PEAR_CommandResponse
-     */
-/*
-    function &makeResponse($status, $message, $encoding = null)
+    function getHelp($command)
     {
-        $obj = &new PEAR_CommandResponse($status, $message, $encoding);
-        return $obj;
+        return array(null, 'No help avaible yet');
     }
-*/
 }
 
 ?>
\ No newline at end of file
index 1fdcf32747dc009c32b98c6d5b37aef4bb0e625a..009c2d243ebf5210edb2d77aed20b0e4e011c03f 100644 (file)
@@ -14,6 +14,8 @@
 // | license@php.net so we can mail you a copy immediately.               |
 // +----------------------------------------------------------------------+
 // | Author: Stig Bakken <ssb@fast.no>                                    |
+// |         Tomas V.V.Cox <cox@idecnet.com>                              |
+// |                                                                      |
 // +----------------------------------------------------------------------+
 //
 // $Id$
@@ -57,44 +59,66 @@ class PEAR_Command_Config extends PEAR_Command_Common
     }
 
     // }}}
+
+    function getHelp($command)
+    {
+        switch ($command) {
+            case 'config-show':
+                $ret = array('[<layer>]', 'Displays the configuration');
+                break;
+            case 'config-get':
+                $ret = array('<parameter> [<layer>]',
+                             'Displays the value of the given parameter');
+                break;
+            case 'config-set':
+                $ret = array('<parameter> <value> [<layer>]',
+                             'Sets the value of a parameter in the config');
+                break;
+        }
+        $ret[1] .= "\n".
+                   "  <layer>    Where to store/get the configuration. The installer\n".
+                   "             supports 'user' (per user conf) and 'system' (global conf)";
+        return $ret;
+    }
     // {{{ run()
 
     function run($command, $options, $params)
     {
-        $cf =$this->config;
+        $cf = &$this->config;
         $failmsg = '';
-        $params[0] = (isset($params[0])) ? $params[0] : null;
-        $params[1] = (isset($params[1])) ? $params[1] : null;
         switch ($command) {
             case 'config-show': {
+                // $params[0] -> the layer
+                if ($error = $this->_checkLayer(@$params[0])) {
+                    $failmsg .= $error;
+                    break;
+                }
                 $keys = $cf->getKeys();
                 sort($keys);
                 $this->ui->startTable(array('caption' => 'Configuration:'));
-                if (isset($params[0]) && $cf->isDefined($params[0])) {
-                    foreach ($keys as $key) {
-                        $type = $cf->getType($key);
-                        $value = $cf->get($key, $params[0]);
-                        if ($type == 'password' && $value) {
-                            $value = '********';
-                        }
-                        $this->ui->tableRow(array($key, $value));
+                foreach ($keys as $key) {
+                    $type = $cf->getType($key);
+                    $value = $cf->get($key, @$params[0]);
+                    if ($type == 'password' && $value) {
+                        $value = '********';
                     }
-                } else {
-                    foreach ($keys as $key) {
-                        $type = $cf->getType($key);
-                        $value = $cf->get($key, $params[0]);
-                        if ($type == 'password' && $value) {
-                            $value = '********';
-                        }
-                        $this->ui->tableRow(array($key, $value));
+                    if (empty($value)) {
+                        $value = '<not set>';
                     }
+                    $this->ui->tableRow(array($key, $value));
                 }
                 $this->ui->endTable();
                 break;
             }
             case 'config-get': {
+                // $params[0] -> the parameter
+                // $params[1] -> the layer
+                if ($error = $this->_checkLayer(@$params[1])) {
+                    $failmsg .= $error;
+                    break;
+                }
                 if (sizeof($params) < 1 || sizeof($params) > 2) {
-                    $failmsg .= "config-get expects 1 or 2 parameters";
+                    $failmsg .= "config-get expects 1 or 2 parameters. Try \"help config-get\" for help";
                 } elseif (sizeof($params) == 1) {
                     $this->ui->displayLine("$params[0] = " . $cf->get($params[0]));
                 } else {
@@ -104,15 +128,22 @@ class PEAR_Command_Config extends PEAR_Command_Common
                 break;
             }
             case 'config-set': {
+                // $param[0] -> a parameter to set
+                // $param[1] -> the value for the parameter
+                // $param[2] -> the layer
                 if (sizeof($params) < 2 || sizeof($params) > 3) {
-                    $failmsg .= "config-set expects 2 or 3 parameters";
+                    $failmsg .= "config-set expects 2 or 3 parameters. Try \"help config-set\" for help";
+                    break;
+                }
+                if ($error = $this->_checkLayer(@$params[2])) {
+                    $failmsg .= $error;
                     break;
+                }
+                if (!call_user_func_array(array(&$cf, 'set'), $params))
+                {
+                    $failmsg = "config-set (" . implode(", ", $params) . ") failed";
                 } else {
-                    if (!call_user_func_array(array($cf, 'set'), $params))
-                    {
-                        $failmsg = "config-set (" .
-                             implode(", ", $params) . ") failed";
-                    }
+                    $cf->store();
                 }
                 break;
             }
@@ -127,6 +158,24 @@ class PEAR_Command_Config extends PEAR_Command_Common
     }
 
     // }}}
+
+    /**
+    * 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)) {
+            $layers = $this->config->getLayers();
+            if (!in_array($layer, $layers)) {
+                return " only the layers: \"" . implode('" or "', $layers) . "\" are supported";
+            }
+        }
+        return false;
+    }
+
 }
 
 ?>
\ No newline at end of file
index 7204c309bfd76a714c8d956119420fef813eb739..e037c0a1bb8699d94e30938281b5f0ad0cb702f1 100644 (file)
@@ -28,9 +28,6 @@ require_once "PEAR/Installer.php";
  */
 class PEAR_Command_Install extends PEAR_Command_Common
 {
-    // {{{ properties
-    // }}}
-
     // {{{ constructor
 
     /**
@@ -57,27 +54,68 @@ class PEAR_Command_Install extends PEAR_Command_Common
         return array('install', 'uninstall', 'upgrade');
     }
 
+    function getHelp($command)
+    {
+        switch ($command) {
+            case 'install':
+                $ret = array('<pear package>',
+                             'Installs a PEAR package created by the "package" command');
+                break;
+            case 'uninstall':
+                $ret = array('<package>',
+                             'Uninstalls a previously installed PEAR package');
+                break;
+            case 'upgrade':
+                $ret = array('<pear package>',
+                             'Upgrades a PEAR package installed in the system');
+                break;
+        }
+        $ret[0] = "[-n] [-f] [-s] [-Z] {$ret[0]}";
+        $ret[1] = "{$ret[1]}\n" .
+                  "   -f    forces the installation of the package\n".
+                  "         when it is already installed\n".
+                  "   -n    do not take care of package dependencies\n".
+                  "   -s    soft update: install or upgrade only if needed\n".
+                  "   -Z    no compression: download plain .tar files";
+        return $ret;
+    }
+
+    // }}}
+    // {{{ getOptions()
+
+    function getOptions()
+    {
+        return array('f', 'n', 's', 'Z');
+    }
+
     // }}}
     // {{{ run()
 
     function run($command, $options, $params)
     {
-        $installer = &new PEAR_Installer($this->config->get('php_dir'),
-                                         $this->config->get('ext_dir'),
-                                         $this->config->get('doc_dir'));
+        $installer = &new PEAR_Installer($this->config);
+        $installer->setFrontend($this->ui);
         $installer->debug = $this->config->get('verbose');
 
         $failmsg = '';
         $opts = array();
+        if (isset($options['f'])) {
+            $opts['force'] = true;
+        }
+        if (isset($options['n'])) {
+            $opts['nodeps'] = true;
+        }
+        if (isset($options['s'])) {
+            $opts['soft'] = true;
+        }
+        if (isset($options['Z'])) {
+            $opts['nocompress'] = true;
+        }
         switch ($command) {
             case 'upgrade':
                 $opts['upgrade'] = true;
                 // fall through
             case 'install': {
-                if (isset($options['f'])) {
-                    $opts['force'] = true;
-                }
-                // XXX The ['nodeps'] option is still missing
                 if ($installer->install(@$params[0], $opts, $this->config)) {
                     $this->ui->displayLine("install ok");
                 } else {
@@ -104,11 +142,6 @@ class PEAR_Command_Install extends PEAR_Command_Common
     }
 
     // }}}
-
-    function getOptions()
-    {
-        return array('f');
-    }
 }
 
 ?>
\ No newline at end of file
index a95f45a1fd6fdceab8b4d7e5d54546c22749008a..eb2d9771b2f0d29ac429d5b1f3efd103e811f017 100644 (file)
@@ -1,4 +1,22 @@
 <?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/Packager.php';
@@ -20,6 +38,26 @@ class PEAR_Command_Package extends PEAR_Command_Common
 
     // }}}
 
+    // {{{ _displayValidationResults()
+
+    function _displayValidationResults($err, $warn, $strict = false)
+    {
+        foreach ($err as $e) {
+            $this->ui->displayLine("Error: $e");
+        }
+        foreach ($warn as $w) {
+            $this->ui->displayLine("Warning: $w");
+        }
+        $this->ui->displayLine(sprintf('Validation: %d error(s), %d warning(s)',
+                                       sizeof($err), sizeof($warn)));
+        if ($strict && sizeof($err) > 0) {
+            $this->ui->displayLine("Fix these errors and try again.");
+            return false;
+        }
+        return true;
+    }
+
+    // }}}
     // {{{ getCommands()
 
     /**
@@ -30,8 +68,43 @@ class PEAR_Command_Package extends PEAR_Command_Common
     function getCommands()
     {
         return array('package',
+                     'package-info',
                      'package-list',
-                     'package-info');
+                     'package-validate',
+                     'cvstag');
+    }
+
+    // }}}
+    // {{{ getOptions()
+
+    function getOptions()
+    {
+        return array('Z', 'n' /*, 'f', 'd', 'q', 'Q'*/);
+    }
+
+    // }}}
+    // {{{ getHelp()
+
+    function getHelp($command)
+    {
+        switch ($command) {
+            case 'package':
+                return array('[<package.xml>]',
+                             'Creates a PEAR package from its description file (usually '.
+                             'named as package.xml)');
+            case 'package-list':
+                return array('<pear package>',
+                             'List the contents of a PEAR package');
+            case 'packge-info':
+                return array('<pear package>',
+                             'Shows information about a PEAR package');
+            case 'package-validate':
+                return array('<package.(tgz|tar|xml)>',
+                             'Verifies a package or description file');
+            case 'cvstag':
+                return array('<package.xml>',
+                             'Runs "cvs tag" on files contained in a release');
+        }
     }
 
     // }}}
@@ -58,13 +131,19 @@ class PEAR_Command_Package extends PEAR_Command_Common
             // {{{ package
 
             case 'package': {
-                $pkginfofile = isset($params[0]) ? $params[0] : null;
+                $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml';
                 ob_start();
                 $packager =& new PEAR_Packager($this->config->get('php_dir'),
                                                $this->config->get('ext_dir'),
                                                $this->config->get('doc_dir'));
                 $packager->debug = $this->config->get('verbose');
-                $result = $packager->Package($pkginfofile);
+                $err = $warn = array();
+                $packager->validatePackageInfo($pkginfofile, $err, $warn);
+                if (!$this->_displayValidationResults($err, $warn, true)) {
+                    break;
+                }
+                $compress = empty($options['Z']) ? true : false;
+                $result = $packager->Package($pkginfofile, $compress);
                 $output = ob_get_contents();
                 ob_end_clean();
                 $lines = explode("\n", $output);
@@ -72,9 +151,7 @@ class PEAR_Command_Package extends PEAR_Command_Common
                     $this->ui->displayLine($line);
                 }
                 if (PEAR::isError($result)) {
-                    $this->ui->displayLine("Package failed!");
-                } else {
-                    $this->ui->displayLine("Package ok.");
+                    $this->ui->displayLine("Package failed: ".$result->getMessage());
                 }
                 break;
             }
@@ -83,7 +160,14 @@ class PEAR_Command_Package extends PEAR_Command_Common
             // {{{ package-list
 
             case 'package-list': {
+                // $params[0] -> the PEAR package to list its contents
+                if (sizeof($params) != 1) {
+                    $failmsg = "Command package-list requires a valid PEAR package filename ".
+                               " as the first argument. Try the command \"help package-list\"";
+                    break;
+                }
                 $obj = new PEAR_Common();
+
                 if (PEAR::isError($info = $obj->infoFromTgzFile($params[0]))) {
                     return $info;
                 }
@@ -96,9 +180,9 @@ class PEAR_Command_Package extends PEAR_Command_Common
                 foreach ($list as $file => $att) {
                     if (isset($att['baseinstalldir'])) {
                         $dest = $att['baseinstalldir'] . DIRECTORY_SEPARATOR .
-                                basename($file);
+                                $file;
                     } else {
-                        $dest = basename($file);
+                        $dest = $file;
                     }
                     switch ($att['role']) {
                         case 'test':
@@ -204,6 +288,89 @@ class PEAR_Command_Package extends PEAR_Command_Common
                 break;
             }
 
+            // }}}
+            // {{{ package-validate
+
+            case 'package-validate': {
+                if (sizeof($params) < 1) {
+                    $params[0] = "package.xml";
+                }
+                $obj = new PEAR_Common;
+                $info = null;
+                if (file_exists($params[0])) {
+                    $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);
+                break;
+            }
+
+            // }}}
+            // {{{ cvstag
+
+            case 'cvstag': {
+                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)) {
+                    break;
+                }
+                $version = $info['version'];
+                $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version);
+                $cvstag = "RELEASE_$cvsversion";
+                $files = array_keys($info['filelist']);
+                $command = "cvs";
+                /* until the getopt bug is fixed, these won't work:
+                if (isset($options['q'])) {
+                    $command .= ' -q';
+                }
+                if (isset($options['Q'])) {
+                    $command .= ' -Q';
+                }
+                */
+                $command .= ' tag';
+                if (isset($options['f'])) {
+                    $command .= ' -f';
+                }
+                /* neither will this one:
+                if (isset($options['d'])) {
+                    $command .= ' -d';
+                }
+                */
+                $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]);
+                foreach ($files as $file) {
+                    $command .= ' ' . escapeshellarg($file);
+                }
+                $this->ui->displayLine("+ $command");
+                if (empty($options['n'])) {
+                    $fp = popen($command, "r");
+                    while ($line = fgets($fp, 1024)) {
+                        $this->ui->displayLine(rtrim($line));
+                    }
+                    pclose($fp);
+                }
+                break;
+            }
+
             // }}}
             default: {
                 return false;
@@ -217,7 +384,6 @@ class PEAR_Command_Package extends PEAR_Command_Common
 
     // }}}
 
-
 }
 
 ?>
\ No newline at end of file
index 25e0c576b410c9cef11abe23b970d7064d518bc8..92777094ca1a17e2e21ef514eb31b192dfd0da63 100644 (file)
@@ -29,7 +29,15 @@ class PEAR_Command_Registry extends PEAR_Command_Common
      */
     function getCommands()
     {
-        return array('list-installed');
+        return array('list-installed', 'shell-test');
+    }
+
+    function getHelp($command)
+    {
+        switch ($command) {
+            case 'list-installed':
+                return array(null, 'List the installed PEAR packages in the system');
+        }
     }
 
     // }}}
@@ -54,6 +62,8 @@ class PEAR_Command_Registry extends PEAR_Command_Common
         $failmsg = '';
         $cf = &PEAR_Config::singleton();
         switch ($command) {
+            // {{{ list-installed
+
             case 'list-installed': {
                 $reg = new PEAR_Registry($cf->get('php_dir'));
                 $installed = $reg->packageInfo();
@@ -63,16 +73,47 @@ class PEAR_Command_Registry extends PEAR_Command_Common
                           'border' => true));
                 foreach ($installed as $package) {
                     if ($i++ % 20 == 0) {
-                        $this->ui->tableRow(array('Package', 'Version', 'State'),
-                                        array('bold' => true));
+                        $this->ui->tableRow(
+                            array('Package', 'Version', 'State'),
+                            array('bold' => true));
                     }
                     $this->ui->tableRow(array($package['package'],
                                               $package['version'],
-                                              $package['release_state']));
+                                              @$package['release_state']));
                 }
                 $this->ui->endTable();
                 break;
             }
+
+            // }}}
+            case 'shell-test': {
+                // silence error messages for the rest of the execution
+                PEAR::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 {
+                    PEAR::popErrorHandling();
+                    PEAR::raiseError("$command: expects 1 to 3 parameters");
+                    exit(1);
+                }
+                break;
+            }
             default: {
                 return false;
             }
diff --git a/pear/PEAR/CommandResponse.php b/pear/PEAR/CommandResponse.php
deleted file mode 100644 (file)
index 2771550..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-<?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.php";
-
-define('PEAR_COMMAND_FAILURE', 0);
-define('PEAR_COMMAND_SUCCESS', 1);
-define('PEAR_COMMAND_PARTIAL', 2);
-
-/**
- * PEAR_CommandResponse is for returning an "environment-neutral"
- * response to the application when a PEAR command is done.  This
- * means that there should be no HTML markup etc. in the message.  The
- * application should try rendering the message "as-is" with
- * linebreaks and preferably a fixed-width font.
- */
-class PEAR_CommandResponse extends PEAR
-{
-    /** Status code (one of the PEAR_COMMAND_* constants
-     * @var int
-     */
-    var $status = null;
-
-    /** Message for user, in plain text.
-     * @var string
-     */
-    var $message = '';
-
-    /** Character set/encoding of $message.
-     * @var string
-     */
-    var $encoding = 'ISO-8859-1';
-
-    /**
-     * Constructor.  Not very exciting.
-     *
-     * @param int     Command status, one of:
-     *                PEAR_COMMAND_SUCCESS : the command was successful
-     *                PEAR_COMMAND_FAILURE : the command failed
-     *                PEAR_COMMAND_PARTIAL : the command was successful,
-     *                but requires some other command to complete the
-     *                operation (for example if the user must confirm
-     *                something).
-     * @param string  Message for the user.
-     * @param string  (optional) What character encoding the message
-     *                is in, defaults to ISO-8859-1.
-     * @access public
-     */
-    function PEAR_CommandRepsonse($status, $message, $encoding = null)
-    {
-        if ($encoding !== null) {
-            $this->setEncoding($encoding);
-        }
-        $this->status = $status;
-        $this->message = $message;
-    }
-
-    /**
-     * Get the response status code.
-     * @return int response status code
-     * @access public
-     */
-    function getStatus()
-    {
-        return $this->status;
-    }
-
-    /**
-     * Get the response message.
-     * @return string response message
-     * @access public
-     */
-    function getMessage()
-    {
-        return $this->message;
-    }
-
-    /**
-     * Get the response message charset encoding.
-     * @return string response message charset encoding
-     * @access public
-     */
-    function getEncoding()
-    {
-        return $this->encoding;
-    }
-
-    /**
-     * Set the response message charset encoding.
-     * @param string Which encoding to use, valid charsets are currently
-     *               ISO-8859-{1-15} and UTF-8.
-     * @return bool true if the encoding was valid, false if not
-     * @access public
-     */
-    function setEncoding($encoding)
-    {
-        if (preg_match('/^ISO-8859-([1-9]|1[1-5])$/i', $encoding) ||
-            strcasecmp('UTF-8', $encoding) == 0) {
-            $this->encoding = $encoding;
-            return true;
-        }
-        return false;
-    }
-}
-
-?>
\ No newline at end of file
index efbaaac2a77b0921044db8dd405000eaa0110b7c..63696ed63038d4423dc9a4a3ce47ff626e41635e 100644 (file)
@@ -57,16 +57,49 @@ class PEAR_Common extends PEAR
     var $pkginfo = array();
 
     /**
-     * Permitted maintainer roles
+     * Valid maintainer roles
      * @var array
      */
     var $maintainer_roles = array('lead','developer','contributor','helper');
 
     /**
-     * Permitted release states
+     * Valid release states
      * @var array
      */
-    var $releases_states  = array('alpha','beta','stable','snapshot','devel');
+    var $release_states  = array('alpha','beta','stable','snapshot','devel');
+
+    /**
+     * Valid dependency types
+     * @var array
+     */
+    var $dependency_types  = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi');
+
+    /**
+     * Valid dependency relations
+     * @var array
+     */
+    var $dependency_relations  = array('has','eq','lt','le','gt','ge');
+
+    /**
+     * Valid file roles
+     * @var array
+     */
+    var $file_roles  = array('php','ext','test','doc','data','extsrc','script');
+
+    /**
+     * Valid replacement types
+     * @var array
+     */
+    var $replacement_types  = array('php-const', 'pear-config');
+
+    /**
+     * User Interface object (PEAR_Frontend_* class).  If null,
+     * log() uses print.
+     * @var object
+     */
+    var $ui = null;
+
+    var $current_path = null;
 
     // }}}
 
@@ -159,7 +192,11 @@ class PEAR_Common extends PEAR
     function log($level, $msg)
     {
         if ($this->debug >= $level) {
-            print "$msg\n";
+            if (is_object($this->ui)) {
+                $this->ui->displayLine($msg);
+            } else {
+                print "$msg\n";
+            }
         }
     }
 
@@ -168,13 +205,13 @@ class PEAR_Common extends PEAR
 
     /**
      * Create and register a temporary directory.
-     * 
+     *
      * @param string (optional) Directory to use as tmpdir.  Will use
      * system defaults (for example /tmp or c:\windows\temp) if not
      * specified
      *
      * @return string name of created directory
-     * 
+     *
      * @access public
      */
     function mkTempDir($tmpdir = '')
@@ -192,6 +229,15 @@ class PEAR_Common extends PEAR
     }
 
     // }}}
+    // {{{ setFrontend()
+
+    function setFrontend(&$ui)
+    {
+        $this->ui = &$ui;
+    }
+
+    // }}}
+
     // {{{ _element_start()
 
     /**
@@ -247,7 +293,7 @@ class PEAR_Common extends PEAR
     function _element_end($xp, $name)
     {
     }
-    
+
     // }}}
 
     // Support for package DTD v1.0:
@@ -284,6 +330,34 @@ class PEAR_Common extends PEAR
                     $this->dir_role = $attribs['role'];
                 }
                 break;
+            case 'file':
+                if (isset($attribs['name'])) {
+                    $path = '';
+                    if (count($this->dir_names)) {
+                        foreach ($this->dir_names as $dir) {
+                            $path .= $dir . DIRECTORY_SEPARATOR;
+                        }
+                    }
+                    $path .= $attribs['name'];
+                    unset($attribs['name']);
+                    $this->current_path = $path;
+                    $this->filelist[$path] = $attribs;
+                    // Set the baseinstalldir only if the file don't have this attrib
+                    if (!isset($this->filelist[$path]['baseinstalldir']) &&
+                        isset($this->dir_install))
+                    {
+                        $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
+                    }
+                    // Set the Role
+                    if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
+                        $this->filelist[$path]['role'] = $this->dir_role;
+                    }
+                }
+                break;
+            case 'replace':
+                $this->filelist[$this->current_path]['replacements'][] = $attribs;
+                break;
+
             case 'libfile':
                 $this->lib_atts = $attribs;
                 $this->lib_atts['role'] = 'extsrc';
@@ -368,11 +442,7 @@ class PEAR_Common extends PEAR
                 $this->current_maintainer['email'] = $data;
                 break;
             case 'role':
-                if (!in_array($data, $this->maintainer_roles)) {
-                    trigger_error("The maintainer role: '$data' is not valid", E_USER_WARNING);
-                } else {
-                    $this->current_maintainer['role'] = $data;
-                }
+                $this->current_maintainer['role'] = $data;
                 break;
             case 'version':
                 $data = ereg_replace ('[^a-zA-Z0-9._\-]', '_', $data);
@@ -397,9 +467,7 @@ class PEAR_Common extends PEAR
                 }
                 break;
             case 'state':
-                if (!in_array($data, $this->releases_states)) {
-                    trigger_error("The release state: '$data' is not valid", E_USER_WARNING);
-                } elseif ($this->in_changelog) {
+                if ($this->in_changelog) {
                     $this->current_release['release_state'] = $data;
                 } else {
                     $this->pkginfo['release_state'] = $data;
@@ -420,24 +488,25 @@ class PEAR_Common extends PEAR
                 array_pop($this->dir_names);
                 break;
             case 'file':
-                $this->current_file = $data;
-                $path = '';
-                if (count($this->dir_names)) {
-                    foreach ($this->dir_names as $dir) {
-                        $path .= $dir . DIRECTORY_SEPARATOR;
+                if ($data) {
+                    $path = '';
+                    if (count($this->dir_names)) {
+                        foreach ($this->dir_names as $dir) {
+                            $path .= $dir . DIRECTORY_SEPARATOR;
+                        }
+                    }
+                    $path .= $data;
+                    $this->filelist[$path] = $this->current_attributes;
+                    // Set the baseinstalldir only if the file don't have this attrib
+                    if (!isset($this->filelist[$path]['baseinstalldir']) &&
+                        isset($this->dir_install))
+                    {
+                        $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
+                    }
+                    // Set the Role
+                    if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
+                        $this->filelist[$path]['role'] = $this->dir_role;
                     }
-                }
-                $path .= $this->current_file;
-                $this->filelist[$path] = $this->current_attributes;
-                // Set the baseinstalldir only if the file don't have this attrib
-                if (!isset($this->filelist[$path]['baseinstalldir']) &&
-                    isset($this->dir_install))
-                {
-                    $this->filelist[$path]['baseinstalldir'] = $this->dir_install;
-                }
-                // Set the Role
-                if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) {
-                    $this->filelist[$path]['role'] = $this->dir_role;
                 }
                 break;
             case 'libfile':
@@ -504,7 +573,9 @@ class PEAR_Common extends PEAR
      */
     function _pkginfo_cdata_1_0($xp, $data)
     {
-        $this->cdata .= $data;
+        if (isset($this->cdata)) {
+            $this->cdata .= $data;
+        }
     }
 
     // }}}
@@ -527,7 +598,12 @@ class PEAR_Common extends PEAR
         if (!@is_file($file)) {
             return $this->raiseError('tgz :: could not open file');
         }
-        $tar = new Archive_Tar($file, true);
+        if (substr($file, -4) == '.tar') {
+            $compress = false;
+        } else {
+            $compress = true;
+        }
+        $tar = new Archive_Tar($file, $compress);
         $content = $tar->listContent();
         if (!is_array($content)) {
             return $this->raiseError('tgz :: could not get contents of package');
@@ -694,6 +770,7 @@ class PEAR_Common extends PEAR
      */
     function _makeReleaseXml($pkginfo, $changelog = false)
     {
+        // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!!
         $indent = $changelog ? "  " : "";
         $ret = "$indent  <release>\n";
         if (!empty($pkginfo['version'])) {
@@ -709,9 +786,9 @@ class PEAR_Common extends PEAR
             $ret .= "$indent    <state>$pkginfo[release_state]</state>\n";
         }
         if (!empty($pkginfo['release_notes'])) {
-            $ret .= "$indent    <notes>$pkginfo[release_notes]</notes>\n";
+            $ret .= "$indent    <notes>".htmlspecialchars($pkginfo['release_notes'])."</notes>\n";
         }
-        if (sizeof($pkginfo['release_deps']) > 0) {
+        if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) {
             $ret .= "$indent    <deps>\n";
             foreach ($pkginfo['release_deps'] as $dep) {
                 $ret .= "$indent      <dep type=\"$dep[type]\" rel=\"$dep[rel]\"";
@@ -729,20 +806,38 @@ class PEAR_Common extends PEAR
         if (isset($pkginfo['filelist'])) {
             $ret .= "$indent    <filelist>\n";
             foreach ($pkginfo['filelist'] as $file => $fa) {
-                if ($fa['role'] == 'extsrc') {
+                if (@$fa['role'] == 'extsrc') {
                     $ret .= "$indent      <libfile>\n";
                     $ret .= "$indent        <libname>$file</libname>\n";
                     $ret .= "$indent        <sources>$fa[sources]</sources>\n";
                     $ret .= "$indent      </libfile>\n";
                 } else {
-                    $ret .= "$indent      <file role=\"$fa[role]\"";
+                    @$ret .= "$indent      <file role=\"$fa[role]\"";
                     if (isset($fa['baseinstalldir'])) {
-                        $ret .= " baseinstalldir=\"$fa[baseinstalldir]\"";
+                        $ret .= ' baseinstalldir="' .
+                             htmlspecialchars($fa['baseinstalldir']) . '"';
                     }
                     if (isset($fa['md5sum'])) {
                         $ret .= " md5sum=\"$fa[md5sum]\"";
                     }
-                    $ret .= ">$file</file>\n";
+                    if (!empty($fa['install-as'])) {
+                        $ret .= ' install-as="' .
+                             htmlspecialchars($fa['install-as']) . '"';
+                    }
+                    $ret .= ' name="' . htmlspecialchars($file) . '"';
+                    if (empty($fa['replacements'])) {
+                        $ret .= "/>\n";
+                    } else {
+                        $ret .= ">\n";
+                        foreach ($fa['replacements'] as $r) {
+                            $ret .= "$indent        <replace";
+                            foreach ($r as $k => $v) {
+                                $ret .= " $k=\"" . htmlspecialchars($v) .'"';
+                            }
+                            $ret .= "/>\n";
+                        }
+                        @$ret .= "$indent      </file>\n";
+                    }
                 }
             }
             $ret .= "$indent    </filelist>\n";
@@ -752,5 +847,142 @@ class PEAR_Common extends PEAR
     }
 
     // }}}
+    // {{{ validatePackageInfo()
+
+    function validatePackageInfo($info, &$errors, &$warnings)
+    {
+        if (is_string($info) && file_exists($info)) {
+            $tmp = substr($info, -4);
+            if ($tmp == '.xml') {
+                $info = $this->infoFromDescriptionFile($info);
+            } elseif ($tmp == '.tar' || $tmp == '.tgz') {
+                $info = $this->infoFromTgzFile($info);
+            } else {
+                $fp = fopen($params[0], "r");
+                $test = fread($fp, 5);
+                fclose($fp);
+                if ($test == "<?xml") {
+                    $info = $obj->infoFromDescriptionFile($params[0]);
+                } else {
+                    $info = $obj->infoFromTgzFile($params[0]);
+                }
+            }
+            if (PEAR::isError($info)) {
+                return $this->raiseError($info);
+            }
+        }
+        if (!is_array($info)) {
+            return false;
+        }
+        $errors = array();
+        $warnings = array();
+        if (empty($info['package'])) {
+            $errors[] = 'missing package name';
+        }
+        if (empty($info['summary'])) {
+            $errors[] = 'missing summary';
+        } elseif (strpos(trim($info['summary']), "\n") !== false) {
+            $warnings[] = 'summary should be on a single line';
+        }
+        if (empty($info['description'])) {
+            $errors[] = 'missing description';
+        }
+        if (empty($info['release_license'])) {
+            $errors[] = 'missing license';
+        }
+        if (empty($info['version'])) {
+            $errors[] = 'missing version';
+        }
+        if (empty($info['release_state'])) {
+            $errors[] = 'missing release state';
+        } elseif (!in_array($info['release_state'], $this->release_states)) {
+            $errors[] = "invalid release state `$info[release_state]', should be one of: ".implode(' ', $this->release_states);
+        }
+        if (empty($info['release_date'])) {
+            $errors[] = 'missing release date';
+        } elseif (!preg_match('/^\d{4}-\d\d-\d\d$/', $info['release_date'])) {
+            $errors[] = "invalid release date `$info[release_date]', format is YYYY-MM-DD";
+        }
+        if (empty($info['release_notes'])) {
+            $errors[] = "missing release notes";
+        }
+        if (empty($info['maintainers'])) {
+            $errors[] = 'no maintainer(s)';
+        } else {
+            $i = 1;
+            foreach ($info['maintainers'] as $m) {
+                if (empty($m['handle'])) {
+                    $errors[] = "maintainer $i: missing handle";
+                }
+                if (empty($m['role'])) {
+                    $errors[] = "maintainer $i: missing role";
+                } elseif (!in_array($m['role'], $this->maintainer_roles)) {
+                    $errors[] = "maintainer $i: invalid role `$m[role]', should be one of: ".implode(' ', $this->maintainer_roles);
+                }
+                if (empty($m['name'])) {
+                    $errors[] = "maintainer $i: missing name";
+                }
+                if (empty($m['email'])) {
+                    $errors[] = "maintainer $i: missing email";
+                }
+                $i++;
+            }
+        }
+        if (!empty($info['deps'])) {
+            $i = 1;
+            foreach ($info['deps'] as $d) {
+                if (empty($d['type'])) {
+                    $errors[] = "depenency $i: missing type";
+                } elseif (!in_array($d['type'], $this->dependency_types)) {
+                    $errors[] = "depenency $i: invalid type, should be one of: ".implode(' ', $this->depenency_types);
+                }
+                if (empty($d['rel'])) {
+                    $errors[] = "dependency $i: missing relation";
+                } elseif (!in_array($d['rel'], $this->dependency_relations)) {
+                    $errors[] = "dependency $i: invalid relation, should be one of: ".implode(' ', $this->dependency_relations);
+                }
+                if ($d['rel'] != 'has' && empty($d['version'])) {
+                    $warnings[] = "dependency $i: missing version";
+                } elseif ($d['rel'] == 'has' && !empty($d['version'])) {
+                    $warnings[] = "dependency $i: version ignored for `has' dependencies";
+                }
+                if ($d['type'] == 'php' && !empty($d['name'])) {
+                    $warnings[] = "dependency $i: name ignored for php type dependencies";
+                } elseif ($d['type'] != 'php' && empty($d['name'])) {
+                    $errors[] = "dependency $i: missing name";
+                }
+                $i++;
+            }
+        }
+        if (empty($info['filelist'])) {
+            $errors[] = 'no files';
+        } else {
+            foreach ($info['filelist'] as $file => $fa) {
+                if (empty($fa['role'])) {
+                    $errors[] = "$file: missing role";
+                } elseif (!in_array($fa['role'], $this->file_roles)) {
+                    $errors[] = "$file: invalid role, should be one of: ".implode(' ', $this->file_roles);
+                } elseif ($fa['role'] == 'extsrc' && empty($fa['sources'])) {
+                    $errors[] = "$file: no source files";
+                }
+                // (ssb) Any checks we can do for baseinstalldir?
+                // (cox) Perhaps checks that either the target dir and baseInstall
+                //       doesn't cointain "../../"
+            }
+        }
+        return true;
+    }
+
+    // }}}
+    /**
+    * Get the valid roles for a PEAR package maintainer
+    *
+    * @static
+    */
+    function getUserRoles()
+    {
+        $common = &new PEAR_Common;
+        return $common->maintainer_roles;
+    }
 }
 ?>
\ No newline at end of file
index 62ad1cdea3a8935e3c77365a72b44a16282a17d8..3efe11323597dba0b780a55515b58c32da0422d2 100644 (file)
@@ -27,23 +27,19 @@ require_once 'PEAR.php';
 $GLOBALS['_PEAR_Config_instance'] = null;
 
 define('PEAR_CONFIG_DEFAULT_DOCDIR',
-       PHP_DATADIR.DIRECTORY_SEPARATOR.'pear'.DIRECTORY_SEPARATOR.'doc');
+       PHP_DATADIR.DIRECTORY_SEPARATOR.'doc'.DIRECTORY_SEPARATOR.'pear');
+
+// in case a --without-pear PHP installation is used
+if (!defined('PEAR_INSTALL_DIR')) {
+    define('PEAR_INSTALL_DIR', PHP_LIBDIR);
+}
+if (!defined('PEAR_EXTENSION_DIR')) {
+    define('PEAR_EXTENSION_DIR', PHP_EXTENSION_DIR);
+}
+
 /**
- * This is a class for storing simple configuration values keeping
- * track of which are system-defined, user-defined or defaulted.  By
- * default, only user-defined settings are stored back to the user's
- * configuration file.
- *
- * Configuration member is a simple associative array.  Used keys:
- *
- *  master_server      which server to query for mirror lists etc.
- *  server             which server/mirror we're currently using
- *  username           PEAR username
- *  password           PEAR password (stored base64-encoded)
- *  php_dir            Where to install .php files
- *  ext_dir            Directory to install compiled libs in
- *  doc_dir            Directory to install documentation in
- *
+ * This is a class for storing configuration data, keeping track of
+ * which are system-defined, user-defined or defaulted.
  */
 class PEAR_Config extends PEAR
 {
@@ -105,7 +101,12 @@ class PEAR_Config extends PEAR
         'doc_dir' => array(
             'type' => 'directory',
             'default' => PEAR_CONFIG_DEFAULT_DOCDIR,
-            'doc' => 'directory where documentation is located',
+            'doc' => 'directory where documentation is installed',
+            ),
+        'bin_dir' => array(
+            'type' => 'directory',
+            'default' => PHP_BINDIR,
+            'doc' => 'directory where executables are installed',
             ),
         'username' => array(
             'type' => 'string',
@@ -765,6 +766,21 @@ when installing packages without a version or state specified',
         return isset($this->configuration[$layer]);
     }
 
+    // }}}
+    // {{{ getLayers()
+
+    /**
+     * Returns the layers defined (except the 'default' one)
+     *
+     * @return array of the defined layers
+     */
+    function getLayers()
+    {
+        $cf = $this->configuration;
+        unset($cf['default']);
+        return array_keys($cf);
+    }
+
     // }}}
 }
 
index c6af633f662b506fa322921e9f03254f707a24a4..76327df0effe3d128a4abad89bcf76b23b63cf78 100644 (file)
@@ -29,7 +29,10 @@ require_once "PEAR.php";
 
 class PEAR_Dependency
 {
-
+    function PEAR_Dependency(&$registry)
+    {
+        $this->registry = &$registry;
+    }
     /**
     * This method maps the xml dependency definition to the
     * PEAR_dependecy one
@@ -87,9 +90,6 @@ class PEAR_Dependency
      */
     function checkPackage($name, $req = null, $relation = 'has')
     {
-        if (empty($this->registry)) {
-            $this->registry = new PEAR_Registry;
-        }
         if (!$this->registry->packageExists($name)) {
             return "'$name' PEAR package is not installed";
         }
index ae6d9c043659e8f7ab72440f2629c2a312b70b16..e8cc5e49e483928329b32f3ddb74ebcb3c1314b2 100644 (file)
@@ -25,6 +25,14 @@ class PEAR_Frontend_CLI extends PEAR
 {
     // {{{ properties
 
+    /**
+     * What type of user interface this frontend is for.
+     * @var string
+     * @access public
+     */
+    var $type = 'CLI';
+    var $lp = ''; // line prefix
+
     var $omode = 'plain';
     var $params = array();
     var $term = array(
@@ -56,16 +64,28 @@ class PEAR_Frontend_CLI extends PEAR
 
     // }}}
 
-    // For now, all the display functions print a "| " at the
-    // beginning of the line.  This is just a temporary thing, it
-    // is for discovering commands that use print instead of
-    // the UI layer.
-
     // {{{ displayLine(text)
 
     function displayLine($text)
     {
-        print "| $text\n";
+        print "$this->lp$text\n";
+    }
+
+    // }}}
+    // {{{ displayError(eobj)
+
+    function displayError($eobj)
+    {
+        return $this->displayLine($eobj->getMessage());
+    }
+
+    // }}}
+    // {{{ displayFatalError(eobj)
+
+    function displayFatalError($eobj)
+    {
+        $this->displayError($eobj);
+        exit(1);
     }
 
     // }}}
@@ -73,8 +93,8 @@ class PEAR_Frontend_CLI extends PEAR
 
     function displayHeading($title)
     {
-        print "| ".$this->bold($title)."\n";
-        print "| ".str_repeat("=", strlen($title))."\n";
+        print $this->lp.$this->bold($title)."\n";
+        print $this->lp.str_repeat("=", strlen($title))."\n";
     }
 
     // }}}
@@ -85,7 +105,7 @@ class PEAR_Frontend_CLI extends PEAR
         if ($type == 'password') {
             system('stty -echo');
         }
-        print "$prompt ";
+        print "$this->lp$prompt ";
         if ($default) {
             print "[$default] ";
         }
@@ -110,7 +130,7 @@ class PEAR_Frontend_CLI extends PEAR
     {
         static $positives = array('y', 'yes', 'on', '1');
         static $negatives = array('n', 'no', 'off', '0');
-        print "$prompt [$default] : ";
+        print "$this->lp$prompt [$default] : ";
         $fp = fopen("php://stdin", "r");
         $line = fgets($fp, 2048);
         fclose($fp);
index 0e9dbdaf191e03021ced5316d2eb7653ef7e918e..95e679c6891e80ec7fbf5d7f1107391a744336e7 100644 (file)
@@ -38,48 +38,60 @@ class PEAR_Installer extends PEAR_Common
 {
     // {{{ properties
 
-    /** name of the package directory, for example Foo-1.0 */
+    /** name of the package directory, for example Foo-1.0
+     * @var string
+     */
     var $pkgdir;
 
-    /** directory where PHP code files go */
+    /** directory where PHP code files go
+     * @var string
+     */
     var $phpdir;
 
-    /** directory where PHP extension files go */
+    /** directory where PHP extension files go
+     * @var string
+     */
     var $extdir;
 
-    /** directory where documentation goes */
+    /** directory where documentation goes
+     * @var string
+     */
     var $docdir;
 
     /** directory where the package wants to put files, relative
-     *  to one of the three previous dirs
+     *  to one of the previous dirs
+     * @var string
      */
     var $destdir = '';
 
-    /** debug level (integer) */
+    /** debug level
+     * @var int
+     */
     var $debug = 1;
 
-    /** temporary directory */
+    /** temporary directory
+     * @var string
+     */
     var $tmpdir;
 
-    /** PEAR_Registry object used by the installer */
+    /** PEAR_Registry object used by the installer
+     * @var object
+     */
     var $registry;
 
+    /** PEAR_Config object used by the installer
+     * @var object
+     */
+    var $config;
+
     // }}}
 
     // {{{ constructor
 
-    function PEAR_Installer($phpdir = PEAR_INSTALL_DIR,
-                            $extdir = PEAR_EXTENSION_DIR,
-                            $docdir = null)
+    function PEAR_Installer(&$config)
     {
         $this->PEAR();
-        $this->phpdir = $phpdir;
-        $this->extdir = $extdir;
-        if ($docdir === null) {
-            $docdir = PHP_DATADIR . DIRECTORY_SEPARATOR . 'pear' .
-                      DIRECTORY_SEPARATOR . 'doc';
-        }
-        $this->docdir = $docdir;
+        $this->config = &$config;
     }
 
     // }}}
@@ -88,11 +100,11 @@ class PEAR_Installer extends PEAR_Common
 
     function _deletePackageFiles($package)
     {
-        $info = $this->registry->packageInfo($package);
-        if ($info == null) {
+        $filelist = $this->registry->packageInfo($package, 'filelist');
+        if ($filelist == null) {
             return $this->raiseError("$package not installed");
         }
-        foreach ($info['filelist'] as $file => $props) {
+        foreach ($filelist as $file => $props) {
             $path = $props['installed_as'];
             // XXX TODO: do a "rmdir -p dirname($path)" to maintain clean the fs
             if (!@unlink($path)) {
@@ -108,30 +120,40 @@ class PEAR_Installer extends PEAR_Common
 
     function _installFile($file, $atts, $tmp_path)
     {
-        $type = strtolower($atts['role']);
-        switch ($type) {
-            case 'test':
+        switch ($atts['role']) {
+            case 'test': case 'data': case 'ext':
                 // don't install test files for now
-                $this->log(2, "+ Test file $file won't be installed yet");
+                $this->log(2, "+ $file: $atts[role] file not installed yet");
                 return true;
-                break;
             case 'doc':
-                $dest_dir = $this->docdir . DIRECTORY_SEPARATOR .
-                            $this->pkginfo['package'];
+                $dest_dir = $this->config->get('doc_dir') .
+                     DIRECTORY_SEPARATOR . $this->pkginfo['package'];
                 break;
+            case 'extsrc':
+                // don't install test files for now
+                $this->log(2, "+ $file: no support for building extensions yet");
+                return true;
             case 'php':
-            default: {
-                $dest_dir = $this->phpdir;
-                if (isset($atts['baseinstalldir'])) {
-                    $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
-                }
-                if (dirname($file) != '.') {
-                    $dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
-                }
+                $dest_dir = $this->config->get('php_dir');
+                break;
+            case 'script': {
+                $dest_dir = $this->config->get('bin_dir');
                 break;
             }
+            default:
+                break;
+        }
+        if (isset($atts['baseinstalldir'])) {
+            $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir'];
+        }
+        if (dirname($file) != '.') {
+            $dest_dir .= DIRECTORY_SEPARATOR . dirname($file);
+        }
+        if (empty($atts['install-as'])) {
+            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
+        } else {
+            $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as'];
         }
-        $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file);
         if (!@is_dir($dest_dir)) {
             if (!$this->mkDirHier($dest_dir)) {
                 $this->log(0, "failed to mkdir $dest_dir");
@@ -140,13 +162,55 @@ class PEAR_Installer extends PEAR_Common
             $this->log(2, "+ created dir $dest_dir");
         }
         $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file;
-        $orig_perms = fileperms($orig_file);
-        if (!@copy($orig_file, $dest_file)) {
-            $this->log(0, "failed to copy $orig_file to $dest_file");
-            return false;
+        if (empty($atts['replacements'])) {
+            if (!@copy($orig_file, $dest_file)) {
+                $this->log(0, "failed to copy $orig_file to $dest_file");
+                return false;
+            }
+            $this->log(2, "+ copy $orig_file to $dest_file");
+        } else {
+            $fp = fopen($orig_file, "r");
+            $contents = fread($fp, filesize($orig_file));
+            fclose($fp);
+            $subst_from = $subst_to = array();
+            foreach ($atts['replacements'] as $a) {
+                $to = '';
+                if ($a['type'] == 'php-const') {
+                    if (preg_match('/^[a-z0-9_]+$/i', $a['to'])) {
+                        eval("\$to = $a[to];");
+                    } else {
+                        $this->log(0, "invalid php-const replacement: $a[to]");
+                        continue;
+                    }
+                } elseif ($a['type'] == 'pear-config') {
+                    $to = $this->config->get($a['to']);
+                }
+                if ($to) {
+                    $subst_from = $a['from'];
+                    $subst_to = $to;
+                }
+            }
+            if (sizeof($subst_from)) {
+                $contents = str_replace($subst_from, $subst_to, $contents);
+            }
+            $wp = @fopen($dest_file, "w");
+            if (!is_resource($wp)) {
+                $this->log(0, "failed to create $dest_file");
+                return false;
+            }
+            fwrite($wp, $contents);
+            fclose($wp);
+        }
+        if (!OS_WINDOWS) {
+            if ($atts['role'] == 'script') {
+                $mode = 0755;
+            } else {
+                $mode = 0644;
+            }
+            if (!@chmod($dest_file, $mode)) {
+                $this->log(0, "failed to change mode of $dest_file");
+            }
         }
-        chmod($dest_file, $orig_perms);
-        $this->log(2, "+ copy $orig_file to $dest_file");
 
         // Store the full path where the file was installed for easy unistall
         $this->pkginfo['filelist'][$file]['installed_as'] = $dest_file;
@@ -171,9 +235,10 @@ class PEAR_Installer extends PEAR_Common
         // recognized options:
         // - register_only : update registry but don't install files
         // - upgrade       : upgrade existing install
+        // - soft          : fail silently
         //
         if (empty($this->registry)) {
-            $this->registry = new PEAR_Registry($this->phpdir);
+            $this->registry = &new PEAR_Registry($this->config->get('php_dir'));
         }
         $oldcwd = getcwd();
         $need_download = false;
@@ -182,12 +247,18 @@ class PEAR_Installer extends PEAR_Common
         } elseif (!@is_file($pkgfile)) {
             if (preg_match('/^[A-Z][A-Za-z0-9_]+$/', $pkgfile)) {
                 // valid package name
+                if ($this->registry->packageExists($pkgfile)) {
+                    return $this->raiseError("$pkgfile already installed");
+                }
                 if ($config === null) {
                     $pkgfile = "http://pear.php.net/get/$pkgfile";
                 } else {
                     $pkgfile = "http://" . $config->get('master_server') .
                          "/get/$pkgfile";
                 }
+                if (!extension_loaded("zlib")) {
+                    $pkgfile .= '?uncompress=yes';
+                }
                 $need_download = true;
             } else {
                 return $this->raiseError("could not open the package file: $pkgfile");
@@ -260,7 +331,7 @@ class PEAR_Installer extends PEAR_Common
         //  ==> XXX This part should be removed later on
         $flag_old_format = false;
         if (!is_file($descfile)) {
-          // ----- Look for old package .tgz archive format
+          // ----- Look for old package archive format
           // In this format the package.xml file was inside the package directory name
           $dp = opendir($tmpdir);
           do {
@@ -291,7 +362,9 @@ class PEAR_Installer extends PEAR_Common
         if (isset($pkginfo['release_deps']) && !isset($options['nodeps'])) {
             $error = $this->checkDeps($pkginfo);
             if ($error) {
-                $this->log(0, $error);
+                if (empty($options['soft'])) {
+                    $this->log(0, $error);
+                }
                 return $this->raiseError('Dependencies failed');
             }
         }
@@ -314,7 +387,7 @@ class PEAR_Installer extends PEAR_Common
             }
             if (empty($options['register_only'])) {
                 // when upgrading, remove old release's files first:
-                $this->_deletePackageFiles($package);
+                $this->_deletePackageFiles($pkgname);
             }
         }
 
@@ -323,7 +396,7 @@ class PEAR_Installer extends PEAR_Common
         // info from the package it self we want to access from _installFile
         $this->pkginfo = $pkginfo;
         if (empty($options['register_only'])) {
-            if (!is_dir($this->phpdir)) {
+            if (!is_dir($this->config->get('php_dir'))) {
                 chdir($oldcwd);
                 return $this->raiseError("no script destination directory\n",
                                          null, PEAR_ERROR_DIE);
@@ -365,7 +438,7 @@ class PEAR_Installer extends PEAR_Common
     function uninstall($package)
     {
         if (empty($this->registry)) {
-            $this->registry = new PEAR_Registry($this->phpdir);
+            $this->registry = new PEAR_Registry($this->config->get('php_dir'));
         }
 
         // Delete the files
@@ -380,7 +453,7 @@ class PEAR_Installer extends PEAR_Common
 
     function checkDeps(&$pkginfo)
     {
-        $deps = new PEAR_Dependency;
+        $deps = &new PEAR_Dependency($this->registry);
         $errors = null;
         if (is_array($pkginfo['release_deps'])) {
             foreach($pkginfo['release_deps'] as $dep) {
index c314e55f8d953f39f3c634cccb8262bf86dcfb49..7930203f707040fb541400b8de6a2499b3d2e51e 100644 (file)
@@ -51,7 +51,6 @@ class PEAR_Packager extends PEAR_Common
 
     function _PEAR_Packager()
     {
-        chdir($this->orig_pwd);
         $this->_PEAR_Common();
     }
 
@@ -59,7 +58,7 @@ class PEAR_Packager extends PEAR_Common
 
     // {{{ package()
 
-    function package($pkgfile = null)
+    function package($pkgfile = null, $compress = true)
     {
         $this->orig_pwd = getcwd();
         if (empty($pkgfile)) {
@@ -67,7 +66,7 @@ class PEAR_Packager extends PEAR_Common
         }
         $pkginfo = $this->infoFromDescriptionFile($pkgfile);
         if (PEAR::isError($pkginfo)) {
-            return $pkginfo;
+            return $this->raiseError($pkginfo);
         }
         // XXX This needs to be checked in infoFromDescriptionFile
         //     or at least a helper method to do the proper checks
@@ -108,10 +107,10 @@ class PEAR_Packager extends PEAR_Common
         }
         $new_xml = $this->xmlFromInfo($pkginfo);
         if (PEAR::isError($new_xml)) {
-            return $new_xml;
+            return $this->raiseError($new_xml);
         }
         $tmpdir = $this->mkTempDir(getcwd());
-        $newpkgfile = $tmpdir . DIRECTORY_SEPARATOR . $pkgfile;
+        $newpkgfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml';
         $np = @fopen($newpkgfile, "w");
         if (!$np) {
             return $this->raiseError("PEAR_Packager: unable to rewrite $pkgfile");
@@ -120,13 +119,14 @@ class PEAR_Packager extends PEAR_Common
         fclose($np);
 
         // TAR the Package -------------------------------------------
-        $dest_package = $this->orig_pwd . DIRECTORY_SEPARATOR . "{$pkgver}.tgz";
-        $tar =& new Archive_Tar($dest_package, true);
+        $ext = $compress ? '.tgz' : '.tar';
+        $dest_package = $this->orig_pwd . DIRECTORY_SEPARATOR . $pkgver . $ext;
+        $tar =& new Archive_Tar($dest_package, $compress);
         $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors
         // ----- Creates with the package.xml file
         $ok = $tar->createModify($newpkgfile, '', $tmpdir);
         if (PEAR::isError($ok)) {
-            return $ok;
+            return $this->raiseError($ok);
         } elseif (!$ok) {
             return $this->raiseError('PEAR_Packager: tarball creation failed');
         }
@@ -137,11 +137,23 @@ class PEAR_Packager extends PEAR_Common
         $this->log(1, "Package $dest_package done");
         $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pkgversion);
         $cvstag = "RELEASE_$cvsversion";
-        $this->log(1, "CVS release tag: $cvstag");
+        $this->log(0, "Tag the released code with `pear cvstag $pkgfile'");
+        $this->log(0, "(or set the CVS tag $cvstag by hand)");
         return $dest_package;
     }
 
     // }}}
 }
 
+if (!function_exists('md5_file')) {
+    function md5_file($file) {
+        if (!$fd = @fopen($file, 'r')) {
+            return false;
+        }
+        $md5 = md5(fread($fd, filesize($file)));
+        fclose($fd);
+        return $md5;
+    }
+}
+
 ?>
\ No newline at end of file
index c09e3abddb8a83f1bffb52626804812838c914d3..3d84120bccd829860a060592487805d60de5ee26 100644 (file)
@@ -57,7 +57,7 @@ class PEAR_Registry extends PEAR
 
     // }}}
 
-    // {{{ PEAR_Registry
+    // {{{ constructor
 
     /**
      * PEAR_Registry constructor.
@@ -79,7 +79,7 @@ class PEAR_Registry extends PEAR
     }
 
     // }}}
-    // {{{ _PEAR_Registry
+    // {{{ destructor
 
     /**
      * PEAR_Registry destructor.  Makes sure no locks are forgotten.
@@ -208,26 +208,36 @@ class PEAR_Registry extends PEAR
      */
     function _lock($mode = LOCK_EX)
     {
-        if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
-            // XXX does not check type of lock (LOCK_SH/LOCK_EX)
-            return true;
-        }
-        if (PEAR::isError($err = $this->_assertStateDir())) {
-            return $err;
-        }
-        $this->lock_fp = @fopen($this->lockfile, 'w');
-        if (!is_resource($this->lock_fp)) {
-            return $this->raiseError("could not create lock file: $php_errormsg");
-        }
-        if (!(int)flock($this->lock_fp, $mode)) {
-            switch ($mode) {
-                case LOCK_SH: $str = 'shared';    break;
-                case LOCK_EX: $str = 'exclusive'; break;
-                case LOCK_UN: $str = 'unlock';    break;
-                default:      $str = 'unknown';   break;
+        if(!strstr(php_uname(), 'Windows 95/98')) {    
+            if ($mode != LOCK_UN && is_resource($this->lock_fp)) {
+                // XXX does not check type of lock (LOCK_SH/LOCK_EX)
+                return true;
+            }
+            if (PEAR::isError($err = $this->_assertStateDir())) {
+                return $err;
+            }
+            $open_mode = 'w';
+            // XXX People reported problems with LOCK_SH and 'w'
+            if ($mode === LOCK_SH) {
+                if (@!is_file($this->lockfile)) {
+                    touch($this->lockfile);
+                }
+                $open_mode = 'r';
+            }
+            $this->lock_fp = @fopen($this->lockfile, $open_mode);
+            if (!is_resource($this->lock_fp)) {
+                return $this->raiseError("could not create lock file: $php_errormsg");
+            }
+            if (!(int)flock($this->lock_fp, $mode)) {
+                switch ($mode) {
+                    case LOCK_SH: $str = 'shared';    break;
+                    case LOCK_EX: $str = 'exclusive'; break;
+                    case LOCK_UN: $str = 'unlock';    break;
+                    default:      $str = 'unknown';   break;
+                }
+                return $this->raiseError("could not acquire $str lock ($this->lockfile)",
+                                         PEAR_REGISTRY_ERROR_LOCK);
             }
-            return $this->raiseError("could not acquire $str lock ($this->lockfile)",
-                                     PEAR_REGISTRY_ERROR_LOCK);
         }
         return true;
     }
index 1f20db6508c6cf07cd54c0ea0cc4b3168fb1cf4a..482ff88dde94453d837b62c7c14aea24e8760b80 100644 (file)
@@ -38,7 +38,7 @@ class PEAR_Remote extends PEAR
     function PEAR_Remote(&$config)
     {
         $this->PEAR();
-        $this->config = $config;
+        $this->config = &$config;
     }
 
     // }}}
@@ -50,6 +50,8 @@ class PEAR_Remote extends PEAR
         if (!extension_loaded("xmlrpc")) {
             return $this->raiseError("xmlrpc support not loaded");
         }
+        $params = func_get_args();
+        array_shift($params);
         $method = str_replace("_", ".", $method);
         $request = xmlrpc_encode_request($method, $params);
         $server_host = $this->config->get("master_server");
diff --git a/pear/PEAR/Uploader.php b/pear/PEAR/Uploader.php
deleted file mode 100644 (file)
index 99212f6..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-<?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>                                    |
-// +----------------------------------------------------------------------+
-//
-
-require_once "PEAR/Common.php";
-
-/**
- * Administration class used to install PEAR packages and maintain the
- * installed package database.
- *
- * @since PHP 4.0.2
- * @author Stig Bakken <ssb@fast.no>
- */
-class PEAR_Uploader extends PEAR_Common
-{
-    // {{{ properties
-
-    var $_tempfiles = array();
-
-    // }}}
-
-    // {{{ constructor
-
-    function PEAR_Uploader()
-    {
-        $this->PEAR_Common();
-    }
-
-    // }}}
-
-    function upload($pkgfile, $infofile = null)
-    {
-        if ($infofile === null) {
-            $info = $this->infoFromTarBall($pkgfile);
-        } else {
-            $info = $this->infoFromDescriptionFile($infofile);
-        }
-        if (PEAR::isError($info)) {
-            return $info;
-        }
-        
-    }
-}
-
-?>
index a0cb045559384ad8795f9e25c903e30f8ef8a5d0..a77af2d393e8c697e64ac4d888ef50a87d754cef 100644 (file)
@@ -1,10 +1,10 @@
 <!--
-     $Id: package.dtd,v 1.17.2.1 2002-04-09 18:04:28 ssb Exp $
+     $Id: package.dtd,v 1.17.2.2 2002-04-09 19:04:08 ssb Exp $
 
-     This is the PEAR package description, version 1.0b4.
+     This is the PEAR package description, version 1.0b6.
      It should be used with the informal public identifier:
 
-         "-//PHP Group//DTD PEAR Package 1.0b4//EN//XML"
+         "-//PHP Group//DTD PEAR Package 1.0b6//EN//XML"
 
      Copyright (c) 1997-2002 The PHP Group             
 
 <!ATTLIST dir name           CDATA #REQUIRED
               baseinstalldir CDATA #IMPLIED>
 
-<!ELEMENT file (#PCDATA)>
-<!ATTLIST file role           (php|ext|test|doc|data) 'php'
+<!ELEMENT file (replace*)>
+<!ATTLIST file role           (php|ext|test|doc|data|script) 'php'
                debug          (na|on|off)        'na'
                threaded       (na|on|off)        'na'
                format         CDATA              #IMPLIED
                baseinstalldir CDATA              #IMPLIED
                platform       CDATA              #IMPLIED
-               md5sum         CDATA              #IMPLIED>
+               md5sum         CDATA              #IMPLIED
+               name           CDATA              #REQUIRED
+               install-as     CDATA              #IMPLIED>
+
+<!ELEMENT replace EMPTY>
+<!ATTLIST replace from        CDATA              #REQUIRED
+                  to          CDATA              #REQUIRED
+                  type        CDATA              #REQUIRED>
 
 <!ELEMENT libfile (libname|sources|includes|libadd)+>
 
@@ -80,6 +87,6 @@
 
 <!ELEMENT dep (#PCDATA)>
 <!ATTLIST dep
-       type    (pkg|ext|php|prog|ldlib|ltlib|os|websrv|sapi) #REQUIRED
+       type    (pkg|ext|php|prog|ldlib|rtlib|os|websrv|sapi) #REQUIRED
        rel     (has|eq|lt|le|gt|ge)                          'has'
        version CDATA                                         #IMPLIED>
index a8c626b0242998b9a3328dc0cb5c2273842eccf8..c6f8cf0a0a61bb8c3ae87c580fe4a3a7b86516ab 100644 (file)
@@ -28,6 +28,7 @@ AC_DEFUN(PHP_WITH_PHP_CONFIG,[
 ])
 dnl
 AC_DEFUN(PHP_EXT_BUILDDIR,[.])dnl
+AC_DEFUN(PHP_EXT_DIR,[""])dnl
 AC_DEFUN(PHP_EXT_SRCDIR,[$abs_srcdir])dnl
 AC_DEFUN(PHP_ALWAYS_SHARED,[
   ext_output="yes, shared"
index 4a818ef4be9b26ed660c9a8d2c1a75a2b9b1a724..d93108c1bd6678f13dd92878dd8287ab4e435123 100755 (executable)
@@ -16,16 +16,16 @@ REM ----------------------------------------------------------------------
 REM  Authors:     Alexander Merz (alexmerz@php.net)                         
 REM ----------------------------------------------------------------------
 REM
-REM  $Id: pear.bat,v 1.4 2001/10/13 06:22:09 mj Exp $
+REM  $Id: pear.bat,v 1.7 2002/04/09 09:59:17 imajes Exp $
 
 REM change this four lines to match the paths of your system
 REM -------------------
 set PHP_PATH=c:\php
 set PEAR_INSTALL_DIR=c:\php\pear
 set PEAR_EXTENSION_DIR=c:\php\extensions
-set PEAR_DOC_DIR=c:\php\pear
+set PEAR_DOC_DIR=c:\php\pear\docs
 REM -------------------
 set DIRECTORY_SEPARATOR=\
 
-%PHP_PATH%\php.exe -q %PEAR_INSTALL_DIR%\scripts\pearwin.php %1 %2 %3 %4 %5 %6
+%PHP_PATH%\php.exe -q %PEAR_INSTALL_DIR%\scripts\pear.in %1 %2 %3 %4 %5 %6 %7 %8 %9
 @ECHO ON
\ No newline at end of file
index 862e20e35edbbb0090909cf9baefa4314c3f6786..a3361edf3fa519fdeadd416aefeedfe480d8dd37 100644 (file)
 // +----------------------------------------------------------------------+
 //
 
+ini_set('allow_url_fopen', true);
+set_time_limit(0);
+ob_implicit_flush(true);
+ini_set('track_errors', true);
+ini_set('html_errors', false);
+
 require_once 'PEAR.php';
-require_once "PEAR/Config.php";
-require_once "PEAR/Command.php";
-require_once "Console/Getopt.php";
+require_once 'PEAR/Config.php';
+require_once 'PEAR/Command.php';
+require_once 'Console/Getopt.php';
 
 PEAR_Command::setFrontendType('CLI');
 $all_commands = PEAR_Command::getCommands();
 $cmd_options  = PEAR_Command::getOptions();
-
-$progname = basename($argv[0]);
-
-PEAR::setErrorHandling(PEAR_ERROR_DIE, "$progname: %s\n");
-$argv = Console_Getopt::readPHPArgv();
+$ui = &PEAR_Command::getFrontendObject();
+$progname = basename(__FILE__);
 
 // XXX change Getopt to use raiseError() ?
+$argv = Console_Getopt::readPHPArgv();
 $options = Console_Getopt::getopt($argv, "c:C:d:D:h?sSqu:v" . $cmd_options);
 if (PEAR::isError($options)) {
     usage($options);
 }
 
+PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError"));
 $opts = $options[0];
 
 $pear_user_config = '';
@@ -124,23 +129,37 @@ 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');
+    fputs($stderr, "\n");
     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,
+    if ($helpsubject != null) {
+        $put = cmdHelp($helpsubject);
+    } else {
+        $put =
+            "Usage: $progname [options] command [command-options] <parameters>\n".
+            "Type \"$progname help options\" to list all options.\n".
+            "Type \"$progname help <command>\" to get the help for the specified command.\n".
+            "Commands:\n   " . implode("\n   ", array_keys($all_commands));
+    }
+    fputs($stderr, "$put\n\n");
+    fclose($stderr);
+    exit;
+}
+
+function cmdHelp($command)
+{
+    global $progname, $all_commands, $config;
+    if ($command == "options") {
+        return
         "Options:\n".
         "     -v         increase verbosity level (default 1)\n".
         "     -q         be quiet, decrease verbosity level\n".
@@ -151,54 +170,11 @@ function usage($error = null, $helpsubject = null)
         "     -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");
+        "     -h, -?     display help/usage (this message)\n";
+    } elseif ($help = PEAR_Command::getHelp($command)) {
+        return "Usage : $progname $command {$help[0]}\n{$help[1]}";
     }
-    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";
+    return "No such command";
 }
 
 // }}}