[ Index ] |
|
Code source de PHP PEAR 1.4.5 |
1 <?php 2 /** 3 * PEAR_Command_Install (install, upgrade, upgrade-all, uninstall, bundle, run-scripts commands) 4 * 5 * PHP versions 4 and 5 6 * 7 * LICENSE: This source file is subject to version 3.0 of the PHP license 8 * that is available through the world-wide-web at the following URI: 9 * http://www.php.net/license/3_0.txt. If you did not receive a copy of 10 * the PHP License and are unable to obtain it through the web, please 11 * send a note to license@php.net so we can mail you a copy immediately. 12 * 13 * @category pear 14 * @package PEAR 15 * @author Stig Bakken <ssb@php.net> 16 * @author Greg Beaver <cellog@php.net> 17 * @copyright 1997-2006 The PHP Group 18 * @license http://www.php.net/license/3_0.txt PHP License 3.0 19 * @version CVS: $Id: Install.php,v 1.121 2007/01/06 04:41:31 cellog Exp $ 20 * @link http://pear.php.net/package/PEAR 21 * @since File available since Release 0.1 22 */ 23 24 /** 25 * base class 26 */ 27 require_once 'PEAR/Command/Common.php'; 28 29 /** 30 * PEAR commands for installation or deinstallation/upgrading of 31 * packages. 32 * 33 * @category pear 34 * @package PEAR 35 * @author Stig Bakken <ssb@php.net> 36 * @author Greg Beaver <cellog@php.net> 37 * @copyright 1997-2006 The PHP Group 38 * @license http://www.php.net/license/3_0.txt PHP License 3.0 39 * @version Release: 1.5.0 40 * @link http://pear.php.net/package/PEAR 41 * @since Class available since Release 0.1 42 */ 43 class PEAR_Command_Install extends PEAR_Command_Common 44 { 45 // {{{ properties 46 47 var $commands = array( 48 'install' => array( 49 'summary' => 'Install Package', 50 'function' => 'doInstall', 51 'shortcut' => 'i', 52 'options' => array( 53 'force' => array( 54 'shortopt' => 'f', 55 'doc' => 'will overwrite newer installed packages', 56 ), 57 'loose' => array( 58 'shortopt' => 'l', 59 'doc' => 'do not check for recommended dependency version', 60 ), 61 'nodeps' => array( 62 'shortopt' => 'n', 63 'doc' => 'ignore dependencies, install anyway', 64 ), 65 'register-only' => array( 66 'shortopt' => 'r', 67 'doc' => 'do not install files, only register the package as installed', 68 ), 69 'soft' => array( 70 'shortopt' => 's', 71 'doc' => 'soft install, fail silently, or upgrade if already installed', 72 ), 73 'nobuild' => array( 74 'shortopt' => 'B', 75 'doc' => 'don\'t build C extensions', 76 ), 77 'nocompress' => array( 78 'shortopt' => 'Z', 79 'doc' => 'request uncompressed files when downloading', 80 ), 81 'installroot' => array( 82 'shortopt' => 'R', 83 'arg' => 'DIR', 84 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', 85 ), 86 'packagingroot' => array( 87 'shortopt' => 'P', 88 'arg' => 'DIR', 89 'doc' => 'root directory used when packaging files, like RPM packaging', 90 ), 91 'ignore-errors' => array( 92 'doc' => 'force install even if there were errors', 93 ), 94 'alldeps' => array( 95 'shortopt' => 'a', 96 'doc' => 'install all required and optional dependencies', 97 ), 98 'onlyreqdeps' => array( 99 'shortopt' => 'o', 100 'doc' => 'install all required dependencies', 101 ), 102 'offline' => array( 103 'shortopt' => 'O', 104 'doc' => 'do not attempt to download any urls or contact channels', 105 ), 106 'pretend' => array( 107 'shortopt' => 'p', 108 'doc' => 'Only list the packages that would be downloaded', 109 ), 110 ), 111 'doc' => '[channel/]<package> ... 112 Installs one or more PEAR packages. You can specify a package to 113 install in four ways: 114 115 "Package-1.0.tgz" : installs from a local file 116 117 "http://example.com/Package-1.0.tgz" : installs from 118 anywhere on the net. 119 120 "package.xml" : installs the package described in 121 package.xml. Useful for testing, or for wrapping a PEAR package in 122 another package manager such as RPM. 123 124 "Package[-version/state][.tar]" : queries your default channel\'s server 125 ({config master_server}) and downloads the newest package with 126 the preferred quality/state ({config preferred_state}). 127 128 To retrieve Package version 1.1, use "Package-1.1," to retrieve 129 Package state beta, use "Package-beta." To retrieve an uncompressed 130 file, append .tar (make sure there is no file by the same name first) 131 132 To download a package from another channel, prefix with the channel name like 133 "channel/Package" 134 135 More than one package may be specified at once. It is ok to mix these 136 four ways of specifying packages. 137 '), 138 'upgrade' => array( 139 'summary' => 'Upgrade Package', 140 'function' => 'doInstall', 141 'shortcut' => 'up', 142 'options' => array( 143 'force' => array( 144 'shortopt' => 'f', 145 'doc' => 'overwrite newer installed packages', 146 ), 147 'loose' => array( 148 'shortopt' => 'l', 149 'doc' => 'do not check for recommended dependency version', 150 ), 151 'nodeps' => array( 152 'shortopt' => 'n', 153 'doc' => 'ignore dependencies, upgrade anyway', 154 ), 155 'register-only' => array( 156 'shortopt' => 'r', 157 'doc' => 'do not install files, only register the package as upgraded', 158 ), 159 'nobuild' => array( 160 'shortopt' => 'B', 161 'doc' => 'don\'t build C extensions', 162 ), 163 'nocompress' => array( 164 'shortopt' => 'Z', 165 'doc' => 'request uncompressed files when downloading', 166 ), 167 'installroot' => array( 168 'shortopt' => 'R', 169 'arg' => 'DIR', 170 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', 171 ), 172 'packagingroot' => array( 173 'shortopt' => 'P', 174 'arg' => 'DIR', 175 'doc' => 'root directory used when packaging files, like RPM packaging', 176 ), 177 'ignore-errors' => array( 178 'doc' => 'force install even if there were errors', 179 ), 180 'alldeps' => array( 181 'shortopt' => 'a', 182 'doc' => 'install all required and optional dependencies', 183 ), 184 'onlyreqdeps' => array( 185 'shortopt' => 'o', 186 'doc' => 'install all required dependencies', 187 ), 188 'offline' => array( 189 'shortopt' => 'O', 190 'doc' => 'do not attempt to download any urls or contact channels', 191 ), 192 'pretend' => array( 193 'shortopt' => 'p', 194 'doc' => 'Only list the packages that would be downloaded', 195 ), 196 ), 197 'doc' => '<package> ... 198 Upgrades one or more PEAR packages. See documentation for the 199 "install" command for ways to specify a package. 200 201 When upgrading, your package will be updated if the provided new 202 package has a higher version number (use the -f option if you need to 203 upgrade anyway). 204 205 More than one package may be specified at once. 206 '), 207 'upgrade-all' => array( 208 'summary' => 'Upgrade All Packages', 209 'function' => 'doInstall', 210 'shortcut' => 'ua', 211 'options' => array( 212 'nodeps' => array( 213 'shortopt' => 'n', 214 'doc' => 'ignore dependencies, upgrade anyway', 215 ), 216 'register-only' => array( 217 'shortopt' => 'r', 218 'doc' => 'do not install files, only register the package as upgraded', 219 ), 220 'nobuild' => array( 221 'shortopt' => 'B', 222 'doc' => 'don\'t build C extensions', 223 ), 224 'nocompress' => array( 225 'shortopt' => 'Z', 226 'doc' => 'request uncompressed files when downloading', 227 ), 228 'installroot' => array( 229 'shortopt' => 'R', 230 'arg' => 'DIR', 231 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', 232 ), 233 'ignore-errors' => array( 234 'doc' => 'force install even if there were errors', 235 ), 236 'loose' => array( 237 'doc' => 'do not check for recommended dependency version', 238 ), 239 ), 240 'doc' => ' 241 Upgrades all packages that have a newer release available. Upgrades are 242 done only if there is a release available of the state specified in 243 "preferred_state" (currently {config preferred_state}), or a state considered 244 more stable. 245 '), 246 'uninstall' => array( 247 'summary' => 'Un-install Package', 248 'function' => 'doUninstall', 249 'shortcut' => 'un', 250 'options' => array( 251 'nodeps' => array( 252 'shortopt' => 'n', 253 'doc' => 'ignore dependencies, uninstall anyway', 254 ), 255 'register-only' => array( 256 'shortopt' => 'r', 257 'doc' => 'do not remove files, only register the packages as not installed', 258 ), 259 'installroot' => array( 260 'shortopt' => 'R', 261 'arg' => 'DIR', 262 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', 263 ), 264 'ignore-errors' => array( 265 'doc' => 'force install even if there were errors', 266 ), 267 'offline' => array( 268 'shortopt' => 'O', 269 'doc' => 'do not attempt to uninstall remotely', 270 ), 271 ), 272 'doc' => '[channel/]<package> ... 273 Uninstalls one or more PEAR packages. More than one package may be 274 specified at once. Prefix with channel name to uninstall from a 275 channel not in your default channel ({config default_channel}) 276 '), 277 'bundle' => array( 278 'summary' => 'Unpacks a Pecl Package', 279 'function' => 'doBundle', 280 'shortcut' => 'bun', 281 'options' => array( 282 'destination' => array( 283 'shortopt' => 'd', 284 'arg' => 'DIR', 285 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', 286 ), 287 'force' => array( 288 'shortopt' => 'f', 289 'doc' => 'Force the unpacking even if there were errors in the package', 290 ), 291 ), 292 'doc' => '<package> 293 Unpacks a Pecl Package into the selected location. It will download the 294 package if needed. 295 '), 296 'run-scripts' => array( 297 'summary' => 'Run Post-Install Scripts bundled with a package', 298 'function' => 'doRunScripts', 299 'shortcut' => 'rs', 300 'options' => array( 301 ), 302 'doc' => '<package> 303 Run post-installation scripts in package <package>, if any exist. 304 '), 305 ); 306 307 // }}} 308 // {{{ constructor 309 310 /** 311 * PEAR_Command_Install constructor. 312 * 313 * @access public 314 */ 315 function PEAR_Command_Install(&$ui, &$config) 316 { 317 parent::PEAR_Command_Common($ui, $config); 318 } 319 320 // }}} 321 322 /** 323 * For unit testing purposes 324 */ 325 function &getDownloader(&$ui, $options, &$config) 326 { 327 if (!class_exists('PEAR_Downloader')) { 328 require_once 'PEAR/Downloader.php'; 329 } 330 $a = &new PEAR_Downloader($ui, $options, $config); 331 return $a; 332 } 333 334 /** 335 * For unit testing purposes 336 */ 337 function &getInstaller(&$ui) 338 { 339 if (!class_exists('PEAR_Installer')) { 340 require_once 'PEAR/Installer.php'; 341 } 342 $a = &new PEAR_Installer($ui); 343 return $a; 344 } 345 346 function enableExtension($binaries, $type) 347 { 348 if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { 349 return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); 350 } 351 $ini = $this->_parseIni($phpini); 352 if (PEAR::isError($ini)) { 353 return $ini; 354 } 355 $fp = @fopen($phpini, 'wb'); 356 if (!$fp) { 357 return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); 358 } 359 $line = 0; 360 if ($type == 'extsrc' || $type == 'extbin') { 361 $search = 'extensions'; 362 $enable = 'extension'; 363 } else { 364 $search = 'zend_extensions'; 365 ob_start(); 366 phpinfo(INFO_GENERAL); 367 $info = ob_get_contents(); 368 ob_end_clean(); 369 $debug = function_exists('leak') ? '_debug' : ''; 370 $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; 371 $enable = 'zend_extension' . $debug . $ts; 372 } 373 foreach ($ini[$search] as $line => $extension) { 374 if (in_array($extension, $binaries, true) || in_array( 375 $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { 376 // already enabled - assume if one is, all are 377 return true; 378 } 379 } 380 if ($line) { 381 $newini = array_slice($ini['all'], 0, $line); 382 } else { 383 $newini = array(); 384 } 385 foreach ($binaries as $binary) { 386 if ($ini['extension_dir']) { 387 $binary = basename($binary); 388 } 389 $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n"); 390 } 391 $newini = array_merge($newini, array_slice($ini['all'], $line)); 392 foreach ($newini as $line) { 393 fwrite($fp, $line); 394 } 395 fclose($fp); 396 return true; 397 } 398 399 function disableExtension($binaries, $type) 400 { 401 if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { 402 return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); 403 } 404 $ini = $this->_parseIni($phpini); 405 if (PEAR::isError($ini)) { 406 return $ini; 407 } 408 $line = 0; 409 if ($type == 'extsrc' || $type == 'extbin') { 410 $search = 'extensions'; 411 $enable = 'extension'; 412 } else { 413 $search = 'zend_extensions'; 414 ob_start(); 415 phpinfo(INFO_GENERAL); 416 $info = ob_get_contents(); 417 ob_end_clean(); 418 $debug = function_exists('leak') ? '_debug' : ''; 419 $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; 420 $enable = 'zend_extension' . $debug . $ts; 421 } 422 $found = false; 423 foreach ($ini[$search] as $line => $extension) { 424 if (in_array($extension, $binaries, true) || in_array( 425 $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { 426 $found = true; 427 break; 428 } 429 } 430 if (!$found) { 431 // not enabled 432 return true; 433 } 434 $fp = @fopen($phpini, 'wb'); 435 if (!$fp) { 436 return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); 437 } 438 if ($line) { 439 $newini = array_slice($ini['all'], 0, $line); 440 // delete the enable line 441 $newini = array_merge($newini, array_slice($ini['all'], $line + 1)); 442 } else { 443 $newini = array_slice($ini['all'], 1); 444 } 445 foreach ($newini as $line) { 446 fwrite($fp, $line); 447 } 448 fclose($fp); 449 return true; 450 } 451 452 function _parseIni($filename) 453 { 454 if (file_exists($filename)) { 455 if (filesize($filename) > 300000) { 456 return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting'); 457 } 458 ob_start(); 459 phpinfo(INFO_GENERAL); 460 $info = ob_get_contents(); 461 ob_end_clean(); 462 $debug = function_exists('leak') ? '_debug' : ''; 463 $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; 464 $zend_extension_line = 'zend_extension' . $debug . $ts; 465 $all = @file($filename); 466 if (!$all) { 467 return PEAR::raiseError('php.ini "' . $filename .'" could not be read'); 468 } 469 $zend_extensions = $extensions = array(); 470 // assume this is right, but pull from the php.ini if it is found 471 $extension_dir = ini_get('extension_dir'); 472 foreach ($all as $linenum => $line) { 473 $line = trim($line); 474 if (!$line) { 475 continue; 476 } 477 if ($line[0] == ';') { 478 continue; 479 } 480 if (strtolower(substr($line, 0, 13)) == 'extension_dir') { 481 $line = trim(substr($line, 13)); 482 if ($line[0] == '=') { 483 $x = trim(substr($line, 1)); 484 $x = explode(';', $x); 485 $extension_dir = str_replace('"', '', array_shift($x)); 486 continue; 487 } 488 } 489 if (strtolower(substr($line, 0, 9)) == 'extension') { 490 $line = trim(substr($line, 9)); 491 if ($line[0] == '=') { 492 $x = trim(substr($line, 1)); 493 $x = explode(';', $x); 494 $extensions[$linenum] = str_replace('"', '', array_shift($x)); 495 continue; 496 } 497 } 498 if (strtolower(substr($line, 0, strlen($zend_extension_line))) == 499 $zend_extension_line) { 500 $line = trim(substr($line, strlen($zend_extension_line))); 501 if ($line[0] == '=') { 502 $x = trim(substr($line, 1)); 503 $x = explode(';', $x); 504 $zend_extensions[$linenum] = str_replace('"', '', array_shift($x)); 505 continue; 506 } 507 } 508 } 509 return array( 510 'extensions' => $extensions, 511 'zend_extensions' => $zend_extensions, 512 'extension_dir' => $extension_dir, 513 'all' => $all, 514 ); 515 } else { 516 return PEAR::raiseError('php.ini "' . $filename . '" does not exist'); 517 } 518 } 519 520 // {{{ doInstall() 521 522 function doInstall($command, $options, $params) 523 { 524 if (empty($this->installer)) { 525 $this->installer = &$this->getInstaller($this->ui); 526 } 527 if ($command == 'upgrade') { 528 $options['upgrade'] = true; 529 } 530 if (isset($options['installroot']) && isset($options['packagingroot'])) { 531 return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot'); 532 } 533 if (isset($options['packagingroot']) && $this->config->get('verbose') > 2) { 534 $this->ui->outputData('using package root: ' . $options['packagingroot']); 535 } 536 $reg = &$this->config->getRegistry(); 537 if ($command == 'upgrade-all') { 538 $options['upgrade'] = true; 539 $reg = &$this->config->getRegistry(); 540 $savechannel = $this->config->get('default_channel'); 541 $params = array(); 542 foreach ($reg->listChannels() as $channel) { 543 if ($channel == '__uri') { 544 continue; 545 } 546 $this->config->set('default_channel', $channel); 547 $chan = &$reg->getChannel($channel); 548 if (PEAR::isError($chan)) { 549 return $this->raiseError($chan); 550 } 551 if ($chan->supportsREST($this->config->get('preferred_mirror')) && 552 $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { 553 $dorest = true; 554 unset($remote); 555 } else { 556 $dorest = false; 557 $remote = &$this->config->getRemote($this->config); 558 } 559 $state = $this->config->get('preferred_state'); 560 $installed = array_flip($reg->listPackages($channel)); 561 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 562 if ($dorest) { 563 $rest = &$this->config->getREST('1.0', array()); 564 $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); 565 } else { 566 if (empty($state) || $state == 'any') { 567 $latest = $remote->call("package.listLatestReleases"); 568 } else { 569 $latest = $remote->call("package.listLatestReleases", $state); 570 } 571 } 572 PEAR::staticPopErrorHandling(); 573 if (PEAR::isError($latest) || !is_array($latest)) { 574 continue; 575 } 576 foreach ($latest as $package => $info) { 577 $package = strtolower($package); 578 if (!isset($installed[$package])) { 579 // skip packages we don't have installed 580 continue; 581 } 582 $inst_version = $reg->packageInfo($package, 'version', $channel); 583 if (version_compare("$info[version]", "$inst_version", "le")) { 584 // installed version is up-to-date 585 continue; 586 } 587 $params[] = $reg->parsedPackageNameToString(array('package' => $package, 588 'channel' => $channel)); 589 $this->ui->outputData(array('data' => "Will upgrade $package"), $command); 590 } 591 } 592 $this->config->set('default_channel', $savechannel); 593 } 594 $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); 595 $errors = array(); 596 $downloaded = array(); 597 $downloaded = &$this->downloader->download($params); 598 if (PEAR::isError($downloaded)) { 599 return $this->raiseError($downloaded); 600 } 601 $errors = $this->downloader->getErrorMsgs(); 602 if (count($errors)) { 603 $err['data'] = array(); 604 foreach ($errors as $error) { 605 $err['data'][] = array($error); 606 } 607 $err['headline'] = 'Install Errors'; 608 $this->ui->outputData($err); 609 if (!count($downloaded)) { 610 return $this->raiseError("$command failed"); 611 } 612 } 613 $data = array( 614 'headline' => 'Packages that would be Installed' 615 ); 616 if (isset($options['pretend'])) { 617 foreach ($downloaded as $package) { 618 $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage())); 619 } 620 $this->ui->outputData($data, 'pretend'); 621 return true; 622 } 623 $this->installer->setOptions($options); 624 $this->installer->sortPackagesForInstall($downloaded); 625 if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) { 626 $this->raiseError($err->getMessage()); 627 return true; 628 } 629 $extrainfo = array(); 630 if (isset($options['packagingroot'])) { 631 $packrootphp_dir = $this->installer->_prependPath( 632 $this->config->get('php_dir', null, 'pear.php.net'), 633 $options['packagingroot']); 634 $instreg = new PEAR_Registry($packrootphp_dir); 635 } else { 636 $instreg = $reg; 637 } 638 foreach ($downloaded as $param) { 639 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 640 $info = $this->installer->install($param, $options); 641 PEAR::staticPopErrorHandling(); 642 if (PEAR::isError($info)) { 643 $oldinfo = $info; 644 $pkg = &$param->getPackageFile(); 645 if ($info->getCode() != PEAR_INSTALLER_NOBINARY) { 646 if (!($info = $pkg->installBinary($this->installer))) { 647 $this->ui->outputData('ERROR: ' .$oldinfo->getMessage()); 648 continue; 649 } 650 // we just installed a different package than requested, 651 // let's change the param and info so that the rest of this works 652 $param = $info[0]; 653 $info = $info[1]; 654 } 655 } 656 if (is_array($info)) { 657 if ($param->getPackageType() == 'extsrc' || 658 $param->getPackageType() == 'extbin' || 659 $param->getPackageType() == 'zendextsrc' || 660 $param->getPackageType() == 'zendextbin') { 661 $pkg = &$param->getPackageFile(); 662 if ($instbin = $pkg->getInstalledBinary()) { 663 $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel()); 664 } else { 665 $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel()); 666 } 667 foreach ($instpkg->getFilelist() as $name => $atts) { 668 $pinfo = pathinfo($atts['installed_as']); 669 if (!isset($pinfo['extension']) || 670 in_array($pinfo['extension'], array('c', 'h'))) { 671 continue; // make sure we don't match php_blah.h 672 } 673 if ((strpos($pinfo['basename'], 'php_') === 0 && 674 $pinfo['extension'] == 'dll') || 675 // most unices 676 $pinfo['extension'] == 'so' || 677 // hp-ux 678 $pinfo['extension'] == 'sl') { 679 $binaries[] = array($atts['installed_as'], $pinfo); 680 break; 681 } 682 } 683 foreach ($binaries as $pinfo) { 684 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 685 $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType()); 686 PEAR::staticPopErrorHandling(); 687 if (PEAR::isError($ret)) { 688 $extrainfo[] = $ret->getMessage(); 689 if ($param->getPackageType() == 'extsrc' || 690 $param->getPackageType() == 'extbin') { 691 $exttype = 'extension'; 692 } else { 693 ob_start(); 694 phpinfo(INFO_GENERAL); 695 $info = ob_get_contents(); 696 ob_end_clean(); 697 $debug = function_exists('leak') ? '_debug' : ''; 698 $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; 699 $exttype = 'zend_extension' . $debug . $ts; 700 } 701 $extrainfo[] = 'You should add "' . $exttype . '=' . 702 $pinfo[1]['basename'] . '" to php.ini'; 703 } else { 704 $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() . 705 ' enabled in php.ini'; 706 } 707 } 708 } 709 if ($this->config->get('verbose') > 0) { 710 $channel = $param->getChannel(); 711 $label = $reg->parsedPackageNameToString( 712 array( 713 'channel' => $channel, 714 'package' => $param->getPackage(), 715 'version' => $param->getVersion(), 716 )); 717 $out = array('data' => "$command ok: $label"); 718 if (isset($info['release_warnings'])) { 719 $out['release_warnings'] = $info['release_warnings']; 720 } 721 $this->ui->outputData($out, $command); 722 if (!isset($options['register-only']) && !isset($options['offline'])) { 723 if ($this->config->isDefinedLayer('ftp')) { 724 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 725 $info = $this->installer->ftpInstall($param); 726 PEAR::staticPopErrorHandling(); 727 if (PEAR::isError($info)) { 728 $this->ui->outputData($info->getMessage()); 729 $this->ui->outputData("remote install failed: $label"); 730 } else { 731 $this->ui->outputData("remote install ok: $label"); 732 } 733 } 734 } 735 } 736 $deps = $param->getDeps(); 737 if ($deps) { 738 if (isset($deps['group'])) { 739 $groups = $deps['group']; 740 if (!isset($groups[0])) { 741 $groups = array($groups); 742 } 743 foreach ($groups as $group) { 744 if ($group['attribs']['name'] == 'default') { 745 // default group is always installed, unless the user 746 // explicitly chooses to install another group 747 continue; 748 } 749 $this->ui->outputData($param->getPackage() . ': Optional feature ' . 750 $group['attribs']['name'] . ' available (' . 751 $group['attribs']['hint'] . ')'); 752 } 753 $extrainfo[] = 'To install use "pear install ' . 754 $reg->parsedPackageNameToString( 755 array('package' => $param->getPackage(), 756 'channel' => $param->getChannel()), true) . 757 '#featurename"'; 758 } 759 } 760 if (isset($options['installroot'])) { 761 $reg = &$this->config->getRegistry(); 762 } 763 if (isset($options['packagingroot'])) { 764 $instreg = new PEAR_Registry($packrootphp_dir); 765 } else { 766 $instreg = $reg; 767 } 768 $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel()); 769 // $pkg may be NULL if install is a 'fake' install via --packagingroot 770 if (is_object($pkg)) { 771 $pkg->setConfig($this->config); 772 if ($list = $pkg->listPostinstallScripts()) { 773 $pn = $reg->parsedPackageNameToString(array('channel' => 774 $param->getChannel(), 'package' => $param->getPackage()), true); 775 $extrainfo[] = $pn . ' has post-install scripts:'; 776 foreach ($list as $file) { 777 $extrainfo[] = $file; 778 } 779 $extrainfo[] = 'Use "pear run-scripts ' . $pn . '" to run'; 780 $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES'; 781 } 782 } 783 } else { 784 return $this->raiseError("$command failed"); 785 } 786 } 787 if (count($extrainfo)) { 788 foreach ($extrainfo as $info) { 789 $this->ui->outputData($info); 790 } 791 } 792 return true; 793 } 794 795 // }}} 796 // {{{ doUninstall() 797 798 function doUninstall($command, $options, $params) 799 { 800 if (empty($this->installer)) { 801 $this->installer = &$this->getInstaller($this->ui); 802 } 803 if (isset($options['remoteconfig'])) { 804 $e = $this->config->readFTPConfigFile($options['remoteconfig']); 805 if (!PEAR::isError($e)) { 806 $this->installer->setConfig($this->config); 807 } 808 } 809 if (sizeof($params) < 1) { 810 return $this->raiseError("Please supply the package(s) you want to uninstall"); 811 } 812 $reg = &$this->config->getRegistry(); 813 $newparams = array(); 814 $badparams = array(); 815 foreach ($params as $pkg) { 816 $channel = $this->config->get('default_channel'); 817 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 818 $parsed = $reg->parsePackageName($pkg, $channel); 819 PEAR::staticPopErrorHandling(); 820 if (!$parsed || PEAR::isError($parsed)) { 821 $badparams[] = $pkg; 822 continue; 823 } 824 $package = $parsed['package']; 825 $channel = $parsed['channel']; 826 $info = &$reg->getPackage($package, $channel); 827 if ($info === null && 828 ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) { 829 // make sure this isn't a package that has flipped from pear to pecl but 830 // used a package.xml 1.0 831 $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net'; 832 $info = &$reg->getPackage($package, $testc); 833 if ($info !== null) { 834 $channel = $testc; 835 } 836 } 837 if ($info === null) { 838 $badparams[] = $pkg; 839 } else { 840 $newparams[] = &$info; 841 // check for binary packages (this is an alias for those packages if so) 842 if ($installedbinary = $info->getInstalledBinary()) { 843 $this->ui->log('adding binary package ' . 844 $reg->parsedPackageNameToString(array('channel' => $channel, 845 'package' => $installedbinary), true)); 846 $newparams[] = &$reg->getPackage($installedbinary, $channel); 847 } 848 // add the contents of a dependency group to the list of installed packages 849 if (isset($parsed['group'])) { 850 $group = $info->getDependencyGroup($parsed['group']); 851 if ($group) { 852 $installed = &$reg->getInstalledGroup($group); 853 if ($installed) { 854 foreach ($installed as $i => $p) { 855 $newparams[] = &$installed[$i]; 856 } 857 } 858 } 859 } 860 } 861 } 862 $err = $this->installer->sortPackagesForUninstall($newparams); 863 if (PEAR::isError($err)) { 864 $this->ui->outputData($err->getMessage(), $command); 865 return true; 866 } 867 $params = $newparams; 868 // twist this to use it to check on whether dependent packages are also being uninstalled 869 // for circular dependencies like subpackages 870 $this->installer->setUninstallPackages($newparams); 871 $params = array_merge($params, $badparams); 872 foreach ($params as $pkg) { 873 $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); 874 if ($err = $this->installer->uninstall($pkg, $options)) { 875 $this->installer->popErrorHandling(); 876 if (PEAR::isError($err)) { 877 $this->ui->outputData($err->getMessage(), $command); 878 continue; 879 } 880 if ($pkg->getPackageType() == 'extsrc' || 881 $pkg->getPackageType() == 'extbin' || 882 $pkg->getPackageType() == 'zendextsrc' || 883 $pkg->getPackageType() == 'zendextbin') { 884 if ($instbin = $pkg->getInstalledBinary()) { 885 continue; // this will be uninstalled later 886 } 887 foreach ($pkg->getFilelist() as $name => $atts) { 888 $pinfo = pathinfo($atts['installed_as']); 889 if (!isset($pinfo['extension']) || 890 in_array($pinfo['extension'], array('c', 'h'))) { 891 continue; // make sure we don't match php_blah.h 892 } 893 if ((strpos($pinfo['basename'], 'php_') === 0 && 894 $pinfo['extension'] == 'dll') || 895 // most unices 896 $pinfo['extension'] == 'so' || 897 // hp-ux 898 $pinfo['extension'] == 'sl') { 899 $binaries[] = array($atts['installed_as'], $pinfo); 900 break; 901 } 902 } 903 foreach ($binaries as $pinfo) { 904 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 905 $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType()); 906 PEAR::staticPopErrorHandling(); 907 if (PEAR::isError($ret)) { 908 $extrainfo[] = $ret->getMessage(); 909 if ($pkg->getPackageType() == 'extsrc' || 910 $pkg->getPackageType() == 'extbin') { 911 $exttype = 'extension'; 912 } else { 913 ob_start(); 914 phpinfo(INFO_GENERAL); 915 $info = ob_get_contents(); 916 ob_end_clean(); 917 $debug = function_exists('leak') ? '_debug' : ''; 918 $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; 919 $exttype = 'zend_extension' . $debug . $ts; 920 } 921 $this->ui->outputData('Unable to remove "' . $exttype . '=' . 922 $pinfo[1]['basename'] . '" from php.ini', $command); 923 } else { 924 $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() . 925 ' disabled in php.ini', $command); 926 } 927 } 928 } 929 $savepkg = $pkg; 930 if ($this->config->get('verbose') > 0) { 931 if (is_object($pkg)) { 932 $pkg = $reg->parsedPackageNameToString($pkg); 933 } 934 $this->ui->outputData("uninstall ok: $pkg", $command); 935 } 936 if (!isset($options['offline']) && is_object($savepkg) && 937 defined('PEAR_REMOTEINSTALL_OK')) { 938 if ($this->config->isDefinedLayer('ftp')) { 939 $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); 940 $info = $this->installer->ftpUninstall($savepkg); 941 $this->installer->popErrorHandling(); 942 if (PEAR::isError($info)) { 943 $this->ui->outputData($info->getMessage()); 944 $this->ui->outputData("remote uninstall failed: $pkg"); 945 } else { 946 $this->ui->outputData("remote uninstall ok: $pkg"); 947 } 948 } 949 } 950 } else { 951 $this->installer->popErrorHandling(); 952 if (is_object($pkg)) { 953 $pkg = $reg->parsedPackageNameToString($pkg); 954 } 955 return $this->raiseError("uninstall failed: $pkg"); 956 } 957 } 958 return true; 959 } 960 961 // }}} 962 963 964 // }}} 965 // {{{ doBundle() 966 /* 967 (cox) It just downloads and untars the package, does not do 968 any check that the PEAR_Installer::_installFile() does. 969 */ 970 971 function doBundle($command, $options, $params) 972 { 973 $downloader = &$this->getDownloader($this->ui, array('force' => true, 'nodeps' => true, 974 'soft' => true, 'downloadonly' => true), $this->config); 975 $reg = &$this->config->getRegistry(); 976 if (sizeof($params) < 1) { 977 return $this->raiseError("Please supply the package you want to bundle"); 978 } 979 980 if (isset($options['destination'])) { 981 if (!is_dir($options['destination'])) { 982 System::mkdir('-p ' . $options['destination']); 983 } 984 $dest = realpath($options['destination']); 985 } else { 986 $pwd = getcwd(); 987 if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) { 988 $dest = $pwd . DIRECTORY_SEPARATOR . 'ext'; 989 } else { 990 $dest = $pwd; 991 } 992 } 993 $downloader->setDownloadDir($dest); 994 $result = &$downloader->download(array($params[0])); 995 if (PEAR::isError($result)) { 996 return $result; 997 } 998 $pkgfile = &$result[0]->getPackageFile(); 999 $pkgname = $pkgfile->getName(); 1000 $pkgversion = $pkgfile->getVersion(); 1001 1002 // Unpacking ------------------------------------------------- 1003 $dest .= DIRECTORY_SEPARATOR . $pkgname; 1004 $orig = $pkgname . '-' . $pkgversion; 1005 1006 $tar = &new Archive_Tar($pkgfile->getArchiveFile()); 1007 if (!$tar->extractModify($dest, $orig)) { 1008 return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile()); 1009 } 1010 $this->ui->outputData("Package ready at '$dest'"); 1011 // }}} 1012 } 1013 1014 // }}} 1015 1016 function doRunScripts($command, $options, $params) 1017 { 1018 if (!isset($params[0])) { 1019 return $this->raiseError('run-scripts expects 1 parameter: a package name'); 1020 } 1021 $reg = &$this->config->getRegistry(); 1022 PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); 1023 $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); 1024 PEAR::staticPopErrorHandling(); 1025 if (PEAR::isError($parsed)) { 1026 return $this->raiseError($parsed); 1027 } 1028 $package = &$reg->getPackage($parsed['package'], $parsed['channel']); 1029 if (is_object($package)) { 1030 $package->setConfig($this->config); 1031 $package->runPostinstallScripts(); 1032 } else { 1033 return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry'); 1034 } 1035 $this->ui->outputData('Install scripts complete', $command); 1036 return true; 1037 } 1038 } 1039 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 14:08:00 2007 | par Balluche grâce à PHPXref 0.7 |