ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
System.php
Go to the documentation of this file.
1 <?php
20 require_once 'PEAR.php';
21 require_once 'Console/Getopt.php';
22 
23 $GLOBALS['_System_temp_files'] = array();
24 
59 class System
60 {
71  function _parseArgs($argv, $short_options, $long_options = null)
72  {
73  if (!is_array($argv) && $argv !== null) {
74  $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY);
75  }
76  return Console_Getopt::getopt2($argv, $short_options);
77  }
78 
88  function raiseError($error)
89  {
90  if (PEAR::isError($error)) {
91  $error = $error->getMessage();
92  }
93  trigger_error($error, E_USER_WARNING);
94  return false;
95  }
96 
122  function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false)
123  {
124  $struct = array('dirs' => array(), 'files' => array());
125  if (($dir = @opendir($sPath)) === false) {
126  if (!$silent) {
127  System::raiseError("Could not open dir $sPath");
128  }
129  return $struct; // XXX could not open error
130  }
131 
132  $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ?
133  $list = array();
134  while (false !== ($file = readdir($dir))) {
135  if ($file != '.' && $file != '..') {
136  $list[] = $file;
137  }
138  }
139 
140  closedir($dir);
141  natsort($list);
142  if ($aktinst < $maxinst || $maxinst == 0) {
143  foreach ($list as $val) {
144  $path = $sPath . DIRECTORY_SEPARATOR . $val;
145  if (is_dir($path) && !is_link($path)) {
146  $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent);
147  $struct = array_merge_recursive($struct, $tmp);
148  } else {
149  $struct['files'][] = $path;
150  }
151  }
152  }
153 
154  return $struct;
155  }
156 
165  function _multipleToStruct($files)
166  {
167  $struct = array('dirs' => array(), 'files' => array());
168  settype($files, 'array');
169  foreach ($files as $file) {
170  if (is_dir($file) && !is_link($file)) {
171  $tmp = System::_dirToStruct($file, 0);
172  $struct = array_merge_recursive($tmp, $struct);
173  } else {
174  if (!in_array($file, $struct['files'])) {
175  $struct['files'][] = $file;
176  }
177  }
178  }
179  return $struct;
180  }
181 
191  function rm($args)
192  {
193  $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-)
194  if (PEAR::isError($opts)) {
195  return System::raiseError($opts);
196  }
197  foreach ($opts[0] as $opt) {
198  if ($opt[0] == 'r') {
199  $do_recursive = true;
200  }
201  }
202  $ret = true;
203  if (isset($do_recursive)) {
204  $struct = System::_multipleToStruct($opts[1]);
205  foreach ($struct['files'] as $file) {
206  if (!@unlink($file)) {
207  $ret = false;
208  }
209  }
210 
211  rsort($struct['dirs']);
212  foreach ($struct['dirs'] as $dir) {
213  if (!@rmdir($dir)) {
214  $ret = false;
215  }
216  }
217  } else {
218  foreach ($opts[1] as $file) {
219  $delete = (is_dir($file)) ? 'rmdir' : 'unlink';
220  if (!@$delete($file)) {
221  $ret = false;
222  }
223  }
224  }
225  return $ret;
226  }
227 
237  function mkDir($args)
238  {
239  $opts = System::_parseArgs($args, 'pm:');
240  if (PEAR::isError($opts)) {
241  return System::raiseError($opts);
242  }
243 
244  $mode = 0777; // default mode
245  foreach ($opts[0] as $opt) {
246  if ($opt[0] == 'p') {
247  $create_parents = true;
248  } elseif ($opt[0] == 'm') {
249  // if the mode is clearly an octal number (starts with 0)
250  // convert it to decimal
251  if (strlen($opt[1]) && $opt[1]{0} == '0') {
252  $opt[1] = octdec($opt[1]);
253  } else {
254  // convert to int
255  $opt[1] += 0;
256  }
257  $mode = $opt[1];
258  }
259  }
260 
261  $ret = true;
262  if (isset($create_parents)) {
263  foreach ($opts[1] as $dir) {
264  $dirstack = array();
265  while ((!file_exists($dir) || !is_dir($dir)) &&
266  $dir != DIRECTORY_SEPARATOR) {
267  array_unshift($dirstack, $dir);
268  $dir = dirname($dir);
269  }
270 
271  while ($newdir = array_shift($dirstack)) {
272  if (!is_writeable(dirname($newdir))) {
273  $ret = false;
274  break;
275  }
276 
277  if (!mkdir($newdir, $mode)) {
278  $ret = false;
279  }
280  }
281  }
282  } else {
283  foreach($opts[1] as $dir) {
284  if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) {
285  $ret = false;
286  }
287  }
288  }
289 
290  return $ret;
291  }
292 
308  function &cat($args)
309  {
310  $ret = null;
311  $files = array();
312  if (!is_array($args)) {
313  $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
314  }
315 
316  $count_args = count($args);
317  for ($i = 0; $i < $count_args; $i++) {
318  if ($args[$i] == '>') {
319  $mode = 'wb';
320  $outputfile = $args[$i+1];
321  break;
322  } elseif ($args[$i] == '>>') {
323  $mode = 'ab+';
324  $outputfile = $args[$i+1];
325  break;
326  } else {
327  $files[] = $args[$i];
328  }
329  }
330  $outputfd = false;
331  if (isset($mode)) {
332  if (!$outputfd = fopen($outputfile, $mode)) {
333  $err = System::raiseError("Could not open $outputfile");
334  return $err;
335  }
336  $ret = true;
337  }
338  foreach ($files as $file) {
339  if (!$fd = fopen($file, 'r')) {
340  System::raiseError("Could not open $file");
341  continue;
342  }
343  while ($cont = fread($fd, 2048)) {
344  if (is_resource($outputfd)) {
345  fwrite($outputfd, $cont);
346  } else {
347  $ret .= $cont;
348  }
349  }
350  fclose($fd);
351  }
352  if (is_resource($outputfd)) {
353  fclose($outputfd);
354  }
355  return $ret;
356  }
357 
382  function mktemp($args = null)
383  {
384  static $first_time = true;
385  $opts = System::_parseArgs($args, 't:d');
386  if (PEAR::isError($opts)) {
387  return System::raiseError($opts);
388  }
389 
390  foreach ($opts[0] as $opt) {
391  if ($opt[0] == 'd') {
392  $tmp_is_dir = true;
393  } elseif ($opt[0] == 't') {
394  $tmpdir = $opt[1];
395  }
396  }
397 
398  $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp';
399  if (!isset($tmpdir)) {
400  $tmpdir = System::tmpdir();
401  }
402 
403  if (!System::mkDir(array('-p', $tmpdir))) {
404  return false;
405  }
406 
407  $tmp = tempnam($tmpdir, $prefix);
408  if (isset($tmp_is_dir)) {
409  unlink($tmp); // be careful possible race condition here
410  if (!mkdir($tmp, 0700)) {
411  return System::raiseError("Unable to create temporary directory $tmpdir");
412  }
413  }
414 
415  $GLOBALS['_System_temp_files'][] = $tmp;
416  if (isset($tmp_is_dir)) {
417  //$GLOBALS['_System_temp_files'][] = dirname($tmp);
418  }
419 
420  if ($first_time) {
421  PEAR::registerShutdownFunc(array('System', '_removeTmpFiles'));
422  $first_time = false;
423  }
424 
425  return $tmp;
426  }
427 
435  function _removeTmpFiles()
436  {
437  if (count($GLOBALS['_System_temp_files'])) {
438  $delete = $GLOBALS['_System_temp_files'];
439  array_unshift($delete, '-r');
440  System::rm($delete);
441  $GLOBALS['_System_temp_files'] = array();
442  }
443  }
444 
454  function tmpdir()
455  {
456  if (OS_WINDOWS) {
457  if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) {
458  return $var;
459  }
460  if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) {
461  return $var;
462  }
463  if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) {
464  return $var;
465  }
466  if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) {
467  return $var;
468  }
469  return getenv('SystemRoot') . '\temp';
470  }
471  if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) {
472  return $var;
473  }
474  return realpath('/tmp');
475  }
476 
487  function which($program, $fallback = false)
488  {
489  // enforce API
490  if (!is_string($program) || '' == $program) {
491  return $fallback;
492  }
493 
494  // full path given
495  if (basename($program) != $program) {
496  $path_elements[] = dirname($program);
497  $program = basename($program);
498  } else {
499  // Honor safe mode
500  if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) {
501  $path = getenv('PATH');
502  if (!$path) {
503  $path = getenv('Path'); // some OSes are just stupid enough to do this
504  }
505  }
506  $path_elements = explode(PATH_SEPARATOR, $path);
507  }
508 
509  if (OS_WINDOWS) {
510  $exe_suffixes = getenv('PATHEXT')
511  ? explode(PATH_SEPARATOR, getenv('PATHEXT'))
512  : array('.exe','.bat','.cmd','.com');
513  // allow passing a command.exe param
514  if (strpos($program, '.') !== false) {
515  array_unshift($exe_suffixes, '');
516  }
517  // is_executable() is not available on windows for PHP4
518  $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file';
519  } else {
520  $exe_suffixes = array('');
521  $pear_is_executable = 'is_executable';
522  }
523 
524  foreach ($exe_suffixes as $suff) {
525  foreach ($path_elements as $dir) {
526  $file = $dir . DIRECTORY_SEPARATOR . $program . $suff;
527  if (@$pear_is_executable($file)) {
528  return $file;
529  }
530  }
531  }
532  return $fallback;
533  }
534 
559  function find($args)
560  {
561  if (!is_array($args)) {
562  $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY);
563  }
564  $dir = realpath(array_shift($args));
565  if (!$dir) {
566  return array();
567  }
568  $patterns = array();
569  $depth = 0;
570  $do_files = $do_dirs = true;
571  $args_count = count($args);
572  for ($i = 0; $i < $args_count; $i++) {
573  switch ($args[$i]) {
574  case '-type':
575  if (in_array($args[$i+1], array('d', 'f'))) {
576  if ($args[$i+1] == 'd') {
577  $do_files = false;
578  } else {
579  $do_dirs = false;
580  }
581  }
582  $i++;
583  break;
584  case '-name':
585  $name = preg_quote($args[$i+1], '#');
586  // our magic characters ? and * have just been escaped,
587  // so now we change the escaped versions to PCRE operators
588  $name = strtr($name, array('\?' => '.', '\*' => '.*'));
589  $patterns[] = '('.$name.')';
590  $i++;
591  break;
592  case '-maxdepth':
593  $depth = $args[$i+1];
594  break;
595  }
596  }
597  $path = System::_dirToStruct($dir, $depth, 0, true);
598  if ($do_files && $do_dirs) {
599  $files = array_merge($path['files'], $path['dirs']);
600  } elseif ($do_dirs) {
601  $files = $path['dirs'];
602  } else {
603  $files = $path['files'];
604  }
605  if (count($patterns)) {
606  $dsq = preg_quote(DIRECTORY_SEPARATOR, '#');
607  $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#';
608  $ret = array();
609  $files_count = count($files);
610  for ($i = 0; $i < $files_count; $i++) {
611  // only search in the part of the file below the current directory
612  $filepart = basename($files[$i]);
613  if (preg_match($pattern, $filepart)) {
614  $ret[] = $files[$i];
615  }
616  }
617  return $ret;
618  }
619  return $files;
620  }
621 }