function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) { $test = parent::processInstallation($pkg, $atts, $file, $tmp_path, $layer); if (@file_exists($test[2])) { // configuration has already been installed, check for mods if (md5_file($test[2]) !== md5_file($test[3])) { // 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; } if (!@copy($old, $newloc . DIRECTORY_SEPARATOR . 'savefile')) { 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->addFileOperation('rename', array($newloc . DIRECTORY_SEPARATOR . 'savefile', $old, false)); $this->installer->addFileOperation('delete', array($newloc . DIRECTORY_SEPARATOR . 'savefile')); } } return $test; }
function beforeInsert($q, $roo) { if (isset($q['_remote_upload'])) { require_once 'System.php'; $tmpdir = System::mktemp("-d remote_upload"); $path = $tmpdir . '/' . basename($q['_remote_upload']); if (!file_exists($path)) { file_put_contents($path, file_get_contents($q['_remote_upload'])); } $imageInfo = getimagesize($path); require_once 'File/MimeType.php'; $y = new File_MimeType(); $ext = $y->toExt(trim((string) $imageInfo['mime'])); if (!preg_match("/\\." . $ext . "\$/", $path, $matches)) { rename($path, $path . "." . $ext); $path .= "." . $ext; } if (!$this->createFrom($path)) { $roo->jerr("erro making image" . $q['_remote_upload']); } if (!empty($q['_return_after_create'])) { return; } $roo->addEvent("ADD", $this, $this->toEventString()); $r = DB_DataObject::factory($this->tableName()); $r->id = $this->id; $roo->loadMap($r); $r->limit(1); $r->find(true); $roo->jok($r->URL(-1, '/Images') . '#attachment-' . $r->id); } }
/** * Send a bunch of files or directories as an archive * * Example: * <code> * require_once 'HTTP/Download/Archive.php'; * HTTP_Download_Archive::send( * 'myArchive.tgz', * '/var/ftp/pub/mike', * HTTP_DOWNLOAD_BZ2, * '', * '/var/ftp/pub' * ); * </code> * * @see Archive_Tar::createModify() * @static * @access public * @return mixed Returns true on success or PEAR_Error on failure. * @param string $name name the sent archive should have * @param mixed $files files/directories * @param string $type archive type * @param string $add_path path that should be prepended to the files * @param string $strip_path path that should be stripped from the files */ function send($name, $files, $type = HTTP_DOWNLOAD_TGZ, $add_path = '', $strip_path = '') { $tmp = System::mktemp(); switch ($type = strToUpper($type)) { case HTTP_DOWNLOAD_TAR: include_once 'Archive/Tar.php'; $arc = &new Archive_Tar($tmp); $content_type = 'x-tar'; break; case HTTP_DOWNLOAD_TGZ: include_once 'Archive/Tar.php'; $arc = &new Archive_Tar($tmp, 'gz'); $content_type = 'x-gzip'; break; case HTTP_DOWNLOAD_BZ2: include_once 'Archive/Tar.php'; $arc = &new Archive_Tar($tmp, 'bz2'); $content_type = 'x-bzip2'; break; case HTTP_DOWNLOAD_ZIP: include_once 'Archive/Zip.php'; $arc = &new Archive_Zip($tmp); $content_type = 'x-zip'; break; default: return PEAR::raiseError( 'Archive type not supported: ' . $type, HTTP_DOWNLOAD_E_INVALID_ARCHIVE_TYPE ); } if ($type == HTTP_DOWNLOAD_ZIP) { $options = array( 'add_path' => $add_path, 'remove_path' => $strip_path); if (!$arc->create($files, $options)) { return PEAR::raiseError('Archive creation failed.'); } } else { if (!$e = $arc->createModify($files, $add_path, $strip_path)) { return PEAR::raiseError('Archive creation failed.'); } if (PEAR::isError($e)) { return $e; } } unset($arc); $dl = &new HTTP_Download(array('file' => $tmp)); $dl->setContentType('application/' . $content_type); $dl->setContentDisposition(HTTP_DOWNLOAD_ATTACHMENT, $name); return $dl->send(); }
function post() { if (isset($_REQUEST['_convertToPlain'])) { require_once 'System.php'; $tmpdir = System::mktemp("-d convertPlain"); $path = $tmpdir . '/' . time() . '.html'; if (isset($_REQUEST['_check_unsubscribe'])) { libxml_use_internal_errors(true); $doc = new DOMDocument('1.0', 'UTF-8'); $doc->loadHTML($_REQUEST['bodytext']); $xpath = new DOMXpath($doc); foreach ($xpath->query('//a[@href]') as $a) { $href = $a->getAttribute('href'); if (!preg_match('/^#unsubscribe/', $href)) { continue; } $a->parentNode->replaceChild($doc->createTextNode($a->nodeValue . ' {unsubscribe_link}'), $a); } $_REQUEST['bodytext'] = $doc->saveHTML(); libxml_use_internal_errors(false); } if (!file_exists($path)) { file_put_contents($path, $_REQUEST['bodytext']); } require_once 'File/Convert.php'; $fc = new File_Convert($path, 'text/html'); $plain = $fc->convert('text/plain'); $this->jok(file_get_contents($plain)); } // Import from URL if (isset($_REQUEST['importUrl'])) { $this->checkHeader($_REQUEST['importUrl']); $data = $this->convertStyle($_REQUEST['importUrl'], '', true); $this->jok($data); } // Import from file $htmlFile = DB_DataObject::factory('images'); $htmlFile->setFrom(array('onid' => 0, 'ontable' => 'crm_mailing_list_message')); $htmlFile->onUpload(false); if ($htmlFile->mimetype != 'text/html') { $this->jerr('accept html file only!'); } if (!file_exists($htmlFile->getStoreName())) { $this->jerr('update failed!'); } $data = $this->convertStyle('', $htmlFile->getStoreName(), false); $htmlFile->delete(); unlink($htmlFile->getStoreName()) or die('Unable to delete the file'); $this->jok($data); }
function save($fn) { require_once __DIR__ . '/../../Document/Word/Writer.php'; require_once __DIR__ . '/../../System.php'; $this->tmpdir = System::mktemp("-d abitodocx"); //$this->tmpdir = '/tmp'; $this->link = ''; $this->style[] = array(); $this->keepSection = false; $this->writer = new Document_Word_Writer(); // New Word Document $this->section = $this->writer->createSection(); $this->pass = 1; $this->parseAbi(); $this->pass = 2; $this->parseAbi(); $this->saveDocx($fn); // uses this->writer... }
/** * Create and register a temporary directory. * * @param string $tmpdir (optional) Directory to use as tmpdir. * Will use system defaults (for example * /tmp or c:\windows\temp) if not specified * * @return string name of created directory * * @access public */ function mkTempDir($tmpdir = '') { $topt = $tmpdir ? array('-t', $tmpdir) : array(); $topt = array_merge($topt, array('-d', 'pear')); if (!class_exists('System')) { require_once 'System.php'; } if (!($tmpdir = System::mktemp($topt))) { return false; } $this->addTempFile($tmpdir); return $tmpdir; }
<?php /** * Unit tests for HTML_Template_Sigma class * * $Id: test.php,v 1.3 2004/04/10 10:28:45 avb Exp $ */ require_once 'System.php'; $Sigma_cache_dir = System::mktemp('-d sigma'); // What class are we going to test? // It is possible to also use the unit tests to test HTML_Template_ITX, which // also implements Integrated Templates API $IT_class = 'Sigma'; // $IT_class = 'ITX'; // Sigma_cache_testcase is useless if testing HTML_Template_ITX $testcases = array('Sigma_api_testcase', 'Sigma_cache_testcase', 'Sigma_usage_testcase'); if (@file_exists('../' . $IT_class . '.php')) { require_once '../' . $IT_class . '.php'; } else { require_once 'HTML/Template/' . $IT_class . '.php'; } require_once 'PHPUnit.php'; $suite =& new PHPUnit_TestSuite(); foreach ($testcases as $testcase) { include_once $testcase . '.php'; $methods = preg_grep('/^test/i', get_class_methods($testcase)); foreach ($methods as $method) { $suite->addTest(new $testcase($method)); } } require_once './Console_TestListener.php';
function doMakeRPM($command, $options, $params) { require_once 'System.php'; require_once 'Archive/Tar.php'; 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']}"); } $reg =& $this->config->getRegistry(); $pkg =& $this->getPackageFile($this->config, $this->_debug); $pf =& $pkg->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); if (PEAR::isError($pf)) { $u = $pf->getUserinfo(); if (is_array($u)) { foreach ($u as $err) { if (is_array($err)) { $err = $err['message']; } $this->ui->outputData($err); } } return $this->raiseError("{$params['0']} is not a valid package"); } $tmpdir = System::mktemp(array('-d', 'pear2rpm')); $instroot = System::mktemp(array('-d', 'pear2rpm')); $tmp = $this->config->get('verbose'); $this->config->set('verbose', 0); $installer = $this->getInstaller($this->ui); require_once 'PEAR/Downloader/Package.php'; $pack = new PEAR_Downloader_Package($installer); $pack->setPackageFile($pf); $params[0] =& $pack; $installer->setOptions(array('installroot' => $instroot, 'nodeps' => true, 'soft' => true)); $installer->setDownloadedPackages($params); $info = $installer->install($params[0], array('installroot' => $instroot, 'nodeps' => true, 'soft' => true)); $pkgdir = $pf->getPackage() . '-' . $pf->getVersion(); $info['rpm_xml_dir'] = '/var/lib/pear'; $this->config->set('verbose', $tmp); if (isset($options['spec-template'])) { $spec_template = $options['spec-template']; } else { $spec_template = '@DATA-DIR@/PEAR/template.spec'; } $info['possible_channel'] = ''; $info['extra_config'] = ''; if (isset($options['rpm-pkgname'])) { $rpm_pkgname_format = $options['rpm-pkgname']; } else { if ($pf->getChannel() == 'pear.php.net' || $pf->getChannel() == 'pecl.php.net') { $alias = 'PEAR'; } else { $chan =& $reg->getChannel($pf->getChannel()); $alias = $chan->getAlias(); $alias = strtoupper($alias); $info['possible_channel'] = $pf->getChannel() . '/'; } $rpm_pkgname_format = $alias . '::%s'; } $info['extra_headers'] = ''; $info['doc_files'] = ''; $info['files'] = ''; $info['package2xml'] = ''; $info['rpm_package'] = sprintf($rpm_pkgname_format, $pf->getPackage()); $srcfiles = 0; foreach ($info['filelist'] as $name => $attr) { if (!isset($attr['role'])) { continue; } $name = preg_replace('![/:\\\\]!', '/', $name); 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/" . $pf->getPackage(); break; case 'data': $prefix = "{$c_prefix}/data/" . $pf->getPackage(); break; case 'script': $prefix = '%{_bindir}'; break; default: // non-standard roles $prefix = "{$c_prefix}/{$attr['role']}/" . $pf->getPackage(); $info['extra_config'] .= "\n -d {$attr[role]}_dir={$c_prefix}/{$attr[role]} \\"; $this->ui->outputData('WARNING: role "' . $attr['role'] . '" used, ' . 'and will be installed in "' . $c_prefix . '/' . $attr['role'] . '/' . $pf->getPackage() . ' - hand-edit the final .spec if this is wrong', $command); break; } $name = str_replace('\\', '/', $name); $info['files'] .= "{$prefix}/{$name}\n"; } } if ($srcfiles > 0) { require_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) { if ($k == 'master_server') { $chan = $reg->getChannel($pf->getChannel()); $info[$k] = $chan->getServer(); continue; } $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}"); } $info['package'] = $pf->getPackage(); $info['version'] = $pf->getVersion(); $info['release_license'] = $pf->getLicense(); if ($pf->getDeps()) { if ($pf->getPackagexmlVersion() == '1.0') { $requires = $conflicts = array(); foreach ($pf->getDeps() as $dep) { if (isset($dep['optional']) && $dep['optional'] == 'yes') { continue; } if ($dep['type'] != 'pkg') { continue; } if (isset($dep['channel']) && $dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net') { $chan =& $reg->getChannel($dep['channel']); $package = strtoupper($chan->getAlias()) . '::' . $dep['name']; } else { $package = 'PEAR::' . $dep['name']; } $trans = array('>' => '>', '<' => '<', '>=' => '>=', '<=' => '<=', '=' => '=', 'gt' => '>', 'lt' => '<', 'ge' => '>=', 'le' => '<=', 'eq' => '='); if ($dep['rel'] == 'has') { $requires[] = $package; } elseif ($dep['rel'] == 'not') { $conflicts[] = $package; } elseif ($dep['rel'] == 'ne') { $conflicts[] = $package . ' = ' . $dep['version']; } elseif (isset($trans[$dep['rel']])) { $requires[] = $package . ' ' . $trans[$dep['rel']] . ' ' . $dep['version']; } } if (count($requires)) { $info['extra_headers'] .= 'Requires: ' . implode(', ', $requires) . "\n"; } if (count($conflicts)) { $info['extra_headers'] .= 'Conflicts: ' . implode(', ', $conflicts) . "\n"; } } else { $info['package2xml'] = '2'; // tell the spec to use package2.xml $requires = $conflicts = array(); $deps = $pf->getDeps(true); if (isset($deps['required']['package'])) { if (!isset($deps['required']['package'][0])) { $deps['required']['package'] = array($deps['required']['package']); } foreach ($deps['required']['package'] as $dep) { if ($dep['channel'] != 'pear.php.net' && $dep['channel'] != 'pecl.php.net') { $chan =& $reg->getChannel($dep['channel']); $package = strtoupper($chan->getAlias()) . '::' . $dep['name']; } else { $package = 'PEAR::' . $dep['name']; } if (isset($dep['conflicts']) && (isset($dep['min']) || isset($dep['max']))) { $deprange = array(); if (isset($dep['min'])) { $deprange[] = array($dep['min'], '>='); } if (isset($dep['max'])) { $deprange[] = array($dep['max'], '<='); } if (isset($dep['exclude'])) { if (!is_array($dep['exclude']) || !isset($dep['exclude'][0])) { $dep['exclude'] = array($dep['exclude']); } if (count($deprange)) { $excl = $dep['exclude']; // change >= to > if excluding the min version // change <= to < if excluding the max version for ($i = 0; $i < count($excl); $i++) { if (isset($deprange[0]) && $excl[$i] == $deprange[0][0]) { $deprange[0][1] = '<'; unset($dep['exclude'][$i]); } if (isset($deprange[1]) && $excl[$i] == $deprange[1][0]) { $deprange[1][1] = '>'; unset($dep['exclude'][$i]); } } } if (count($dep['exclude'])) { $dep['exclude'] = array_values($dep['exclude']); $newdeprange = array(); // remove excludes that are outside the existing range for ($i = 0; $i < count($dep['exclude']); $i++) { if ($dep['exclude'][$i] < $dep['min'] || $dep['exclude'][$i] > $dep['max']) { unset($dep['exclude'][$i]); } } $dep['exclude'] = array_values($dep['exclude']); usort($dep['exclude'], 'version_compare'); // take the remaining excludes and // split the dependency into sub-ranges $lastmin = $deprange[0]; for ($i = 0; $i < count($dep['exclude']) - 1; $i++) { $newdeprange[] = '(' . $package . " {$lastmin[1]} {$lastmin[0]} and " . $package . ' < ' . $dep['exclude'][$i] . ')'; $lastmin = array($dep['exclude'][$i], '>'); } if (isset($dep['max'])) { $newdeprange[] = '(' . $package . " {$lastmin[1]} {$lastmin[0]} and " . $package . ' < ' . $dep['max'] . ')'; } $conflicts[] = implode(' or ', $deprange); } else { $conflicts[] = $package . " {$deprange[0][1]} {$deprange[0][0]}" . (isset($deprange[1]) ? " and {$package} {$deprange[1][1]} {$deprange[1][0]}" : ''); } } continue; } if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['exclude'])) { if (isset($dep['conflicts'])) { $conflicts[] = $package; } else { $requires[] = $package; } } else { if (isset($dep['min'])) { $requires[] = $package . ' >= ' . $dep['min']; } if (isset($dep['max'])) { $requires[] = $package . ' <= ' . $dep['max']; } if (isset($dep['exclude'])) { $ex = $dep['exclude']; if (!is_array($ex)) { $ex = array($ex); } foreach ($ex as $ver) { $conflicts[] = $package . ' = ' . $ver; } } } } require_once 'Archive/Tar.php'; $tar = new Archive_Tar($pf->getArchiveFile()); $tar->pushErrorHandling(PEAR_ERROR_RETURN); $a = $tar->extractInString('package2.xml'); $tar->popErrorHandling(); if ($a === null || PEAR::isError($a)) { $info['package2xml'] = ''; // this doesn't have a package.xml version 1.0 $requires[] = 'PEAR::PEAR >= ' . $deps['required']['pearinstaller']['min']; } if (count($requires)) { $info['extra_headers'] .= 'Requires: ' . implode(', ', $requires) . "\n"; } if (count($conflicts)) { $info['extra_headers'] .= 'Conflicts: ' . implode(', ', $conflicts) . "\n"; } } } } // remove the trailing newline $info['extra_headers'] = trim($info['extra_headers']); if (function_exists('file_get_contents')) { fclose($fp); $spec_contents = preg_replace('/@([a-z0-9_-]+)@/e', '$info["\\1"]', file_get_contents($spec_template)); } else { $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; }
/** * Retrieve the directory that downloads will happen in * @access private * @return string */ function getDownloadDir() { if (isset($this->_downloadDir)) { return $this->_downloadDir; } $downloaddir = $this->config->get('download_dir'); if (empty($downloaddir)) { if (!class_exists('System')) { require_once 'System.php'; } if (PEAR::isError($downloaddir = System::mktemp('-d'))) { return $downloaddir; } $this->log(3, '+ tmp dir created at ' . $downloaddir); } return $this->_downloadDir = $downloaddir; }
function _detectGlibcVersion() { static $glibc = false; if ($glibc !== false) { return $glibc; // no need to run this multiple times } $major = $minor = 0; include_once "System.php"; // Use glibc's <features.h> header file to // get major and minor version number: if (@file_exists('/usr/include/features.h') && @is_readable('/usr/include/features.h')) { if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) { $features_file = fopen('/usr/include/features.h', 'rb'); while (!feof($features_file)) { $line = fgets($features_file, 8192); if (!$line || strpos($line, '#define') === false) { continue; } if (strpos($line, '__GLIBC__')) { // major version number #define __GLIBC__ version $line = preg_split('/\\s+/', $line); $glibc_major = trim($line[2]); if (isset($glibc_minor)) { break; } continue; } if (strpos($line, '__GLIBC_MINOR__')) { // got the minor version number // #define __GLIBC_MINOR__ version $line = preg_split('/\\s+/', $line); $glibc_minor = trim($line[2]); if (isset($glibc_major)) { break; } continue; } } fclose($features_file); if (!isset($glibc_major) || !isset($glibc_minor)) { return $glibc = ''; } return $glibc = 'glibc' . trim($glibc_major) . "." . trim($glibc_minor); } // no cpp $tmpfile = System::mktemp("glibctest"); $fp = fopen($tmpfile, "w"); fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n"); fclose($fp); $cpp = popen("/usr/bin/cpp {$tmpfile}", "r"); while ($line = fgets($cpp, 1024)) { if ($line[0] == '#' || trim($line) == '') { continue; } if (list($major, $minor) = explode(' ', trim($line))) { break; } } pclose($cpp); unlink($tmpfile); } // features.h if (!($major && $minor) && @is_link('/lib/libc.so.6')) { // Let's try reading the libc.so.6 symlink if (preg_match('/^libc-(.*)\\.so$/', basename(readlink('/lib/libc.so.6')), $matches)) { list($major, $minor) = explode('.', $matches[1]); } } if (!($major && $minor)) { return $glibc = ''; } return $glibc = "glibc{$major}.{$minor}"; }
/** * Saves GraphViz markup to file (in DOT language) * * @param string $file File to write the GraphViz markup to. * * @return string File to which the GraphViz markup was written, FALSE or * or PEAR_Error on failure. * @access public */ function saveParsedGraph($file = '') { $parsedGraph = $this->parse(); if (!empty($parsedGraph)) { if (empty($file)) { $file = System::mktemp('graph_'); } if ($fp = @fopen($file, 'wb')) { @fputs($fp, $parsedGraph); @fclose($fp); return $file; } } if ($this->_returnFalseOnError) { return false; } $error = PEAR::raiseError('Could not save graph'); return $error; }
/** * Build an extension from source. Runs "phpize" in the source * directory, but compiles in a temporary directory * (TMPDIR/pear-build-USER/PACKAGE-VERSION). * * @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or * a PEAR_PackageFile object * * @param mixed $callback callback function used to report output, * see PEAR_Builder::_runCommand for details * * @return array an array of associative arrays with built files, * format: * array( array( 'file' => '/path/to/ext.so', * 'php_api' => YYYYMMDD, * 'zend_mod_api' => YYYYMMDD, * 'zend_ext_api' => YYYYMMDD ), * ... ) * * @access public * * @see PEAR_Builder::_runCommand */ function build($descfile, $callback = null) { if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php(.+)?$/', $this->config->get('php_bin'), $matches)) { if (isset($matches[2]) && strlen($matches[2]) && trim($matches[2]) != trim($this->config->get('php_prefix'))) { $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . ' appears to have a prefix ' . $matches[2] . ', but' . ' config variable php_prefix does not match'); } if (isset($matches[3]) && strlen($matches[3]) && trim($matches[3]) != trim($this->config->get('php_suffix'))) { $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . ' appears to have a suffix ' . $matches[3] . ', but' . ' config variable php_suffix does not match'); } } $this->current_callback = $callback; if (PEAR_OS == "Windows") { return $this->_build_win32($descfile, $callback); } if (PEAR_OS != 'Unix') { return $this->raiseError("building extensions not supported on this platform"); } if (is_object($descfile)) { $pkg = $descfile; $descfile = $pkg->getPackageFile(); if (is_a($pkg, 'PEAR_PackageFile_v1')) { $dir = dirname($descfile); } else { $dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName(); // automatically delete at session end $this->addTempFile($dir); } } else { $pf =& new PEAR_PackageFile($this->config); $pkg =& $pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); if (PEAR::isError($pkg)) { return $pkg; } $dir = dirname($descfile); } $old_cwd = getcwd(); if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { return $this->raiseError("could not chdir to {$dir}"); } $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); if (is_dir($vdir)) { chdir($vdir); } $dir = getcwd(); $this->log(2, "building in {$dir}"); putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH')); $err = $this->_runCommand($this->config->get('php_prefix') . "phpize" . $this->config->get('php_suffix'), array(&$this, 'phpizeCallback')); if (PEAR::isError($err)) { return $err; } if (!$err) { return $this->raiseError("`phpize' failed"); } // {{{ start of interactive part $configure_command = "{$dir}/configure"; $configure_options = $pkg->getConfigureOptions(); if ($configure_options) { foreach ($configure_options as $o) { $default = array_key_exists('default', $o) ? $o['default'] : null; list($r) = $this->ui->userDialog('build', array($o['prompt']), array('text'), array($default)); if (substr($o['name'], 0, 5) == 'with-' && ($r == 'yes' || $r == 'autodetect')) { $configure_command .= " --{$o['name']}"; } else { $configure_command .= " --{$o['name']}=" . trim($r); } } } // }}} end of interactive part // FIXME make configurable if (!($user = getenv('USER'))) { $user = '******'; } $tmpdir = $this->config->get('temp_dir'); $build_basedir = System::mktemp(" -t {$tmpdir} -d pear-build-{$user}"); $build_dir = "{$build_basedir}/{$vdir}"; $inst_dir = "{$build_basedir}/install-{$vdir}"; $this->log(1, "building in {$build_dir}"); if (is_dir($build_dir)) { System::rm(array('-rf', $build_dir)); } if (!System::mkDir(array('-p', $build_dir))) { return $this->raiseError("could not create build dir: {$build_dir}"); } $this->addTempFile($build_dir); if (!System::mkDir(array('-p', $inst_dir))) { return $this->raiseError("could not create temporary install dir: {$inst_dir}"); } $this->addTempFile($inst_dir); $make_command = getenv('MAKE') ? getenv('MAKE') : 'make'; $to_run = array($configure_command, $make_command, "{$make_command} INSTALL_ROOT=\"{$inst_dir}\" install", "find \"{$inst_dir}\" | xargs ls -dils"); if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) { return $this->raiseError("could not chdir to {$build_dir}"); } putenv('PHP_PEAR_VERSION=1.9.2'); foreach ($to_run as $cmd) { $err = $this->_runCommand($cmd, $callback); if (PEAR::isError($err)) { chdir($old_cwd); return $err; } if (!$err) { chdir($old_cwd); return $this->raiseError("`{$cmd}' failed"); } } if (!($dp = opendir("modules"))) { chdir($old_cwd); return $this->raiseError("no `modules' directory found"); } $built_files = array(); $prefix = exec($this->config->get('php_prefix') . "php-config" . $this->config->get('php_suffix') . " --prefix"); $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files); chdir($old_cwd); return $built_files; }
/** * @param string filename to download * @param string version/state * @param string original value passed to command-line * @param string|null preferred state (snapshot/devel/alpha/beta/stable) * Defaults to configuration preferred state * @return null|PEAR_Error|string * @access private */ function _downloadFile($pkgfile, $version, $origpkgfile, $state = null) { if (is_null($state)) { $state = $this->_preferredState; } // {{{ check the package filename, and whether it's already installed $need_download = false; if (preg_match('#^(http|ftp)://#', $pkgfile)) { $need_download = true; } elseif (!@is_file($pkgfile)) { if ($this->validPackageName($pkgfile)) { if ($this->_registry->packageExists($pkgfile)) { if (empty($this->_options['upgrade']) && empty($this->_options['force'])) { $errors[] = "{$pkgfile} already installed"; return; } } $pkgfile = $this->getPackageDownloadUrl($pkgfile, $version); $need_download = true; } else { if (strlen($pkgfile)) { $errors[] = "Could not open the package file: {$pkgfile}"; } else { $errors[] = "No package file given"; } return; } } // }}} // {{{ Download package ----------------------------------------------- if ($need_download) { $downloaddir = $this->_config->get('download_dir'); if (empty($downloaddir)) { if (PEAR::isError($downloaddir = System::mktemp('-d'))) { return $downloaddir; } $this->log(3, '+ tmp dir created at ' . $downloaddir); } $callback = $this->ui ? array(&$this, '_downloadCallback') : null; $this->pushErrorHandling(PEAR_ERROR_RETURN); $file = $this->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback); $this->popErrorHandling(); if (PEAR::isError($file)) { if ($this->validPackageName($origpkgfile)) { if (!PEAR::isError($info = $this->_remote->call('package.info', $origpkgfile))) { if (!count($info['releases'])) { return $this->raiseError('Package ' . $origpkgfile . ' has no releases'); } else { return $this->raiseError('No releases of preferred state "' . $state . '" exist for package ' . $origpkgfile . '. Use ' . $origpkgfile . '-state to install another' . ' state (like ' . $origpkgfile . '-beta)', PEAR_INSTALLER_ERROR_NO_PREF_STATE); } } else { return $pkgfile; } } else { return $this->raiseError($file); } } $pkgfile = $file; } // }}} return $pkgfile; }
function package($pkgfile = null, $compress = true) { // {{{ validate supplied package.xml file if (empty($pkgfile)) { $pkgfile = 'package.xml'; } // $this->pkginfo gets populated inside $pkginfo = $this->infoFromDescriptionFile($pkgfile); if (PEAR::isError($pkginfo)) { return $this->raiseError($pkginfo); } $pkgdir = dirname(realpath($pkgfile)); $pkgfile = basename($pkgfile); $errors = $warnings = array(); $this->validatePackageInfo($pkginfo, $errors, $warnings, $pkgdir); foreach ($warnings as $w) { $this->log(1, "Warning: {$w}"); } foreach ($errors as $e) { $this->log(0, "Error: {$e}"); } if (sizeof($errors) > 0) { return $this->raiseError('Errors in package'); } // }}} $pkgver = $pkginfo['package'] . '-' . $pkginfo['version']; // {{{ Create the package file list $filelist = array(); $i = 0; foreach ($pkginfo['filelist'] as $fname => $atts) { $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; if (!file_exists($file)) { return $this->raiseError("File does not exist: {$fname}"); } else { $filelist[$i++] = $file; if (empty($pkginfo['filelist'][$fname]['md5sum'])) { $md5sum = md5_file($file); $pkginfo['filelist'][$fname]['md5sum'] = $md5sum; } $this->log(2, "Adding file {$fname}"); } } // }}} // {{{ regenerate package.xml $new_xml = $this->xmlFromInfo($pkginfo); if (PEAR::isError($new_xml)) { return $this->raiseError($new_xml); } if (!($tmpdir = System::mktemp(array('-d')))) { return $this->raiseError("PEAR_Packager: mktemp failed"); } $newpkgfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; $np = @fopen($newpkgfile, 'wb'); if (!$np) { return $this->raiseError("PEAR_Packager: unable to rewrite {$pkgfile} as {$newpkgfile}"); } fwrite($np, $new_xml); fclose($np); // }}} // {{{ TAR the Package ------------------------------------------- $ext = $compress ? '.tgz' : '.tar'; $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; $tar =& new Archive_Tar($dest_package, $compress); $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors // ----- Creates with the package.xml file $ok = $tar->createModify(array($newpkgfile), '', $tmpdir); if (PEAR::isError($ok)) { return $this->raiseError($ok); } elseif (!$ok) { return $this->raiseError('PEAR_Packager: tarball creation failed'); } // ----- Add the content of the package if (!$tar->addModify($filelist, $pkgver, $pkgdir)) { return $this->raiseError('PEAR_Packager: tarball creation failed'); } $this->log(1, "Package {$dest_package} done"); if (file_exists("{$pkgdir}/CVS/Root")) { $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pkginfo['version']); $cvstag = "RELEASE_{$cvsversion}"; $this->log(1, "Tag the released code with `pear cvstag {$pkgfile}'"); $this->log(1, "(or set the CVS tag {$cvstag} by hand)"); } // }}} return $dest_package; }
/** * Installs the files within the package file specified. * * @param $pkgfile path to the package file * * @return array package info if successful, null if not */ function install($pkgfile, $options = array()) { // recognized options: // - force : force installation // - register-only : update registry but don't install files // - upgrade : upgrade existing install // - soft : fail silently // $php_dir = $this->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->registry =& new PEAR_Registry($php_dir); $this->installroot = $options['installroot']; } else { $registry =& $this->registry; $this->installroot = ''; } $need_download = false; // ==> XXX should be removed later on $flag_old_format = false; if (preg_match('#^(http|ftp)://#', $pkgfile)) { $need_download = true; } elseif (!@is_file($pkgfile)) { if ($this->validPackageName($pkgfile)) { if ($this->registry->packageExists($pkgfile) && empty($options['upgrade']) && empty($options['force'])) { return $this->raiseError("{$pkgfile} already installed"); } $pkgfile = $this->getPackageDownloadUrl($pkgfile); $need_download = true; } else { if (strlen($pkgfile)) { return $this->raiseError("Could not open the package file: {$pkgfile}"); } else { return $this->raiseError("No package file given"); } } } // Download package ----------------------------------------------- if ($need_download) { $downloaddir = $this->config->get('download_dir'); if (empty($downloaddir)) { if (PEAR::isError($downloaddir = System::mktemp('-d'))) { return $downloaddir; } $this->log(2, '+ tmp dir created at ' . $downloaddir); } $callback = $this->ui ? array(&$this, '_downloadCallback') : null; $file = $this->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback); if (PEAR::isError($file)) { return $this->raiseError($file); } $pkgfile = $file; } if (substr($pkgfile, -4) == '.xml') { $descfile = $pkgfile; } else { // Decompress pack in tmp dir ------------------------------------- // To allow relative package file names $oldcwd = getcwd(); if (@chdir(dirname($pkgfile))) { $pkgfile = getcwd() . DIRECTORY_SEPARATOR . basename($pkgfile); chdir($oldcwd); } if (PEAR::isError($tmpdir = System::mktemp('-d'))) { return $tmpdir; } $this->log(2, '+ tmp dir created at ' . $tmpdir); $tar = new Archive_Tar($pkgfile); if (!@$tar->extract($tmpdir)) { return $this->raiseError("unable to unpack {$pkgfile}"); } // ----- Look for existing package file $descfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; if (!is_file($descfile)) { // ----- Look for old package archive format // In this format the package.xml file was inside the // Package-n.n directory $dp = opendir($tmpdir); do { $pkgdir = readdir($dp); } while ($pkgdir[0] == '.'); $descfile = $tmpdir . DIRECTORY_SEPARATOR . $pkgdir . DIRECTORY_SEPARATOR . 'package.xml'; $flag_old_format = true; $this->log(0, "warning : you are using an archive with an old format"); } // <== XXX This part should be removed later on } if (!is_file($descfile)) { return $this->raiseError("no package.xml file after extracting the archive"); } // Parse xml file ----------------------------------------------- $pkginfo = $this->infoFromDescriptionFile($descfile); if (PEAR::isError($pkginfo)) { return $pkginfo; } $this->validatePackageInfo($pkginfo, $errors, $warnings); // XXX We allow warnings, do we have to do it? if (count($errors)) { if (empty($options['force'])) { return $this->raiseError("The following errors where found (use force option to install anyway):\n" . implode("\n", $errors)); } else { $this->log(0, "warning : the following errors were found:\n" . implode("\n", $errors)); } } $pkgname = $pkginfo['package']; // Check dependencies ------------------------------------------- if (isset($pkginfo['release_deps']) && empty($options['nodeps'])) { $error = $this->checkDeps($pkginfo); if ($error) { if (empty($options['soft'])) { $this->log(0, $error); } return $this->raiseError("{$pkgname}: dependencies failed"); } } if (empty($options['force'])) { // checks to do when not in "force" mode $test = $this->registry->checkFileMap($pkginfo); if (sizeof($test)) { $tmp = $test; foreach ($tmp as $file => $pkg) { if ($pkg == $pkgname) { unset($test[$file]); } } if (sizeof($test)) { $msg = "{$pkgname}: conflicting files found:\n"; $longest = max(array_map("strlen", array_keys($test))); $fmt = "%{$longest}s (%s)\n"; foreach ($test as $file => $pkg) { $msg .= sprintf($fmt, $file, $pkg); } return $this->raiseError($msg); } } } if (empty($options['upgrade'])) { // checks to do only when installing new packages if (empty($options['force']) && $this->registry->packageExists($pkgname)) { return $this->raiseError("{$pkgname} already installed"); } } else { // checks to do only when upgrading packages if (!$this->registry->packageExists($pkgname)) { return $this->raiseError("{$pkgname} not installed"); } $v1 = $this->registry->packageInfo($pkgname, 'version'); $v2 = $pkginfo['version']; $cmp = version_compare("{$v1}", "{$v2}", 'gt'); if (empty($options['force']) && !version_compare("{$v2}", "{$v1}", 'gt')) { return $this->raiseError("upgrade to a newer version ({$v2} is not newer than {$v1})"); } if (empty($options['register-only'])) { // when upgrading, remove old release's files first: if (PEAR::isError($err = $this->_deletePackageFiles($pkgname))) { return $this->raiseError($err); } } } // Copy files to dest dir --------------------------------------- // info from the package it self we want to access from _installFile $this->pkginfo =& $pkginfo; // used to determine whether we should build any C code $this->source_files = 0; if (empty($options['register-only'])) { if (!is_dir($php_dir)) { return $this->raiseError("no script destination directory\n", null, PEAR_ERROR_DIE); } // don't want strange characters $pkgname = ereg_replace('[^a-zA-Z0-9._]', '_', $pkginfo['package']); $pkgversion = ereg_replace('[^a-zA-Z0-9._\\-]', '_', $pkginfo['version']); $tmp_path = dirname($descfile); if (substr($pkgfile, -4) != '.xml') { $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkgversion; } // ==> XXX This part should be removed later on if ($flag_old_format) { $tmp_path = dirname($descfile); } // <== XXX This part should be removed later on foreach ($pkginfo['filelist'] as $file => $atts) { $this->expectError(PEAR_INSTALLER_FAILED); $res = $this->_installFile($file, $atts, $tmp_path); $this->popExpect(); if (PEAR::isError($res)) { if (empty($options['ignore-errors'])) { $this->rollbackFileTransaction(); return $this->raiseError($res); } else { $this->log(0, "Warning: " . $res->getMessage()); } } if ($res != PEAR_INSTALLER_OK) { // Do not register files that were not installed unset($pkginfo['filelist'][$file]); } } if ($this->source_files > 0 && empty($options['nobuild'])) { $this->log(1, "{$this->source_files} source files, building"); $bob =& new PEAR_Builder($this->ui); $bob->debug = $this->debug; $built = $bob->build($descfile, array(&$this, '_buildCallback')); if (PEAR::isError($built)) { $this->rollbackFileTransaction(); return $built; } foreach ($built as $ext) { $bn = basename($ext['file']); $this->log(2, "installing {$bn}"); $dest = $this->config->get('ext_dir') . DIRECTORY_SEPARATOR . $bn; $this->log(3, "+ cp {$ext['file']} ext_dir"); $copyto = $this->_prependPath($dest, $this->installroot); if (!@copy($ext['file'], $copyto)) { $this->rollbackFileTransaction(); return $this->raiseError("failed to copy {$bn} to {$copyto}"); } $pkginfo['filelist'][$bn] = array('role' => 'ext', 'installed_as' => $dest, 'php_api' => $ext['php_api'], 'zend_mod_api' => $ext['zend_mod_api'], 'zend_ext_api' => $ext['zend_ext_api']); } } } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); } // Register that the package is installed ----------------------- if (empty($options['upgrade'])) { // if 'force' is used, replace the info in registry if (!empty($options['force']) && $this->registry->packageExists($pkgname)) { $this->registry->deletePackage($pkgname); } $ret = $this->registry->addPackage($pkgname, $pkginfo); } else { $ret = $this->registry->updatePackage($pkgname, $pkginfo, false); } if (!$ret) { return null; } return $pkginfo; }
/** * Installs the files within the package file specified. * * @param string|PEAR_Downloader_Package $pkgfile path to the package file, * or a pre-initialized packagefile object * @param array $options * recognized options: * - installroot : optional prefix directory for installation * - force : force installation * - register-only : update registry but don't install files * - upgrade : upgrade existing install * - soft : fail silently * - nodeps : ignore dependency conflicts/missing dependencies * - alldeps : install all dependencies * - onlyreqdeps : install only required dependencies * * @return array|PEAR_Error package info if successful */ function install($pkgfile, $options = array()) { $this->_options = $options; $this->_registry =& $this->config->getRegistry(); if (is_object($pkgfile)) { $dlpkg =& $pkgfile; $pkg = $pkgfile->getPackageFile(); $pkgfile = $pkg->getArchiveFile(); $descfile = $pkg->getPackageFile(); } else { $descfile = $pkgfile; $pkg = $this->_parsePackageXml($descfile); if (PEAR::isError($pkg)) { return $pkg; } } $tmpdir = dirname($descfile); if (realpath($descfile) != realpath($pkgfile)) { // Use the temp_dir since $descfile can contain the download dir path $tmpdir = $this->config->get('temp_dir', null, 'pear.php.net'); $tmpdir = System::mktemp('-d -t "' . $tmpdir . '"'); $tar = new Archive_Tar($pkgfile); if (!$tar->extract($tmpdir)) { return $this->raiseError("unable to unpack {$pkgfile}"); } } $name = $pkg->getName(); $channel = $pkg->getChannel(); if (isset($options['installroot'])) { $this->config->setInstallRoot($options['installroot']); $this->_registry =& $this->config->getRegistry(); $installregistry =& $this->_registry; $this->installroot = ''; // all done automagically now $php_dir = $this->config->get('php_dir', null, $channel); } else { $this->config->setInstallRoot(false); $this->_registry =& $this->config->getRegistry(); if (isset($this->_options['packagingroot'])) { $regdir = $this->_prependPath($this->config->get('php_dir', null, 'pear.php.net'), $this->_options['packagingroot']); $metadata_dir = $this->config->get('metadata_dir', null, 'pear.php.net'); if ($metadata_dir) { $metadata_dir = $this->_prependPath($metadata_dir, $this->_options['packagingroot']); } $packrootphp_dir = $this->_prependPath($this->config->get('php_dir', null, $channel), $this->_options['packagingroot']); $installregistry =& new PEAR_Registry($regdir, false, false, $metadata_dir); if (!$installregistry->channelExists($channel, true)) { // we need to fake a channel-discover of this channel $chanobj = $this->_registry->getChannel($channel, true); $installregistry->addChannel($chanobj); } $php_dir = $packrootphp_dir; } else { $installregistry =& $this->_registry; $php_dir = $this->config->get('php_dir', null, $channel); } $this->installroot = ''; } // checks to do when not in "force" mode if (empty($options['force']) && (file_exists($this->config->get('php_dir')) && is_dir($this->config->get('php_dir')))) { $testp = $channel == 'pear.php.net' ? $name : array($channel, $name); $instfilelist = $pkg->getInstallationFileList(true); if (PEAR::isError($instfilelist)) { return $instfilelist; } // ensure we have the most accurate registry $installregistry->flushFileMap(); $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); if (PEAR::isError($test)) { return $test; } if (sizeof($test)) { $pkgs = $this->getInstallPackages(); $found = false; foreach ($pkgs as $param) { if ($pkg->isSubpackageOf($param)) { $found = true; break; } } if ($found) { // subpackages can conflict with earlier versions of parent packages $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); $tmp = $test; foreach ($tmp as $file => $info) { if (is_array($info)) { if (strtolower($info[1]) == strtolower($param->getPackage()) && strtolower($info[0]) == strtolower($param->getChannel())) { if (isset($parentreg['filelist'][$file])) { unset($parentreg['filelist'][$file]); } else { $pos = strpos($file, '/'); $basedir = substr($file, 0, $pos); $file2 = substr($file, $pos + 1); if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir) { unset($parentreg['filelist'][$file2]); } } unset($test[$file]); } } else { if (strtolower($param->getChannel()) != 'pear.php.net') { continue; } if (strtolower($info) == strtolower($param->getPackage())) { if (isset($parentreg['filelist'][$file])) { unset($parentreg['filelist'][$file]); } else { $pos = strpos($file, '/'); $basedir = substr($file, 0, $pos); $file2 = substr($file, $pos + 1); if (isset($parentreg['filelist'][$file2]['baseinstalldir']) && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir) { unset($parentreg['filelist'][$file2]); } } unset($test[$file]); } } } $pfk =& new PEAR_PackageFile($this->config); $parentpkg =& $pfk->fromArray($parentreg); $installregistry->updatePackage2($parentpkg); } if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { $tmp = $test; foreach ($tmp as $file => $info) { if (is_string($info)) { // pear.php.net packages are always stored as strings if (strtolower($info) == strtolower($param->getPackage())) { // upgrading existing package unset($test[$file]); } } } } if (count($test)) { $msg = "{$channel}/{$name}: conflicting files found:\n"; $longest = max(array_map("strlen", array_keys($test))); $fmt = "%{$longest}s (%s)\n"; foreach ($test as $file => $info) { if (!is_array($info)) { $info = array('pear.php.net', $info); } $info = $info[0] . '/' . $info[1]; $msg .= sprintf($fmt, $file, $info); } if (!isset($options['ignore-errors'])) { return $this->raiseError($msg); } if (!isset($options['soft'])) { $this->log(0, "WARNING: {$msg}"); } } } } $this->startFileTransaction(); // Figure out what channel to use and if the package exists or not $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($name, $channel); if (!$test) { $test = $installregistry->packageExists($name, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($name, $channel); } // checks to do only when installing new packages if (empty($options['upgrade']) && empty($options['soft'])) { if (empty($options['force']) && $test) { return $this->raiseError("{$channel}/{$name} is already installed"); } } else { // Upgrade if ($test) { $v1 = $installregistry->packageInfo($name, 'version', $usechannel); $v2 = $pkg->getVersion(); $cmp = version_compare("{$v1}", "{$v2}", 'gt'); if (empty($options['force']) && !version_compare("{$v2}", "{$v1}", 'gt')) { return $this->raiseError("upgrade to a newer version ({$v2} is not newer than {$v1})"); } } } // Do cleanups for upgrade and install, remove old release's files first if ($test && empty($options['register-only'])) { $err = $this->_deletePackageFiles($name, $usechannel, true); if (PEAR::isError($err)) { if (!isset($options['ignore-errors'])) { return $this->raiseError($err); } if (!isset($options['soft'])) { $this->log(0, 'WARNING: ' . $err->getMessage()); } } else { $backedup = $err; } } // Copy files to dest dir // info from the package it self we want to access from _installFile $this->pkginfo =& $pkg; // used to determine whether we should build any C code $this->source_files = 0; $savechannel = $this->config->get('default_channel'); if (empty($options['register-only']) && !is_dir($php_dir)) { if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { return $this->raiseError("no installation destination directory '{$php_dir}'\n"); } } if (substr($pkgfile, -4) != '.xml') { $tmpdir .= DIRECTORY_SEPARATOR . $name . '-' . $pkg->getVersion(); } $this->configSet('default_channel', $channel); // install files $filelist = $pkg->getInstallationFilelist(); if (PEAR::isError($filelist)) { return $filelist; } $p =& $installregistry->getPackage($name, $channel); $dirtree = empty($options['register-only']) && $p ? $p->getDirTree() : false; $pkg->resetFilelist(); $version = $installregistry->packageInfo($pkg->getPackage(), 'version', $pkg->getChannel()); $pkg->setLastInstalledVersion($version); foreach ($filelist as $file => $atts) { $this->expectError(PEAR_INSTALLER_FAILED); if ($pkg->getPackagexmlVersion() == '1.0') { $res = $this->_installFile($file, $atts, $tmpdir, $options); } else { $res = $this->_installFile2($pkg, $file, $atts, $tmpdir, $options); } $this->popExpect(); if (PEAR::isError($res)) { if (empty($options['ignore-errors'])) { $this->rollbackFileTransaction(); if ($res->getMessage() == "file does not exist") { $this->raiseError("file {$file} in package.xml does not exist"); } return $this->raiseError($res); } if (!isset($options['soft'])) { $this->log(0, "Warning: " . $res->getMessage()); } } $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { // Register files that were installed $pkg->installedFile($file, $atts); } } // compile and install source files if ($this->source_files > 0 && empty($options['nobuild'])) { if (!isset($options['__compile_configureoptions'])) { $options['__compile_configureoptions'] = array(); } if (PEAR::isError($err = $this->_compileSourceFiles($savechannel, $pkg, $options['__compile_configureoptions']))) { return $err; } } if (isset($backedup)) { $this->_removeBackups($backedup); } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); $this->configSet('default_channel', $savechannel); return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); } // See if package already exists $usechannel = $channel; if ($channel == 'pecl.php.net') { $test = $installregistry->packageExists($name, $channel); if (!$test) { $test = $installregistry->packageExists($name, 'pear.php.net'); $usechannel = 'pear.php.net'; } } else { $test = $installregistry->packageExists($name, $channel); } $ret = false; $installphase = 'install'; $oldversion = false; // Register that the package is installed if (empty($options['upgrade'])) { // if 'force' is used, replace the info in registry if (!empty($options['force']) && $test) { $oldversion = $installregistry->packageInfo($name, 'version', $usechannel); $installregistry->deletePackage($name, $usechannel); } $ret = $installregistry->addPackage2($pkg); } else { if ($dirtree) { $this->startFileTransaction(); // attempt to delete empty directories uksort($dirtree, array($this, '_sortDirs')); foreach ($dirtree as $dir => $notused) { $this->addFileOperation('rmdir', array($dir)); } $this->commitFileTransaction(); } // new: upgrade installs a package if it isn't installed if (!$test) { $ret = $installregistry->addPackage2($pkg); } else { if ($usechannel != $channel) { $installregistry->deletePackage($name, $usechannel); $ret = $installregistry->addPackage2($pkg); } else { $ret = $installregistry->updatePackage2($pkg); } $installphase = 'upgrade'; } } if (!$ret) { $this->configSet('default_channel', $savechannel); return $this->raiseError("Adding package {$channel}/{$name} to registry failed"); } // }}} $this->configSet('default_channel', $savechannel); if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist if (PEAR_Task_Common::hasPostinstallTasks()) { PEAR_Task_Common::runPostinstallTasks($installphase); } } return $pkg->toArray(true); }
function package($pkgfile = null, $compress = true) { if (empty($pkgfile)) { $pkgfile = 'package.xml'; } $pkginfo = $this->infoFromDescriptionFile($pkgfile); if (PEAR::isError($pkginfo)) { return $this->raiseError($pkginfo); } if (empty($pkginfo['version'])) { return $this->raiseError("No version info found in {$pkgfile}"); } // TMP DIR ------------------------------------------------- // We allow calls like "pear package /home/user/mypack/package.xml" $oldcwd = getcwd(); if (!@chdir(dirname($pkgfile))) { return $this->raiseError('Could not chdir to ' . dirname($pkgfile)); } $pkgfile = basename($pkgfile); if (@$pkginfo['release_state'] == 'snapshot' && empty($pkginfo['version'])) { $pkginfo['version'] = date('Ymd'); } // don't want strange characters $pkgname = preg_replace('/[^a-z0-9._]/i', '_', $pkginfo['package']); $pkgversion = preg_replace('/[^a-z0-9._-]/i', '_', $pkginfo['version']); $pkgver = $pkgname . '-' . $pkgversion; // ----- Create the package file list $filelist = array(); $i = 0; // Copy files ----------------------------------------------- foreach ($pkginfo['filelist'] as $fname => $atts) { if (!file_exists($fname)) { chdir($oldcwd); return $this->raiseError("File {$fname} does not exist"); } else { $filelist[$i++] = $fname; if (empty($pkginfo['filelist'][$fname]['md5sum'])) { $md5sum = md5_file($fname); $pkginfo['filelist'][$fname]['md5sum'] = $md5sum; } $this->log(2, "Adding file {$fname}"); } } $new_xml = $this->xmlFromInfo($pkginfo); if (PEAR::isError($new_xml)) { chdir($oldcwd); return $this->raiseError($new_xml); } if (!($tmpdir = System::mktemp('-t ' . getcwd() . ' -d'))) { return $this->raiseError("PEAR_Packager: mktemp failed"); } $newpkgfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; $np = @fopen($newpkgfile, "w"); if (!$np) { chdir($oldcwd); return $this->raiseError("PEAR_Packager: unable to rewrite {$pkgfile} as {$newpkgfile}"); } fwrite($np, $new_xml); fclose($np); // TAR the Package ------------------------------------------- $ext = $compress ? '.tgz' : '.tar'; $dest_package = $oldcwd . DIRECTORY_SEPARATOR . $pkgver . $ext; $tar =& new Archive_Tar($dest_package, $compress); $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors // ----- Creates with the package.xml file $ok = $tar->createModify($newpkgfile, '', $tmpdir); if (PEAR::isError($ok)) { chdir($oldcwd); return $this->raiseError($ok); } elseif (!$ok) { chdir($oldcwd); return $this->raiseError('PEAR_Packager: tarball creation failed'); } // ----- Add the content of the package if (!$tar->addModify($filelist, $pkgver)) { chdir($oldcwd); return $this->raiseError('PEAR_Packager: tarball creation failed'); } $this->log(1, "Package {$dest_package} done"); if (file_exists("CVS/Root")) { $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pkgversion); $cvstag = "RELEASE_{$cvsversion}"; $this->log(1, "Tag the released code with `pear cvstag {$pkgfile}'"); $this->log(1, "(or set the CVS tag {$cvstag} by hand)"); } chdir($oldcwd); return $dest_package; }
/** * Create and register a temporary directory. * * @param string $tmpdir (optional) Directory to use as tmpdir. * Will use system defaults (for example * /tmp or c:\windows\temp) if not specified * * @return string name of created directory * * @access public */ function mkTempDir($tmpdir = '') { if ($tmpdir) { $topt = array('-t', $tmpdir); } else { $topt = array(); } $topt = array_merge($topt, array('-d', 'pear')); if (!($tmpdir = System::mktemp($topt))) { return false; } $this->addTempFile($tmpdir); return $tmpdir; }
/** * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file. * @access public * @param string contents of package.xml file * @param int package state (one of PEAR_VALIDATE_* constants) * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @using Archive_Tar to extract the files * @using fromPackageFile() to load the package after the package.xml * file is extracted. */ function &fromTgzFile($file, $state) { if (!class_exists('Archive_Tar')) { require_once 'Archive/Tar.php'; } $tar = new Archive_Tar($file); if ($this->_debug <= 1) { $tar->pushErrorHandling(PEAR_ERROR_RETURN); } $content = $tar->listContent(); if ($this->_debug <= 1) { $tar->popErrorHandling(); } if (!is_array($content)) { if (is_string($file) && strlen($file < 255) && (!file_exists($file) || !@is_file($file))) { $ret = PEAR::raiseError("could not open file \"{$file}\""); return $ret; } $file = realpath($file); $ret = PEAR::raiseError("Could not get contents of package \"{$file}\"" . '. Invalid tgz file.'); return $ret; } if (!count($content) && !@is_file($file)) { $ret = PEAR::raiseError("could not open file \"{$file}\""); return $ret; } $xml = null; $origfile = $file; foreach ($content as $file) { $name = $file['filename']; if ($name == 'package2.xml') { // allow a .tgz to distribute both versions $xml = $name; break; } if ($name == 'package.xml') { $xml = $name; break; } elseif (preg_match('/package.xml$/', $name, $match)) { $xml = $name; break; } } $tmpdir = System::mktemp('-t "' . $this->_config->get('temp_dir') . '" -d pear'); if ($tmpdir === false) { $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); return $ret; } PEAR_PackageFile::addTempFile($tmpdir); $this->_extractErrors(); PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { $extra = implode("\n", $this->_extractErrors()); if ($extra) { $extra = ' ' . $extra; } PEAR::staticPopErrorHandling(); $ret = PEAR::raiseError('could not extract the package.xml file from "' . $origfile . '"' . $extra); return $ret; } PEAR::staticPopErrorHandling(); $ret =& PEAR_PackageFile::fromPackageFile("{$tmpdir}/{$xml}", $state, $origfile); return $ret; }
/** * Installs the files within the package file specified. * * @param string $pkgfile path to the package file * @param array $options * recognized options: * - installroot : optional prefix directory for installation * - force : force installation * - register-only : update registry but don't install files * - upgrade : upgrade existing install * - soft : fail silently * - nodeps : ignore dependency conflicts/missing dependencies * - alldeps : install all dependencies * - onlyreqdeps : install only required dependencies * * @return array|PEAR_Error package info if successful */ function install($pkgfile, $options = array()) { $php_dir = $this->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); // ==> XXX should be removed later on $flag_old_format = false; if (substr($pkgfile, -4) == '.xml') { $descfile = $pkgfile; } else { // {{{ Decompress pack in tmp dir ------------------------------------- // To allow relative package file names $pkgfile = realpath($pkgfile); if (PEAR::isError($tmpdir = System::mktemp('-d'))) { return $tmpdir; } $this->log(3, '+ tmp dir created at ' . $tmpdir); $tar = new Archive_Tar($pkgfile); if (!@$tar->extract($tmpdir)) { return $this->raiseError("unable to unpack {$pkgfile}"); } // {{{ Look for existing package file $descfile = $tmpdir . DIRECTORY_SEPARATOR . 'package.xml'; if (!is_file($descfile)) { // ----- Look for old package archive format // In this format the package.xml file was inside the // Package-n.n directory $dp = opendir($tmpdir); do { $pkgdir = readdir($dp); } while ($pkgdir[0] == '.'); $descfile = $tmpdir . DIRECTORY_SEPARATOR . $pkgdir . DIRECTORY_SEPARATOR . 'package.xml'; $flag_old_format = true; $this->log(0, "warning : you are using an archive with an old format"); } // }}} // <== XXX This part should be removed later on // }}} } if (!is_file($descfile)) { return $this->raiseError("no package.xml file after extracting the archive"); } // Parse xml file ----------------------------------------------- $pkginfo = $this->infoFromDescriptionFile($descfile); if (PEAR::isError($pkginfo)) { return $pkginfo; } $this->validatePackageInfo($pkginfo, $errors, $warnings); // XXX We allow warnings, do we have to do it? if (count($errors)) { if (empty($options['force'])) { return $this->raiseError("The following errors where found (use force option to install anyway):\n" . implode("\n", $errors)); } else { $this->log(0, "warning : the following errors were found:\n" . implode("\n", $errors)); } } $pkgname = $pkginfo['package']; // {{{ Check dependencies ------------------------------------------- if (isset($pkginfo['release_deps']) && empty($options['nodeps'])) { $dep_errors = ''; $error = $this->checkDeps($pkginfo, $dep_errors); if ($error == true) { if (empty($options['soft'])) { $this->log(0, substr($dep_errors, 1)); } return $this->raiseError("{$pkgname}: Dependencies failed"); } else { if (!empty($dep_errors)) { // Print optional dependencies if (empty($options['soft'])) { $this->log(0, $dep_errors); } } } } // }}} // {{{ checks to do when not in "force" mode if (empty($options['force'])) { $test = $this->registry->checkFileMap($pkginfo); if (sizeof($test)) { $tmp = $test; foreach ($tmp as $file => $pkg) { if ($pkg == $pkgname) { unset($test[$file]); } } if (sizeof($test)) { $msg = "{$pkgname}: conflicting files found:\n"; $longest = max(array_map("strlen", array_keys($test))); $fmt = "%{$longest}s (%s)\n"; foreach ($test as $file => $pkg) { $msg .= sprintf($fmt, $file, $pkg); } return $this->raiseError($msg); } } } // }}} $this->startFileTransaction(); if (empty($options['upgrade'])) { // checks to do only when installing new packages if (empty($options['force']) && $this->registry->packageExists($pkgname)) { return $this->raiseError("{$pkgname} already installed"); } } else { if ($this->registry->packageExists($pkgname)) { $v1 = $this->registry->packageInfo($pkgname, 'version'); $v2 = $pkginfo['version']; $cmp = version_compare("{$v1}", "{$v2}", 'gt'); if (empty($options['force']) && !version_compare("{$v2}", "{$v1}", 'gt')) { return $this->raiseError("upgrade to a newer version ({$v2} is not newer than {$v1})"); } if (empty($options['register-only'])) { // when upgrading, remove old release's files first: if (PEAR::isError($err = $this->_deletePackageFiles($pkgname))) { return $this->raiseError($err); } } } } // {{{ Copy files to dest dir --------------------------------------- // info from the package it self we want to access from _installFile $this->pkginfo =& $pkginfo; // used to determine whether we should build any C code $this->source_files = 0; if (empty($options['register-only'])) { if (!is_dir($php_dir)) { return $this->raiseError("no script destination directory\n", null, PEAR_ERROR_DIE); } $tmp_path = dirname($descfile); if (substr($pkgfile, -4) != '.xml') { $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkginfo['version']; } // ==> XXX This part should be removed later on if ($flag_old_format) { $tmp_path = dirname($descfile); } // <== XXX This part should be removed later on // {{{ install files foreach ($pkginfo['filelist'] as $file => $atts) { $this->expectError(PEAR_INSTALLER_FAILED); $res = $this->_installFile($file, $atts, $tmp_path, $options); $this->popExpect(); if (PEAR::isError($res)) { if (empty($options['ignore-errors'])) { $this->rollbackFileTransaction(); if ($res->getMessage() == "file does not exist") { $this->raiseError("file {$file} in package.xml does not exist"); } return $this->raiseError($res); } else { $this->log(0, "Warning: " . $res->getMessage()); } } if ($res != PEAR_INSTALLER_OK) { // Do not register files that were not installed unset($pkginfo['filelist'][$file]); } } // }}} // {{{ compile and install source files if ($this->source_files > 0 && empty($options['nobuild'])) { $this->log(1, "{$this->source_files} source files, building"); $bob =& new PEAR_Builder($this->ui); $bob->debug = $this->debug; $built = $bob->build($descfile, array(&$this, '_buildCallback')); if (PEAR::isError($built)) { $this->rollbackFileTransaction(); return $built; } $this->log(1, "\nBuild process completed successfully"); foreach ($built as $ext) { $bn = basename($ext['file']); list($_ext_name, ) = explode('.', $bn); if (extension_loaded($_ext_name)) { $this->raiseError("Extension '{$_ext_name}' already loaded. Please unload it " . "in your php.ini file prior to install or upgrade it."); } $dest = $this->config->get('ext_dir') . DIRECTORY_SEPARATOR . $bn; $this->log(1, "Installing '{$bn}' at ext_dir ({$dest})"); $this->log(3, "+ cp {$ext['file']} ext_dir ({$dest})"); $copyto = $this->_prependPath($dest, $this->installroot); if (!@copy($ext['file'], $copyto)) { $this->rollbackFileTransaction(); return $this->raiseError("failed to copy {$bn} to {$copyto}"); } $pkginfo['filelist'][$bn] = array('role' => 'ext', 'installed_as' => $dest, 'php_api' => $ext['php_api'], 'zend_mod_api' => $ext['zend_mod_api'], 'zend_ext_api' => $ext['zend_ext_api']); } } // }}} } if (!$this->commitFileTransaction()) { $this->rollbackFileTransaction(); return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); } // }}} $ret = false; // {{{ Register that the package is installed ----------------------- if (empty($options['upgrade'])) { // if 'force' is used, replace the info in registry if (!empty($options['force']) && $this->registry->packageExists($pkgname)) { $this->registry->deletePackage($pkgname); } $ret = $this->registry->addPackage($pkgname, $pkginfo); } else { // new: upgrade installs a package if it isn't installed if (!$this->registry->packageExists($pkgname)) { $ret = $this->registry->addPackage($pkgname, $pkginfo); } else { $ret = $this->registry->updatePackage($pkgname, $pkginfo, false); } } if (!$ret) { return $this->raiseError("Adding package {$pkgname} to registry failed"); } // }}} return $pkginfo; }
function _detectGlibcVersion() { // Use glibc's <features.h> header file to // get major and minor version number: include_once "System.php"; $tmpfile = System::mktemp("glibctest"); $fp = fopen($tmpfile, "w"); fwrite($fp, "#include <features.h>\n__GLIBC__ __GLIBC_MINOR__\n"); fclose($fp); $cpp = popen("/usr/bin/cpp {$tmpfile}", "r"); $major = $minor = 0; while ($line = fgets($cpp, 1024)) { if ($line[0] == '#' || trim($line) == '') { continue; } if (list($major, $minor) = explode(' ', trim($line))) { break; } } pclose($cpp); unlink($tmpfile); if (!($major && $minor) && is_link('/lib/libc.so.6')) { // Let's try reading the libc.so.6 symlink if (ereg('^libc-([.*])\\.so$', basename(readlink('/lib/libc.so.6')), $matches)) { list($major, $minor) = explode('.', $matches); } } if (!($major && $minor)) { return ''; } return "glibc{$major}.{$minor}"; }
} if (empty($test_dir)) { $config->set('test_dir', $with_dir . $ds . 'test', 'default'); } if (empty($www_dir)) { $config->set('www_dir', $with_dir . $ds . 'htdocs', 'default'); } if (empty($cfg_dir)) { $config->set('cfg_dir', $with_dir . $ds . 'cfg', 'default'); } if (empty($man_dir)) { $config->set('man_dir', $with_dir . $ds . 'local' . $ds . 'man', 'default'); } if (!is_writable($config->get('cache_dir'))) { include_once 'System.php'; $cdir = System::mktemp(array('-d', 'pear')); if (PEAR::isError($cdir)) { $ui->outputData("[PEAR] cannot make new temporary directory: " . $cdir); die(1); } $oldcachedir = $config->get('cache_dir'); $config->set('cache_dir', $cdir); } } // PHP executable if (!empty($php_bin)) { $config->set('php_bin', $php_bin); } // PHP prefix if (isset($prefix)) { if ($prefix != 'a') {
function doSign($command, $options, $params) { // should move most of this code into PEAR_Packager // so it'll be easy to implement "pear package --sign" if (count($params) !== 1) { return $this->raiseError("bad parameter(s), try \"help {$command}\""); } require_once 'System.php'; require_once 'Archive/Tar.php'; if (!file_exists($params[0])) { return $this->raiseError("file does not exist: {$params['0']}"); } $obj = $this->getPackageFile($this->config, $this->_debug); $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); if (PEAR::isError($info)) { return $this->raiseError($info); } $tar = new Archive_Tar($params[0]); $tmpdir = System::mktemp('-d pearsign'); if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) { return $this->raiseError("failed to extract tar file"); } if (file_exists("{$tmpdir}/package.sig")) { return $this->raiseError("package already signed"); } $packagexml = 'package.xml'; if (file_exists("{$tmpdir}/package2.xml")) { $packagexml = 'package2.xml'; } if (file_exists("{$tmpdir}/package.sig")) { unlink("{$tmpdir}/package.sig"); } if (!file_exists("{$tmpdir}/{$packagexml}")) { return $this->raiseError("Extracted file {$tmpdir}/{$packagexml} not found."); } $input = $this->ui->userDialog($command, array('GnuPG Passphrase'), array('password')); if (!isset($input[0])) { //use empty passphrase $input[0] = ''; } $devnull = isset($options['verbose']) ? '' : ' 2>/dev/null'; $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output {$tmpdir}/package.sig {$tmpdir}/{$packagexml}" . $devnull, "w"); if (!$gpg) { return $this->raiseError("gpg command failed"); } fwrite($gpg, "{$input['0']}\n"); if (pclose($gpg) || !file_exists("{$tmpdir}/package.sig")) { return $this->raiseError("gpg sign failed"); } if (!$tar->addModify("{$tmpdir}/package.sig", '', $tmpdir)) { return $this->raiseError('failed adding signature to file'); } $this->ui->outputData("Package signed.", $command); return true; }
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; }
function _parsePackageXml(&$descfile, &$tmpdir) { if (substr($descfile, -4) == '.xml') { $tmpdir = false; } else { // {{{ Decompress pack in tmp dir ------------------------------------- // To allow relative package file names $descfile = realpath($descfile); if (PEAR::isError($tmpdir = System::mktemp('-d'))) { return $tmpdir; } $this->log(3, '+ tmp dir created at ' . $tmpdir); // }}} } // Parse xml file ----------------------------------------------- $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $p =& $pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); PEAR::staticPopErrorHandling(); if (PEAR::isError($p)) { if (is_array($p->getUserInfo())) { foreach ($p->getUserInfo() as $err) { $loglevel = $err['level'] == 'error' ? 0 : 1; if (!isset($this->_options['soft'])) { $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); } } } return $this->raiseError('Installation failed: invalid package file'); } else { $descfile = $p->getPackageFile(); } return $p; }
/** * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini * @return true|PEAR_Error */ function readFTPConfigFile($path) { do { // poor man's try if (!class_exists('PEAR_FTP')) { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { require_once 'PEAR/FTP.php'; } } if (!class_exists('PEAR_FTP')) { return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); } $this->_ftp =& new PEAR_FTP(); $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); $e = $this->_ftp->init($path); if (PEAR::isError($e)) { $this->_ftp->popErrorHandling(); return $e; } $tmp = System::mktemp('-d'); PEAR_Common::addTempFile($tmp); $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . 'pear.ini', false, FTP_BINARY); if (PEAR::isError($e)) { $this->_ftp->popErrorHandling(); return $e; } PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); $this->_ftp->disconnect(); $this->_ftp->popErrorHandling(); $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; $e = $this->readConfigFile(null, 'ftp'); if (PEAR::isError($e)) { return $e; } $fail = array(); foreach ($this->configuration_info as $key => $val) { if (in_array($this->getGroup($key), array('File Locations', 'File Locations (Advanced)')) && $this->getType($key) == 'directory') { // any directory configs must be set for this to work if (!isset($this->configuration['ftp'][$key])) { $fail[] = $key; } } } if (!count($fail)) { return true; } $fail = '"' . implode('", "', $fail) . '"'; unset($this->files['ftp']); unset($this->configuration['ftp']); return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . 'directory configuration variables. These variables were not set: ' . $fail); } while (false); // poor man's catch unset($this->files['ftp']); return PEAR::raiseError('no remote host specified'); }
function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml') { if (!$this->_packagefile->validate($state)) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml', null, null, null, $this->_packagefile->getValidationWarnings()); } if ($where === null) { if (!($where = System::mktemp(array('-d')))) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed'); } } elseif (!@System::mkDir(array('-p', $where))) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' . ' not be created'); } $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; $np = @fopen($newpkgfile, 'wb'); if (!$np) { return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' . "{$name} as {$newpkgfile}"); } fwrite($np, $this->toXml($state)); fclose($np); return $newpkgfile; }
function doBundle($command, $options, $params) { if (empty($this->installer)) { $this->installer =& new PEAR_Installer($this->ui); } $installer =& $this->installer; if (sizeof($params) < 1) { return $this->raiseError("Please supply the package you want to bundle"); } $pkgfile = $params[0]; $need_download = false; if (preg_match('#^(http|ftp)://#', $pkgfile)) { $need_download = true; } elseif (!@is_file($pkgfile)) { if ($installer->validPackageName($pkgfile)) { $pkgfile = $installer->getPackageDownloadUrl($pkgfile); $need_download = true; } else { if (strlen($pkgfile)) { return $this->raiseError("Could not open the package file: {$pkgfile}"); } else { return $this->raiseError("No package file given"); } } } // Download package ----------------------------------------------- if ($need_download) { $downloaddir = $installer->config->get('download_dir'); if (empty($downloaddir)) { if (PEAR::isError($downloaddir = System::mktemp('-d'))) { return $downloaddir; } $installer->log(2, '+ tmp dir created at ' . $downloaddir); } $callback = $this->ui ? array(&$installer, '_downloadCallback') : null; $file = $installer->downloadHttp($pkgfile, $this->ui, $downloaddir, $callback); if (PEAR::isError($file)) { return $this->raiseError($file); } $pkgfile = $file; } // Parse xml file ----------------------------------------------- $pkginfo = $installer->infoFromTgzFile($pkgfile); if (PEAR::isError($pkginfo)) { return $this->raiseError($pkginfo); } $installer->validatePackageInfo($pkginfo, $errors, $warnings); // XXX We allow warnings, do we have to do it? if (count($errors)) { if (empty($options['force'])) { return $this->raiseError("The following errors where found:\n" . implode("\n", $errors)); } else { $this->log(0, "warning : the following errors were found:\n" . implode("\n", $errors)); } } $pkgname = $pkginfo['package']; // Unpacking ------------------------------------------------- if (isset($options['destination'])) { if (!is_dir($options['destination'])) { System::mkdir('-p ' . $options['destination']); } $dest = realpath($options['destination']); } else { $pwd = getcwd(); if (is_dir($pwd . DIRECTORY_SEPARATOR . 'ext')) { $dest = $pwd . DIRECTORY_SEPARATOR . 'ext'; } else { $dest = $pwd; } } $dest .= DIRECTORY_SEPARATOR . $pkgname; $orig = $pkgname . '-' . $pkginfo['version']; $tar = new Archive_Tar($pkgfile); if (!@$tar->extractModify($dest, $orig)) { return $this->raiseError("unable to unpack {$pkgfile}"); } $this->ui->outputData("Package ready at '{$dest}'"); // }}} }
/** * Retrieve the directory that downloads will happen in * @access private * @return string */ function getDownloadDir() { if (isset($this->_downloadDir)) { return $this->_downloadDir; } $downloaddir = $this->config->get('download_dir'); if (empty($downloaddir) || is_dir($downloaddir) && !is_writable($downloaddir)) { if (is_dir($downloaddir) && !is_writable($downloaddir)) { $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . '" is not writeable. Change download_dir config variable to ' . 'a writeable dir to avoid this warning'); } if (!class_exists('System')) { require_once 'System.php'; } if (PEAR::isError($downloaddir = System::mktemp('-d'))) { return $downloaddir; } $this->log(3, '+ tmp dir created at ' . $downloaddir); } if (!is_writable($downloaddir)) { if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || !is_writable($downloaddir)) { return PEAR::raiseError('download directory "' . $downloaddir . '" is not writeable. Change download_dir config variable to ' . 'a writeable dir'); } } return $this->_downloadDir = $downloaddir; }
function doUpdate($command, $options, $params) { if (!class_exists('System')) { require_once 'System.php'; } $tmpdir = System::mktemp(array('-d')); $reg =& $this->config->getRegistry(); if (sizeof($params) != 1) { return $this->raiseError("No channel file specified"); } $lastmodified = false; if ((!file_exists($params[0]) || is_dir($params[0])) && $reg->channelExists(strtolower($params[0]))) { $c = $reg->getChannel(strtolower($params[0])); $this->ui->outputData('Retrieving channel.xml from remote server'); $dl =& $this->getDownloader(array()); // if force is specified, use a timestamp of "1" to force retrieval $lastmodified = isset($options['force']) ? false : $c->lastModified(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $contents = $dl->downloadHttp('http://' . $c->getName() . '/channel.xml', $this->ui, $tmpdir, null, $lastmodified); PEAR::staticPopErrorHandling(); if (PEAR::isError($contents)) { return $this->raiseError('Cannot retrieve channel.xml for channel "' . $c->getName() . '"'); } list($contents, $lastmodified) = $contents; if (!$contents) { $this->ui->outputData("Channel {$params['0']} channel.xml is up to date"); return; } $contents = implode('', file($contents)); if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $channel = new PEAR_ChannelFile(); $channel->fromXmlString($contents); if (!$channel->getErrors()) { // security check: is the downloaded file for the channel we got it from? if (strtolower($channel->getName()) != strtolower($c->getName())) { if (isset($options['force'])) { $this->ui->log(0, 'WARNING: downloaded channel definition file' . ' for channel "' . $channel->getName() . '" from channel "' . strtolower($c->getName()) . '"'); } else { return $this->raiseError('ERROR: downloaded channel definition file' . ' for channel "' . $channel->getName() . '" from channel "' . strtolower($c->getName()) . '"'); } } } } else { if (strpos($params[0], '://')) { $dl =& $this->getDownloader(); PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $loc = $dl->downloadHttp($params[0], $this->ui, $tmpdir, null, $lastmodified); PEAR::staticPopErrorHandling(); if (PEAR::isError($loc)) { return $this->raiseError("Cannot open " . $params[0]); } else { list($loc, $lastmodified) = $loc; $contents = implode('', file($loc)); } } else { $fp = @fopen($params[0], 'r'); if (!$fp) { return $this->raiseError("Cannot open " . $params[0]); } $contents = ''; while (!feof($fp)) { $contents .= fread($fp, 1024); } fclose($fp); } if (!class_exists('PEAR_ChannelFile')) { require_once 'PEAR/ChannelFile.php'; } $channel = new PEAR_ChannelFile(); $channel->fromXmlString($contents); } $exit = false; if (count($errors = $channel->getErrors(true))) { foreach ($errors as $error) { $this->ui->outputData(ucfirst($error['level'] . ': ' . $error['message'])); if (!$exit) { $exit = $error['level'] == 'error' ? true : false; } } if ($exit) { return $this->raiseError('Invalid channel.xml file'); } } if (!$reg->channelExists($channel->getName())) { return $this->raiseError('Error: Channel "' . $channel->getName() . '" does not exist, use channel-add to add an entry'); } $ret = $reg->updateChannel($channel, $lastmodified); if (PEAR::isError($ret)) { return $ret; } if (!$ret) { return $this->raiseError('Updating Channel "' . $channel->getName() . '" in registry failed'); } $this->config->setChannels($reg->listChannels()); $this->config->writeConfigFile(); $this->ui->outputData('Update of Channel "' . $channel->getName() . '" succeeded'); }