Skip to content

Commit

Permalink
- remove the xml parser code (use PEAR_Common::infoFromDescFile)
Browse files Browse the repository at this point in the history
- 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
tvvcox committed Jul 18, 2001
1 parent 97c0042 commit 65af935
Showing 1 changed file with 159 additions and 40 deletions.
199 changes: 159 additions & 40 deletions pear/PEAR/Installer.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]>
*/
Expand Down Expand Up @@ -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);
}
Expand All @@ -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()
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -446,7 +565,7 @@ function charHandler($xp, $data)
break;
}
}

*/
// }}}

// {{{ classesDeclaredBy()
Expand Down

0 comments on commit 65af935

Please sign in to comment.