Example #1
0
 /**
  * Replace all line endings with line endings customized for the current OS
  *
  * See validateXml() source for the complete list of allowed fields
  * @param \Pyrus\PackageInterface
  * @param resource open file pointer, set to the beginning of the file
  * @param string the eventual final file location (informational only)
  * @return string
  */
 function startSession($fp, $dest)
 {
     $contents = stream_get_contents($fp);
     \Pyrus\Logger::log(3, "replacing all line endings with \\n in {$dest}");
     $contents = preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents);
     rewind($fp);
     ftruncate($fp, 0);
     fwrite($fp, $contents);
     return true;
 }
Example #2
0
 function __construct($debugging = false)
 {
     if (!$debugging) {
         set_exception_handler(array($this, 'exceptionHandler'));
     }
     \Pyrus\Logger::attach($this);
     if (!isset(static::$commandParser)) {
         $schemapath = \Pyrus\Main::getDataPath() . '/customcommand-2.0.xsd';
         $defaultcommands = \Pyrus\Main::getDataPath() . '/built-in-commands.xml';
         // Check for a local-developer-commands.xml file
         $localcommands = false;
         if (file_exists(\Pyrus\Main::getDataPath() . '/local-developer-commands.xml')) {
             $localcommands = realpath(\Pyrus\Main::getDataPath() . '/local-developer-commands.xml');
         }
         $parser = new \Pyrus\XMLParser();
         $commands = $parser->parse($defaultcommands, $schemapath);
         $commands = $commands['commands']['command'];
         if ($localcommands) {
             // Add in local commands
             $localcommands = $parser->parse($localcommands, $schemapath);
             $commands = array_merge($commands, $localcommands['commands']['command']);
         }
         if ('@PACKAGE_VERSION@' == '@' . 'PACKAGE_VERSION@') {
             $version = '2.0.0a4';
             // running from git
         } else {
             $version = '@PACKAGE_VERSION@';
         }
         static::$commandParser = new \Pyrus\ScriptFrontend(array('version' => $version, 'description' => 'Pyrus, the PHP manager', 'name' => 'php ' . basename($_SERVER['argv'][0])));
         // set up our custom renderer for help options
         static::$commandParser->accept(new \Pyrus\ScriptFrontend\Renderer(static::$commandParser));
         // set up command-less options and argument
         static::$commandParser->addOption('verbose', array('short_name' => '-v', 'long_name' => '--verbose', 'action' => 'Counter', 'description' => 'increase verbosity'));
         static::$commandParser->addOption('paranoid', array('short_name' => '-p', 'long_name' => '--paranoid', 'action' => 'Counter', 'description' => 'set or increase paranoia level'));
         \Pyrus\PluginRegistry::registerFrontend($this);
         \Pyrus\PluginRegistry::addCommand($commands);
     }
     $term = getenv('TERM');
     if (function_exists('posix_isatty') && !posix_isatty(1)) {
         // output is being redirected to a file or through a pipe
     } elseif ($term) {
         if (preg_match('/^(xterm|vt220|linux)/', $term)) {
             $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109);
             $this->term['normal'] = sprintf("%c%c%c", 27, 91, 109);
         } elseif (preg_match('/^vt100/', $term)) {
             $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0);
             $this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0);
         }
     }
 }
Example #3
0
 function getRelativeLocation(\Pyrus\PackageFileInterface $pkg, \Pyrus\PackageFile\v2Iterator\FileTag $file, $retDir = false)
 {
     if ($this->md5 === null) {
         return parent::getRelativeLocation($pkg, $file, $retDir);
     }
     $info = parent::getRelativeLocation($pkg, $file, $retDir);
     $path = \Pyrus\Config::current()->cfg_dir . DIRECTORY_SEPARATOR;
     if ($retDir) {
         $filepath = $info[1];
     } else {
         $filepath = $info;
     }
     if (@file_exists($path . $filepath)) {
         // configuration has already been installed, check for modifications
         // made by the user
         $md5 = md5_file($path . $filepath);
         $newmd5 = $pkg->files[$file->packagedname]['attribs'];
         if (!isset($newmd5['md5sum'])) {
             $newmd5 = md5_file($pkg->getFilePath($file->packagedname));
         } else {
             $newmd5 = $newmd5['md5sum'];
         }
         // first check to see if the user modified the file
         // next check to see if the config file changed from the last installed version
         // if both tests are satisfied, install the new file under another name and display a warning
         if ($md5 !== $this->md5 && $md5 !== $newmd5) {
             // configuration has been modified, so save our version as
             // configfile.new-version
             $old = $filepath;
             $filepath .= '.new-' . $pkg->version['release'];
             \Pyrus\Logger::log(0, "WARNING: configuration file {$old} is being installed as {$filepath}, " . "you should manually merge in changes to the existing configuration file");
         }
     }
     if ($retDir) {
         $info[1] = $filepath;
     } else {
         $info = $filepath;
     }
     return $info;
 }
Example #4
0
 /**
  * Extract configuration from system + user configuration files
  *
  * Configuration is stored in XML format, in two locations.
  *
  * The system configuration contains all of the important directory
  * configuration variables like data_dir, and the location of php.ini and
  * the php executable php.exe or php.  This configuration is tightly bound
  * to the repository, and cannot be moved.  As such, php_dir is auto-defined
  * as dirname(/path/to/pear/.config), or /path/to/pear.
  *
  * Only 1 user configuration file is allowed, and contains user-specific
  * settings, including the locations where to download package releases
  * and where to cache files downloaded from the internet.  If false is passed
  * in, \Pyrus\Config will attempt to guess at the config file location as
  * documented in the class docblock {@link \Pyrus\Config}.
  * @param string $pearDirectory
  * @param string|false $userfile
  */
 protected function loadConfigFile($pearDirectory, $snapshot = null)
 {
     if (!file_exists($pearDirectory . DIRECTORY_SEPARATOR . '.configsnapshots')) {
         // no configurations - this may be an extracted-from-disk install.
         // in this case, we use the defaults, as this is intended
         return;
     }
     $snapshotdir = $pearDirectory . DIRECTORY_SEPARATOR . '.configsnapshots';
     $snapshotfile = $snapshotdir . DIRECTORY_SEPARATOR . $snapshot;
     if (!file_exists($snapshotfile)) {
         if (preg_match('/^\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}[-:]\\d{2}[-:]\\d{2}$/', $snapshot)) {
             // passed a date, locate a matching snapshot
             if (!strpos($snapshot, ':')) {
                 // change YYYY-MM-DD HH-MM-SS to YYYY-MM-DD HH:MM:SS
                 $snapshot = explode(' ', $snapshot);
                 $snapshot[1] = str_replace('-', ':', $snapshot[1]);
                 $snapshot = implode(' ', $snapshot);
             }
             $us = new \DateTime($snapshot);
             $dir = new \RegexIterator(new \RecursiveDirectoryIterator($snapshotdir), '/configsnapshot\\-\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}\\-\\d{2}\\-\\d{2}.xml/', \RegexIterator::MATCH, \RegexIterator::USE_KEY);
             foreach ($dir as $match) {
                 $matches[] = $match;
             }
             usort($matches, array($this, 'datediff'));
             unset($match);
             $found = false;
             foreach ($matches as $match) {
                 $match = substr($match->getFileName(), strlen('configsnapshot-'));
                 $match = str_replace('.xml', '', $match);
                 $match = explode(' ', $match);
                 $match[1] = str_replace('-', ':', $match[1]);
                 $match = implode(' ', $match);
                 $testdate = new \DateTime($match);
                 if ($testdate > $us) {
                     continue;
                 }
                 if ($testdate == $us) {
                     // found a snapshot match
                     $found = true;
                     break;
                 }
                 if ($us > $testdate) {
                     // we fall between these two snapshots, so use this one
                     $found = true;
                     break;
                 }
             }
             if (!$found) {
                 // no config snapshots
                 return parent::loadConfigFile($pearDirectory);
             }
             $snapshotfile = $snapshotdir . DIRECTORY_SEPARATOR . 'configsnapshot-' . str_replace(':', '-', $match) . '.xml';
         }
     }
     \Pyrus\Logger::log(5, 'Loading configuration snapshot ' . $snapshotfile . ' for ' . $pearDirectory);
     try {
         $this->helperLoadConfigFile($pearDirectory, $snapshotfile, 'snapshot');
     } catch (\Exception $e) {
         // no config snapshots found, so simply load the existing config
         return parent::loadConfigFile($pearDirectory);
     }
 }
Example #5
0
 /**
  *
  * @param string|array pass in an array of format
  *                     array(
  *                      'package' => 'pname',
  *                     ['channel' => 'channame',]
  *                     ['version' => 'version',]
  *                     ['state' => 'state',])
  *                     or a string of format [channame/]pname[-version|-state]
  */
 protected function fromString($param)
 {
     try {
         $pname = Config::parsePackageName($param, true);
     } catch (\Pyrus\ChannelRegistry\ParseException $e) {
         if ($e->why !== 'channel') {
             throw new Exception('invalid package name/package file "' . $param . '"', $e);
         }
         if (Config::current()->auto_discover) {
             try {
                 try {
                     $chan = new \Pyrus\Channel(new \Pyrus\ChannelFile('https://' . $e->params['channel'] . '/channel.xml'));
                 } catch (\Exception $e) {
                     $chan = new \Pyrus\Channel(new \Pyrus\ChannelFile('http://' . $e->params['channel'] . '/channel.xml'));
                 }
             } catch (\Exception $e) {
                 throw new Exception('Cannot auto-discover channel ' . $e->params['channel'], $e);
             }
             Config::current()->channelregistry[] = $chan;
             try {
                 Config::parsePackageName($param, Config::current()->default_channel);
             } catch (\Exception $e) {
                 throw new Exception('invalid package name/package file "' . $param . '"', $e);
             }
         } else {
             \Pyrus\Logger::log(0, 'Channel "' . $param['channel'] . '" is not initialized, use ' . '"pyrus channel-discover ' . $param['channel'] . '" to initialize' . 'or pyrus set auto_discover 1');
         }
     }
     $this->parsedname = $pname;
     $this->explicitVersion = isset($pname['version']) ? $pname['version'] : false;
     $this->explicitState = isset($pname['state']) ? $pname['state'] : false;
     $this->explicitGroup = isset($pname['group']) ? true : false;
     $reg = Config::current()->registry;
     $version = $reg->info($pname['package'], $pname['channel'], 'version');
     $stability = $reg->info($pname['package'], $pname['channel'], 'state');
     if (!isset(\Pyrus\Main::$options['force']) && !isset(\Pyrus\Main::$options['downloadonly']) && $version && $this->explicitVersion && !isset($pname['group'])) {
         if (version_compare($version, $pname['version'], '>=')) {
             throw new InstalledException(Config::parsedPackageNameToString($pname, true) . ' is already installed and is newer than detected ' . 'release version ' . $pname['version']);
         }
     }
     if (!$this->explicitVersion && $stability) {
         // if installed, use stability of the installed package,
         // but only if it is less restrictive than preferred_state.
         // This allows automatic upgrade to a newer beta for 1 package
         // even if preferred_state is stable, for instance.
         $states = \Pyrus\Installer::betterStates(Config::current()->preferred_state);
         $newstates = \Pyrus\Installer::betterStates($stability);
         if (count($newstates) > count($states)) {
             $this->explicitState = $stability;
         }
     }
     $this->type = 'abstract';
     $ret = $this->getRemotePackage($pname);
     if ($this->explicitVersion) {
         $ret->setExplicitVersion($this->explicitVersion);
         $ret->version['release'] = $this->explicitVersion;
     }
     if ($this->explicitState) {
         $ret->setExplicitState($this->explicitState);
     }
     return $ret;
 }
Example #6
0
 /**
  * validate a downloaded package against installed packages
  *
  * @param $pkg downloaded package package.xml object
  * @param array $params full list of packages to install
  * @return bool
  */
 function validateDownloadedPackage(\Pyrus\PackageFileInterface $pkg, $params = array())
 {
     $me = $pkg->channel . '/' . $pkg->name;
     $reg = Config::current()->registry;
     $deppackages = $reg->getDependentPackages($pkg);
     $fail = false;
     if ($deppackages) {
         $actual = array();
         // first, remove packages that will be installed
         foreach ($deppackages as $package) {
             foreach ($params as $packd) {
                 if (strtolower($packd->name) == strtolower($package->name) && $packd->channel == $package->channel) {
                     \Pyrus\Logger::log(3, 'skipping installed package check of "' . Config::parsedPackageNameToString(array('channel' => $package->channel, 'package' => $package->name), true) . '", version "' . $packd->version['release'] . '" will be ' . 'downloaded and installed');
                     continue 2;
                 }
             }
             $actual[] = $package;
         }
         foreach ($actual as $package) {
             $checker = new \Pyrus\Dependency\Validator(array('channel' => $package->channel, 'package' => $package->name), $this->_state, $this->errs);
             foreach ($params as $packd) {
                 $deps = $package->dependencies['required']->package;
                 if (isset($deps[$me])) {
                     $ret = $checker->_validatePackageDownload($deps[$me], array($pkg, $package));
                 }
                 $deps = $package->dependencies['required']->subpackage;
                 if (isset($deps[$me])) {
                     $ret = $checker->_validatePackageDownload($deps[$me], array($pkg));
                 }
                 $deps = $package->dependencies['optional']->package;
                 if (isset($deps[$me])) {
                     $ret = $checker->_validatePackageDownload($deps[$me], array($pkg, $package));
                 }
                 $deps = $package->dependencies['optional']->subpackage;
                 if (isset($deps[$me])) {
                     $ret = $checker->_validatePackageDownload($deps[$me], array($pkg));
                 }
             }
         }
     }
     if (count($this->errs->E_ERROR)) {
         return $this->raiseError('%s cannot be installed, conflicts with installed packages');
     }
     return true;
 }
Example #7
0
 function _analyzeBundledPackages()
 {
     if (!$this->_pf->type == 'bundle') {
         return false;
     }
     if (!$this->_pf->packagefile) {
         return false;
     }
     $dir_prefix = $this->_pf->filepath;
     foreach ($this->_pf->bundledpackage as $package) {
         if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) {
             $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('File "' . $dir_prefix . DIRECTORY_SEPARATOR . $package . '" in package.xml does not exist');
             continue;
         }
         \Pyrus\Logger::log(1, "Analyzing bundled package {$package}");
         try {
             $ret = new \Pyrus\Package\Tar($dir_prefix . DIRECTORY_SEPARATOR . $package);
         } catch (\Exception $e) {
             $this->errors->E_ERROR[] = new \Pyrus\PackageFile\Exception('File "' . $dir_prefix . DIRECTORY_SEPARATOR . $package . '" in package.xml is not valid', $e);
             continue;
         }
     }
     return true;
 }
Example #8
0
 /**
  * Figure out which version is best, and use this, or error out if none work
  * @param \Pyrus\PackageFile\v2\Dependencies\Package $compositeDep
  *        the composite of all dependencies on this package, as calculated
  *        by {@link \Pyrus\Package\Dependency::getCompositeDependency()}
  */
 function figureOutBestVersion(\Pyrus\PackageFile\v2\Dependencies\Package $compositeDep, $versions = null, \Pyrus\PackageFile\v2\Dependencies\Package $compositeConflictingDep = null)
 {
     // set up release list if not done yet
     $this->rewind();
     $ok = \Pyrus\Installer::betterStates($this->minimumStability, true);
     $v = $this->explicitVersion;
     $n = $this->channel . '/' . $this->name;
     $failIfExplicit = function ($versioninfo) use($v, $n) {
         if ($v && $versioninfo['v'] == $v) {
             throw new Exception($n . ' Cannot be installed, it does not satisfy ' . 'all dependencies');
         }
     };
     foreach ($this->releaseList as $versioninfo) {
         if (isset(\Pyrus\Main::$options['force'])) {
             // found one
             if ($this->versionSet && $versioninfo['v'] != $this->version['release']) {
                 // inform the installer we need to reset dependencies
                 $this->version['release'] = $versioninfo['v'];
                 return true;
             }
             $this->version['release'] = $versioninfo['v'];
             return;
         }
         if ($versions && !in_array($versioninfo['v'], $versions)) {
             continue;
         }
         if (!isset(\Pyrus\Main::$options['force']) && isset($versioninfo['m'])) {
             // minimum PHP version required
             if (version_compare($versioninfo['m'], $this->getPHPVersion(), '>')) {
                 $failIfExplicit($versioninfo);
                 continue;
             }
         }
         if (!in_array($versioninfo['s'], $ok) && !isset(\Pyrus\Main::$options['force'])) {
             // release is not stable enough
             continue;
         }
         if ($this->explicitVersion && $versioninfo['v'] != $this->explicitVersion) {
             continue;
         }
         if (!$compositeDep->satisfied($versioninfo['v'])) {
             $failIfExplicit($versioninfo);
             continue;
         }
         if ($compositeConflictingDep && !$compositeConflictingDep->satisfied($versioninfo['v'])) {
             $failIfExplicit($versioninfo);
             continue;
         }
         $paranoia = \Pyrus\Main::getParanoiaLevel();
         if (!$this->explicitVersion && $paranoia > 1) {
             // first, we check to see if we are upgrading
             if (isset(\Pyrus\Main::$options['upgrade'])) {
                 // now we check to see if we are installed
                 if (isset(Config::current()->registry->package[$n])) {
                     $installed = Config::current()->registry->info($this->name, $this->channel, 'apiversion');
                     $installed = explode('.', $installed);
                     if (count($installed) == 2) {
                         $installed[] = '0';
                     }
                     if (count($installed) == 1) {
                         $installed[] = '0';
                         $installed[] = '0';
                     }
                     if (isset($this->parent->protocols->rest['REST1.3'])) {
                         $api = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . strtolower($this->name) . '/v2.' . $versioninfo['v'] . '.xml', false, false, 'text/xml');
                     } else {
                         throw new Exception('Channel ' . $this->channel . ' does not support ' . 'a paranoia greater than 1');
                     }
                     $api = explode('.', $api['a']);
                     if (count($api) == 2) {
                         $api[] = '0';
                     }
                     if (count($api) == 1) {
                         $api[] = '0';
                         $api[] = '0';
                     }
                     if ($paranoia > 4) {
                         $paranoia = 4;
                     }
                     switch ($paranoia) {
                         case 4:
                             if ($installed != $api) {
                                 Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API has changed');
                                 continue 2;
                             }
                             break;
                         case 3:
                             if ($installed[0] == $api[0] && $installed[1] != $api[1]) {
                                 Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API has added' . ' new features');
                                 continue 2;
                             }
                             // break intentionally omitted
                         // break intentionally omitted
                         case 2:
                             if ($installed[0] != $api[0]) {
                                 Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API breaks' . ' backwards compatibility');
                                 continue 2;
                             }
                             break;
                     }
                 }
             }
         }
         // found one
         if ($this->versionSet && $versioninfo['v'] != $this->version['release']) {
             // inform the installer we need to reset dependencies
             $this->version['release'] = $versioninfo['v'];
             return true;
         }
         $this->version['release'] = $versioninfo['v'];
         return;
     }
     throw new Exception('Unable to locate a package release for ' . $this->channel . '/' . $this->name . ' that can satisfy all dependencies');
 }
Example #9
0
 function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings)
 {
     $info = '';
     $warn = false;
     if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) {
         $this->save_text($temp_skipif, $section_text['SKIPIF']);
         $output = $this->system_with_timeout("{$this->_php}{$ini_settings} -f \"{$temp_skipif}\"");
         $output = $output[1];
         $loutput = ltrim($output);
         unlink($temp_skipif);
         if (!strncasecmp('skip', $loutput, 4)) {
             $skipreason = "SKIP {$tested}";
             if (preg_match('/^\\s*skip\\s*(.+)\\s*/i', $output, $m)) {
                 $skipreason .= '(reason: ' . $m[1] . ')';
             }
             if (!isset($this->_options['quiet'])) {
                 \Pyrus\Logger::log(0, $skipreason);
             }
             if (isset($this->_options['tapoutput'])) {
                 return array('ok', ' # skip ' . $reason);
             }
             return 'SKIPPED';
         }
         if (!strncasecmp('info', $loutput, 4) && preg_match('/^\\s*info\\s*(.+)\\s*/i', $output, $m)) {
             $info = " (info: {$m['1']})";
         }
         if (!strncasecmp('warn', $loutput, 4) && preg_match('/^\\s*warn\\s*(.+)\\s*/i', $output, $m)) {
             $warn = true;
             /* only if there is a reason */
             $info = " (warn: {$m['1']})";
         }
     }
     return array('warn' => $warn, 'info' => $info);
 }
Example #10
0
 public function listPackages($channel)
 {
     $dir = $this->_namePath($channel, '');
     if (!@file_exists($dir)) {
         return array();
     }
     $ret = array();
     try {
         $parser = new \Pyrus\XMLParser();
         foreach (new \DirectoryIterator($dir) as $file) {
             if ($file->isDot()) {
                 continue;
             }
             try {
                 foreach (new \DirectoryIterator($file->getPathName()) as $registries) {
                     if ($registries->isDir()) {
                         continue;
                     }
                     $a = $parser->parse($registries->getPathName());
                     $ret[] = $a['package']['name'];
                 }
             } catch (\Exception $e) {
                 \Pyrus\Logger::log(0, 'Warning: corrupted XML registry entry: ' . $file->getPathName() . ': ' . $e);
             }
         }
     } catch (\Exception $e) {
         throw new Exception('Could not open channel directory for ' . 'channel ' . $channel, $e);
     }
     return $ret;
 }
Example #11
0
 final function packageTimeValidate(\Pyrus\Package $package, array $fileXml)
 {
     if (!isset($this->info['validationmethod'])) {
         return true;
     }
     if (!method_exists($this, $this->info['validationmethod'])) {
         \Pyrus\Logger::log(0, 'WARNING: custom role ' . $this->info['name'] . ' specifies non-existing validation method ' . $this->info['validationmethod']);
         return true;
     }
     return $this->{$this->info['validationmethod']}($package, $fileXml);
 }
Example #12
0
 /**
  * Unlike other tasks, the installed file name is passed in instead of the file contents,
  * because this task is handled post-installation
  * @param \Pyrus\PackageInterface
  * @param string path to the post-install script
  * @return bool false to skip this file
  */
 function setupPostInstall()
 {
     $files = \Pyrus\Config::current()->registry->info($this->pkg->name, $this->pkg->channel, 'installedfiles');
     foreach ($files as $path => $info) {
         if ($info['name'] == $this->_filename) {
             break;
         }
     }
     Logger::log(0, 'Including external post-installation script "' . $path . '" - any errors are in this script');
     include $path;
     if (class_exists($this->scriptClass) === false) {
         throw new Exception('init of post-install script class "' . $this->scriptClass . '" failed');
     }
     Logger::log(0, 'Inclusion succeeded');
     $this->obj = new $this->scriptClass();
     Logger::log(1, 'running post-install script "' . $this->scriptClass . '->init()"');
     try {
         $this->obj->init2($this->pkg, $this->lastVersion);
     } catch (\Exception $e) {
         throw new Exception('init of post-install script "' . $this->scriptClass . '->init()" failed', $e);
     }
     Logger::log(0, 'init succeeded');
     return true;
 }
Example #13
0
 function _install($info, $replace)
 {
     $database = static::getRegistry($this->_path);
     if (!$replace) {
         $info = $info->toRaw();
         // this avoids potential exception on setting date/time
         // which can happen if $info is a registry package that
         // has been uninstalled
         $info->date = date('Y-m-d');
         $info->time = date('H:i:s');
     }
     $licloc = $info->license;
     $licuri = $info->license['uri'];
     $licpath = $info->license['path'];
     $sql = '
         INSERT INTO packages
           (lcname, name, channel, version, apiversion, summary, packagetype,
            description, stability, apistability, releasedate,
            releasetime, license, licenseuri, licensepath,
            releasenotes, lastinstalledversion, installedwithpear,
            installtimeconfig)
         VALUES(:lcname, :name, :channel, :versionrelease, :versionapi, :summary,
             :packagetype, :description, :stabilityrelease, :stabilityapi,
             :date, :time, :license, :licenseuri, :licensepath, :notes,
             :lastinstalledv, :lastinstalledp, :lastinstalltime
         )';
     $stmt = $database->prepare($sql);
     $n = $info->name;
     $c = $info->channel;
     $stmt->bindValue(':lcname', strtolower($n));
     $stmt->bindValue(':name', $n);
     $stmt->bindValue(':channel', $c);
     $stmt->bindValue(':versionrelease', $info->version['release']);
     $stmt->bindValue(':versionapi', $info->version['api']);
     $stmt->bindValue(':summary', $info->summary);
     $stmt->bindValue(':description', $info->description);
     $stmt->bindValue(':packagetype', $info->type);
     $stmt->bindValue(':stabilityrelease', $info->stability['release']);
     $stmt->bindValue(':stabilityapi', $info->stability['api']);
     $stmt->bindValue(':date', $info->date);
     $stmt->bindValue(':time', $info->time);
     $stmt->bindValue(':license', $info->license['name']);
     $stmt->bindValue(':licenseuri', $licuri, $licuri === null ? SQLITE3_NULL : SQLITE3_TEXT);
     $stmt->bindValue(':licensepath', $licpath, $licpath === null ? SQLITE3_NULL : SQLITE3_TEXT);
     $stmt->bindValue(':notes', $info->notes);
     $stmt->bindValue(':lastinstalledv', null, SQLITE3_NULL);
     if ('@PACKAGE_VERSION@' == '@' . 'PACKAGE_VERSION@') {
         $v = '2.0.0a1';
     } else {
         $v = '@PACKAGE_VERSION@';
     }
     $stmt->bindValue(':lastinstalledp', $v);
     $stmt->bindValue(':lastinstalltime', Config::configSnapshot());
     $stmt->execute();
     $stmt->close();
     $n = strtolower($n);
     $sql = '
         INSERT INTO maintainers
           (packages_name, packages_channel, role, name, user, email, active)
         VALUES
             (:name, :channel, :role, :m_name, :m_user, :m_email, :m_active)';
     $stmt = $database->prepare($sql);
     foreach ($info->allmaintainers as $role => $maintainers) {
         foreach ($maintainers as $maintainer) {
             $stmt->clear();
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':role', $role);
             $stmt->bindValue(':m_name', $maintainer->name);
             $stmt->bindValue(':m_user', $maintainer->user);
             $stmt->bindValue(':m_email', $maintainer->email);
             $stmt->bindValue(':m_active', $maintainer->active);
             @$stmt->execute();
         }
     }
     $stmt->close();
     $curconfig = Config::current();
     $roles = array();
     $sql = '
         INSERT INTO configureoptions
           (packages_name, packages_channel, name, prompt, defaultValue)
         VALUES(:name, :channel, :oname, :prompt, :default)';
     \Pyrus\Logger::log(4, 'Preparing SQL: ' . $sql);
     $stmt = $database->prepare($sql);
     $stmt->bindValue(':name', $n);
     \Pyrus\Logger::log(4, 'Binding SQL parameter :name: ' . var_export($n, true));
     $stmt->bindValue(':channel', $c);
     \Pyrus\Logger::log(4, 'Binding SQL parameter :channel: ' . var_export($c, true));
     foreach ($info->installrelease->configureoption as $option) {
         $stmt->bindValue(':oname', $option->name);
         \Pyrus\Logger::log(4, 'Binding SQL parameter :oname: ' . var_export($option->name, true));
         $stmt->bindValue(':prompt', $option->prompt);
         \Pyrus\Logger::log(4, 'Binding SQL parameter :prompt: ' . var_export($option->prompt, true));
         if ($option->default === null) {
             $stmt->bindValue(':default', null, SQLITE3_NULL);
             \Pyrus\Logger::log(4, 'Binding SQL parameter :default: NULL');
         } else {
             $stmt->bindValue(':default', $option->default);
             \Pyrus\Logger::log(4, 'Binding SQL parameter :default: ' . var_export($option->default, true));
         }
         $stmt->execute();
     }
     $sql = '
         INSERT INTO files
           (packages_name, packages_channel, packagepath, configpath, role,
            relativepath, origpath, baseinstalldir, tasks, md5sum)
         VALUES(:name, :channel, :path, :configpath, :role, :relativepath, :origpath, :baseinstall, :tasks, :md5)';
     $stmt = $database->prepare($sql);
     $stmt->bindValue(':name', $n);
     $stmt->bindValue(':channel', $c);
     foreach (Role::getValidRoles($info->getPackageType()) as $role) {
         // set up a list of file role => configuration variable
         // for storing in the registry
         $roles[$role] = Role::factory($info->getPackageType(), $role);
     }
     foreach ($info->installcontents as $file) {
         $relativepath = $roles[$file->role]->getRelativeLocation($info, $file);
         if (!$relativepath) {
             continue;
         }
         $p = $curconfig->{$roles[$file->role]->getLocationConfig()};
         $stmt->bindValue(':relativepath', $relativepath);
         $stmt->bindValue(':configpath', $p);
         $stmt->bindValue(':path', $p . DIRECTORY_SEPARATOR . $relativepath);
         $stmt->bindValue(':origpath', $file->packagedname);
         $stmt->bindValue(':role', $file->role);
         $stmt->bindValue(':baseinstall', $file->baseinstalldir);
         $stmt->bindValue(':tasks', serialize($file->tasks));
         if ($file->md5sum) {
             $stmt->bindValue(':md5', $file->md5sum);
         } else {
             // clearly the person installing doesn't care about this, so
             // use a dummy value
             $stmt->bindValue(':md5', md5(''));
         }
         $stmt->execute();
     }
     $stmt->close();
     $sql = '
         INSERT INTO baseinstalldirs
           (packages_name, packages_channel, dirname, baseinstall)
         VALUES(:name, :channel, :dirname, :baseinstall)';
     $stmt = $database->prepare($sql);
     foreach ($info->getBaseInstallDirs() as $dir => $base) {
         $stmt->bindValue(':name', $n);
         $stmt->bindValue(':channel', $c);
         $stmt->bindValue(':dirname', $dir);
         $stmt->bindValue(':baseinstall', $base);
         $stmt->execute();
     }
     $stmt->close();
     if (count($info->compatible)) {
         $sql = '
             INSERT INTO compatible_releases
                 (packages_name, packages_channel,
                  compat_package, compat_channel, min, max)
             VALUES
                 (:name, :channel, :cname, :cchannel, :min, :max)';
         $stmt = $database->prepare($sql);
         $stmt->bindValue(':name', $n);
         $stmt->bindValue(':channel', $c);
         $sql2 = '
             INSERT INTO compatible_releases_exclude
                 (packages_name, packages_channel,
                  compat_package, compat_channel, exclude)
             VALUES
                 (:name, :channel, :cname, :cchannel, :exclude)';
         $stmt2 = $database->prepare($sql2);
         $stmt2->bindValue(':name', $n);
         $stmt2->bindValue(':channel', $c);
         foreach ($info->compatible as $compatible) {
             $stmt->bindValue(':cname', $compatible->name);
             $stmt->bindValue(':cchannel', $compatible->channel);
             $stmt->bindValue(':min', $compatible->min);
             $stmt->bindValue(':max', $compatible->max);
             $stmt->execute();
             if (isset($compatible->exclude)) {
                 $stmt2->bindValue(':cname', $compatible->name);
                 $stmt2->bindValue(':cchannel', $compatible->channel);
                 foreach ($compatible->exclude as $exclude) {
                     $stmt2->bindValue(':exclude', $exclude);
                     $stmt2->execute();
                 }
             }
         }
     }
     $sql = '
         INSERT INTO extension_dependencies
             (required, packages_name, packages_channel, extension,
              conflicts, min, max, recommended)
         VALUES
             (:required, :name, :channel, :extension,
              :conflicts, :min, :max, :recommended)';
     $stmt = $database->prepare($sql);
     foreach (array('required', 'optional') as $required) {
         foreach ($info->dependencies[$required]->extension as $d) {
             // $d is a \Pyrus\PackageFile\v2\Dependencies\Package object
             $req = $required == 'required' ? 1 : 0;
             $stmt->bindValue(':required', $req, SQLITE3_INTEGER);
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':extension', $d->name);
             $stmt->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
             $stmt->bindValue(':min', $d->min);
             $stmt->bindValue(':max', $d->max);
             $stmt->bindValue(':recommended', $d->recommended);
             $stmt->execute();
             if (isset($d->exclude)) {
                 $sql = '
                     INSERT INTO extension_dependencies_exclude
                      (required, packages_name, packages_channel,
                       extension, exclude, conflicts)
                     VALUES(:required, :name, :channel, :extension,
                            :exclude, :conflicts)';
                 $stmt1 = $database->prepare($sql);
                 foreach ($d->exclude as $exclude) {
                     $stmt1->clear();
                     $req = $required == 'required' ? 1 : 0;
                     $stmt1->bindValue(':required', $req, SQLITE3_INTEGER);
                     $stmt1->bindValue(':name', $n);
                     $stmt1->bindValue(':channel', $c);
                     $stmt1->bindValue(':extension', $d->name);
                     $stmt1->bindValue(':exclude', $exclude);
                     $stmt1->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
                     $stmt1->execute();
                 }
                 $stmt1->close();
             }
         }
     }
     $stmt->close();
     $sql = '
         INSERT INTO package_dependencies
             (required, packages_name, packages_channel, deppackage,
              depchannel, conflicts, min, max, recommended, is_subpackage, providesextension)
         VALUES
             (:required, :name, :channel, :dep_package, :dep_channel,
              :conflicts, :min, :max, :recommended, :sub, :ext)';
     $stmt = $database->prepare($sql);
     $first = true;
     foreach (array('required', 'optional') as $required) {
         foreach (array('package', 'subpackage') as $package) {
             foreach ($info->dependencies[$required]->{$package} as $d) {
                 // $d is a \Pyrus\PackageFile\v2\Dependencies\Package object
                 $sub = $package == 'subpackage';
                 if (!$first) {
                     $stmt->clear();
                     $first = false;
                 }
                 $req = $required == 'required' ? 1 : 0;
                 $stmt->bindValue(':required', $req, SQLITE3_INTEGER);
                 $stmt->bindValue(':name', $n);
                 $stmt->bindValue(':channel', $c);
                 $stmt->bindValue(':dep_package', $d->name);
                 $stmt->bindValue(':dep_channel', $d->channel);
                 $con = $d->conflicts;
                 $stmt->bindValue(':conflicts', $con, SQLITE3_INTEGER);
                 $stmt->bindValue(':min', $d->min);
                 $stmt->bindValue(':max', $d->max);
                 $stmt->bindValue(':recommended', $d->recommended);
                 $stmt->bindValue(':sub', $sub);
                 if ($d->providesextension) {
                     $stmt->bindValue(':ext', $d->providesextension);
                 } else {
                     $stmt->bindValue(':ext', null, SQLITE3_NULL);
                 }
                 $stmt->execute();
                 if (isset($d->exclude)) {
                     $sql = '
                         INSERT INTO package_dependencies_exclude
                          (required, packages_name, packages_channel,
                           deppackage, depchannel, exclude, conflicts, is_subpackage)
                         VALUES(:required, :name, :channel, :dep_package,
                             :dep_channel, :exclude, :conflicts, :sub)';
                     $stmt1 = $database->prepare($sql);
                     foreach ($d->exclude as $exclude) {
                         $stmt1->clear();
                         $req = $required == 'required' ? 1 : 0;
                         $stmt1->bindValue(':required', $req, SQLITE3_INTEGER);
                         $stmt1->bindValue(':name', $n);
                         $stmt1->bindValue(':channel', $c);
                         $stmt1->bindValue(':dep_package', $d->name);
                         $stmt1->bindValue(':dep_channel', $d->channel);
                         $stmt1->bindValue(':exclude', $exclude);
                         $stmt1->bindValue(':sub', $sub);
                         $con = $d->conflicts;
                         $stmt1->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
                         $stmt1->execute();
                     }
                     $stmt1->close();
                 }
             }
         }
     }
     $stmt->close();
     $sql = '
         INSERT INTO php_dependencies
           (packages_name, packages_channel, min, max)
         VALUES
             (:name, :channel, :min, :max)';
     $max = $info->dependencies['required']->php->max;
     $stmt = $database->prepare($sql);
     $stmt->bindValue(':name', $n);
     $stmt->bindValue(':channel', $c);
     $stmt->bindValue(':min', $info->dependencies['required']->php->min);
     if ($max === null) {
         $stmt->bindValue(':max', $max, SQLITE3_NULL);
     } else {
         $stmt->bindValue(':max', $max);
     }
     $stmt->execute();
     $stmt->close();
     $sql = '
         INSERT INTO php_dependencies_exclude
           (packages_name, packages_channel, exclude)
         VALUES
             (:name, :channel, :exclude)';
     $stmt = $database->prepare($sql);
     if ($info->dependencies['required']->php->exclude) {
         foreach ($info->dependencies['required']->php->exclude as $exclude) {
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':exclude', $exclude);
             $stmt->execute();
         }
     }
     $stmt->close();
     $sql = '
         INSERT INTO pearinstaller_dependencies
           (packages_name, packages_channel, min, max)
         VALUES
             (:name, :channel, :min, :max)';
     $max = $info->dependencies['required']->pearinstaller->max;
     $stmt = $database->prepare($sql);
     $stmt->bindValue(':name', $n);
     $stmt->bindValue(':channel', $c);
     $stmt->bindValue(':min', $info->dependencies['required']->pearinstaller->min);
     if ($max === null) {
         $stmt->bindValue(':max', $max, SQLITE3_NULL);
     } else {
         $stmt->bindValue(':max', $max);
     }
     $stmt->execute();
     $stmt->close();
     $sql = '
         INSERT INTO pearinstaller_dependencies_exclude
           (packages_name, packages_channel, exclude)
         VALUES
             (:name, :channel, :exclude)';
     $stmt = $database->prepare($sql);
     if ($info->dependencies['required']->pearinstaller->exclude) {
         foreach ($info->dependencies['required']->pearinstaller->exclude as $exclude) {
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':exclude', $exclude);
             $stmt->execute();
         }
     }
     $stmt->close();
     if (isset($info->dependencies['required']->os)) {
         $sql = '
             INSERT INTO os_dependencies
               (packages_name, packages_channel, osname, conflicts)
             VALUES
                 (:name, :channel, :os, :conflicts)';
         $stmt = $database->prepare($sql);
         foreach ($info->dependencies['required']->os as $dep) {
             $stmt->clear();
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':os', $dep->name);
             $stmt->bindValue(':conflicts', $dep->conflicts, SQLITE3_INTEGER);
             $stmt->execute();
         }
         $stmt->close();
     }
     if (isset($info->dependencies['required']->arch)) {
         $sql = '
             INSERT INTO arch_dependencies
               (packages_name, packages_channel, pattern, conflicts)
             VALUES
                 (:name, :channel, :arch, :conflicts)';
         $stmt = $database->prepare($sql);
         foreach ($info->dependencies['required']->arch as $dep) {
             $stmt->clear();
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':arch', $dep->pattern);
             $stmt->bindValue(':conflicts', $dep->conflicts, SQLITE3_INTEGER);
             $stmt->execute();
         }
         $stmt->close();
     }
     foreach ($info->dependencies['group'] as $group) {
         $sql = '
             INSERT INTO dep_groups
                 (packages_name, packages_channel, groupname, grouphint)
             VALUES
                 (:name, :channel, :groupname, :grouphint)';
         $stmt = $database->prepare($sql);
         $stmt->bindValue(':name', $n);
         $stmt->bindValue(':channel', $c);
         $stmt->bindValue(':groupname', $group->name);
         $stmt->bindValue(':grouphint', $group->hint);
         $stmt->execute();
         $stmt->close();
         $sql = '
             INSERT INTO extension_dependencies
                 (required, packages_name, packages_channel, extension,
                  conflicts, min, max, recommended, groupname)
             VALUES
                 (0, :name, :channel, :extension,
                  :conflicts, :min, :max, :recommended, :groupname)';
         $stmt = $database->prepare($sql);
         foreach ($group->extension as $d) {
             // $d is a \Pyrus\PackageFile\v2\Dependencies\Package object
             $stmt->clear();
             $stmt->bindValue(':name', $n);
             $stmt->bindValue(':channel', $c);
             $stmt->bindValue(':extension', $d->name);
             $stmt->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
             $stmt->bindValue(':min', $d->min);
             $stmt->bindValue(':max', $d->max);
             $stmt->bindValue(':recommended', $d->recommended);
             $stmt->bindValue(':groupname', $group->name);
             $stmt->execute();
             if (isset($d->exclude)) {
                 $sql = '
                     INSERT INTO extension_dependencies_exclude
                      (required, packages_name, packages_channel,
                       extension, exclude, conflicts, groupname)
                     VALUES(0, :name, :channel, :extension,
                            :exclude, :conflicts, :groupname)';
                 $stmt1 = $database->prepare($sql);
                 foreach ($d->exclude as $exclude) {
                     $stmt1->clear();
                     $stmt1->bindValue(':name', $n);
                     $stmt1->bindValue(':channel', $c);
                     $stmt1->bindValue(':extension', $d->name);
                     $stmt1->bindValue(':exclude', $exclude);
                     $stmt1->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
                     $stmt1->bindValue(':groupname', $group->name);
                     $stmt1->execute();
                 }
                 $stmt1->close();
             }
         }
         $stmt->close();
         $sql = '
             INSERT INTO package_dependencies
               (required, packages_name, packages_channel, deppackage,
                depchannel, conflicts, min, max, recommended, is_subpackage, groupname, providesextension)
             VALUES
                 (0, :name, :channel, :dep_package, :dep_channel, :conflicts, :min, :max, :recommended, :sub,
                  :group, :ext)';
         $stmt = $database->prepare($sql);
         foreach (array('package', 'subpackage') as $package) {
             foreach ($group->{$package} as $d) {
                 // $d is a \Pyrus\PackageFile\v2\Dependencies\Package object
                 $sub = $package == 'subpackage';
                 $ext = $d->providesextension;
                 $stmt->clear();
                 $stmt->bindValue(':name', $n);
                 $stmt->bindValue(':channel', $c);
                 $stmt->bindValue(':dep_package', $d->name);
                 $stmt->bindValue(':dep_channel', $d->channel);
                 $stmt->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
                 $stmt->bindValue(':min', $d->min);
                 $stmt->bindValue(':max', $d->max);
                 $stmt->bindValue(':recommended', $d->recommended);
                 $stmt->bindValue(':sub', $sub);
                 $stmt->bindValue(':group', $group->name);
                 if ($ext) {
                     $stmt->bindValue(':ext', $ext);
                 } else {
                     $stmt->bindValue(':ext', $ext, SQLITE3_NULL);
                 }
                 $stmt->execute();
                 if (isset($d->exclude)) {
                     $sql = '
                         INSERT INTO package_dependencies_exclude
                          (required, packages_name, packages_channel,
                           deppackage, depchannel, exclude, conflicts, is_subpackage, groupname)
                         VALUES(0, :name, :channel, :dep_package,
                             :dep_channel, :exclude, :conflicts, :sub, :group)';
                     $stmt1 = $database->prepare($sql);
                     foreach ($d->exclude as $exclude) {
                         $stmt1->clear();
                         $req = 0;
                         $stmt1->bindValue(':required', $req, SQLITE3_INTEGER);
                         $stmt1->bindValue(':name', $n);
                         $stmt1->bindValue(':channel', $c);
                         $stmt1->bindValue(':dep_package', $d->name);
                         $stmt1->bindValue(':dep_channel', $d->channel);
                         $stmt1->bindValue(':exclude', $exclude);
                         $stmt1->bindValue(':sub', $sub);
                         $stmt1->bindValue(':group', $group->name);
                         $stmt1->bindValue(':conflicts', $d->conflicts, SQLITE3_INTEGER);
                         $stmt1->execute();
                     }
                     $stmt1->close();
                 }
             }
         }
     }
     $stmt->close();
 }
Example #14
0
 /**
  * Do a package.xml 1.0 replacement, with additional package-info fields available
  *
  * See validateXml() source for the complete list of allowed fields
  * @param \Pyrus\PackageInterface
  * @param resource open file pointer, set to the beginning of the file
  * @param string the eventual final file location (informational only)
  * @return string|false
  */
 function startSession($fp, $dest)
 {
     $contents = stream_get_contents($fp);
     $subst_from = $subst_to = array();
     foreach ($this->_replacements as $a) {
         $a = $a['attribs'];
         $to = '';
         if ($a['type'] == 'pear-config') {
             if ($this->installphase == Common::PACKAGE) {
                 return false;
             }
             $to = \Pyrus\Config::current()->{$a['to']};
             if (is_null($to)) {
                 \Pyrus\Logger::log(0, "{$dest}: invalid pear-config replacement: {$a['to']}");
                 return false;
             }
         } elseif ($a['type'] == 'php-const') {
             if ($this->installphase == Common::PACKAGE) {
                 return false;
             }
             if (defined($a['to'])) {
                 $to = constant($a['to']);
             } else {
                 \Pyrus\Logger::log(0, "{$dest}: invalid php-const replacement: {$a['to']}");
                 return false;
             }
         } else {
             if ($t = $this->pkg->{$a['to']}) {
                 if ($a['to'] == 'version') {
                     $t = $t['release'];
                 }
                 $to = $t;
             } else {
                 \Pyrus\Logger::log(0, "{$dest}: invalid package-info replacement: {$a['to']}");
                 return false;
             }
         }
         if (!is_null($to)) {
             $subst_from[] = $a['from'];
             $subst_to[] = $to;
         }
     }
     \Pyrus\Logger::log(3, "doing " . sizeof($subst_from) . " substitution(s) for {$dest}");
     if (sizeof($subst_from)) {
         $contents = str_replace($subst_from, $subst_to, $contents);
     }
     rewind($fp);
     ftruncate($fp, 0);
     fwrite($fp, $contents);
     return true;
 }
Example #15
0
 public function listPackages($channel)
 {
     $dir = $this->_namePath($channel, '');
     if (!@file_exists($dir)) {
         return array();
     }
     $ret = array();
     try {
         foreach (new \DirectoryIterator($dir) as $file) {
             if ($file->isDot() || !$file->isFile()) {
                 continue;
             }
             $a = @unserialize(file_get_contents($file->getPathName()));
             // $a['name'] is not set on v1 regs
             if ($a !== false && isset($a['name'])) {
                 $ret[] = $a['name'];
             } elseif ($a !== false && isset($a['package'])) {
                 $ret[] = $a['package'];
             } else {
                 \Pyrus\Logger::log(0, 'Warning: corrupted REG registry entry: ' . $file->getPathName());
             }
         }
     } catch (\Exception $e) {
         throw new Exception('Could not open channel directory for channel ' . $channel, $e);
     }
     return $ret;
 }