PageRenderTime 96ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/contrib/pfcInstaller2/System.php

https://github.com/touv/phpfreechat
PHP | 587 lines | 360 code | 18 blank | 209 comment | 97 complexity | 280dd4d725a486ffff1605aa16c77a6e MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * File/Directory manipulation
  4. *
  5. * PHP versions 4 and 5
  6. *
  7. * LICENSE: This source file is subject to version 3.0 of the PHP license
  8. * that is available through the world-wide-web at the following URI:
  9. * http://www.php.net/license/3_0.txt. If you did not receive a copy of
  10. * the PHP License and are unable to obtain it through the web, please
  11. * send a note to license@php.net so we can mail you a copy immediately.
  12. *
  13. * @category pear
  14. * @package System
  15. * @author Tomas V.V.Cox <cox@idecnet.com>
  16. * @copyright 1997-2006 The PHP Group
  17. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  18. * @version CVS: $Id: System.php,v 1.53.2.1 2006/06/16 13:55:16 pajoye Exp $
  19. * @link http://pear.php.net/package/PEAR
  20. * @since File available since Release 0.1
  21. */
  22. /**
  23. * base class
  24. */
  25. require_once 'PEAR.php';
  26. require_once 'Console/Getopt.php';
  27. $GLOBALS['_System_temp_files'] = array();
  28. /**
  29. * System offers cross plattform compatible system functions
  30. *
  31. * Static functions for different operations. Should work under
  32. * Unix and Windows. The names and usage has been taken from its respectively
  33. * GNU commands. The functions will return (bool) false on error and will
  34. * trigger the error with the PHP trigger_error() function (you can silence
  35. * the error by prefixing a '@' sign after the function call).
  36. *
  37. * Documentation on this class you can find in:
  38. * http://pear.php.net/manual/
  39. *
  40. * Example usage:
  41. * if (!@System::rm('-r file1 dir1')) {
  42. * print "could not delete file1 or dir1";
  43. * }
  44. *
  45. * In case you need to to pass file names with spaces,
  46. * pass the params as an array:
  47. *
  48. * System::rm(array('-r', $file1, $dir1));
  49. *
  50. * @category pear
  51. * @package System
  52. * @author Tomas V.V. Cox <cox@idecnet.com>
  53. * @copyright 1997-2006 The PHP Group
  54. * @license http://www.php.net/license/3_0.txt PHP License 3.0
  55. * @version Release: 1.4.11
  56. * @link http://pear.php.net/package/PEAR
  57. * @since Class available since Release 0.1
  58. */
  59. class System
  60. {
  61. /**
  62. * returns the commandline arguments of a function
  63. *
  64. * @param string $argv the commandline
  65. * @param string $short_options the allowed option short-tags
  66. * @param string $long_options the allowed option long-tags
  67. * @return array the given options and there values
  68. * @access private
  69. */
  70. function _parseArgs($argv, $short_options, $long_options = null)
  71. {
  72. if (!is_array($argv) && $argv !== null) {
  73. $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY);
  74. }
  75. return Console_Getopt::getopt2($argv, $short_options);
  76. }
  77. /**
  78. * Output errors with PHP trigger_error(). You can silence the errors
  79. * with prefixing a "@" sign to the function call: @System::mkdir(..);
  80. *
  81. * @param mixed $error a PEAR error or a string with the error message
  82. * @return bool false
  83. * @access private
  84. */
  85. function raiseError($error)
  86. {
  87. if (PEAR::isError($error)) {
  88. $error = $error->getMessage();
  89. }
  90. trigger_error($error, E_USER_WARNING);
  91. return false;
  92. }
  93. /**
  94. * Creates a nested array representing the structure of a directory
  95. *
  96. * System::_dirToStruct('dir1', 0) =>
  97. * Array
  98. * (
  99. * [dirs] => Array
  100. * (
  101. * [0] => dir1
  102. * )
  103. *
  104. * [files] => Array
  105. * (
  106. * [0] => dir1/file2
  107. * [1] => dir1/file3
  108. * )
  109. * )
  110. * @param string $sPath Name of the directory
  111. * @param integer $maxinst max. deep of the lookup
  112. * @param integer $aktinst starting deep of the lookup
  113. * @return array the structure of the dir
  114. * @access private
  115. */
  116. function _dirToStruct($sPath, $maxinst, $aktinst = 0)
  117. {
  118. $struct = array('dirs' => array(), 'files' => array());
  119. if (($dir = @opendir($sPath)) === false) {
  120. System::raiseError("Could not open dir $sPath");
  121. return $struct; // XXX could not open error
  122. }
  123. $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
  124. $list = array();
  125. while (false !== ($file = readdir($dir))) {
  126. if ($file != '.' && $file != '..') {
  127. $list[] = $file;
  128. }
  129. }
  130. closedir($dir);
  131. sort($list);
  132. if ($aktinst < $maxinst || $maxinst == 0) {
  133. foreach($list as $val) {
  134. $path = $sPath . DIRECTORY_SEPARATOR . $val;
  135. if (is_dir($path) && !is_link($path)) {
  136. $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1);
  137. $struct = array_merge_recursive($tmp, $struct);
  138. } else {
  139. $struct['files'][] = $path;
  140. }
  141. }
  142. }
  143. return $struct;
  144. }
  145. /**
  146. * Creates a nested array representing the structure of a directory and files
  147. *
  148. * @param array $files Array listing files and dirs
  149. * @return array
  150. * @see System::_dirToStruct()
  151. */
  152. function _multipleToStruct($files)
  153. {
  154. $struct = array('dirs' => array(), 'files' => array());
  155. settype($files, 'array');
  156. foreach ($files as $file) {
  157. if (is_dir($file) && !is_link($file)) {
  158. $tmp = System::_dirToStruct($file, 0);
  159. $struct = array_merge_recursive($tmp, $struct);
  160. } else {
  161. $struct['files'][] = $file;
  162. }
  163. }
  164. return $struct;
  165. }
  166. /**
  167. * The rm command for removing files.
  168. * Supports multiple files and dirs and also recursive deletes
  169. *
  170. * @param string $args the arguments for rm
  171. * @return mixed PEAR_Error or true for success
  172. * @access public
  173. */
  174. function rm($args)
  175. {
  176. $opts = System::_parseArgs($args, 'rf'); // "f" do nothing but like it :-)
  177. if (PEAR::isError($opts)) {
  178. return System::raiseError($opts);
  179. }
  180. foreach($opts[0] as $opt) {
  181. if ($opt[0] == 'r') {
  182. $do_recursive = true;
  183. }
  184. }
  185. $ret = true;
  186. if (isset($do_recursive)) {
  187. $struct = System::_multipleToStruct($opts[1]);
  188. foreach($struct['files'] as $file) {
  189. if (!@unlink($file)) {
  190. $ret = false;
  191. }
  192. }
  193. foreach($struct['dirs'] as $dir) {
  194. if (!@rmdir($dir)) {
  195. $ret = false;
  196. }
  197. }
  198. } else {
  199. foreach ($opts[1] as $file) {
  200. $delete = (is_dir($file)) ? 'rmdir' : 'unlink';
  201. if (!@$delete($file)) {
  202. $ret = false;
  203. }
  204. }
  205. }
  206. return $ret;
  207. }
  208. /**
  209. * Make directories.
  210. *
  211. * The -p option will create parent directories
  212. * @param string $args the name of the director(y|ies) to create
  213. * @return bool True for success
  214. * @access public
  215. */
  216. function mkDir($args)
  217. {
  218. $opts = System::_parseArgs($args, 'pm:');
  219. if (PEAR::isError($opts)) {
  220. return System::raiseError($opts);
  221. }
  222. $mode = 0777; // default mode
  223. foreach($opts[0] as $opt) {
  224. if ($opt[0] == 'p') {
  225. $create_parents = true;
  226. } elseif($opt[0] == 'm') {
  227. // if the mode is clearly an octal number (starts with 0)
  228. // convert it to decimal
  229. if (strlen($opt[1]) && $opt[1]{0} == '0') {
  230. $opt[1] = octdec($opt[1]);
  231. } else {
  232. // convert to int
  233. $opt[1] += 0;
  234. }
  235. $mode = $opt[1];
  236. }
  237. }
  238. $ret = true;
  239. if (isset($create_parents)) {
  240. foreach($opts[1] as $dir) {
  241. $dirstack = array();
  242. while (!@is_dir($dir) && $dir != DIRECTORY_SEPARATOR) {
  243. array_unshift($dirstack, $dir);
  244. $dir = dirname($dir);
  245. }
  246. while ($newdir = array_shift($dirstack)) {
  247. if (!is_writeable(dirname($newdir))) {
  248. $ret = false;
  249. break;
  250. }
  251. if (!mkdir($newdir, $mode)) {
  252. $ret = false;
  253. }
  254. }
  255. }
  256. } else {
  257. foreach($opts[1] as $dir) {
  258. if (!@is_dir($dir) && !mkdir($dir, $mode)) {
  259. $ret = false;
  260. }
  261. }
  262. }
  263. return $ret;
  264. }
  265. /**
  266. * Concatenate files
  267. *
  268. * Usage:
  269. * 1) $var = System::cat('sample.txt test.txt');
  270. * 2) System::cat('sample.txt test.txt > final.txt');
  271. * 3) System::cat('sample.txt test.txt >> final.txt');
  272. *
  273. * Note: as the class use fopen, urls should work also (test that)
  274. *
  275. * @param string $args the arguments
  276. * @return boolean true on success
  277. * @access public
  278. */
  279. function &cat($args)
  280. {
  281. $ret = null;
  282. $files = array();
  283. if (!is_array($args)) {
  284. $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
  285. }
  286. for($i=0; $i < count($args); $i++) {
  287. if ($args[$i] == '>') {
  288. $mode = 'wb';
  289. $outputfile = $args[$i+1];
  290. break;
  291. } elseif ($args[$i] == '>>') {
  292. $mode = 'ab+';
  293. $outputfile = $args[$i+1];
  294. break;
  295. } else {
  296. $files[] = $args[$i];
  297. }
  298. }
  299. if (isset($mode)) {
  300. if (!$outputfd = fopen($outputfile, $mode)) {
  301. $err = System::raiseError("Could not open $outputfile");
  302. return $err;
  303. }
  304. $ret = true;
  305. }
  306. foreach ($files as $file) {
  307. if (!$fd = fopen($file, 'r')) {
  308. System::raiseError("Could not open $file");
  309. continue;
  310. }
  311. while ($cont = fread($fd, 2048)) {
  312. if (isset($outputfd)) {
  313. fwrite($outputfd, $cont);
  314. } else {
  315. $ret .= $cont;
  316. }
  317. }
  318. fclose($fd);
  319. }
  320. if (@is_resource($outputfd)) {
  321. fclose($outputfd);
  322. }
  323. return $ret;
  324. }
  325. /**
  326. * Creates temporary files or directories. This function will remove
  327. * the created files when the scripts finish its execution.
  328. *
  329. * Usage:
  330. * 1) $tempfile = System::mktemp("prefix");
  331. * 2) $tempdir = System::mktemp("-d prefix");
  332. * 3) $tempfile = System::mktemp();
  333. * 4) $tempfile = System::mktemp("-t /var/tmp prefix");
  334. *
  335. * prefix -> The string that will be prepended to the temp name
  336. * (defaults to "tmp").
  337. * -d -> A temporary dir will be created instead of a file.
  338. * -t -> The target dir where the temporary (file|dir) will be created. If
  339. * this param is missing by default the env vars TMP on Windows or
  340. * TMPDIR in Unix will be used. If these vars are also missing
  341. * c:\windows\temp or /tmp will be used.
  342. *
  343. * @param string $args The arguments
  344. * @return mixed the full path of the created (file|dir) or false
  345. * @see System::tmpdir()
  346. * @access public
  347. */
  348. function mktemp($args = null)
  349. {
  350. static $first_time = true;
  351. $opts = System::_parseArgs($args, 't:d');
  352. if (PEAR::isError($opts)) {
  353. return System::raiseError($opts);
  354. }
  355. foreach($opts[0] as $opt) {
  356. if($opt[0] == 'd') {
  357. $tmp_is_dir = true;
  358. } elseif($opt[0] == 't') {
  359. $tmpdir = $opt[1];
  360. }
  361. }
  362. $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
  363. if (!isset($tmpdir)) {
  364. $tmpdir = System::tmpdir();
  365. }
  366. if (!System::mkDir(array('-p', $tmpdir))) {
  367. return false;
  368. }
  369. $tmp = tempnam($tmpdir, $prefix);
  370. if (isset($tmp_is_dir)) {
  371. unlink($tmp); // be careful possible race condition here
  372. if (!mkdir($tmp, 0700)) {
  373. return System::raiseError("Unable to create temporary directory $tmpdir");
  374. }
  375. }
  376. $GLOBALS['_System_temp_files'][] = $tmp;
  377. if ($first_time) {
  378. PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
  379. $first_time = false;
  380. }
  381. return $tmp;
  382. }
  383. /**
  384. * Remove temporary files created my mkTemp. This function is executed
  385. * at script shutdown time
  386. *
  387. * @access private
  388. */
  389. function _removeTmpFiles()
  390. {
  391. if (count($GLOBALS['_System_temp_files'])) {
  392. $delete = $GLOBALS['_System_temp_files'];
  393. array_unshift($delete, '-r');
  394. System::rm($delete);
  395. $GLOBALS['_System_temp_files'] = array();
  396. }
  397. }
  398. /**
  399. * Get the path of the temporal directory set in the system
  400. * by looking in its environments variables.
  401. * Note: php.ini-recommended removes the "E" from the variables_order setting,
  402. * making unavaible the $_ENV array, that s why we do tests with _ENV
  403. *
  404. * @return string The temporal directory on the system
  405. */
  406. function tmpdir()
  407. {
  408. if (OS_WINDOWS) {
  409. if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
  410. return $var;
  411. }
  412. if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
  413. return $var;
  414. }
  415. if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
  416. return $var;
  417. }
  418. return getenv('SystemRoot') . '\temp';
  419. }
  420. if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
  421. return $var;
  422. }
  423. return '/tmp';
  424. }
  425. /**
  426. * The "which" command (show the full path of a command)
  427. *
  428. * @param string $program The command to search for
  429. * @param mixed $fallback Value to return if $program is not found
  430. *
  431. * @return mixed A string with the full path or false if not found
  432. * @author Stig Bakken <ssb@php.net>
  433. */
  434. function which($program, $fallback = false)
  435. {
  436. // enforce API
  437. if (!is_string($program) || '' == $program) {
  438. return $fallback;
  439. }
  440. // available since 4.3.0RC2
  441. if (defined('PATH_SEPARATOR')) {
  442. $path_delim = PATH_SEPARATOR;
  443. } else {
  444. $path_delim = OS_WINDOWS ? ';' : ':';
  445. }
  446. // full path given
  447. if (basename($program) != $program) {
  448. $path_elements[] = dirname($program);
  449. $program = basename($program);
  450. } else {
  451. // Honor safe mode
  452. if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) {
  453. $path = getenv('PATH');
  454. if (!$path) {
  455. $path = getenv('Path'); // some OSes are just stupid enough to do this
  456. }
  457. }
  458. $path_elements = explode($path_delim, $path);
  459. }
  460. if (OS_WINDOWS) {
  461. $exe_suffixes = getenv('PATHEXT')
  462. ? explode($path_delim, getenv('PATHEXT'))
  463. : array('.exe','.bat','.cmd','.com');
  464. // allow passing a command.exe param
  465. if (strpos($program, '.') !== false) {
  466. array_unshift($exe_suffixes, '');
  467. }
  468. // is_executable() is not available on windows for PHP4
  469. $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file';
  470. } else {
  471. $exe_suffixes = array('');
  472. $pear_is_executable = 'is_executable';
  473. }
  474. foreach ($exe_suffixes as $suff) {
  475. foreach ($path_elements as $dir) {
  476. $file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
  477. if (@$pear_is_executable($file)) {
  478. return $file;
  479. }
  480. }
  481. }
  482. return $fallback;
  483. }
  484. /**
  485. * The "find" command
  486. *
  487. * Usage:
  488. *
  489. * System::find($dir);
  490. * System::find("$dir -type d");
  491. * System::find("$dir -type f");
  492. * System::find("$dir -name *.php");
  493. * System::find("$dir -name *.php -name *.htm*");
  494. * System::find("$dir -maxdepth 1");
  495. *
  496. * Params implmented:
  497. * $dir -> Start the search at this directory
  498. * -type d -> return only directories
  499. * -type f -> return only files
  500. * -maxdepth <n> -> max depth of recursion
  501. * -name <pattern> -> search pattern (bash style). Multiple -name param allowed
  502. *
  503. * @param mixed Either array or string with the command line
  504. * @return array Array of found files
  505. *
  506. */
  507. function find($args)
  508. {
  509. if (!is_array($args)) {
  510. $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
  511. }
  512. $dir = array_shift($args);
  513. $patterns = array();
  514. $depth = 0;
  515. $do_files = $do_dirs = true;
  516. for ($i = 0; $i < count($args); $i++) {
  517. switch ($args[$i]) {
  518. case '-type':
  519. if (in_array($args[$i+1], array('d', 'f'))) {
  520. if ($args[$i+1] == 'd') {
  521. $do_files = false;
  522. } else {
  523. $do_dirs = false;
  524. }
  525. }
  526. $i++;
  527. break;
  528. case '-name':
  529. if (OS_WINDOWS) {
  530. if ($args[$i+1]{0} == '\\') {
  531. // prepend drive
  532. $args[$i+1] = addslashes(substr(getcwd(), 0, 2) . $args[$i + 1]);
  533. }
  534. // escape path separators to avoid PCRE problems
  535. $args[$i+1] = str_replace('\\', '\\\\', $args[$i+1]);
  536. }
  537. $patterns[] = "(" . preg_replace(array('/\./', '/\*/'),
  538. array('\.', '.*', ),
  539. $args[$i+1])
  540. . ")";
  541. $i++;
  542. break;
  543. case '-maxdepth':
  544. $depth = $args[$i+1];
  545. break;
  546. }
  547. }
  548. $path = System::_dirToStruct($dir, $depth);
  549. if ($do_files && $do_dirs) {
  550. $files = array_merge($path['files'], $path['dirs']);
  551. } elseif ($do_dirs) {
  552. $files = $path['dirs'];
  553. } else {
  554. $files = $path['files'];
  555. }
  556. if (count($patterns)) {
  557. $patterns = implode('|', $patterns);
  558. $ret = array();
  559. for ($i = 0; $i < count($files); $i++) {
  560. if (preg_match("#^$patterns\$#", $files[$i])) {
  561. $ret[] = $files[$i];
  562. }
  563. }
  564. return $ret;
  565. }
  566. return $files;
  567. }
  568. }
  569. ?>