From: Stig Bakken Date: Mon, 29 Oct 2001 12:15:53 +0000 (+0000) Subject: * moved System.php out of Experimental/ X-Git-Tag: ChangeLog~492 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f8055473a40b84506e44269987942c9ae0ea1963;p=php * moved System.php out of Experimental/ --- diff --git a/pear/Makefile.in b/pear/Makefile.in index c0dc8999ca..a7d421f420 100644 --- a/pear/Makefile.in +++ b/pear/Makefile.in @@ -107,6 +107,7 @@ PEAR_FILES = \ PEAR/Uploader.php \ Payment/Verisign.php \ Schedule/At.php \ + System.php \ XML/Parser.php install-data-local: diff --git a/pear/PEAR/Common.php b/pear/PEAR/Common.php index b0c5b51448..0cc55debf1 100644 --- a/pear/PEAR/Common.php +++ b/pear/PEAR/Common.php @@ -22,15 +22,15 @@ require_once 'PEAR.php'; require_once 'Archive/Tar.php'; -require_once 'Experimental/System.php'; +require_once 'System.php'; /** -* TODO: -* - check in inforFromDescFile that the minimal data needed is present -* (pack name, version, files, others?) -* - perhaps use parser folding to be less restrictive with the format -* of the package.xml file -*/ + * TODO: + * - check in inforFromDescFile that the minimal data needed is present + * (pack name, version, files, others?) + * - perhaps use parser folding to be less restrictive with the format + * of the package.xml file + */ class PEAR_Common extends PEAR { // {{{ properties diff --git a/pear/System.php b/pear/System.php new file mode 100644 index 0000000000..841e00b368 --- /dev/null +++ b/pear/System.php @@ -0,0 +1,286 @@ + | +// | | +// +----------------------------------------------------------------------+ +// +// $Id$ +// + +// TODO: +// - Test under Windows (help is really appreciated in this point) +// - Build strong tests +// - Error reporting (now shows standar php errors) +// - Write doc + +require_once 'PEAR.php'; +require_once 'Console/Getopt.php'; + +/** +* System offers cross plattform compatible system functions +* +* Static functions for different operations. Should work under +* Unix and Windows. The names and usage has been taken from its repectively +* GNU commands. +* +* Usage: System::rm('-r file1 dir1'); +* +* ------------------- EXPERIMENTAL STATUS ------------------- +* +* @package System +* @author Tomas V.V.Cox +* @version $Version$ +* @access public +*/ +class System extends PEAR +{ + /** + * returns the commandline arguments of a function + * + * @param string $argv the commandline + * @param string $short_options the allowed option short-tags + * @param string $long_options the allowed option long-tags + * @return array the given options and there values + * @access private + */ + function _parseArgs($argv, $short_options, $long_options = null) + { + if (!is_array($argv)) { + $argv = preg_split('/\s+/', $argv); + } + $options = Console_Getopt::getopt($argv, $short_options); + return $options; + } + + /** + * Creates a nested array representing the structure of a directory + * + * System::_dirToStruct('dir1', 0) => + * Array + * ( + * [dirs] => Array + * ( + * [0] => dir1 + * ) + * + * [files] => Array + * ( + * [0] => dir1/file2 + * [1] => dir1/file3 + * ) + * ) + * @param string $sPath Name of the directory + * @param integer $maxinst max. deep of the lookup + * @param integer $aktinst starting deep of the lookup + * @return array the structure of the dir + * @access private + */ + + function _dirToStruct($sPath, $maxinst, $aktinst = 0) + { + $struct = array('dirs' => array(), 'files' => array()); + if (($dir = @opendir($sPath)) === false) { + return $struct; // XXX could not open error + } + $struct['dirs'][] = $sPath; // XXX don't add if '.' or '..' ? + $list = array(); + while ($file = readdir($dir)) { + if ($file != '.' && $file != '..') { + $list[] = $file; + } + } + closedir($dir); + sort($list); + foreach($list as $val) { + $path = $sPath . DIRECTORY_SEPARATOR . $val; + if (is_dir($path)) { + if ($aktinst < $maxinst || $maxinst == 0) { + $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1); + $struct = array_merge_recursive($tmp, $struct); + } + } else { + $struct['files'][] = $path; + } + } + return $struct; + } + + /** + * Creates a nested array representing the structure of a directory and files + * + * @param array $files Array listing files and dirs + * @return array + * @see System::_dirToStruct() + */ + function _multipleToStruct($files) + { + $struct = array('dirs' => array(), 'files' => array()); + foreach($files as $file) { + if (is_dir($file)) { + $tmp = System::_dirToStruct($file, 0); + $struct = array_merge_recursive($tmp, $struct); + } else { + $struct['files'][] = $file; + } + } + return $struct; + } + + /** + * The rm command for removing files. + * Supports multiple files and dirs and also recursive deletes + * + * @param string $args the arguments for rm + * @return mixed PEAR_Error or true for success + * @access public + */ + function rm($args) + { + $opts = System::_parseArgs($args, 'rf'); // "f" do nothing but like it :-) + if (PEAR::isError($opts)) { + return $opts; + } + foreach($opts[0] as $opt) { + if ($opt[0] == 'r') { + $do_recursive = true; + } + } + if (isset($do_recursive)) { + $struct = System::_multipleToStruct($opts[1]); + if (PEAR::isError($struct)) { + return $struct; + } + foreach($struct['files'] as $file) { + unlink($file); // XXXX Works under Windows? + } + foreach($struct['dirs'] as $dir) { + rmdir($dir); + } + } else { + foreach ($opts[1] as $file) { + $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; // XXXX Windows? + $delete($file); + } + } + return true; + } + + /** + * Make directories + * + * @param string $args the name of the director(y|ies) to create + * @return mixed PEAR_Error or true for success + * @access public + */ + function mkDir($args) + { + $opts = System::_parseArgs($args, 'pm:'); + if (PEAR::isError($opts)) { + return $opts; + } + $mode = 0777; // default mode + foreach($opts[0] as $opt) { + if ($opt[0] == 'p') { + $create_parents = true; + } elseif($opt[0] == 'm') { + $mode = $opt[1]; + } + } + if (isset($create_parents)) { + foreach($opts[1] as $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, $mode)) { + break; // XXX error + } + } + } + } else { + foreach($opts[1] as $dir) { + if (!mkdir($dir, $mode)) { + continue; // XXX error + } + } + } + return true; + } + + /** + * Concatenate files + * + * Usage: + * 1) $var = System::cat('sample.txt test.txt'); + * 2) System::cat('sample.txt test.txt > final.txt'); + * 3) System::cat('sample.txt test.txt >> final.txt'); + * + * Note: as the class use fopen, urls should work also (test that) + * + * @param string $args the arguments + * @return boolean true on success + * @access public + */ + function &cat($args) + { + $ret = null; + $files = array(); + if (!is_array($args)) { + $args = preg_split('/\s+/', $args); + } + for($i=0; $i < count($args); $i++) { + if ($args[$i] == '>') { + $mode = 'wb'; + $outputfile = $args[$i+1]; + break; + } elseif ($args[$i] == '>>') { + $mode = 'ab+'; + $outputfile = $args[$i+1]; + break; + } else { + $files[] = $args[$i]; + } + } + if (isset($mode)) { + if (!$outputfd = fopen($outputfile, $mode)) { + return $this->raiseError("Could not open $outputfile"); + } + $ret = true; + } + foreach($files as $file) { + if (!$fd = fopen($file, 'r')) { + return $this->raiseError("Could not open $file"); + } + while(!feof($fd)) { + $cont = fread($fd, 2048); + if (isset($outputfd)) { + fwrite($outputfd, $cont); + } else { + $ret .= $cont; + } + } + fclose($fd); + } + if (@is_resource($outputfd)) { + fclose($outputfd); + } + return $ret; + } + +} +?> \ No newline at end of file