!C99Shell v. 1.0 pre-release build #13!

Software: Apache. PHP/5.5.15 

uname -a: Windows NT SVR-DMZ 6.1 build 7600 (Windows Server 2008 R2 Enterprise Edition) i586 

SYSTEM 

Safe-mode: OFF (not secure)

C:\dmz\php\pear\PEAR\   drwxrwxrwx
Free 4.13 GB of 39.52 GB (10.45%)
Detected drives: [ a ] [ c ] [ d ] [ e ] [ f ]
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     Installer.php (68.81 KB)      -rw-rw-rw-
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php
/**
 * PEAR_Installer
 *
 * PHP versions 4 and 5
 *
 * @category   pear
 * @package    PEAR
 * @author     Stig Bakken <ssb@php.net>
 * @author     Tomas V.V. Cox <cox@idecnet.com>
 * @author     Martin Jansen <mj@php.net>
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    CVS: $Id: Installer.php 313024 2011-07-06 19:51:24Z dufuz $
 * @link       http://pear.php.net/package/PEAR
 * @since      File available since Release 0.1
 */

/**
 * Used for installation groups in package.xml 2.0 and platform exceptions
 */
require_once 'OS/Guess.php';
require_once 
'PEAR/Downloader.php';

define('PEAR_INSTALLER_NOBINARY', -240);
/**
 * Administration class used to install PEAR packages and maintain the
 * installed package database.
 *
 * @category   pear
 * @package    PEAR
 * @author     Stig Bakken <ssb@php.net>
 * @author     Tomas V.V. Cox <cox@idecnet.com>
 * @author     Martin Jansen <mj@php.net>
 * @author     Greg Beaver <cellog@php.net>
 * @copyright  1997-2009 The Authors
 * @license    http://opensource.org/licenses/bsd-license.php New BSD License
 * @version    Release: 1.9.4
 * @link       http://pear.php.net/package/PEAR
 * @since      Class available since Release 0.1
 */
class PEAR_Installer extends PEAR_Downloader
{
    
// {{{ properties

    /** name of the package directory, for example Foo-1.0
     * @var string
     */
    
var $pkgdir;

    
/** directory where PHP code files go
     * @var string
     */
    
var $phpdir;

    
/** directory where PHP extension files go
     * @var string
     */
    
var $extdir;

    
/** directory where documentation goes
     * @var string
     */
    
var $docdir;

    
/** installation root directory (ala PHP's INSTALL_ROOT or
     * automake's DESTDIR
     * @var string
     */
    
var $installroot '';

    
/** debug level
     * @var int
     */
    
var $debug 1;

    
/** temporary directory
     * @var string
     */
    
var $tmpdir;

    
/**
     * PEAR_Registry object used by the installer
     * @var PEAR_Registry
     */
    
var $registry;

    
/**
     * array of PEAR_Downloader_Packages
     * @var array
     */
    
var $_downloadedPackages;

    
/** List of file transactions queued for an install/upgrade/uninstall.
     *
     *  Format:
     *    array(
     *      0 => array("rename => array("from-file", "to-file")),
     *      1 => array("delete" => array("file-to-delete")),
     *      ...
     *    )
     *
     * @var array
     */
    
var $file_operations = array();

    
// }}}

    // {{{ constructor

    /**
     * PEAR_Installer constructor.
     *
     * @param object $ui user interface object (instance of PEAR_Frontend_*)
     *
     * @access public
     */
    
function PEAR_Installer(&$ui)
    {
        
parent::PEAR_Common();
        
$this->setFrontendObject($ui);
        
$this->debug $this->config->get('verbose');
    }

    function 
setOptions($options)
    {
        
$this->_options $options;
    }

    function 
setConfig(&$config)
    {
        
$this->config    = &$config;
        
$this->_registry = &$config->getRegistry();
    }

    
// }}}

    
function _removeBackups($files)
    {
        foreach (
$files as $path) {
            
$this->addFileOperation('removebackup', array($path));
        }
    }

    
// {{{ _deletePackageFiles()

    /**
     * Delete a package's installed files, does not remove empty directories.
     *
     * @param string package name
     * @param string channel name
     * @param bool if true, then files are backed up first
     * @return bool TRUE on success, or a PEAR error on failure
     * @access protected
     */
    
function _deletePackageFiles($package$channel false$backup false)
    {
        if (!
$channel) {
            
$channel 'pear.php.net';
        }

        if (!
strlen($package)) {
            return 
$this->raiseError("No package to uninstall given");
        }

        if (
strtolower($package) == 'pear' && $channel == 'pear.php.net') {
            
// to avoid race conditions, include all possible needed files
            
require_once 'PEAR/Task/Common.php';
            require_once 
'PEAR/Task/Replace.php';
            require_once 
'PEAR/Task/Unixeol.php';
            require_once 
'PEAR/Task/Windowseol.php';
            require_once 
'PEAR/PackageFile/v1.php';
            require_once 
'PEAR/PackageFile/v2.php';
            require_once 
'PEAR/PackageFile/Generator/v1.php';
            require_once 
'PEAR/PackageFile/Generator/v2.php';
        }

        
$filelist $this->_registry->packageInfo($package'filelist'$channel);
        if (
$filelist == null) {
            return 
$this->raiseError("$channel/$package not installed");
        }

        
$ret = array();
        foreach (
$filelist as $file => $props) {
            if (empty(
$props['installed_as'])) {
                continue;
            }

            
$path $props['installed_as'];
            if (
$backup) {
                
$this->addFileOperation('backup', array($path));
                
$ret[] = $path;
            }

            
$this->addFileOperation('delete', array($path));
        }

        if (
$backup) {
            return 
$ret;
        }

        return 
true;
    }

    
// }}}
    // {{{ _installFile()

    /**
     * @param string filename
     * @param array attributes from <file> tag in package.xml
     * @param string path to install the file in
     * @param array options from command-line
     * @access private
     */
    
function _installFile($file$atts$tmp_path$options)
    {
        
// {{{ return if this file is meant for another platform
        
static $os;
        if (!isset(
$this->_registry)) {
            
$this->_registry = &$this->config->getRegistry();
        }

        if (isset(
$atts['platform'])) {
            if (empty(
$os)) {
                
$os = new OS_Guess();
            }

            if (
strlen($atts['platform']) && $atts['platform']{0} == '!') {
                
$negate   true;
                
$platform substr($atts['platform'], 1);
            } else {
                
$negate    false;
                
$platform $atts['platform'];
            }

            if ((bool) 
$os->matchSignature($platform) === $negate) {
                
$this->log(3"skipped $file (meant for $atts[platform], we are ".$os->getSignature().")");
                return 
PEAR_INSTALLER_SKIPPED;
            }
        }
        
// }}}

        
$channel $this->pkginfo->getChannel();
        
// {{{ assemble the destination paths
        
switch ($atts['role']) {
            case 
'src':
            case 
'extsrc':
                
$this->source_files++;
                return;
            case 
'doc':
            case 
'data':
            case 
'test':
                
$dest_dir $this->config->get($atts['role'] . '_dir'null$channel) .
                            
DIRECTORY_SEPARATOR $this->pkginfo->getPackage();
                unset(
$atts['baseinstalldir']);
                break;
            case 
'ext':
            case 
'php':
                
$dest_dir $this->config->get($atts['role'] . '_dir'null$channel);
                break;
            case 
'script':
                
$dest_dir $this->config->get('bin_dir'null$channel);
                break;
            default:
                return 
$this->raiseError("Invalid role `$atts[role]' for file $file");
        }

        
$save_destdir $dest_dir;
        if (!empty(
$atts['baseinstalldir'])) {
            
$dest_dir .= DIRECTORY_SEPARATOR $atts['baseinstalldir'];
        }

        if (
dirname($file) != '.' && empty($atts['install-as'])) {
            
$dest_dir .= DIRECTORY_SEPARATOR dirname($file);
        }

        if (empty(
$atts['install-as'])) {
            
$dest_file $dest_dir DIRECTORY_SEPARATOR basename($file);
        } else {
            
$dest_file $dest_dir DIRECTORY_SEPARATOR $atts['install-as'];
        }
        
$orig_file $tmp_path DIRECTORY_SEPARATOR $file;

        
// Clean up the DIRECTORY_SEPARATOR mess
        
$ds2 DIRECTORY_SEPARATOR DIRECTORY_SEPARATOR;
        list(
$dest_file$orig_file) = preg_replace(array('!\\\\+!''!/!'"!$ds2+!"),
                                                    array(
DIRECTORY_SEPARATOR,
                                                          
DIRECTORY_SEPARATOR,
                                                          
DIRECTORY_SEPARATOR),
                                                    array(
$dest_file$orig_file));
        
$final_dest_file $installed_as $dest_file;
        if (isset(
$this->_options['packagingroot'])) {
            
$installedas_dest_dir  dirname($final_dest_file);
            
$installedas_dest_file $dest_dir DIRECTORY_SEPARATOR '.tmp' basename($final_dest_file);
            
$final_dest_file $this->_prependPath($final_dest_file$this->_options['packagingroot']);
        } else {
            
$installedas_dest_dir  dirname($final_dest_file);
            
$installedas_dest_file $installedas_dest_dir DIRECTORY_SEPARATOR '.tmp' basename($final_dest_file);
        }

        
$dest_dir  dirname($final_dest_file);
        
$dest_file $dest_dir DIRECTORY_SEPARATOR '.tmp' basename($final_dest_file);
        if (
preg_match('~/\.\.(/|\\z)|^\.\./~'str_replace('\\''/'$dest_file))) {
            return 
$this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference .."PEAR_INSTALLER_FAILED);
        }
        
// }}}

        
if (empty($this->_options['register-only']) &&
              (!
file_exists($dest_dir) || !is_dir($dest_dir))) {
            if (!
$this->mkDirHier($dest_dir)) {
                return 
$this->raiseError("failed to mkdir $dest_dir",
                                         
PEAR_INSTALLER_FAILED);
            }
            
$this->log(3"+ mkdir $dest_dir");
        }

        
// pretty much nothing happens if we are only registering the install
        
if (empty($this->_options['register-only'])) {
            if (empty(
$atts['replacements'])) {
                if (!
file_exists($orig_file)) {
                    return 
$this->raiseError("file $orig_file does not exist",
                                             
PEAR_INSTALLER_FAILED);
                }

                if (!@
copy($orig_file$dest_file)) {
                    return 
$this->raiseError("failed to write $dest_file$php_errormsg",
                                             
PEAR_INSTALLER_FAILED);
                }

                
$this->log(3"+ cp $orig_file $dest_file");
                if (isset(
$atts['md5sum'])) {
                    
$md5sum md5_file($dest_file);
                }
            } else {
                
// {{{ file with replacements
                
if (!file_exists($orig_file)) {
                    return 
$this->raiseError("file does not exist",
                                             
PEAR_INSTALLER_FAILED);
                }

                
$contents file_get_contents($orig_file);
                if (
$contents === false) {
                    
$contents '';
                }

                if (isset(
$atts['md5sum'])) {
                    
$md5sum md5($contents);
                }

                
$subst_from $subst_to = array();
                foreach (
$atts['replacements'] as $a) {
                    
$to '';
                    if (
$a['type'] == 'php-const') {
                        if (
preg_match('/^[a-z0-9_]+\\z/i'$a['to'])) {
                            eval(
"\$to = $a[to];");
                        } else {
                            if (!isset(
$options['soft'])) {
                                
$this->log(0"invalid php-const replacement: $a[to]");
                            }
                            continue;
                        }
                    } elseif (
$a['type'] == 'pear-config') {
                        if (
$a['to'] == 'master_server') {
                            
$chan $this->_registry->getChannel($channel);
                            if (!
PEAR::isError($chan)) {
                                
$to $chan->getServer();
                            } else {
                                
$to $this->config->get($a['to'], null$channel);
                            }
                        } else {
                            
$to $this->config->get($a['to'], null$channel);
                        }
                        if (
is_null($to)) {
                            if (!isset(
$options['soft'])) {
                                
$this->log(0"invalid pear-config replacement: $a[to]");
                            }
                            continue;
                        }
                    } elseif (
$a['type'] == 'package-info') {
                        if (
$t $this->pkginfo->packageInfo($a['to'])) {
                            
$to $t;
                        } else {
                            if (!isset(
$options['soft'])) {
                                
$this->log(0"invalid package-info replacement: $a[to]");
                            }
                            continue;
                        }
                    }
                    if (!
is_null($to)) {
                        
$subst_from[] = $a['from'];
                        
$subst_to[] = $to;
                    }
                }

                
$this->log(3"doing ".sizeof($subst_from)." substitution(s) for $final_dest_file");
                if (
sizeof($subst_from)) {
                    
$contents str_replace($subst_from$subst_to$contents);
                }

                
$wp = @fopen($dest_file"wb");
                if (!
is_resource($wp)) {
                    return 
$this->raiseError("failed to create $dest_file$php_errormsg",
                                             
PEAR_INSTALLER_FAILED);
                }

                if (@
fwrite($wp$contents) === false) {
                    return 
$this->raiseError("failed writing to $dest_file$php_errormsg",
                                             
PEAR_INSTALLER_FAILED);
                }

                
fclose($wp);
                
// }}}
            
}

            
// {{{ check the md5
            
if (isset($md5sum)) {
                if (
strtolower($md5sum) === strtolower($atts['md5sum'])) {
                    
$this->log(2"md5sum ok: $final_dest_file");
                } else {
                    if (empty(
$options['force'])) {
                        
// delete the file
                        
if (file_exists($dest_file)) {
                            
unlink($dest_file);
                        }

                        if (!isset(
$options['ignore-errors'])) {
                            return 
$this->raiseError("bad md5sum for file $final_dest_file",
                                                 
PEAR_INSTALLER_FAILED);
                        }

                        if (!isset(
$options['soft'])) {
                            
$this->log(0"warning : bad md5sum for file $final_dest_file");
                        }
                    } else {
                        if (!isset(
$options['soft'])) {
                            
$this->log(0"warning : bad md5sum for file $final_dest_file");
                        }
                    }
                }
            }
            
// }}}
            // {{{ set file permissions
            
if (!OS_WINDOWS) {
                if (
$atts['role'] == 'script') {
                    
$mode 0777 & ~(int)octdec($this->config->get('umask'));
                    
$this->log(3"+ chmod +x $dest_file");
                } else {
                    
$mode 0666 & ~(int)octdec($this->config->get('umask'));
                }

                if (
$atts['role'] != 'src') {
                    
$this->addFileOperation("chmod", array($mode$dest_file));
                    if (!@
chmod($dest_file$mode)) {
                        if (!isset(
$options['soft'])) {
                            
$this->log(0"failed to change mode of $dest_file$php_errormsg");
                        }
                    }
                }
            }
            
// }}}

            
if ($atts['role'] == 'src') {
                
rename($dest_file$final_dest_file);
                
$this->log(2"renamed source file $dest_file to $final_dest_file");
            } else {
                
$this->addFileOperation("rename", array($dest_file$final_dest_file,
                    
$atts['role'] == 'ext'));
            }
        }

        
// Store the full path where the file was installed for easy unistall
        
if ($atts['role'] != 'script') {
            
$loc $this->config->get($atts['role'] . '_dir');
        } else {
            
$loc $this->config->get('bin_dir');
        }

        if (
$atts['role'] != 'src') {
            
$this->addFileOperation("installed_as", array($file$installed_as,
                                    
$loc,
                                    
dirname(substr($installedas_dest_filestrlen($loc)))));
        }

        
//$this->log(2, "installed: $dest_file");
        
return PEAR_INSTALLER_OK;
    }

    
// }}}
    // {{{ _installFile2()

    /**
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
     * @param string filename
     * @param array attributes from <file> tag in package.xml
     * @param string path to install the file in
     * @param array options from command-line
     * @access private
     */
    
function _installFile2(&$pkg$file, &$real_atts$tmp_path$options)
    {
        
$atts $real_atts;
        if (!isset(
$this->_registry)) {
            
$this->_registry = &$this->config->getRegistry();
        }

        
$channel $pkg->getChannel();
        
// {{{ assemble the destination paths
        
if (!in_array($atts['attribs']['role'],
              
PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) {
            return 
$this->raiseError('Invalid role `' $atts['attribs']['role'] .
                    
"' for file $file");
        }

        
$role = &PEAR_Installer_Role::factory($pkg$atts['attribs']['role'], $this->config);
        
$err  $role->setup($this$pkg$atts['attribs'], $file);
        if (
PEAR::isError($err)) {
            return 
$err;
        }

        if (!
$role->isInstallable()) {
            return;
        }

        
$info $role->processInstallation($pkg$atts['attribs'], $file$tmp_path);
        if (
PEAR::isError($info)) {
            return 
$info;
        }

        list(
$save_destdir$dest_dir$dest_file$orig_file) = $info;
        if (
preg_match('~/\.\.(/|\\z)|^\.\./~'str_replace('\\''/'$dest_file))) {
            return 
$this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference .."PEAR_INSTALLER_FAILED);
        }

        
$final_dest_file $installed_as $dest_file;
        if (isset(
$this->_options['packagingroot'])) {
            
$final_dest_file $this->_prependPath($final_dest_file,
                
$this->_options['packagingroot']);
        }

        
$dest_dir  dirname($final_dest_file);
        
$dest_file $dest_dir DIRECTORY_SEPARATOR '.tmp' basename($final_dest_file);
        
// }}}

        
if (empty($this->_options['register-only'])) {
            if (!
file_exists($dest_dir) || !is_dir($dest_dir)) {
                if (!
$this->mkDirHier($dest_dir)) {
                    return 
$this->raiseError("failed to mkdir $dest_dir",
                                             
PEAR_INSTALLER_FAILED);
                }
                
$this->log(3"+ mkdir $dest_dir");
            }
        }

        
$attribs $atts['attribs'];
        unset(
$atts['attribs']);
        
// pretty much nothing happens if we are only registering the install
        
if (empty($this->_options['register-only'])) {
            if (!
count($atts)) { // no tasks
                
if (!file_exists($orig_file)) {
                    return 
$this->raiseError("file $orig_file does not exist",
                                             
PEAR_INSTALLER_FAILED);
                }

                if (!@
copy($orig_file$dest_file)) {
                    return 
$this->raiseError("failed to write $dest_file$php_errormsg",
                                             
PEAR_INSTALLER_FAILED);
                }

                
$this->log(3"+ cp $orig_file $dest_file");
                if (isset(
$attribs['md5sum'])) {
                    
$md5sum md5_file($dest_file);
                }
            } else { 
// file with tasks
                
if (!file_exists($orig_file)) {
                    return 
$this->raiseError("file $orig_file does not exist",
                                             
PEAR_INSTALLER_FAILED);
                }

                
$contents file_get_contents($orig_file);
                if (
$contents === false) {
                    
$contents '';
                }

                if (isset(
$attribs['md5sum'])) {
                    
$md5sum md5($contents);
                }

                foreach (
$atts as $tag => $raw) {
                    
$tag str_replace(array($pkg->getTasksNs() . ':''-'), array('''_'), $tag);
                    
$task "PEAR_Task_$tag";
                    
$task = &new $task($this->config$thisPEAR_TASK_INSTALL);
                    if (!
$task->isScript()) { // scripts are only handled after installation
                        
$task->init($raw$attribs$pkg->getLastInstalledVersion());
                        
$res $task->startSession($pkg$contents$final_dest_file);
                        if (
$res === false) {
                            continue; 
// skip this file
                        
}

                        if (
PEAR::isError($res)) {
                            return 
$res;
                        }

                        
$contents $res// save changes
                    
}

                    
$wp = @fopen($dest_file"wb");
                    if (!
is_resource($wp)) {
                        return 
$this->raiseError("failed to create $dest_file$php_errormsg",
                                                 
PEAR_INSTALLER_FAILED);
                    }

                    if (
fwrite($wp$contents) === false) {
                        return 
$this->raiseError("failed writing to $dest_file$php_errormsg",
                                                 
PEAR_INSTALLER_FAILED);
                    }

                    
fclose($wp);
                }
            }

            
// {{{ check the md5
            
if (isset($md5sum)) {
                
// Make sure the original md5 sum matches with expected
                
if (strtolower($md5sum) === strtolower($attribs['md5sum'])) {
                    
$this->log(2"md5sum ok: $final_dest_file");

                    if (isset(
$contents)) {
                        
// set md5 sum based on $content in case any tasks were run.
                        
$real_atts['attribs']['md5sum'] = md5($contents);
                    }
                } else {
                    if (empty(
$options['force'])) {
                        
// delete the file
                        
if (file_exists($dest_file)) {
                            
unlink($dest_file);
                        }

                        if (!isset(
$options['ignore-errors'])) {
                            return 
$this->raiseError("bad md5sum for file $final_dest_file",
                                                     
PEAR_INSTALLER_FAILED);
                        }

                        if (!isset(
$options['soft'])) {
                            
$this->log(0"warning : bad md5sum for file $final_dest_file");
                        }
                    } else {
                        if (!isset(
$options['soft'])) {
                            
$this->log(0"warning : bad md5sum for file $final_dest_file");
                        }
                    }
                }
            } else {
                
$real_atts['attribs']['md5sum'] = md5_file($dest_file);
            }

            
// }}}
            // {{{ set file permissions
            
if (!OS_WINDOWS) {
                if (
$role->isExecutable()) {
                    
$mode 0777 & ~(int)octdec($this->config->get('umask'));
                    
$this->log(3"+ chmod +x $dest_file");
                } else {
                    
$mode 0666 & ~(int)octdec($this->config->get('umask'));
                }

                if (
$attribs['role'] != 'src') {
                    
$this->addFileOperation("chmod", array($mode$dest_file));
                    if (!@
chmod($dest_file$mode)) {
                        if (!isset(
$options['soft'])) {
                            
$this->log(0"failed to change mode of $dest_file$php_errormsg");
                        }
                    }
                }
            }
            
// }}}

            
if ($attribs['role'] == 'src') {
                
rename($dest_file$final_dest_file);
                
$this->log(2"renamed source file $dest_file to $final_dest_file");
            } else {
                
$this->addFileOperation("rename", array($dest_file$final_dest_file$role->isExtension()));
            }
        }

        
// Store the full path where the file was installed for easy uninstall
        
if ($attribs['role'] != 'src') {
            
$loc $this->config->get($role->getLocationConfig(), null$channel);
            
$this->addFileOperation('installed_as', array($file$installed_as,
                                
$loc,
                                
dirname(substr($installed_asstrlen($loc)))));
        }

        
//$this->log(2, "installed: $dest_file");
        
return PEAR_INSTALLER_OK;
    }

    
// }}}
    // {{{ addFileOperation()

    /**
     * Add a file operation to the current file transaction.
     *
     * @see startFileTransaction()
     * @param string $type This can be one of:
     *    - rename:  rename a file ($data has 3 values)
     *    - backup:  backup an existing file ($data has 1 value)
     *    - removebackup:  clean up backups created during install ($data has 1 value)
     *    - chmod:   change permissions on a file ($data has 2 values)
     *    - delete:  delete a file ($data has 1 value)
     *    - rmdir:   delete a directory if empty ($data has 1 value)
     *    - installed_as: mark a file as installed ($data has 4 values).
     * @param array $data For all file operations, this array must contain the
     *    full path to the file or directory that is being operated on.  For
     *    the rename command, the first parameter must be the file to rename,
     *    the second its new name, the third whether this is a PHP extension.
     *
     *    The installed_as operation contains 4 elements in this order:
     *    1. Filename as listed in the filelist element from package.xml
     *    2. Full path to the installed file
     *    3. Full path from the php_dir configuration variable used in this
     *       installation
     *    4. Relative path from the php_dir that this file is installed in
     */
    
function addFileOperation($type$data)
    {
        if (!
is_array($data)) {
            return 
$this->raiseError('Internal Error: $data in addFileOperation'
                
' must be an array, was ' gettype($data));
        }

        if (
$type == 'chmod') {
            
$octmode decoct($data[0]);
            
$this->log(3"adding to transaction: $type $octmode $data[1]");
        } else {
            
$this->log(3"adding to transaction: $type " implode(" "$data));
        }
        
$this->file_operations[] = array($type$data);
    }

    
// }}}
    // {{{ startFileTransaction()

    
function startFileTransaction($rollback_in_case false)
    {
        if (
count($this->file_operations) && $rollback_in_case) {
            
$this->rollbackFileTransaction();
        }
        
$this->file_operations = array();
    }

    
// }}}
    // {{{ commitFileTransaction()

    
function commitFileTransaction()
    {
        
// {{{ first, check permissions and such manually
        
$errors = array();
        foreach (
$this->file_operations as $key => $tr) {
            list(
$type$data) = $tr;
            switch (
$type) {
                case 
'rename':
                    if (!
file_exists($data[0])) {
                        
$errors[] = "cannot rename file $data[0], doesn't exist";
                    }

                    
// check that dest dir. is writable
                    
if (!is_writable(dirname($data[1]))) {
                        
$errors[] = "permission denied ($type): $data[1]";
                    }
                    break;
                case 
'chmod':
                    
// check that file is writable
                    
if (!is_writable($data[1])) {
                        
$errors[] = "permission denied ($type): $data[1] " decoct($data[0]);
                    }
                    break;
                case 
'delete':
                    if (!
file_exists($data[0])) {
                        
$this->log(2"warning: file $data[0] doesn't exist, can't be deleted");
                    }
                    
// check that directory is writable
                    
if (file_exists($data[0])) {
                        if (!
is_writable(dirname($data[0]))) {
                            
$errors[] = "permission denied ($type): $data[0]";
                        } else {
                            
// make sure the file to be deleted can be opened for writing
                            
$fp false;
                            if (!
is_dir($data[0]) &&
                                  (!
is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) {
                                
$errors[] = "permission denied ($type): $data[0]";
                            } elseif (
$fp) {
                                
fclose($fp);
                            }
                        }

                        
/* Verify we are not deleting a file owned by another package
                         * This can happen when a file moves from package A to B in
                         * an upgrade ala http://pear.php.net/17986
                         */
                        
$info = array(
                            
'package' => strtolower($this->pkginfo->getName()),
                            
'channel' => strtolower($this->pkginfo->getChannel()),
                        );
                        
$result $this->_registry->checkFileMap($data[0], $info'1.1');
                        if (
is_array($result)) {
                            
$res array_diff($result$info);
                            if (!empty(
$res)) {
                                
$new $this->_registry->getPackage($result[1], $result[0]);
                                
$this->file_operations[$key] = false;
                                
$this->log(3"file $data[0] was scheduled for removal from {$this->pkginfo->getName()} but is owned by {$new->getChannel()}/{$new->getName()}, removal has been cancelled.");
                            }
                        }
                    }
                    break;
            }

        }
        
// }}}

        
$n count($this->file_operations);
        
$this->log(2"about to commit $n file operations for " $this->pkginfo->getName());

        
$m count($errors);
        if (
$m 0) {
            foreach (
$errors as $error) {
                if (!isset(
$this->_options['soft'])) {
                    
$this->log(1$error);
                }
            }

            if (!isset(
$this->_options['ignore-errors'])) {
                return 
false;
            }
        }

        
$this->_dirtree = array();
        
// {{{ really commit the transaction
        
foreach ($this->file_operations as $i => $tr) {
            if (!
$tr) {
                
// support removal of non-existing backups
                
continue;
            }

            list(
$type$data) = $tr;
            switch (
$type) {
                case 
'backup':
                    if (!
file_exists($data[0])) {
                        
$this->file_operations[$i] = false;
                        break;
                    }

                    if (!@
copy($data[0], $data[0] . '.bak')) {
                        
$this->log(1'Could not copy ' $data[0] . ' to ' $data[0] .
                            
'.bak ' $php_errormsg);
                        return 
false;
                    }
                    
$this->log(3"+ backup $data[0] to $data[0].bak");
                    break;
                case 
'removebackup':
                    if (
file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) {
                        
unlink($data[0] . '.bak');
                        
$this->log(3"+ rm backup of $data[0] ($data[0].bak)");
                    }
                    break;
                case 
'rename':
                    
$test file_exists($data[1]) ? @unlink($data[1]) : null;
                    if (!
$test && file_exists($data[1])) {
                        if (
$data[2]) {
                            
$extra ', this extension must be installed manually.  Rename to "' .
                                
basename($data[1]) . '"';
                        } else {
                            
$extra '';
                        }

                        if (!isset(
$this->_options['soft'])) {
                            
$this->log(1'Could not delete ' $data[1] . ', cannot rename ' .
                                
$data[0] . $extra);
                        }

                        if (!isset(
$this->_options['ignore-errors'])) {
                            return 
false;
                        }
                    }

                    
// permissions issues with rename - copy() is far superior
                    
$perms = @fileperms($data[0]);
                    if (!@
copy($data[0], $data[1])) {
                        
$this->log(1'Could not rename ' $data[0] . ' to ' $data[1] .
                            
' ' $php_errormsg);
                        return 
false;
                    }

                    
// copy over permissions, otherwise they are lost
                    
@chmod($data[1], $perms);
                    @
unlink($data[0]);
                    
$this->log(3"+ mv $data[0] $data[1]");
                    break;
                case 
'chmod':
                    if (!@
chmod($data[1], $data[0])) {
                        
$this->log(1'Could not chmod ' $data[1] . ' to ' .
                            
decoct($data[0]) . ' ' $php_errormsg);
                        return 
false;
                    }

                    
$octmode decoct($data[0]);
                    
$this->log(3"+ chmod $octmode $data[1]");
                    break;
                case 
'delete':
                    if (
file_exists($data[0])) {
                        if (!@
unlink($data[0])) {
                            
$this->log(1'Could not delete ' $data[0] . ' ' .
                                
$php_errormsg);
                            return 
false;
                        }
                        
$this->log(3"+ rm $data[0]");
                    }
                    break;
                case 
'rmdir':
                    if (
file_exists($data[0])) {
                        do {
                            
$testme opendir($data[0]);
                            while (
false !== ($entry readdir($testme))) {
                                if (
$entry == '.' || $entry == '..') {
                                    continue;
                                }
                                
closedir($testme);
                                break 
2// this directory is not empty and can't be
                                         // deleted
                            
}

                            
closedir($testme);
                            if (!@
rmdir($data[0])) {
                                
$this->log(1'Could not rmdir ' $data[0] . ' ' .
                                    
$php_errormsg);
                                return 
false;
                            }
                            
$this->log(3"+ rmdir $data[0]");
                        } while (
false);
                    }
                    break;
                case 
'installed_as':
                    
$this->pkginfo->setInstalledAs($data[0], $data[1]);
                    if (!isset(
$this->_dirtree[dirname($data[1])])) {
                        
$this->_dirtree[dirname($data[1])] = true;
                        
$this->pkginfo->setDirtree(dirname($data[1]));

                        while(!empty(
$data[3]) && dirname($data[3]) != $data[3] &&
                                
$data[3] != '/' && $data[3] != '\\') {
                            
$this->pkginfo->setDirtree($pp =
                                
$this->_prependPath($data[3], $data[2]));
                            
$this->_dirtree[$pp] = true;
                            
$data[3] = dirname($data[3]);
                        }
                    }
                    break;
            }
        }
        
// }}}
        
$this->log(2"successfully committed $n file operations");
        
$this->file_operations = array();
        return 
true;
    }

    
// }}}
    // {{{ rollbackFileTransaction()

    
function rollbackFileTransaction()
    {
        
$n count($this->file_operations);
        
$this->log(2"rolling back $n file operations");
        foreach (
$this->file_operations as $tr) {
            list(
$type$data) = $tr;
            switch (
$type) {
                case 
'backup':
                    if (
file_exists($data[0] . '.bak')) {
                        if (
file_exists($data[0] && is_writable($data[0]))) {
                            
unlink($data[0]);
                        }
                        @
copy($data[0] . '.bak'$data[0]);
                        
$this->log(3"+ restore $data[0] from $data[0].bak");
                    }
                    break;
                case 
'removebackup':
                    if (
file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) {
                        
unlink($data[0] . '.bak');
                        
$this->log(3"+ rm backup of $data[0] ($data[0].bak)");
                    }
                    break;
                case 
'rename':
                    @
unlink($data[0]);
                    
$this->log(3"+ rm $data[0]");
                    break;
                case 
'mkdir':
                    @
rmdir($data[0]);
                    
$this->log(3"+ rmdir $data[0]");
                    break;
                case 
'chmod':
                    break;
                case 
'delete':
                    break;
                case 
'installed_as':
                    
$this->pkginfo->setInstalledAs($data[0], false);
                    break;
            }
        }
        
$this->pkginfo->resetDirtree();
        
$this->file_operations = array();
    }

    
// }}}
    // {{{ mkDirHier($dir)

    
function mkDirHier($dir)
    {
        
$this->addFileOperation('mkdir', array($dir));
        return 
parent::mkDirHier($dir);
    }

    
// }}}
    // {{{ download()

    /**
     * Download any files and their dependencies, if necessary
     *
     * @param array a mixed list of package names, local files, or package.xml
     * @param PEAR_Config
     * @param array options from the command line
     * @param array this is the array that will be populated with packages to
     *              install.  Format of each entry:
     *
     * <code>
     * array('pkg' => 'package_name', 'file' => '/path/to/local/file',
     *    'info' => array() // parsed package.xml
     * );
     * </code>
     * @param array this will be populated with any error messages
     * @param false private recursion variable
     * @param false private recursion variable
     * @param false private recursion variable
     * @deprecated in favor of PEAR_Downloader
     */
    
function download($packages$options, &$config, &$installpackages,
                      &
$errors$installed false$willinstall false$state false)
    {
        
// trickiness: initialize here
        
parent::PEAR_Downloader($this->ui$options$config);
        
$ret             parent::download($packages);
        
$errors          $this->getErrorMsgs();
        
$installpackages $this->getDownloadedPackages();
        
trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " .
                      
"in favor of PEAR_Downloader class"E_USER_WARNING);
        return 
$ret;
    }

    
// }}}
    // {{{ _parsePackageXml()

    
function _parsePackageXml(&$descfile)
    {
        
// Parse xml file -----------------------------------------------
        
$pkg = new PEAR_PackageFile($this->config$this->debug);
        
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
        
$p = &$pkg->fromAnyFile($descfilePEAR_VALIDATE_INSTALLING);
        
PEAR::staticPopErrorHandling();
        if (
PEAR::isError($p)) {
            if (
is_array($p->getUserInfo())) {
                foreach (
$p->getUserInfo() as $err) {
                    
$loglevel $err['level'] == 'error' 1;
                    if (!isset(
$this->_options['soft'])) {
                        
$this->log($loglevelucfirst($err['level']) . ': ' $err['message']);
                    }
                }
            }
            return 
$this->raiseError('Installation failed: invalid package file');
        }

        
$descfile $p->getPackageFile();
        return 
$p;
    }

    
// }}}
    /**
     * Set the list of PEAR_Downloader_Package objects to allow more sane
     * dependency validation
     * @param array
     */
    
function setDownloadedPackages(&$pkgs)
    {
        
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
        
$err $this->analyzeDependencies($pkgs);
        
PEAR::popErrorHandling();
        if (
PEAR::isError($err)) {
            return 
$err;
        }
        
$this->_downloadedPackages = &$pkgs;
    }

    
/**
     * Set the list of PEAR_Downloader_Package objects to allow more sane
     * dependency validation
     * @param array
     */
    
function setUninstallPackages(&$pkgs)
    {
        
$this->_downloadedPackages = &$pkgs;
    }

    function 
getInstallPackages()
    {
        return 
$this->_downloadedPackages;
    }

    
// {{{ install()

    /**
     * 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");
            }
        }

        
$pkgname $pkg->getName();
        
$channel $pkg->getChannel();
        if (isset(
$this->_options['packagingroot'])) {
            
$regdir $this->_prependPath(
                
$this->config->get('php_dir'null'pear.php.net'),
                
$this->_options['packagingroot']);

            
$packrootphp_dir $this->_prependPath(
                
$this->config->get('php_dir'null$channel),
                
$this->_options['packagingroot']);
        }

        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'])) {
                
$installregistry = &new PEAR_Registry($regdir);
                if (!
$installregistry->channelExists($channeltrue)) {
                    
// we need to fake a channel-discover of this channel
                    
$chanobj $this->_registry->getChannel($channeltrue);
                    
$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' $pkgname : array($channel$pkgname);
            
$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($file0$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($file0$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/$pkgname: 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();

        
$usechannel $channel;
        if (
$channel == 'pecl.php.net') {
            
$test $installregistry->packageExists($pkgname$channel);
            if (!
$test) {
                
$test $installregistry->packageExists($pkgname'pear.php.net');
                
$usechannel 'pear.php.net';
            }
        } else {
            
$test $installregistry->packageExists($pkgname$channel);
        }

        if (empty(
$options['upgrade']) && empty($options['soft'])) {
            
// checks to do only when installing new packages
            
if (empty($options['force']) && $test) {
                return 
$this->raiseError("$channel/$pkgname is already installed");
            }
        } else {
            
// Upgrade
            
if ($test) {
                
$v1 $installregistry->packageInfo($pkgname'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'])) {
            
// when upgrading, remove old release's files first:
            
if (PEAR::isError($err $this->_deletePackageFiles($pkgname$usechannel,
                  
true))) {
                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 $pkgname '-' $pkg->getVersion();
        }

        
$this->configSet('default_channel'$channel);
        
// {{{ install files

        
$ver $pkg->getPackagexmlVersion();
        if (
version_compare($ver'2.0''>=')) {
            
$filelist $pkg->getInstallationFilelist();
        } else {
            
$filelist $pkg->getFileList();
        }

        if (
PEAR::isError($filelist)) {
            return 
$filelist;
        }

        
$p = &$installregistry->getPackage($pkgname$channel);
        
$dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false;

        
$pkg->resetFilelist();
        
$pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(),
            
'version'$pkg->getChannel()));
        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 && empty($options['nobuild'])) {
            if (
PEAR::isError($err =
                  
$this->_compileSourceFiles($savechannel$pkg))) {
                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);
        }
        
// }}}

        
$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
            
$usechannel $channel;
            if (
$channel == 'pecl.php.net') {
                
$test $installregistry->packageExists($pkgname$channel);
                if (!
$test) {
                    
$test $installregistry->packageExists($pkgname'pear.php.net');
                    
$usechannel 'pear.php.net';
                }
            } else {
                
$test $installregistry->packageExists($pkgname$channel);
            }

            if (!empty(
$options['force']) && $test) {
                
$oldversion $installregistry->packageInfo($pkgname'version'$usechannel);
                
$installregistry->deletePackage($pkgname$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();
            }

            
$usechannel $channel;
            if (
$channel == 'pecl.php.net') {
                
$test $installregistry->packageExists($pkgname$channel);
                if (!
$test) {
                    
$test $installregistry->packageExists($pkgname'pear.php.net');
                    
$usechannel 'pear.php.net';
                }
            } else {
                
$test $installregistry->packageExists($pkgname$channel);
            }

            
// new: upgrade installs a package if it isn't installed
            
if (!$test) {
                
$ret $installregistry->addPackage2($pkg);
            } else {
                if (
$usechannel != $channel) {
                    
$installregistry->deletePackage($pkgname$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/$pkgname 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);
    }

    
// }}}

    // {{{ _compileSourceFiles()
    /**
     * @param string
     * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2
     */
    
function _compileSourceFiles($savechannel, &$filelist)
    {
        require_once 
'PEAR/Builder.php';
        
$this->log(1"$this->source_files source files, building");
        
$bob = &new PEAR_Builder($this->ui);
        
$bob->debug $this->debug;
        
$built $bob->build($filelist, array(&$this'_buildCallback'));
        if (
PEAR::isError($built)) {
            
$this->rollbackFileTransaction();
            
$this->configSet('default_channel'$savechannel);
            return 
$built;
        }

        
$this->log(1"\nBuild process completed successfully");
        foreach (
$built as $ext) {
            
$bn basename($ext['file']);
            list(
$_ext_name$_ext_suff) = explode('.'$bn);
            if (
$_ext_suff == '.so' || $_ext_suff == '.dll') {
                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');
                }
                
$role 'ext';
            } else {
                
$role 'src';
            }

            
$dest $ext['dest'];
            
$packagingroot '';
            if (isset(
$this->_options['packagingroot'])) {
                
$packagingroot $this->_options['packagingroot'];
            }

            
$copyto $this->_prependPath($dest$packagingroot);
            
$extra  $copyto != $dest " as '$copyto'" '';
            
$this->log(1"Installing '$dest'$extra");

            
$copydir dirname($copyto);
            
// pretty much nothing happens if we are only registering the install
            
if (empty($this->_options['register-only'])) {
                if (!
file_exists($copydir) || !is_dir($copydir)) {
                    if (!
$this->mkDirHier($copydir)) {
                        return 
$this->raiseError("failed to mkdir $copydir",
                            
PEAR_INSTALLER_FAILED);
                    }

                    
$this->log(3"+ mkdir $copydir");
                }

                if (!@
copy($ext['file'], $copyto)) {
                    return 
$this->raiseError("failed to write $copyto ($php_errormsg)"PEAR_INSTALLER_FAILED);
                }

                
$this->log(3"+ cp $ext[file] $copyto");
                
$this->addFileOperation('rename', array($ext['file'], $copyto));
                if (!
OS_WINDOWS) {
                    
$mode 0666 & ~(int)octdec($this->config->get('umask'));
                    
$this->addFileOperation('chmod', array($mode$copyto));
                    if (!@
chmod($copyto$mode)) {
                        
$this->log(0"failed to change mode of $copyto ($php_errormsg)");
                    }
                }
            }


            
$data = array(
                
'role'         => $role,
                
'name'         => $bn,
                
'installed_as' => $dest,
                
'php_api'      => $ext['php_api'],
                
'zend_mod_api' => $ext['zend_mod_api'],
                
'zend_ext_api' => $ext['zend_ext_api'],
            );

            if (
$filelist->getPackageXmlVersion() == '1.0') {
                
$filelist->installedFile($bn$data);
            } else {
                
$filelist->installedFile($bn, array('attribs' => $data));
            }
        }
    }

    
// }}}
    
function &getUninstallPackages()
    {
        return 
$this->_downloadedPackages;
    }
    
// {{{ uninstall()

    /**
     * Uninstall a package
     *
     * This method removes all files installed by the application, and then
     * removes any empty directories.
     * @param string package name
     * @param array Command-line options.  Possibilities include:
     *
     *              - installroot: base installation dir, if not the default
     *              - register-only : update registry but don't remove files
     *              - nodeps: do not process dependencies of other packages to ensure
     *                        uninstallation does not break things
     */
    
function uninstall($package$options = array())
    {
        
$installRoot = isset($options['installroot']) ? $options['installroot'] : '';
        
$this->config->setInstallRoot($installRoot);

        
$this->installroot '';
        
$this->_registry = &$this->config->getRegistry();
        if (
is_object($package)) {
            
$channel $package->getChannel();
            
$pkg     $package;
            
$package $pkg->getPackage();
        } else {
            
$pkg false;
            
$info $this->_registry->parsePackageName($package,
                
$this->config->get('default_channel'));
            
$channel $info['channel'];
            
$package $info['package'];
        }

        
$savechannel $this->config->get('default_channel');
        
$this->configSet('default_channel'$channel);
        if (!
is_object($pkg)) {
            
$pkg $this->_registry->getPackage($package$channel);
        }

        if (!
$pkg) {
            
$this->configSet('default_channel'$savechannel);
            return 
$this->raiseError($this->_registry->parsedPackageNameToString(
                array(
                    
'channel' => $channel,
                    
'package' => $package
                
), true) . ' not installed');
        }

        if (
$pkg->getInstalledBinary()) {
            
// this is just an alias for a binary package
            
return $this->_registry->deletePackage($package$channel);
        }

        
$filelist $pkg->getFilelist();
        
PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
        if (!
class_exists('PEAR_Dependency2')) {
            require_once 
'PEAR/Dependency2.php';
        }

        
$depchecker = &new PEAR_Dependency2($this->config$options,
            array(
'channel' => $channel'package' => $package),
            
PEAR_VALIDATE_UNINSTALLING);
        
$e $depchecker->validatePackageUninstall($this);
        
PEAR::staticPopErrorHandling();
        if (
PEAR::isError($e)) {
            if (!isset(
$options['ignore-errors'])) {
                return 
$this->raiseError($e);
            }

            if (!isset(
$options['soft'])) {
                
$this->log(0'WARNING: ' $e->getMessage());
            }
        } elseif (
is_array($e)) {
            if (!isset(
$options['soft'])) {
                
$this->log(0$e[0]);
            }
        }

        
$this->pkginfo = &$pkg;
        
// pretty much nothing happens if we are only registering the uninstall
        
if (empty($options['register-only'])) {
            
// {{{ Delete the files
            
$this->startFileTransaction();
            
PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
            if (
PEAR::isError($err $this->_deletePackageFiles($package$channel))) {
                
PEAR::popErrorHandling();
                
$this->rollbackFileTransaction();
                
$this->configSet('default_channel'$savechannel);
                if (!isset(
$options['ignore-errors'])) {
                    return 
$this->raiseError($err);
                }

                if (!isset(
$options['soft'])) {
                    
$this->log(0'WARNING: ' $err->getMessage());
                }
            } else {
                
PEAR::popErrorHandling();
            }

            if (!
$this->commitFileTransaction()) {
                
$this->rollbackFileTransaction();
                if (!isset(
$options['ignore-errors'])) {
                    return 
$this->raiseError("uninstall failed");
                }

                if (!isset(
$options['soft'])) {
                    
$this->log(0'WARNING: uninstall failed');
                }
            } else {
                
$this->startFileTransaction();
                
$dirtree $pkg->getDirTree();
                if (
$dirtree === false) {
                    
$this->configSet('default_channel'$savechannel);
                    return 
$this->_registry->deletePackage($package$channel);
                }

                
// attempt to delete empty directories
                
uksort($dirtree, array($this'_sortDirs'));
                foreach(
$dirtree as $dir => $notused) {
                    
$this->addFileOperation('rmdir', array($dir));
                }

                if (!
$this->commitFileTransaction()) {
                    
$this->rollbackFileTransaction();
                    if (!isset(
$options['ignore-errors'])) {
                        return 
$this->raiseError("uninstall failed");
                    }

                    if (!isset(
$options['soft'])) {
                        
$this->log(0'WARNING: uninstall failed');
                    }
                }
            }
            
// }}}
        
}

        
$this->configSet('default_channel'$savechannel);
        
// Register that the package is no longer installed
        
return $this->_registry->deletePackage($package$channel);
    }

    
/**
     * Sort a list of arrays of array(downloaded packagefilename) by dependency.
     *
     * It also removes duplicate dependencies
     * @param array an array of PEAR_PackageFile_v[1/2] objects
     * @return array|PEAR_Error array of array(packagefilename, package.xml contents)
     */
    
function sortPackagesForUninstall(&$packages)
    {
        
$this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config);
        if (
PEAR::isError($this->_dependencyDB)) {
            return 
$this->_dependencyDB;
        }
        
usort($packages, array(&$this'_sortUninstall'));
    }

    function 
_sortUninstall($a$b)
    {
        if (!
$a->getDeps() && !$b->getDeps()) {
            return 
0// neither package has dependencies, order is insignificant
        
}
        if (
$a->getDeps() && !$b->getDeps()) {
            return -
1// $a must be installed after $b because $a has dependencies
        
}
        if (!
$a->getDeps() && $b->getDeps()) {
            return 
1// $b must be installed after $a because $b has dependencies
        
}
        
// both packages have dependencies
        
if ($this->_dependencyDB->dependsOn($a$b)) {
            return -
1;
        }
        if (
$this->_dependencyDB->dependsOn($b$a)) {
            return 
1;
        }
        return 
0;
    }

    
// }}}
    // {{{ _sortDirs()
    
function _sortDirs($a$b)
    {
        if (
strnatcmp($a$b) == -1) return 1;
        if (
strnatcmp($a$b) == 1) return -1;
        return 
0;
    }

    
// }}}

    // {{{ _buildCallback()

    
function _buildCallback($what$data)
    {
        if ((
$what == 'cmdoutput' && $this->debug 1) ||
            (
$what == 'output' && $this->debug 0)) {
            
$this->ui->outputData(rtrim($data), 'build');
        }
    }

    
// }}}
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ ok ]

:: Make Dir ::
 
[ ok ]
:: Make File ::
 
[ ok ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0312 ]--