/** * Delete a package's installed files, does not remove empty directories. * * @param string package name * @param string channel name * @param bool if true, then files are backed up first * @return bool TRUE on success, or a PEAR error on failure * @access protected */ function _deletePackageFiles($package, $channel = false, $backup = false) { if (!$channel) { $channel = 'pear.php.net'; } if (!strlen($package)) { return $this->raiseError("No package to uninstall given"); } if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { // to avoid race conditions, include all possible needed files require_once 'PEAR/Task/Common.php'; require_once 'PEAR/Task/Replace.php'; require_once 'PEAR/Task/Unixeol.php'; require_once 'PEAR/Task/Windowseol.php'; require_once 'PEAR/PackageFile/v1.php'; require_once 'PEAR/PackageFile/v2.php'; require_once 'PEAR/PackageFile/Generator/v1.php'; require_once 'PEAR/PackageFile/Generator/v2.php'; } $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); if ($filelist == null) { return $this->raiseError("{$channel}/{$package} not installed"); } $ret = array(); if ($this->config->isDefinedLayer('ftp') && isset($this->_options['upgrade'])) { $pkg = $this->_registry->getPackage($package, $channel); $this->ftpUninstall($pkg); // no error checking } return parent::_deletePackageFiles($package, $channel, $backup); }
function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) { $test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer); if (@file_exists($test[2]) && @file_exists($test[3])) { // Try sha1 first if (!is_null($this->sha1)) { $sha1 = sha1_file($test[2]); $mod = $sha1 !== $this->sha1 && $sha1 !== sha1_file($test[3]); } else { $md5 = md5_file($test[2]); $mod = $md5 !== $this->md5 && $md5 !== md5_file($test[3]); } // configuration has already been installed, check for mods if ($mod) { // configuration has been modified, so save our version as // configfile-version $old = $test[2]; $test[2] .= '.new-' . $pkg->getVersion(); // backup original and re-install it PEAR::pushErrorHandling(PEAR_ERROR_RETURN); $tmpcfg = $this->config->get('temp_dir'); $newloc = System::mkdir(array('-p', $tmpcfg)); if (!$newloc) { // try temp_dir $newloc = System::mktemp(array('-d')); if (!$newloc || PEAR::isError($newloc)) { PEAR::popErrorHandling(); return PEAR::raiseError('Could not save existing configuration file ' . $old . ', unable to install. Please set temp_dir ' . 'configuration variable to a writeable location and try again'); } } else { $newloc = $tmpcfg; } $temp_file = $newloc . DIRECTORY_SEPARATOR . uniqid('savefile'); if (!@copy($old, $temp_file)) { PEAR::popErrorHandling(); return PEAR::raiseError('Could not save existing configuration file ' . $old . ', unable to install. Please set temp_dir ' . 'configuration variable to a writeable location and try again'); } PEAR::popErrorHandling(); $this->installer->log(0, "WARNING: configuration file {$old} is being installed as {$test['2']}, you should manually merge in changes to the existing configuration file"); $this->installer->addFileOperation('rename', array($temp_file, $old, false)); $this->installer->addFileOperation('delete', array($temp_file)); } } return $test; }
/** * Verify that uninstalling packages passed in to command line is OK. * * @param PEAR_Installer $dl * @return PEAR_Error|true */ function validatePackageUninstall(&$dl) { if (PEAR::isError($this->_dependencydb)) { return $this->_dependencydb; } $params = array(); // construct an array of "downloaded" packages to fool the package dependency checker // into using these to validate uninstalls of circular dependencies $downloaded =& $dl->getUninstallPackages(); foreach ($downloaded as $i => $pf) { if (!class_exists('PEAR_Downloader_Package')) { require_once 'PEAR/Downloader/Package.php'; } $dp =& new PEAR_Downloader_Package($dl); $dp->setPackageFile($downloaded[$i]); $params[$i] =& $dp; } // check cache $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . strtolower($this->_currentPackage['package']); if (isset($dl->___uninstall_package_cache)) { $badpackages = $dl->___uninstall_package_cache; if (isset($badpackages[$memyselfandI]['warnings'])) { foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { $dl->log(0, $warning[0]); } } if (isset($badpackages[$memyselfandI]['errors'])) { foreach ($badpackages[$memyselfandI]['errors'] as $error) { if (is_array($error)) { $dl->log(0, $error[0]); } else { $dl->log(0, $error->getMessage()); } } if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { return $this->warning('warning: %s should not be uninstalled, other installed packages depend ' . 'on this package'); } return $this->raiseError('%s cannot be uninstalled, other installed packages depend on this package'); } return true; } // first, list the immediate parents of each package to be uninstalled $perpackagelist = array(); $allparents = array(); foreach ($params as $i => $param) { $a = array('channel' => strtolower($param->getChannel()), 'package' => strtolower($param->getPackage())); $deps = $this->_dependencydb->getDependentPackages($a); if ($deps) { foreach ($deps as $d) { $pardeps = $this->_dependencydb->getDependencies($d); foreach ($pardeps as $dep) { if (strtolower($dep['dep']['channel']) == $a['channel'] && strtolower($dep['dep']['name']) == $a['package']) { if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); } $perpackagelist[$a['channel'] . '/' . $a['package']][] = array($d['channel'] . '/' . $d['package'], $dep); if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { $allparents[$d['channel'] . '/' . $d['package']] = array(); } if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); } $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']][] = array($d, $dep); } } } } } // next, remove any packages from the parents list that are not installed $remove = array(); foreach ($allparents as $parent => $d1) { foreach ($d1 as $d) { if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { continue; } $remove[$parent] = true; } } // next remove any packages from the parents list that are not passed in for // uninstallation foreach ($allparents as $parent => $d1) { foreach ($d1 as $d) { foreach ($params as $param) { if (strtolower($param->getChannel()) == $d[0][0]['channel'] && strtolower($param->getPackage()) == $d[0][0]['package']) { // found it continue 3; } } $remove[$parent] = true; } } // remove all packages whose dependencies fail // save which ones failed for error reporting $badchildren = array(); do { $fail = false; foreach ($remove as $package => $unused) { if (!isset($allparents[$package])) { continue; } foreach ($allparents[$package] as $kid => $d1) { foreach ($d1 as $depinfo) { if ($depinfo[1]['type'] != 'optional') { if (isset($badchildren[$kid])) { continue; } $badchildren[$kid] = true; $remove[$kid] = true; $fail = true; continue 2; } } } if ($fail) { // start over, we removed some children continue 2; } } } while ($fail); // next, construct the list of packages that can't be uninstalled $badpackages = array(); $save = $this->_currentPackage; foreach ($perpackagelist as $package => $packagedeps) { foreach ($packagedeps as $parent) { if (!isset($remove[$parent[0]])) { continue; } $packagename = $this->_registry->parsePackageName($parent[0]); $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); $packagename['package'] = $pa->getPackage(); $this->_currentPackage = $packagename; // parent is not present in uninstall list, make sure we can actually // uninstall it (parent dep is optional) $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); $parentname['package'] = $pa->getPackage(); $parent[1]['dep']['package'] = $parentname['package']; $parent[1]['dep']['channel'] = $parentname['channel']; if ($parent[1]['type'] == 'optional') { $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); if ($test !== true) { $badpackages[$package]['warnings'][] = $test; } } else { $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); if ($test !== true) { $badpackages[$package]['errors'][] = $test; } } } } $this->_currentPackage = $save; $dl->___uninstall_package_cache = $badpackages; if (isset($badpackages[$memyselfandI])) { if (isset($badpackages[$memyselfandI]['warnings'])) { foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { $dl->log(0, $warning[0]); } } if (isset($badpackages[$memyselfandI]['errors'])) { foreach ($badpackages[$memyselfandI]['errors'] as $error) { if (is_array($error)) { $dl->log(0, $error[0]); } else { $dl->log(0, $error->getMessage()); } } if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { return $this->warning('warning: %s should not be uninstalled, other installed packages depend ' . 'on this package'); } return $this->raiseError('%s cannot be uninstalled, other installed packages depend on this package'); } } return true; }
/** * Verify that uninstalling packages passed in to command line is OK. * * @param PEAR_Installer $dl * @return PEAR_Error|true */ function validatePackageUninstall(&$dl) { if (PEAR::isError($this->_dependencydb)) { return $this->_dependencydb; } $params = array(); // construct an array of "downloaded" packages to fool the package dependency checker // into using these to validate uninstalls of circular dependencies $downloaded =& $dl->getUninstallPackages(); foreach ($downloaded as $i => $pf) { if (!class_exists('PEAR_Downloader_Package')) { require_once 'PEAR/Downloader/Package.php'; } $dp =& new PEAR_Downloader_Package($dl); $dp->setPackageFile($downloaded[$i]); $params[$i] =& $dp; } $deps = $this->_dependencydb->getDependentPackageDependencies($this->_currentPackage); $fail = false; if ($deps) { foreach ($deps as $channel => $info) { foreach ($info as $package => $ds) { foreach ($ds as $d) { $d['dep']['package'] = $d['dep']['name']; $checker =& new PEAR_Dependency2($this->_config, $this->_options, array('channel' => $channel, 'package' => $package), $this->_state); $dep = $d['dep']; $required = $d['type'] == 'required'; $ret = $checker->_validatePackageUninstall($dep, $required, $params, $dl); if (is_array($ret)) { $dl->log(0, $ret[0]); } elseif (PEAR::isError($ret)) { $dl->log(0, $ret->getMessage()); $fail = true; } } } } } if ($fail) { if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { return $this->warning('warning: %s should not be uninstalled, other installed packages depend ' . 'on this package'); } else { return $this->raiseError('%s cannot be uninstalled, other installed packages depend on this package'); } } return true; }
/** * Uninstalls a plugin. * * @param string $plugin The plugin name * @param string $channel The channel name */ public function uninstallPlugin($plugin, $channel = null) { if (false !== strpos($plugin, '/')) { list($channel, $plugin) = explode('/', $plugin); } $channel = is_null($channel) ? $this->environment->getConfig()->get('default_channel') : $channel; $existing = $this->environment->getRegistry()->packageInfo($plugin, 'version', $channel); if (is_null($existing)) { $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Plugin "%s" is not installed', $plugin)))); return false; } $this->dispatcher->notify(new sfEvent($this, 'plugin.pre_uninstall', array('channel' => $channel, 'plugin' => $plugin))); $package = $this->environment->getRegistry()->parsePackageName($plugin, $channel); $installer = new PEAR_Installer($this); $packages = array($this->environment->getRegistry()->getPackage($plugin, $channel)); $installer->setUninstallPackages($packages); $ret = $installer->uninstall($package); if (PEAR::isError($ret)) { throw new sfPluginException(sprintf('Problem uninstalling plugin "%s": %s', $plugin, $ret->getMessage())); } if ($ret) { $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Uninstallation successful for plugin "%s"', $plugin)))); $this->dispatcher->notify(new sfEvent($this, 'plugin.post_uninstall', array('channel' => $channel, 'plugin' => $plugin))); } else { throw new sfPluginException(sprintf('Uninstallation of "%s" plugin failed', $plugin)); } return $ret; }
function doMakeRPM($command, $options, $params) { if (sizeof($params) != 1) { return $this->raiseError("bad parameter(s), try \"help {$command}\""); } if (!file_exists($params[0])) { return $this->raiseError("file does not exist: {$params['0']}"); } include_once "Archive/Tar.php"; include_once "PEAR/Installer.php"; include_once "System.php"; $tar = new Archive_Tar($params[0]); $tmpdir = System::mktemp('-d pear2rpm'); $instroot = System::mktemp('-d pear2rpm'); $tmp = $this->config->get('verbose'); $this->config->set('verbose', 0); $installer = new PEAR_Installer($this->ui); $info = $installer->install($params[0], array('installroot' => $instroot, 'nodeps' => true)); $pkgdir = "{$info['package']}-{$info['version']}"; $info['rpm_xml_dir'] = '/var/lib/pear'; $this->config->set('verbose', $tmp); if (!$tar->extractList("package.xml", $tmpdir, $pkgdir)) { return $this->raiseError("failed to extract {$params['0']}"); } if (!file_exists("{$tmpdir}/package.xml")) { return $this->raiseError("no package.xml found in {$params['0']}"); } if (isset($options['spec-template'])) { $spec_template = $options['spec-template']; } else { $spec_template = $this->config->get('data_dir') . '/PEAR/template.spec'; } if (isset($options['rpm-pkgname'])) { $rpm_pkgname_format = $options['rpm-pkgname']; } else { $rpm_pkgname_format = "PEAR::%s"; } $info['extra_headers'] = ''; $info['doc_files'] = ''; $info['files'] = ''; $info['rpm_package'] = sprintf($rpm_pkgname_format, $info['package']); $srcfiles = 0; foreach ($info['filelist'] as $name => $attr) { if ($attr['role'] == 'doc') { $info['doc_files'] .= " {$name}"; // Map role to the rpm vars } else { $c_prefix = '%{_libdir}/php/pear'; switch ($attr['role']) { case 'php': $prefix = $c_prefix; break; case 'ext': $prefix = '%{_libdir}/php'; break; // XXX good place? // XXX good place? case 'src': $srcfiles++; $prefix = '%{_includedir}/php'; break; // XXX good place? // XXX good place? case 'test': $prefix = "{$c_prefix}/tests/" . $info['package']; break; case 'data': $prefix = "{$c_prefix}/data/" . $info['package']; break; case 'script': $prefix = '%{_bindir}'; break; } $info['files'] .= "{$prefix}/{$name}\n"; } } if ($srcfiles > 0) { include_once "OS/Guess.php"; $os = new OS_Guess(); $arch = $os->getCpu(); } else { $arch = 'noarch'; } $cfg = array('master_server', 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'test_dir'); foreach ($cfg as $k) { $info[$k] = $this->config->get($k); } $info['arch'] = $arch; $fp = @fopen($spec_template, "r"); if (!$fp) { return $this->raiseError("could not open RPM spec file template {$spec_template}: {$php_errormsg}"); } $spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\\1"]', fread($fp, filesize($spec_template))); fclose($fp); $spec_file = "{$info['rpm_package']}-{$info['version']}.spec"; $wp = fopen($spec_file, "wb"); if (!$wp) { return $this->raiseError("could not write RPM spec file {$spec_file}: {$php_errormsg}"); } fwrite($wp, $spec_contents); fclose($wp); $this->ui->outputData("Wrote RPM spec file {$spec_file}", $command); return true; }
// end print $php_dir = $config->get('php_dir'); $options = array(); $options['upgrade'] = true; $install_root = getenv('INSTALL_ROOT'); if (!empty($install_root)) { $options['packagingroot'] = $install_root; $reg =& new PEAR_Registry($options['packagingroot'], false, false, $metadata_dir); } else { $reg = $config->getRegistry('default'); } $ui = PEAR_Frontend::singleton('PEAR_Frontend_CLI'); if (PEAR::isError($ui)) { die($ui->getMessage()); } $installer = new PEAR_Installer($ui); $pkg = new PEAR_PackageFile($config, $debug); foreach ($install_files as $package => $instfile) { $info = $pkg->fromAnyFile($instfile, PEAR_VALIDATE_INSTALLING); if (PEAR::isError($info)) { if (is_array($info->getUserInfo())) { foreach ($info->getUserInfo() as $err) { $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err['message'])); } } $ui->outputData(sprintf("[PEAR] %s: %s", $package, $info->getMessage())); continue; } $new_ver = $info->getVersion(); $downloaderpackage = new PEAR_Downloader_Package($installer); $err = $downloaderpackage->initialize($instfile);