X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=extlib%2FSystem.php;h=7841ae51dc8001d9a6cb2df3ae9d9764e0e9e070;hb=b17e0b4169102cf40d56d0c0ebac704d7bbf2713;hp=db7c3a60b89968c91d4393bfca0a46f81ebbdb05;hpb=25198a8d4cee5b2182f1ecb99192a4108a01afa4;p=quix0rs-gnu-social.git diff --git a/extlib/System.php b/extlib/System.php index db7c3a60b8..7841ae51dc 100644 --- a/extlib/System.php +++ b/extlib/System.php @@ -9,7 +9,6 @@ * @author Tomas V.V.Cox * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php 307683 2011-01-23 21:56:12Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -23,273 +22,41 @@ require_once 'Console/Getopt.php'; $GLOBALS['_System_temp_files'] = array(); /** -* 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 respectively -* GNU commands. The functions will return (bool) false on error and will -* trigger the error with the PHP trigger_error() function (you can silence -* the error by prefixing a '@' sign after the function call, but this -* is not recommended practice. Instead use an error handler with -* {@link set_error_handler()}). -* -* Documentation on this class you can find in: -* http://pear.php.net/manual/ -* -* Example usage: -* if (!@System::rm('-r file1 dir1')) { -* print "could not delete file1 or dir1"; -* } -* -* In case you need to to pass file names with spaces, -* pass the params as an array: -* -* System::rm(array('-r', $file1, $dir1)); -* -* @category pear -* @package System -* @author Tomas V.V. Cox -* @copyright 1997-2006 The PHP Group -* @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.9.2 -* @link http://pear.php.net/package/PEAR -* @since Class available since Release 0.1 -* @static -*/ + * System offers cross platform compatible system functions + * + * Static functions for different operations. Should work under + * Unix and Windows. The names and usage has been taken from its respectively + * GNU commands. The functions will return (bool) false on error and will + * trigger the error with the PHP trigger_error() function (you can silence + * the error by prefixing a '@' sign after the function call, but this + * is not recommended practice. Instead use an error handler with + * {@link set_error_handler()}). + * + * Documentation on this class you can find in: + * http://pear.php.net/manual/ + * + * Example usage: + * if (!@System::rm('-r file1 dir1')) { + * print "could not delete file1 or dir1"; + * } + * + * In case you need to to pass file names with spaces, + * pass the params as an array: + * + * System::rm(array('-r', $file1, $dir1)); + * + * @category pear + * @package System + * @author Tomas V.V. Cox + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: @package_version@ + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + * @static + */ class System { - /** - * 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 - * @static - * @access private - */ - function _parseArgs($argv, $short_options, $long_options = null) - { - if (!is_array($argv) && $argv !== null) { - $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY); - } - return Console_Getopt::getopt2($argv, $short_options); - } - - /** - * Output errors with PHP trigger_error(). You can silence the errors - * with prefixing a "@" sign to the function call: @System::mkdir(..); - * - * @param mixed $error a PEAR error or a string with the error message - * @return bool false - * @static - * @access private - */ - function raiseError($error) - { - if (PEAR::isError($error)) { - $error = $error->getMessage(); - } - trigger_error($error, E_USER_WARNING); - return false; - } - - /** - * 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 - * @param bool $silent if true, do not emit errors. - * @return array the structure of the dir - * @static - * @access private - */ - function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) - { - $struct = array('dirs' => array(), 'files' => array()); - if (($dir = @opendir($sPath)) === false) { - if (!$silent) { - System::raiseError("Could not open dir $sPath"); - } - return $struct; // XXX could not open error - } - - $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? - $list = array(); - while (false !== ($file = readdir($dir))) { - if ($file != '.' && $file != '..') { - $list[] = $file; - } - } - - closedir($dir); - natsort($list); - if ($aktinst < $maxinst || $maxinst == 0) { - foreach ($list as $val) { - $path = $sPath . DIRECTORY_SEPARATOR . $val; - if (is_dir($path) && !is_link($path)) { - $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); - $struct = array_merge_recursive($struct, $tmp); - } 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 - * @static - * @see System::_dirToStruct() - */ - function _multipleToStruct($files) - { - $struct = array('dirs' => array(), 'files' => array()); - settype($files, 'array'); - foreach ($files as $file) { - if (is_dir($file) && !is_link($file)) { - $tmp = System::_dirToStruct($file, 0); - $struct = array_merge_recursive($tmp, $struct); - } else { - if (!in_array($file, $struct['files'])) { - $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 - * @static - * @access public - */ - function rm($args) - { - $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) - if (PEAR::isError($opts)) { - return System::raiseError($opts); - } - foreach ($opts[0] as $opt) { - if ($opt[0] == 'r') { - $do_recursive = true; - } - } - $ret = true; - if (isset($do_recursive)) { - $struct = System::_multipleToStruct($opts[1]); - foreach ($struct['files'] as $file) { - if (!@unlink($file)) { - $ret = false; - } - } - - rsort($struct['dirs']); - foreach ($struct['dirs'] as $dir) { - if (!@rmdir($dir)) { - $ret = false; - } - } - } else { - foreach ($opts[1] as $file) { - $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; - if (!@$delete($file)) { - $ret = false; - } - } - } - return $ret; - } - - /** - * Make directories. - * - * The -p option will create parent directories - * @param string $args the name of the director(y|ies) to create - * @return bool True for success - * @static - * @access public - */ - function mkDir($args) - { - $opts = System::_parseArgs($args, 'pm:'); - if (PEAR::isError($opts)) { - return System::raiseError($opts); - } - - $mode = 0777; // default mode - foreach ($opts[0] as $opt) { - if ($opt[0] == 'p') { - $create_parents = true; - } elseif ($opt[0] == 'm') { - // if the mode is clearly an octal number (starts with 0) - // convert it to decimal - if (strlen($opt[1]) && $opt[1]{0} == '0') { - $opt[1] = octdec($opt[1]); - } else { - // convert to int - $opt[1] += 0; - } - $mode = $opt[1]; - } - } - - $ret = true; - if (isset($create_parents)) { - foreach ($opts[1] as $dir) { - $dirstack = array(); - while ((!file_exists($dir) || !is_dir($dir)) && - $dir != DIRECTORY_SEPARATOR) { - array_unshift($dirstack, $dir); - $dir = dirname($dir); - } - - while ($newdir = array_shift($dirstack)) { - if (!is_writeable(dirname($newdir))) { - $ret = false; - break; - } - - if (!mkdir($newdir, $mode)) { - $ret = false; - } - } - } - } else { - foreach($opts[1] as $dir) { - if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { - $ret = false; - } - } - } - - return $ret; - } - /** * Concatenate files * @@ -298,14 +65,12 @@ class System * 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) + * Note: as the class use fopen, urls should work also * - * @param string $args the arguments + * @param string $args the arguments * @return boolean true on success - * @static - * @access public */ - function &cat($args) + public static function &cat($args) { $ret = null; $files = array(); @@ -317,11 +82,11 @@ class System for ($i = 0; $i < $count_args; $i++) { if ($args[$i] == '>') { $mode = 'wb'; - $outputfile = $args[$i+1]; + $outputfile = $args[$i + 1]; break; } elseif ($args[$i] == '>>') { $mode = 'ab+'; - $outputfile = $args[$i+1]; + $outputfile = $args[$i + 1]; break; } else { $files[] = $args[$i]; @@ -355,6 +120,22 @@ class System return $ret; } + /** + * Output errors with PHP trigger_error(). You can silence the errors + * with prefixing a "@" sign to the function call: @System::mkdir(..); + * + * @param mixed $error a PEAR error or a string with the error message + * @return bool false + */ + protected static function raiseError($error) + { + if (PEAR::isError($error)) { + $error = $error->getMessage(); + } + trigger_error($error, E_USER_WARNING); + return false; + } + /** * Creates temporary files or directories. This function will remove * the created files when the scripts finish its execution. @@ -373,13 +154,11 @@ class System * TMPDIR in Unix will be used. If these vars are also missing * c:\windows\temp or /tmp will be used. * - * @param string $args The arguments + * @param string $args The arguments * @return mixed the full path of the created (file|dir) or false * @see System::tmpdir() - * @static - * @access public */ - function mktemp($args = null) + public static function mktemp($args = null) { static $first_time = true; $opts = System::_parseArgs($args, 't:d'); @@ -400,7 +179,7 @@ class System $tmpdir = System::tmpdir(); } - if (!System::mkDir(array('-p', $tmpdir))) { + if (!System::mkDir(['-p', $tmpdir])) { return false; } @@ -413,9 +192,9 @@ class System } $GLOBALS['_System_temp_files'][] = $tmp; - if (isset($tmp_is_dir)) { + /*if (isset($tmp_is_dir)) { //$GLOBALS['_System_temp_files'][] = dirname($tmp); - } + }*/ if ($first_time) { PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); @@ -426,20 +205,45 @@ class System } /** - * Remove temporary files created my mkTemp. This function is executed - * at script shutdown time + * returns the commandline arguments of a function * - * @static - * @access private + * @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 */ - function _removeTmpFiles() + public static function _parseArgs($argv, $short_options, $long_options = null) { - if (count($GLOBALS['_System_temp_files'])) { - $delete = $GLOBALS['_System_temp_files']; - array_unshift($delete, '-r'); - System::rm($delete); - $GLOBALS['_System_temp_files'] = array(); + if (!is_array($argv) && $argv !== null) { + /* + // Quote all items that are a short option + $av = preg_split('/(\A| )--?[a-z0-9]+[ =]?((? $a) { + if (empty($a)) { + continue; + } + $argv[$k] = trim($a); + } } + + return (new Console_Getopt)->getopt2($argv, $short_options, $long_options); } /** @@ -448,10 +252,9 @@ class System * Note: php.ini-recommended removes the "E" from the variables_order setting, * making unavaible the $_ENV array, that s why we do tests with _ENV * - * @static * @return string The temporary directory on the system */ - function tmpdir() + public static function tmpdir() { if (OS_WINDOWS) { if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { @@ -474,17 +277,222 @@ class System return realpath('/tmp'); } + /** + * Make directories. + * + * The -p option will create parent directories + * @param string $args the name of the director(y|ies) to create + * @return bool True for success + */ + public static function mkDir($args) + { + $opts = System::_parseArgs($args, 'pm:'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + + $mode = 0777; // default mode + foreach ($opts[0] as $opt) { + if ($opt[0] == 'p') { + $create_parents = true; + } elseif ($opt[0] == 'm') { + // if the mode is clearly an octal number (starts with 0) + // convert it to decimal + if (strlen($opt[1]) && $opt[1]{0} == '0') { + $opt[1] = octdec($opt[1]); + } else { + // convert to int + $opt[1] += 0; + } + $mode = $opt[1]; + } + } + + $ret = true; + if (isset($create_parents)) { + foreach ($opts[1] as $dir) { + $dirstack = array(); + while ((!file_exists($dir) || !is_dir($dir)) && + $dir != DIRECTORY_SEPARATOR) { + array_unshift($dirstack, $dir); + $dir = dirname($dir); + } + + while ($newdir = array_shift($dirstack)) { + if (!is_writeable(dirname($newdir))) { + $ret = false; + break; + } + + if (!mkdir($newdir, $mode)) { + $ret = false; + } + } + } + } else { + foreach ($opts[1] as $dir) { + if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { + $ret = false; + } + } + } + + return $ret; + } + + /** + * Remove temporary files created my mkTemp. This function is executed + * at script shutdown time + */ + public static function _removeTmpFiles() + { + if (count($GLOBALS['_System_temp_files'])) { + $delete = $GLOBALS['_System_temp_files']; + array_unshift($delete, '-r'); + System::rm($delete); + $GLOBALS['_System_temp_files'] = array(); + } + } + + /** + * 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 + * @static + * @access public + */ + public static function rm($args) + { + $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + foreach ($opts[0] as $opt) { + if ($opt[0] == 'r') { + $do_recursive = true; + } + } + $ret = true; + if (isset($do_recursive)) { + $struct = System::_multipleToStruct($opts[1]); + foreach ($struct['files'] as $file) { + if (!@unlink($file)) { + $ret = false; + } + } + + rsort($struct['dirs']); + foreach ($struct['dirs'] as $dir) { + if (!@rmdir($dir)) { + $ret = false; + } + } + } else { + foreach ($opts[1] as $file) { + $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; + if (!@$delete($file)) { + $ret = false; + } + } + } + return $ret; + } + + /** + * Creates a nested array representing the structure of a directory and files + * + * @param array $files Array listing files and dirs + * @return array + * @static + * @see System::_dirToStruct() + */ + protected static function _multipleToStruct($files) + { + $struct = array('dirs' => array(), 'files' => array()); + settype($files, 'array'); + foreach ($files as $file) { + if (is_dir($file) && !is_link($file)) { + $tmp = System::_dirToStruct($file, 0); + $struct = array_merge_recursive($tmp, $struct); + } else { + if (!in_array($file, $struct['files'])) { + $struct['files'][] = $file; + } + } + } + return $struct; + } + + /** + * 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 + * @param bool $silent if true, do not emit errors. + * @return array the structure of the dir + */ + protected static function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) + { + $struct = array('dirs' => array(), 'files' => array()); + if (($dir = @opendir($sPath)) === false) { + if (!$silent) { + System::raiseError("Could not open dir $sPath"); + } + return $struct; // XXX could not open error + } + + $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? + $list = array(); + while (false !== ($file = readdir($dir))) { + if ($file != '.' && $file != '..') { + $list[] = $file; + } + } + + closedir($dir); + natsort($list); + if ($aktinst < $maxinst || $maxinst == 0) { + foreach ($list as $val) { + $path = $sPath . DIRECTORY_SEPARATOR . $val; + if (is_dir($path) && !is_link($path)) { + $tmp = System::_dirToStruct($path, $maxinst, $aktinst + 1, $silent); + $struct = array_merge_recursive($struct, $tmp); + } else { + $struct['files'][] = $path; + } + } + } + + return $struct; + } + /** * The "which" command (show the full path of a command) * * @param string $program The command to search for - * @param mixed $fallback Value to return if $program is not found + * @param mixed $fallback Value to return if $program is not found * * @return mixed A string with the full path or false if not found - * @static * @author Stig Bakken */ - function which($program, $fallback = false) + public static function which($program, $fallback = false) { // enforce API if (!is_string($program) || '' == $program) { @@ -496,36 +504,37 @@ class System $path_elements[] = dirname($program); $program = basename($program); } else { - // Honor safe mode - if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { - $path = getenv('PATH'); - if (!$path) { - $path = getenv('Path'); // some OSes are just stupid enough to do this - } + $path = getenv('PATH'); + if (!$path) { + $path = getenv('Path'); // some OSes are just stupid enough to do this } + $path_elements = explode(PATH_SEPARATOR, $path); } if (OS_WINDOWS) { $exe_suffixes = getenv('PATHEXT') - ? explode(PATH_SEPARATOR, getenv('PATHEXT')) - : array('.exe','.bat','.cmd','.com'); + ? explode(PATH_SEPARATOR, getenv('PATHEXT')) + : array('.exe', '.bat', '.cmd', '.com'); // allow passing a command.exe param if (strpos($program, '.') !== false) { array_unshift($exe_suffixes, ''); } - // is_executable() is not available on windows for PHP4 - $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; } else { $exe_suffixes = array(''); - $pear_is_executable = 'is_executable'; } foreach ($exe_suffixes as $suff) { foreach ($path_elements as $dir) { $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; - if (@$pear_is_executable($file)) { + // It's possible to run a .bat on Windows that is_executable + // would return false for. The is_executable check is meaningless... + if (OS_WINDOWS) { return $file; + } else { + if (is_executable($file)) { + return $file; + } } } } @@ -544,19 +553,17 @@ class System * System::find("$dir -name *.php -name *.htm*"); * System::find("$dir -maxdepth 1"); * - * Params implmented: + * Params implemented: * $dir -> Start the search at this directory * -type d -> return only directories * -type f -> return only files * -maxdepth -> max depth of recursion * -name -> search pattern (bash style). Multiple -name param allowed * - * @param mixed Either array or string with the command line + * @param mixed Either array or string with the command line * @return array Array of found files - * @static - * */ - function find($args) + public static function find($args) { if (!is_array($args)) { $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); @@ -572,8 +579,8 @@ class System for ($i = 0; $i < $args_count; $i++) { switch ($args[$i]) { case '-type': - if (in_array($args[$i+1], array('d', 'f'))) { - if ($args[$i+1] == 'd') { + if (in_array($args[$i + 1], array('d', 'f'))) { + if ($args[$i + 1] == 'd') { $do_files = false; } else { $do_dirs = false; @@ -582,15 +589,15 @@ class System $i++; break; case '-name': - $name = preg_quote($args[$i+1], '#'); + $name = preg_quote($args[$i + 1], '#'); // our magic characters ? and * have just been escaped, // so now we change the escaped versions to PCRE operators $name = strtr($name, array('\?' => '.', '\*' => '.*')); - $patterns[] = '('.$name.')'; + $patterns[] = '(' . $name . ')'; $i++; break; case '-maxdepth': - $depth = $args[$i+1]; + $depth = $args[$i + 1]; break; } } @@ -604,7 +611,7 @@ class System } if (count($patterns)) { $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); - $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; + $pattern = '#(^|' . $dsq . ')' . implode('|', $patterns) . '($|' . $dsq . ')#'; $ret = array(); $files_count = count($files); for ($i = 0; $i < $files_count; $i++) { @@ -618,4 +625,4 @@ class System } return $files; } -} \ No newline at end of file +}