Beispiel #1
0
 /**
  * retrieves a list of avaible Packages from master server
  * and downloads them
  *
  * @access public
  * @param string $command the command
  * @param array $options the command options before the command
  * @param array $params the stuff after the command name
  * @return bool true if succesful
  * @throw PEAR_Error 
  */
 function doDownloadAll($command, $options, $params)
 {
     $this->config->set("php_dir", ".");
     $remote = new PEAR_Remote($this->config);
     $remoteInfo = $remote->call("package.listAll");
     if (PEAR::isError($remoteInfo)) {
         return $remoteInfo;
     }
     $cmd =& PEAR_Command::factory("download", $this->config);
     if (PEAR::isError($cmd)) {
         return $cmd;
     }
     foreach ($remoteInfo as $pkgn => $pkg) {
         /**
          * Error handling not neccesary, because already done by 
          * the download command
          */
         $cmd->run("download", array(), array($pkgn));
     }
     return true;
 }
Beispiel #2
0
 /**
  * Execute the 'login' command.
  *
  * @param string $command command name
  *
  * @param array $options option_name => value
  *
  * @param array $params list of additional parameters
  *
  * @return bool TRUE on success, FALSE for unknown commands, or
  * a PEAR error on failure
  *
  * @access public
  */
 function doLogin($command, $options, $params)
 {
     $server = $this->config->get('master_server');
     $remote = new PEAR_Remote($this->config);
     $username = $this->config->get('username');
     if (empty($username)) {
         $username = @$_ENV['USER'];
     }
     $this->ui->outputData("Logging in to {$server}.", $command);
     list($username, $password) = $this->ui->userDialog($command, array('Username', 'Password'), array('text', 'password'), array($username, ''));
     $username = trim($username);
     $password = trim($password);
     $this->config->set('username', $username);
     $this->config->set('password', $password);
     $remote->expectError(401);
     $ok = $remote->call('logintest');
     $remote->popExpect();
     if ($ok === true) {
         $this->ui->outputData("Logged in.", $command);
         $this->config->store();
     } else {
         return $this->raiseError("Login failed!");
     }
 }
Beispiel #3
0
 /**
  * @param array dependency array
  * @access private
  */
 function _getDepPackageDownloadUrl($dep, $parr)
 {
     $xsdversion = isset($dep['rel']) ? '1.0' : '2.0';
     $curchannel = $this->config->get('default_channel');
     if (isset($dep['channel'])) {
         $remotechannel = $dep['channel'];
     } else {
         $remotechannel = 'pear.php.net';
     }
     if (!$this->_registry->channelExists($remotechannel)) {
         do {
             if ($this->config->get('auto_discover')) {
                 if ($this->discover($remotechannel)) {
                     break;
                 }
             }
             return PEAR::raiseError('Unknown remote channel: ' . $remotechannel);
         } while (false);
     }
     $this->configSet('default_channel', $remotechannel);
     $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state');
     if (isset($parr['state']) && isset($parr['version'])) {
         unset($parr['state']);
     }
     $chan =& $this->_registry->getChannel($remotechannel);
     if (PEAR::isError($chan)) {
         return $chan;
     }
     $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel);
     if ($chan->supportsREST($this->config->get('preferred_mirror')) && ($base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')))) {
         $rest =& $this->config->getREST('1.0', $this->_options);
         $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, $state, $version);
         if (PEAR::isError($url)) {
             return $url;
         }
         if ($parr['channel'] != $curchannel) {
             $this->configSet('default_channel', $curchannel);
         }
         if (!is_array($url)) {
             return $url;
         }
         $url['raw'] = false;
         // no checking is necessary for REST
         if (!is_array($url['info'])) {
             return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . 'this should never happen');
         }
         if (isset($url['info']['required'])) {
             if (!class_exists('PEAR_PackageFile_v2')) {
                 require_once 'PEAR/PackageFile/v2.php';
             }
             $pf = new PEAR_PackageFile_v2();
             $pf->setRawChannel($remotechannel);
         } else {
             if (!class_exists('PEAR_PackageFile_v1')) {
                 require_once 'PEAR/PackageFile/v1.php';
             }
             $pf = new PEAR_PackageFile_v1();
         }
         $pf->setRawPackage($url['package']);
         $pf->setDeps($url['info']);
         $pf->setRawState($url['stability']);
         $url['info'] =& $pf;
         if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
             $ext = '.tar';
         } else {
             $ext = '.tgz';
         }
         if (is_array($url)) {
             if (isset($url['url'])) {
                 $url['url'] .= $ext;
             }
         }
         return $url;
     } elseif ($chan->supports('xmlrpc', 'package.getDepDownloadURL', false, '1.1')) {
         if ($version) {
             $url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr, $state, $version);
         } else {
             $url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr, $state);
         }
     } else {
         $url = $this->_remote->call('package.getDepDownloadURL', $xsdversion, $dep, $parr, $state);
     }
     if ($parr['channel'] != $curchannel) {
         $this->configSet('default_channel', $curchannel);
     }
     if (!is_array($url)) {
         return $url;
     }
     if (isset($url['__PEAR_ERROR_CLASS__'])) {
         return PEAR::raiseError($url['message']);
     }
     $url['raw'] = $url['info'];
     $pkg =& $this->getPackagefileObject($this->config, $this->debug);
     PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
     $pinfo =& $pkg->fromXmlString($url['info'], PEAR_VALIDATE_DOWNLOADING, 'remote');
     PEAR::staticPopErrorHandling();
     if (PEAR::isError($pinfo)) {
         if (!isset($this->_options['soft'])) {
             $this->log(0, $pinfo->getMessage());
         }
         return PEAR::raiseError('Remote package.xml is not valid - this should never happen');
     }
     $url['info'] =& $pinfo;
     if (is_array($url)) {
         if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) {
             $ext = '.tar';
         } else {
             $ext = '.tgz';
         }
         if (isset($url['url'])) {
             $url['url'] .= $ext;
         }
     }
     return $url;
 }
Beispiel #4
0
 function doListUpgrades($command, $options, $params)
 {
     include_once "PEAR/Registry.php";
     $remote = new PEAR_Remote($this->config);
     if (empty($params[0])) {
         $state = $this->config->get('preferred_state');
     } else {
         $state = $params[0];
     }
     $caption = 'Available Upgrades';
     if (empty($state) || $state == 'any') {
         $latest = $remote->call("package.listLatestReleases");
     } else {
         $latest = $remote->call("package.listLatestReleases", $state);
         $caption .= ' (' . $state . ')';
     }
     $caption .= ':';
     if (PEAR::isError($latest)) {
         return $latest;
     }
     $reg = new PEAR_Registry($this->config->get('php_dir'));
     $inst = array_flip($reg->listPackages());
     $data = array('caption' => $caption, 'border' => 1, 'headline' => array('Package', 'Version', 'Size'));
     foreach ($latest as $package => $info) {
         if (!isset($inst[$package])) {
             // skip packages we don't have installed
             continue;
         }
         extract($info);
         $inst_version = $reg->packageInfo($package, 'version');
         if (version_compare("{$version}", "{$inst_version}", "le")) {
             // installed version is up-to-date
             continue;
         }
         if ($filesize >= 20480) {
             $filesize += 1024 - $filesize % 1024;
             $fs = sprintf("%dkB", $filesize / 1024);
         } elseif ($filesize > 0) {
             $filesize += 103 - $filesize % 103;
             $fs = sprintf("%.1fkB", $filesize / 1024.0);
         } else {
             $fs = "  -";
             // XXX center instead
         }
         $data['data'][] = array($package, $version, $fs);
     }
     if (empty($data['data'])) {
         $this->ui->outputData('No upgrades available');
     } else {
         $this->ui->outputData($data, $command);
     }
     return true;
 }
Beispiel #5
0
 function doInstall($command, $options, $params)
 {
     if (empty($this->installer)) {
         $this->installer =& new PEAR_Installer($this->ui);
     }
     if ($command == 'upgrade') {
         $options[$command] = true;
     }
     if ($command == 'upgrade-all') {
         include_once "PEAR/Remote.php";
         $options['upgrade'] = true;
         $remote = new PEAR_Remote($this->config);
         $state = $this->config->get('preferred_state');
         if (empty($state) || $state == 'any') {
             $latest = $remote->call("package.listLatestReleases");
         } else {
             $latest = $remote->call("package.listLatestReleases", $state);
         }
         if (PEAR::isError($latest)) {
             return $latest;
         }
         $reg = new PEAR_Registry($this->config->get('php_dir'));
         $installed = array_flip($reg->listPackages());
         $params = array();
         foreach ($latest as $package => $info) {
             if (!isset($installed[$package])) {
                 // skip packages we don't have installed
                 continue;
             }
             $inst_version = $reg->packageInfo($package, 'version');
             if (version_compare("{$info['version']}", "{$inst_version}", "le")) {
                 // installed version is up-to-date
                 continue;
             }
             $params[] = $package;
             $this->ui->outputData("will upgrade {$package}", $command);
         }
     }
     foreach ($params as $pkg) {
         $bn = basename($pkg);
         $info = $this->installer->install($pkg, $options, $this->config);
         if (is_array($info)) {
             if ($this->config->get('verbose') > 0) {
                 $label = "{$info['package']} {$info['version']}";
                 $out = array('data' => "{$command} ok: {$label}");
                 if (isset($info['release_warnings'])) {
                     $out['release_warnings'] = $info['release_warnings'];
                 }
                 $this->ui->outputData($out, $command);
             }
         } else {
             return $this->raiseError("{$command} failed");
         }
     }
     return true;
 }
Beispiel #6
0
 function doInstall($command, $options, $params)
 {
     if (empty($this->installer)) {
         $this->installer =& new PEAR_Installer($this->ui);
     }
     if ($command == 'upgrade') {
         $options['upgrade'] = true;
     }
     if ($command == 'upgrade-all') {
         include_once "PEAR/Remote.php";
         $options['upgrade'] = true;
         $remote = new PEAR_Remote($this->config);
         $state = $this->config->get('preferred_state');
         if (empty($state) || $state == 'any') {
             $latest = $remote->call("package.listLatestReleases");
         } else {
             $latest = $remote->call("package.listLatestReleases", $state);
         }
         if (PEAR::isError($latest)) {
             return $latest;
         }
         $reg = new PEAR_Registry($this->config->get('php_dir'));
         $installed = array_flip($reg->listPackages());
         $params = array();
         foreach ($latest as $package => $info) {
             $package = strtolower($package);
             if (!isset($installed[$package])) {
                 // skip packages we don't have installed
                 continue;
             }
             $inst_version = $reg->packageInfo($package, 'version');
             if (version_compare("{$info['version']}", "{$inst_version}", "le")) {
                 // installed version is up-to-date
                 continue;
             }
             $params[] = $package;
             $this->ui->outputData(array('data' => "Will upgrade {$package}"), $command);
         }
     }
     $errors = array();
     $downloaded = array();
     $this->installer->download($params, $options, $this->config, $downloaded, $errors);
     if ($command != 'upgrade-all') {
         for ($i = 0; $i < count($params); $i++) {
             $params[$i] = $this->installer->extractDownloadFileName($params[$i], $_tmp);
         }
     }
     if (count($errors)) {
         $err['data'] = array($errors);
         $err['headline'] = 'Install Errors';
         $this->ui->outputData($err);
         return $this->raiseError("{$command} failed");
     }
     $this->installer->sortPkgDeps($downloaded);
     foreach ($downloaded as $pkg) {
         $bn = basename($pkg['file']);
         $info = $this->installer->install($pkg['file'], $options, $this->config);
         if (is_array($info)) {
             if ($this->config->get('verbose') > 0) {
                 $label = "{$info['package']} {$info['version']}";
                 $out = array('data' => "{$command} ok: {$label}");
                 if (isset($info['release_warnings'])) {
                     $out['release_warnings'] = $info['release_warnings'];
                 }
                 $this->ui->outputData($out, $command);
             }
         } else {
             return $this->raiseError("{$command} failed");
         }
     }
     return true;
 }
Beispiel #7
0
 /**
  * Process a dependency, download if necessary
  * @param array dependency information from PEAR_Remote call
  * @param array packages that will be installed in this iteration
  * @return false|string|PEAR_Error
  * @access private
  * @todo Add test for relation 'lt'/'le' -> make sure that the dependency requested is
  *       in fact lower than the required value.  This will be very important for BC dependencies
  */
 function _processDependency($package, $info, $mywillinstall)
 {
     $state = $this->_preferredState;
     if (!isset($this->_options['alldeps']) && isset($info['optional']) && $info['optional'] == 'yes') {
         // skip optional deps
         $this->log(0, "skipping Package '{$package}' optional dependency '{$info['name']}'");
         return false;
     }
     // {{{ get releases
     $releases = $this->_remote->call('package.info', $info['name'], 'releases', true);
     if (PEAR::isError($releases)) {
         return $releases;
     }
     if (!count($releases)) {
         if (!isset($this->_installed[strtolower($info['name'])])) {
             $this->pushError("Package '{$package}' dependency '{$info['name']}' " . "has no releases");
         }
         return false;
     }
     $found = false;
     $save = $releases;
     while (count($releases) && !$found) {
         if (!empty($state) && $state != 'any') {
             list($release_version, $release) = each($releases);
             if ($state != $release['state'] && !in_array($release['state'], $this->betterStates($state))) {
                 // drop this release - it ain't stable enough
                 array_shift($releases);
             } else {
                 $found = true;
             }
         } else {
             $found = true;
         }
     }
     if (!count($releases) && !$found) {
         $get = array();
         foreach ($save as $release) {
             $get = array_merge($get, $this->betterStates($release['state'], true));
         }
         $savestate = array_shift($get);
         $this->pushError("Release for '{$package}' dependency '{$info['name']}' " . "has state '{$savestate}', requires '{$state}'");
         return false;
     }
     if (in_array(strtolower($info['name']), $this->_toDownload) || isset($mywillinstall[strtolower($info['name'])])) {
         // skip upgrade check for packages we will install
         return false;
     }
     if (!isset($this->_installed[strtolower($info['name'])])) {
         // check to see if we can install the specific version required
         if ($info['rel'] == 'eq') {
             return $info['name'] . '-' . $info['version'];
         }
         // skip upgrade check for packages we don't have installed
         return $info['name'];
     }
     // }}}
     // {{{ see if a dependency must be upgraded
     $inst_version = $this->_registry->packageInfo($info['name'], 'version');
     if (!isset($info['version'])) {
         // this is a rel='has' dependency, check against latest
         if (version_compare($release_version, $inst_version, 'le')) {
             return false;
         } else {
             return $info['name'];
         }
     }
     if (version_compare($info['version'], $inst_version, 'le')) {
         // installed version is up-to-date
         return false;
     }
     return $info['name'];
 }
Beispiel #8
0
 /**
  * Download any files and their dependencies, if necessary
  *
  * @param array a mixed list of package names, local files, or package.xml
  * @param PEAR_Config
  * @param array options from the command line
  * @param array this is the array that will be populated with packages to
  *              install.  Format of each entry:
  *
  * <code>
  * array('pkg' => 'package_name', 'file' => '/path/to/local/file',
  *    'info' => array() // parsed package.xml
  * );
  * </code>
  * @param array this will be populated with any error messages
  * @param false private recursion variable
  * @param false private recursion variable
  * @param false private recursion variable
  */
 function download($packages, $options, &$config, &$installpackages, &$errors, $installed = false, $willinstall = false, $state = false)
 {
     // recognized options:
     // - onlyreqdeps   : install all required dependencies as well
     // - alldeps       : install all dependencies, including optional
     //
     // {{{ determine preferred state, installroot, etc
     if (!$willinstall) {
         $willinstall = array();
     }
     if (!$state) {
         $state = $config->get('preferred_state');
         if (!$state) {
             // don't inadvertantly use a non-set preferred_state
             $state = null;
         }
     }
     $mywillinstall = array();
     $php_dir = $config->get('php_dir');
     if (isset($options['installroot'])) {
         if (substr($options['installroot'], -1) == DIRECTORY_SEPARATOR) {
             $options['installroot'] = substr($options['installroot'], 0, -1);
         }
         $php_dir = $this->_prependPath($php_dir, $options['installroot']);
         $this->installroot = $options['installroot'];
     } else {
         $this->installroot = '';
     }
     // }}}
     $this->registry =& new PEAR_Registry($php_dir);
     // {{{ download files in this list if necessary
     foreach ($packages as $pkgfile) {
         if (!is_file($pkgfile)) {
             $origpkgfile = $pkgfile;
             $pkgfile = $this->extractDownloadFileName($pkgfile, $version);
             if (!$this->validPackageName($pkgfile)) {
                 return $this->raiseError("Package name '{$pkgfile}' not valid");
             }
             // ignore packages that are installed unless we are upgrading
             $curinfo = $this->registry->packageInfo($pkgfile);
             if ($this->registry->packageExists($pkgfile) && empty($options['upgrade']) && empty($options['force'])) {
                 $this->log(0, "Package '{$curinfo['package']}' already installed, skipping");
                 continue;
             }
             // Retrieve remote release list
             include_once 'PEAR/Remote.php';
             $curver = $curinfo['version'];
             $remote =& new PEAR_Remote($config);
             $releases = $remote->call('package.info', $pkgfile, 'releases');
             if (!count($releases)) {
                 return $this->raiseError("No releases found for package '{$pkgfile}'");
             }
             // Want a specific version/state
             if ($version !== null) {
                 // Passed Foo-1.2
                 if ($this->validPackageVersion($version)) {
                     if (!isset($releases[$version])) {
                         return $this->raiseError("No release with version '{$version}' found for '{$pkgfile}'");
                     }
                     // Passed Foo-alpha
                 } elseif (in_array($version, $this->getReleaseStates())) {
                     $state = $version;
                     $version = 0;
                     foreach ($releases as $ver => $inf) {
                         if ($inf['state'] == $state && version_compare("{$version}", "{$ver}") < 0) {
                             $version = $ver;
                         }
                     }
                     if ($version == 0) {
                         return $this->raiseError("No release with state '{$state}' found for '{$pkgfile}'");
                     }
                     // invalid postfix passed
                 } else {
                     return $this->raiseError("Invalid postfix '-{$version}', be sure to pass a valid PEAR " . "version number or release state");
                 }
                 // Guess what to download
             } else {
                 $states = $this->betterStates($state, true);
                 $possible = false;
                 $version = 0;
                 foreach ($releases as $ver => $inf) {
                     if (in_array($inf['state'], $states) && version_compare("{$version}", "{$ver}") < 0) {
                         $version = $ver;
                     }
                 }
                 if ($version == 0) {
                     return $this->raiseError('No release with state equal to: \'' . implode(', ', $states) . "' found for '{$pkgfile}'");
                 }
             }
             // Check if we haven't already the version
             if (empty($options['force'])) {
                 if ($curinfo['version'] == $version) {
                     $this->log(0, "Package '{$curinfo['package']}-{$curinfo['version']}' already installed, skipping");
                     continue;
                 } elseif (version_compare("{$version}", "{$curinfo['version']}") < 0) {
                     $this->log(0, "Already got '{$curinfo['package']}-{$curinfo['version']}' greater than requested '{$version}', skipping");
                     continue;
                 }
             }
             $pkgfile = $this->_downloadFile($pkgfile, $config, $options, $errors, $version, $origpkgfile, $state);
             if (PEAR::isError($pkgfile)) {
                 return $pkgfile;
             }
         }
         // end is_file()
         $tempinfo = $this->infoFromAny($pkgfile);
         if (isset($options['alldeps']) || isset($options['onlyreqdeps'])) {
             // ignore dependencies if there are any errors
             if (!PEAR::isError($tempinfo)) {
                 $mywillinstall[strtolower($tempinfo['package'])] = @$tempinfo['release_deps'];
             }
         }
         $installpackages[] = array('pkg' => $tempinfo['package'], 'file' => $pkgfile, 'info' => $tempinfo);
     }
     // end foreach($packages)
     // }}}
     // {{{ extract dependencies from downloaded files and then download
     // them if necessary
     if (isset($options['alldeps']) || isset($options['onlyreqdeps'])) {
         include_once "PEAR/Remote.php";
         $remote = new PEAR_Remote($config);
         if (!$installed) {
             $installed = $this->registry->listPackages();
             array_walk($installed, create_function('&$v,$k', '$v = strtolower($v);'));
             $installed = array_flip($installed);
         }
         $deppackages = array();
         // {{{ construct the list of dependencies for each file
         foreach ($mywillinstall as $package => $alldeps) {
             if (!is_array($alldeps)) {
                 continue;
             }
             foreach ($alldeps as $info) {
                 if ($info['type'] != 'pkg') {
                     continue;
                 }
                 if (!isset($options['alldeps']) && isset($info['optional']) && $info['optional'] == 'yes') {
                     // skip optional deps
                     $this->log(0, "skipping Package {$package} optional dependency {$info['name']}");
                     continue;
                 }
                 // {{{ get releases
                 $releases = $remote->call('package.info', $info['name'], 'releases');
                 if (PEAR::isError($releases)) {
                     return $releases;
                 }
                 if (!count($releases)) {
                     if (!isset($installed[strtolower($info['name'])])) {
                         $errors[] = "Package {$package} dependency {$info['name']} " . "has no releases";
                     }
                     continue;
                 }
                 $found = false;
                 $save = $releases;
                 while (count($releases) && !$found) {
                     if (!empty($state) && $state != 'any') {
                         list($release_version, $release) = each($releases);
                         if ($state != $release['state'] && !in_array($release['state'], $this->betterStates($state))) {
                             // drop this release - it ain't stable enough
                             array_shift($releases);
                         } else {
                             $found = true;
                         }
                     } else {
                         $found = true;
                     }
                 }
                 if (!count($releases) && !$found) {
                     $get = array();
                     foreach ($save as $release) {
                         $get = array_merge($get, $this->betterStates($release['state'], true));
                     }
                     $savestate = array_shift($get);
                     $errors[] = "Release for {$package} dependency {$info['name']} " . "has state '{$savestate}', requires {$state}";
                     continue;
                 }
                 if (in_array(strtolower($info['name']), $willinstall) || isset($mywillinstall[strtolower($info['name'])])) {
                     // skip upgrade check for packages we will install
                     continue;
                 }
                 if (!isset($installed[strtolower($info['name'])])) {
                     // skip upgrade check for packages we don't have installed
                     $deppackages[] = $info['name'];
                     continue;
                 }
                 // }}}
                 // {{{ see if a dependency must be upgraded
                 $inst_version = $this->registry->packageInfo($info['name'], 'version');
                 if (!isset($info['version'])) {
                     // this is a rel='has' dependency, check against latest
                     if (version_compare($release_version, $inst_version, 'le')) {
                         continue;
                     } else {
                         $deppackages[] = $info['name'];
                         continue;
                     }
                 }
                 if (version_compare($info['version'], $inst_version, 'le')) {
                     // installed version is up-to-date
                     continue;
                 }
                 $deppackages[] = $info['name'];
                 // }}}
             }
             // foreach($alldeps
         }
         // }}} foreach($willinstall
         if (count($deppackages)) {
             // check dependencies' dependencies
             // combine the list of packages to install
             $temppack = array();
             foreach ($installpackages as $p) {
                 $temppack[] = strtolower($p['info']['package']);
             }
             foreach ($deppackages as $pack) {
                 $temppack[] = strtolower($pack);
             }
             $willinstall = array_merge($willinstall, $temppack);
             $this->download($deppackages, $options, $config, $installpackages, $errors, $installed, $willinstall, $state);
         }
     }
     // }}} if --alldeps or --onlyreqdeps
 }