forked from php/php-src
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- remove the xml parser code (use PEAR_Common::infoFromDescFile)
- added the new package.xml Dir tag support - killed many bugs and warnings (as it is quite usable yet, work is still in progress)
- Loading branch information
Showing
1 changed file
with
159 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,16 +14,23 @@ | |
// | [email protected] so we can mail you a copy immediately. | | ||
// +----------------------------------------------------------------------+ | ||
// | Authors: Stig Bakken <[email protected]> | | ||
// | | | ||
// | Tomas V.V.Cox <[email protected]> | | ||
// +----------------------------------------------------------------------+ | ||
// | ||
// $Id$ | ||
|
||
require_once "PEAR/Common.php"; | ||
|
||
/** | ||
* Administration class used to install PEAR packages and maintain the | ||
* installed package database. | ||
* | ||
* TODO: | ||
* - move the package db handler methods to its own class. | ||
* - install also the package.xml? | ||
* - remove unneeded code | ||
* - only decrompress pack once | ||
* | ||
* @since PHP 4.0.2 | ||
* @author Stig Bakken <[email protected]> | ||
*/ | ||
|
@@ -76,18 +83,18 @@ function PEAR_Installer($phpdir = PEAR_INSTALL_DIR, | |
$this->extdir = $extdir; | ||
$this->docdir = $docdir; | ||
$this->statedir = "/var/lib/php"; // XXX FIXME Windows | ||
$this->loadPackageList("$this->statedir/packages.lst"); | ||
} | ||
|
||
// }}} | ||
// {{{ destructor | ||
|
||
function _PEAR_Installer() | ||
{ | ||
chdir($this->pwd); | ||
if ($this->tmpdir && is_dir($this->tmpdir)) { | ||
system("rm -rf $this->tmpdir"); // XXX FIXME Windows | ||
} | ||
if ($this->pkglist_fp && is_resource($this->pkglist_fp)) { | ||
if (isset($this->pkglist_fp) && is_resource($this->pkglist_fp)) { | ||
flock($this->pkglist_fp, LOCK_UN); | ||
fclose($this->pkglist_fp); | ||
} | ||
|
@@ -98,36 +105,6 @@ function _PEAR_Installer() | |
|
||
// }}} | ||
|
||
// {{{ mkDirHier() | ||
|
||
function mkDirHier($dir) | ||
{ | ||
$dirstack = array(); | ||
while (!@is_dir($dir) && $dir != DIRECTORY_SEPARATOR) { | ||
array_unshift($dirstack, $dir); | ||
$dir = dirname($dir); | ||
} | ||
while ($newdir = array_shift($dirstack)) { | ||
if (mkdir($newdir, 0777)) { | ||
$this->log(1, "created dir $newdir"); | ||
} else { | ||
return $this->raiseError("mkdir($newdir) failed"); | ||
} | ||
} | ||
} | ||
|
||
// }}} | ||
// {{{ log() | ||
|
||
function log($level, $msg) | ||
{ | ||
if ($this->debug >= $level) { | ||
print "$msg\n"; | ||
} | ||
} | ||
|
||
// }}} | ||
|
||
// {{{ lockPackageList() | ||
|
||
function lockPackageList() | ||
|
@@ -234,7 +211,151 @@ function updatePackageListFrom($file) | |
* | ||
* @return bool true if successful, false if not | ||
*/ | ||
|
||
function install($pkgfile) | ||
{ | ||
// XXX FIXME Add here code to manage packages database | ||
//$this->loadPackageList("$this->statedir/packages.lst"); | ||
$this->pwd = getcwd(); | ||
$need_download = false; | ||
if (preg_match('#^(http|ftp)://#', $pkgfile)) { | ||
$need_download = true; | ||
} elseif (!@is_file($pkgfile)) { | ||
return $this->raiseError("$pkgfile: no such file"); | ||
} | ||
// Download package ----------------------------------------------- | ||
if ($need_download) { | ||
$file = basename($pkgfile); | ||
// XXX FIXME use ??? on Windows, use $TMPDIR on unix (use tmpnames?) | ||
$downloaddir = '/tmp/pearinstall'; | ||
if (!$this->mkDirHier($downloaddir)) { | ||
return $this->raiseError("Failed to create tmp dir: $downloaddir"); | ||
} | ||
$downloadfile = $downloaddir.DIRECTORY_SEPARATOR.$file; | ||
$this->log(1, "downloading $pkgfile ..."); | ||
if (!$fp = @fopen($pkgfile, 'r')) { | ||
return $this->raiseError("$pkgfile: failed to download ($php_errormsg)"); | ||
} | ||
if (!$wp = @fopen($downloadfile, 'w')) { | ||
return $this->raiseError("$downloadfile: write failed ($php_errormsg)"); | ||
} | ||
$this->addTempFile($downloadfile); | ||
$bytes = 0; | ||
while ($data = @fread($fp, 16384)) { | ||
$bytes += strlen($data); | ||
if (!@fwrite($wp, $data)) { | ||
return $this->raiseError("$downloadfile: write failed ($php_errormsg)"); | ||
} | ||
} | ||
$pkgfile = $downloadfile; | ||
fclose($fp); | ||
fclose($wp); | ||
$this->log(1, '...done: ' . number_format($bytes, 0, '', ',') . ' bytes'); | ||
} | ||
// Test for package.xml ------------------------------------------- | ||
// XXX FIXME only decompress once | ||
$fp = popen("gzip -dc $pkgfile | tar -tf -", 'r'); | ||
if (!$fp) { | ||
return $this->raiseError("Unable to examine $pkgfile (gzip or tar failed)"); | ||
} | ||
while ($line = fgets($fp, 4096)) { | ||
$line = rtrim($line); | ||
if (preg_match('!^[^/]+/package.xml$!', $line)) { | ||
if (isset($descfile)) { | ||
return $this->raiseError("Invalid package: multiple package.xml files at depth one!"); | ||
} | ||
$descfile = $line; | ||
} | ||
} | ||
pclose($fp); | ||
if (!$descfile) { | ||
return $this->raiseError("Invalid package: no package.xml file found!"); | ||
} | ||
|
||
// Decompress pack in tmp dir ------------------------------------- | ||
// XXX FIXME Windows | ||
$this->tmpdir = tempnam("/tmp", "pear"); | ||
unlink($this->tmpdir); | ||
if (!mkdir($this->tmpdir, 0755)) { | ||
return $this->raiseError("Unable to create temporary directory $this->tmpdir."); | ||
} else { | ||
$this->log(2, '...tmp dir created at ' . $this->tmpdir); | ||
} | ||
$this->addTempFile($this->tmpdir); | ||
|
||
|
||
// XXX FIXME Windows should check for drive | ||
if (substr($pkgfile, 0, 1) == DIRECTORY_SEPARATOR) { | ||
$pkgfilepath = $pkgfile; | ||
} else { | ||
$pkgfilepath = $this->pwd . DIRECTORY_SEPARATOR . $pkgfile; | ||
} | ||
|
||
if (!chdir($this->tmpdir)) { | ||
return $this->raiseError("Unable to chdir to $this->tmpdir."); | ||
} | ||
// XXX FIXME Windows | ||
system("gzip -dc $pkgfilepath | tar -xf -"); | ||
$this->log(2, "launched command: gzip -dc $pkgfilepath | tar -xf -"); | ||
if (!is_file($descfile)) { | ||
$this->log(2, "No desc file found: $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; | ||
} | ||
|
||
// Copy files to dest dir --------------------------------------- | ||
if (!is_dir($this->phpdir)) { | ||
return $this->raiseError("No script destination directory found\n", | ||
null, PEAR_ERROR_DIE); | ||
} | ||
foreach ($pkginfo['filelist'] as $fname => $atts) { | ||
$dest_dir = $this->phpdir . DIRECTORY_SEPARATOR . dirname($fname); | ||
$fname = dirname($descfile) . DIRECTORY_SEPARATOR . $fname; | ||
$this->_copyFile($fname, $dest_dir, $atts); | ||
} | ||
return true; | ||
} | ||
|
||
function _copyFile($file, $dest_dir, $atts) | ||
{ | ||
$type = strtolower($atts["Role"]); | ||
switch ($type) { | ||
case "test": | ||
// don't install test files for now | ||
$this->log(2, "+ Test file $file won't be installed yet"); | ||
return true; | ||
break; | ||
case 'doc': | ||
case 'php': | ||
default: | ||
$dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); | ||
break; | ||
} | ||
if (!@is_dir($dest_dir)) { | ||
if (!$this->mkDirHier($dest_dir)) { | ||
$this->log(0, "failed to mkdir $dest_dir"); | ||
return false; | ||
} | ||
$this->log(2, "+ created dir $dest_dir"); | ||
} | ||
if (!@copy($file, $dest_file)) { | ||
$this->log(0, "failed to copy $file to $dest_file"); | ||
return false; | ||
} | ||
$this->log(2, "+ copy $file to $dest_file"); | ||
// FIXME Update Package database here | ||
//$this->updatePackageListFrom("$d/$file"); | ||
$this->log(1, "installed file $dest_file"); | ||
return true; | ||
} | ||
|
||
/* REMOVEME: This is the old code | ||
function _install($pkgfile) | ||
{ | ||
if (preg_match('#^(http|ftp)://#', $pkgfile)) { | ||
$need_download = true; | ||
|
@@ -356,12 +477,10 @@ function startHandler($xp, $name, $attribs) | |
$this->current_attributes = $attribs; | ||
switch ($name) { | ||
case "Package": | ||
/* | ||
if (strtolower($attribs["Type"]) != "binary") { | ||
return $this->raiseError("Invalid package: only binary packages supported yet."); | ||
} | ||
$this->pkginfo['pkgtype'] = strtolower($attribs["Type"]); | ||
*/ | ||
//if (strtolower($attribs["Type"]) != "binary") { | ||
// return $this->raiseError("Invalid package: only binary packages supported yet."); | ||
//} | ||
//$this->pkginfo['pkgtype'] = strtolower($attribs["Type"]); | ||
break; | ||
} | ||
} | ||
|
@@ -446,7 +565,7 @@ function charHandler($xp, $data) | |
break; | ||
} | ||
} | ||
|
||
*/ | ||
// }}} | ||
|
||
// {{{ classesDeclaredBy() | ||
|