3  * PEAR, the PHP Extension and Application Repository
 
   5  * Command line interface
 
  11  * @author    Stig Bakken <ssb@php.net>
 
  12  * @author    Tomas V.V.Cox <cox@idecnet.com>
 
  13  * @copyright 1997-2009 The Authors
 
  14  * @license   http://opensource.org/licenses/bsd-license.php New BSD License
 
  15  * @link      http://pear.php.net/package/PEAR
 
  19 if (!defined('PEAR_RUNTYPE')) {
 
  20     // this is defined in peclcmd.php as 'pecl'
 
  21     define('PEAR_RUNTYPE', 'pear');
 
  23 define('PEAR_IGNORE_BACKTRACE', 1);
 
  27 //the space is needed for windows include paths with trailing backslash
 
  28 // http://pear.php.net/bugs/bug.php?id=19482
 
  29 if ('@include_path@ ' != '@'.'include_path'.'@ ') {
 
  30     ini_set('include_path', trim('@include_path@ '). PATH_SEPARATOR .  get_include_path());
 
  33     // this is a raw, uninstalled pear, either a cvs checkout, or php distro
 
  36 @ini_set('allow_url_fopen', true);
 
  38 ob_implicit_flush(true);
 
  39 @ini_set('track_errors', true);
 
  40 @ini_set('html_errors', false);
 
  41 $_PEAR_PHPDIR = '#$%^&*';
 
  42 set_error_handler('error_handler');
 
  44 $pear_package_version = "@pear_version@";
 
  46 require_once 'PEAR.php';
 
  47 require_once 'PEAR/Frontend.php';
 
  48 require_once 'PEAR/Config.php';
 
  49 require_once 'PEAR/Command.php';
 
  50 require_once 'Console/Getopt.php';
 
  53 PEAR_Command::setFrontendType('CLI');
 
  54 $all_commands = PEAR_Command::getCommands();
 
  56 // remove this next part when we stop supporting that crap-ass PHP 4.2
 
  57 if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv'])) {
 
  58     echo 'ERROR: either use the CLI php executable, ' .
 
  59          'or set register_argc_argv=On in php.ini';
 
  63 $argv = Console_Getopt::readPHPArgv();
 
  64 // fix CGI sapi oddity - the -- in pear.bat/pear is not removed
 
  65 if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') {
 
  67     $argv = array_values($argv);
 
  69 $progname = PEAR_RUNTYPE;
 
  71 $options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV");
 
  72 if (PEAR::isError($options)) {
 
  79 if ($progname == 'gpear' || $progname == 'pear-gtk') {
 
  82     foreach ($opts as $opt) {
 
  89 $pear_user_config = '';
 
  90 $pear_system_config = '';
 
  91 $store_user_config = false;
 
  92 $store_system_config = false;
 
  95 foreach ($opts as $opt) {
 
  98         $pear_user_config = $opt[1];
 
 101         $pear_system_config = $opt[1];
 
 106 PEAR_Command::setFrontendType($fetype);
 
 107 $ui = &PEAR_Command::getFrontendObject();
 
 108 $config = &PEAR_Config::singleton($pear_user_config, $pear_system_config);
 
 110 if (PEAR::isError($config)) {
 
 112     if ($pear_user_config !== false) {
 
 113         $_file .= $pear_user_config;
 
 115     if ($pear_system_config !== false) {
 
 116         $_file .= '/' . $pear_system_config;
 
 119         $_file = 'The default config file';
 
 121     $config->getMessage();
 
 122     $ui->outputData("ERROR: $_file is not a valid config file or is corrupted.");
 
 123     // We stop, we have no idea where we are :)
 
 127 // this is used in the error handler to retrieve a relative path
 
 128 $_PEAR_PHPDIR = $config->get('php_dir');
 
 129 $ui->setConfig($config);
 
 130 PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError"));
 
 132 $verbose = $config->get("verbose");
 
 136     if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) {
 
 138         foreach ($opts as $opt) {
 
 139             if ($opt[0] == 'd' || $opt[0] == 'D') {
 
 140                 // the user knows what they are doing, and are setting config values
 
 145             // no prior runs, try to install PEAR
 
 146             $parent = dirname(__FILE__);
 
 147             if (strpos($parent, 'scripts')) {
 
 148                 $grandparent = dirname($parent);
 
 149                 $packagexml = $grandparent . DIRECTORY_SEPARATOR . 'package2.xml';
 
 150                 $pearbase = $grandparent;
 
 152                 $packagexml = $parent . DIRECTORY_SEPARATOR . 'package2.xml';
 
 155             if (file_exists($packagexml)) {
 
 160                 $config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php');
 
 161                 $config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data');
 
 162                 $config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs');
 
 163                 $config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests');
 
 166                     $pearbase . DIRECTORY_SEPARATOR . 'extensions'
 
 168                 $config->set('bin_dir', $pearbase);
 
 169                 $config->mergeConfigFile($pearbase . 'pear.ini', false);
 
 171                 $config->set('auto_discover', 1);
 
 176 foreach ($opts as $opt) {
 
 177     $param = !empty($opt[1]) ? $opt[1] : true;
 
 180         if ($param === true) {
 
 182                 'Invalid usage of "-d" option, expected -d config_value=value, ' .
 
 183                 'received "-d"' . "\n"
 
 186         $possible = explode('=', $param);
 
 187         if (count($possible) != 2) {
 
 189                 'Invalid usage of "-d" option, expected ' .
 
 190                 '-d config_value=value, received "' . $param . '"' . "\n"
 
 193         list($key, $value) = explode('=', $param);
 
 194         $config->set($key, $value, 'user');
 
 197         if ($param === true) {
 
 199                 'Invalid usage of "-d" option, expected ' .
 
 200                 '-d config_value=value, received "-d"' . "\n"
 
 203         $possible = explode('=', $param);
 
 204         if (count($possible) != 2) {
 
 206                 'Invalid usage of "-d" option, expected ' .
 
 207                 '-d config_value=value, received "' . $param . '"' . "\n"
 
 210         list($key, $value) = explode('=', $param);
 
 211         $config->set($key, $value, 'system');
 
 214         $store_user_config = true;
 
 217         $store_system_config = true;
 
 220         $config->remove($param, 'user');
 
 223         $config->set('verbose', $config->get('verbose') + 1);
 
 226         $config->set('verbose', $config->get('verbose') - 1);
 
 229         usage(null, 'version');
 
 234         // all non pear params goes to the command
 
 235         $cmdopts[$opt[0]] = $param;
 
 240 if ($store_system_config) {
 
 241     $config->store('system');
 
 244 if ($store_user_config) {
 
 245     $config->store('user');
 
 248 $command = (isset($options[1][0])) ? $options[1][0] : null;
 
 249 if (empty($command) && ($store_user_config || $store_system_config)) {
 
 253 if ($fetype == 'Gtk2') {
 
 254     if (!$config->validConfiguration()) {
 
 256             "CRITICAL ERROR: no existing valid configuration files found in " .
 
 257             "files '$pear_user_config' or '$pear_system_config', " .
 
 258             "please copy an existing configuration file to one of these " .
 
 259             "locations, or use the -c and -s options to create one"
 
 265         if ($command == 'help') {
 
 266             usage(null, isset($options[1][1]) ? $options[1][1] : null);
 
 269         if (!$config->validConfiguration()) {
 
 271                 "CRITICAL ERROR: no existing valid configuration files found " .
 
 272                 "in files '$pear_user_config' or '$pear_system_config', " .
 
 273                 "please copy an existing configuration file to one of " .
 
 274                 "these locations, or use the -c and -s options to create one"
 
 278         PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
 
 279         $cmd = PEAR_Command::factory($command, $config);
 
 280         PEAR::popErrorHandling();
 
 281         if (PEAR::isError($cmd)) {
 
 282             usage(null, isset($options[1][0]) ? $options[1][0] : null);
 
 285         $short_args = $long_args = null;
 
 286         PEAR_Command::getGetoptArgs($command, $short_args, $long_args);
 
 287         array_shift($options[1]);
 
 288         $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args);
 
 290         if (PEAR::isError($tmp)) {
 
 294         list($tmpopt, $params) = $tmp;
 
 296         foreach ($tmpopt as $foo => $tmp2) {
 
 297             list($opt, $value) = $tmp2;
 
 298             if ($value === null) {
 
 299                 $value = true; // options without args
 
 302             if (strlen($opt) == 1) {
 
 303                 $cmdoptions = $cmd->getOptions($command);
 
 304                 foreach ($cmdoptions as $o => $d) {
 
 305                     if (isset($d['shortopt']) && $d['shortopt'] == $opt) {
 
 310                 if (substr($opt, 0, 2) == '--') {
 
 311                     $opts[substr($opt, 2)] = $value;
 
 316         $ok = $cmd->run($command, $opts, $params);
 
 318             PEAR::raiseError("unknown command `$command'");
 
 321         if (PEAR::isError($ok)) {
 
 322             PEAR::setErrorHandling(
 
 323                 PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")
 
 325             PEAR::raiseError($ok);
 
 333  * Display usage information
 
 335  * @param mixed $error       Optional error message
 
 336  * @param mixed $helpsubject Optional subject/command to display help for
 
 340 function usage($error = null, $helpsubject = null)
 
 342     global $progname, $all_commands;
 
 343     $stdout = fopen('php://stdout', 'w');
 
 344     if (PEAR::isError($error)) {
 
 345         fputs($stdout, $error->getMessage() . "\n");
 
 346     } elseif ($error !== null) {
 
 347         fputs($stdout, "$error\n");
 
 350     if ($helpsubject != null) {
 
 351         $put = cmdHelp($helpsubject);
 
 353         $put = "Commands:\n";
 
 354         $maxlen = max(array_map("strlen", $all_commands));
 
 355         $formatstr = "%-{$maxlen}s  %s\n";
 
 356         ksort($all_commands);
 
 357         foreach ($all_commands as $cmd => $class) {
 
 358             $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd));
 
 361             "Usage: $progname [options] command [command-options] <parameters>\n".
 
 362             "Type \"$progname help options\" to list all options.\n".
 
 363             "Type \"$progname help shortcuts\" to list all command shortcuts.\n".
 
 364             "Type \"$progname help version\" or ".
 
 365             "\"$progname version\" to list version information.\n".
 
 366             "Type \"$progname help <command>\" to get the help ".
 
 367             "for the specified command.";
 
 369     fputs($stdout, "$put\n");
 
 372     if ($error === null) {
 
 379  * Return help string for specified command
 
 381  * @param string $command Command to return help for
 
 385 function cmdHelp($command)
 
 387     global $progname, $all_commands, $config;
 
 388     if ($command == "options") {
 
 391         "     -v         increase verbosity level (default 1)\n".
 
 392         "     -q         be quiet, decrease verbosity level\n".
 
 393         "     -c file    find user configuration in `file'\n".
 
 394         "     -C file    find system configuration in `file'\n".
 
 395         "     -d foo=bar set user config variable `foo' to `bar'\n".
 
 396         "     -D foo=bar set system config variable `foo' to `bar'\n".
 
 397         "     -G         start in graphical (Gtk) mode\n".
 
 398         "     -s         store user configuration\n".
 
 399         "     -S         store system configuration\n".
 
 400         "     -u foo     unset `foo' in the user configuration\n".
 
 401         "     -h, -?     display help/usage (this message)\n".
 
 402         "     -V         version information\n";
 
 403     } elseif ($command == "shortcuts") {
 
 404         $sc = PEAR_Command::getShortcuts();
 
 405         $ret = "Shortcuts:\n";
 
 406         foreach ($sc as $s => $c) {
 
 407             $ret .= sprintf("     %-8s %s\n", $s, $c);
 
 411     } elseif ($command == "version") {
 
 412         return "PEAR Version: ".$GLOBALS['pear_package_version'].
 
 413                "\nPHP Version: ".phpversion().
 
 414                "\nZend Engine Version: ".zend_version().
 
 415                "\nRunning on: ".php_uname();
 
 417     } elseif ($help = PEAR_Command::getHelp($command)) {
 
 418         if (is_string($help)) {
 
 419             return "$progname $command [options] $help\n";
 
 422         if ($help[1] === null) {
 
 423             return "$progname $command $help[0]";
 
 426         return "$progname $command [options] $help[0]\n$help[1]";
 
 429     return "Command '$command' is not valid, try '$progname help'";
 
 437  * @param mixed $errno  Error number
 
 438  * @param mixed $errmsg Message
 
 439  * @param mixed $file   Filename
 
 440  * @param mixed $line   Line number
 
 441  * @param mixed $vars   Variables
 
 446 function error_handler($errno, $errmsg, $file, $line, $vars)
 
 448     if ($errno & E_STRICT
 
 449         || $errno & E_DEPRECATED
 
 450         || !error_reporting()
 
 452         if ($errno & E_STRICT) {
 
 455         if ($errno & E_DEPRECATED) {
 
 456             return; // E_DEPRECATED
 
 458         if (!error_reporting() && isset($GLOBALS['config']) && $GLOBALS['config']->get('verbose') < 4) {
 
 459             return false; // @silenced error, show all if debug is high enough
 
 463         E_DEPRECATED  => 'Deprecated Warning',
 
 465         E_WARNING   =>  "Warning",
 
 466         E_PARSE   =>  "Parsing Error",
 
 467         E_STRICT  => 'Strict Warning',
 
 468         E_NOTICE   =>  "Notice",
 
 469         E_CORE_ERROR  =>  "Core Error",
 
 470         E_CORE_WARNING  =>  "Core Warning",
 
 471         E_COMPILE_ERROR  =>  "Compile Error",
 
 472         E_COMPILE_WARNING =>  "Compile Warning",
 
 473         E_USER_ERROR =>  "User Error",
 
 474         E_USER_WARNING =>  "User Warning",
 
 475         E_USER_NOTICE =>  "User Notice"
 
 477     $prefix = $errortype[$errno];
 
 478     global $_PEAR_PHPDIR;
 
 479     if (stristr($file, $_PEAR_PHPDIR)) {
 
 480         $file = substr($file, strlen($_PEAR_PHPDIR) + 1);
 
 482         $file = basename($file);
 
 484     print "\n$prefix: $errmsg in $file on line $line\n";
 
 493  * indent-tabs-mode: nil