[BUGFIX] Autoloader Cache is not updated
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_exec.php
old mode 100755 (executable)
new mode 100644 (file)
index 0f62a4e..f76c8af
@@ -1,72 +1,48 @@
 <?php
 /***************************************************************
-*  Copyright notice
-*  
-*  (c) 2002-2004 René Fritz (r.fritz@colorcube.de)
-*  All rights reserved
-*
-*  This script is part of the Typo3 project. The Typo3 project is
-*  free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License as published by
-*  the Free Software Foundation; either version 2 of the License, or
-*  (at your option) any later version.
-*
-*  The GNU General Public License can be found at
-*  http://www.gnu.org/copyleft/gpl.html.
-*
-*  This script is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  This copyright notice MUST APPEAR in all copies of the script!
-***************************************************************/
-/**
- * t3lib_exec find executables (programs) on unix and windows without knowing where they are
- *
- * $Id$
+ *  Copyright notice
  *
- * @author     René Fritz <r.fritz@colorcube.de>
- */
-/**
- * [CLASS/FUNCTION INDEX of SCRIPT]
+ *  (c) 2002-2011 René Fritz (r.fritz@colorcube.de)
+ *  All rights reserved
  *
+ *  This script is part of the Typo3 project. The Typo3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
  *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
  *
- *   81: class t3lib_exec 
- *   91:     function checkCommand($cmd, $handler='')  
- *  162:     function getCommand($cmd, $handler='', $handlerOpt='')    
- *  191:     function addPaths($paths) 
- *  201:     function _getPaths()      
- *  269:     function _init()  
- *  285:     function _initPaths($paths='')    
- *  340:     function _getOS() 
- *  351:     function _fixPath($path)  
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
  *
- * TOTAL FUNCTIONS: 8
- * (This index is automatically created/updated by the extension "extdeveval")
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+/**
+ * t3lib_exec finds executables (programs) on Unix and Windows without knowing where they are
  *
+ * @author     René Fritz <r.fritz@colorcube.de>
  */
 
 
-
-
-
 /**
  * returns exec command for a program
- * or false
+ * or FALSE
  *
  * This class is meant to be used without instance:
  * $cmd = t3lib_exec::getCommand ('awstats','perl');
  *
- * The data of this class is hold in a global variable. Doing it this way the setup is cached.
+ * The data of this class is cached.
  * That means if a program is found once it don't have to be searched again.
  *
  * user functions:
  *
  * addPaths() could be used to extend the search paths
  * getCommand() get a command string
- * checkCommand() returns true if a command is available
+ * checkCommand() returns TRUE if a command is available
  *
  * Search paths that are included:
  * $TYPO3_CONF_VARS['GFX']['im_path_lzw'] or $TYPO3_CONF_VARS['GFX']['im_path']
  * $GLOBALS['_SERVER']['PATH']
  * '/usr/bin/,/usr/local/bin/' on Unix
  *
- * @author     René Fritz <r.fritz@colorcube.de>
- * @package TYPO3
- * @subpackage t3lib
+ * binaries can be preconfigured with
+ * $TYPO3_CONF_VARS['SYS']['binSetup']
+ *
+ * @author             René Fritz <r.fritz@colorcube.de>
+ * @package            TYPO3
+ * @subpackage t3lib
  */
 class t3lib_exec {
 
+       /** Tells if object is already initialized */
+       protected static $initialized = FALSE;
+
        /**
-        * checks if a command is valid or not
-        * updates global vars
+        * Contains application list. This is an array with the following structure:
+        * - app => file name to the application (like 'tar' or 'bzip2')
+        * - path => full path to the application without application name (like '/usr/bin/' for '/usr/bin/tar')
+        * - valid => TRUE or FALSE
+        * Array key is identical to 'app'.
         *
-        * @param       string          the command that should be executed. eg: "convert"
-        * @param       string          executer for the command. eg: "perl"
-        * @return      boolean         false if cmd is not found, or -1 if the handler is not found
+        * @var array
         */
-       function checkCommand($cmd, $handler='')        {
-
-               t3lib_exec::_init();
-               $osType = t3lib_exec::_getOS();
+       protected static $applications = array();
 
+       /**
+        * Paths where to search for applications
+        *
+        * @var array
+        */
+       protected static $paths = NULL;
 
-#debug($GLOBALS['t3lib_exec'], 't3lib_exec', __LINE__, __FILE__);
+       /**
+        * Checks if a command is valid or not, updates global variables
+        *
+        * @param       string          the command that should be executed. eg: "convert"
+        * @param       string          executer for the command. eg: "perl"
+        * @return      boolean         FALSE if cmd is not found, or -1 if the handler is not found
+        */
+       public static function checkCommand($cmd, $handler = '') {
+               if (!self::init()) {
+                       return FALSE;
+               }
 
-               if ($handler && !t3lib_exec::checkCommand($handler)) {
+               if ($handler && !self::checkCommand($handler)) {
                        return -1;
                }
-                       // already checked and valid
-               if ($GLOBALS['t3lib_exec']['apps'][$cmd]['valid']) {
-                       return true;
+                       // Already checked and valid
+               if (self::$applications[$cmd]['valid']) {
+                       return TRUE;
                }
-                       // is set but was (above) not true
-               if (isset($GLOBALS['t3lib_exec']['apps'][$cmd]['valid'])) {
-                       return false;
+                       // Is set but was (above) not TRUE
+               if (isset(self::$applications[$cmd]['valid'])) {
+                       return FALSE;
                }
-               
-               reset($GLOBALS['t3lib_exec']['paths']);
-               foreach($GLOBALS['t3lib_exec']['paths'] as $path => $validPath) {
-                               // ignore invalid (false) paths
+
+               foreach (self::$paths as $path => $validPath) {
+                               // Ignore invalid (FALSE) paths
                        if ($validPath) {
-                               if ($osType=='WIN') {
-                                       if (@is_file($path.$cmd)) {
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = $path;
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
-                                               return true;
+                               if (TYPO3_OS == 'WIN') {
+                                               // Windows OS
+                                               // TODO Why is_executable() is not called here?
+                                       if (@is_file($path . $cmd)) {
+                                               self::$applications[$cmd]['app'] = $cmd;
+                                               self::$applications[$cmd]['path'] = $path;
+                                               self::$applications[$cmd]['valid'] = TRUE;
+                                               return TRUE;
                                        }
-                                       if (@is_file($path.$cmd.'.exe')) {
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd.'.exe';
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = $path;
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
-                                               return true;
+                                       if (@is_file($path . $cmd . '.exe')) {
+                                               self::$applications[$cmd]['app'] = $cmd . '.exe';
+                                               self::$applications[$cmd]['path'] = $path;
+                                               self::$applications[$cmd]['valid'] = TRUE;
+                                               return TRUE;
                                        }
-                               } else { // UNIX
-                                       if (@is_executable($path.$cmd)) {
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = $path;
-                                               $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
-                                               return true;
+                               } else {
+                                               // Unix-like OS
+                                       $filePath = realpath($path . $cmd);
+                                       if ($filePath && @is_executable($filePath)) {
+                                               self::$applications[$cmd]['app'] = $cmd;
+                                               self::$applications[$cmd]['path'] = $path;
+                                               self::$applications[$cmd]['valid'] = TRUE;
+                                               return TRUE;
                                        }
                                }
                        }
                }
 
-                       // try to get the executable with the command 'which'. It do the same like already done, but maybe on other paths??
-               if ($osType=='UNIX') {
-                       $cmd = @exec ('which '.$val['cmd']);
-
+                       // Try to get the executable with the command 'which'.
+                       // It does the same like already done, but maybe on other paths
+               if (TYPO3_OS != 'WIN') {
+                       $cmd = @t3lib_utility_Command::exec('which ' . $cmd);
                        if (@is_executable($cmd)) {
-                               $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
-                               $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = dirname($cmd).'/';
-                               $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
-                               return true;
+                               self::$applications[$cmd]['app'] = $cmd;
+                               self::$applications[$cmd]['path'] = dirname($cmd) . '/';
+                               self::$applications[$cmd]['valid'] = TRUE;
+                               return TRUE;
                        }
                }
 
-               return false;
+               return FALSE;
        }
-       
+
+
        /**
-        * returns a command string for exec(), system()
+        * Returns a command string for exec(), system()
         *
         * @param       string          the command that should be executed. eg: "convert"
         * @param       string          handler (executor) for the command. eg: "perl"
         * @param       string          options for the handler, like '-w' for "perl"
-        * @return      mixed           returns command string, or false if cmd is not found, or -1 if the handler is not found
+        * @return      mixed           returns command string, or FALSE if cmd is not found, or -1 if the handler is not found
         */
-       function getCommand($cmd, $handler='', $handlerOpt='')  {
-
-               t3lib_exec::_init();
+       public static function getCommand($cmd, $handler = '', $handlerOpt = '') {
+               if (!self::init()) {
+                       return FALSE;
+               }
 
                        // handler
                if ($handler) {
-                       $handler = t3lib_exec::getCommand($handler);
+                       $handler = self::getCommand($handler);
 
                        if (!$handler) {
                                return -1;
                        }
-                       $handler .= ' '.$handlerOpt.' ';
+                       $handler .= ' ' . $handlerOpt . ' ';
                }
 
                        // command
-               if (!t3lib_exec::checkCommand($cmd)) {
-                       return false;
+               if (!self::checkCommand($cmd)) {
+                       return FALSE;
                }
-               $cmd = $GLOBALS['t3lib_exec']['apps'][$cmd]['path'].$GLOBALS['t3lib_exec']['apps'][$cmd]['app'].' ';
+               $cmd = self::$applications[$cmd]['path'] . self::$applications[$cmd]['app'] . ' ';
 
-               return $handler.$cmd;
+               return trim($handler . $cmd);
        }
 
+
        /**
-        * Extend the preset paths. This way an extension can install an axecutable and provide the path to t3lib_exec.
+        * Extend the preset paths. This way an extension can install an executable and provide the path to t3lib_exec.
         *
-        * @param       string          comma seperated list of extra paths where a command should be searched. Relative paths (without leading "/") are prepend with site root path (PATH_site).
-        * @return      [type]          ...
+        * @param       string          comma separated list of extra paths where a command should be searched. Relative paths (without leading "/") are prepend with site root path (PATH_site).
+        * @return      void
         */
-       function addPaths($paths)       {
-               t3lib_exec::_initPaths($paths);
+       public static function addPaths($paths) {
+               self::initPaths($paths);
        }
 
+
        /**
-        * set the search paths from different sources
+        * Returns an array of search paths
         *
-        * @return      [type]          ...
-        * @internal
+        * @param       boolean         If set the array contains invalid path too. Then the key is the path and the value is empty
+        * @return      array           Array of search paths (empty if exec is disabled)
         */
-       function _getPaths()    {
-               global $TYPO3_CONF_VARS;
-
-               $pathsArr = array();
-               $sysPathArr = array();
-               $osType = t3lib_exec::_getOS();
-
-                       // image magick paths first
-                       // im_path_lzw take precedence over im_path
-               if ($imPath = ($TYPO3_CONF_VARS['GFX']['im_path_lzw'] ? $TYPO3_CONF_VARS['GFX']['im_path_lzw'] : $TYPO3_CONF_VARS['GFX']['im_path'])) {
-                       $imPath = t3lib_exec::_fixPath($imPath);
-                       $pathsArr[$imPath] = $imPath;
+       public static function getPaths($addInvalid = FALSE) {
+               if (!self::init()) {
+                       return array();
                }
 
-                       // add configured paths
-               if ($TYPO3_CONF_VARS['SYS']['binPath']) {
-                       $sysPath = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['SYS']['binPath'],1);
-                       reset($sysPath);
-                       while(list(,$val)=each($sysPath)) {
-                               $val = t3lib_exec::_fixPath($val);
-                               $sysPathArr[$val]=$val;
-                       }
-               }
-
-
-               
+               $paths = self::$paths;
 
-# ???? t3lib_div::getIndpEnv('REQUEST_URI');
-
-
-                       // add path from environment
-#TODO: how does this work for WIN
-               if ($GLOBALS['_SERVER']['PATH']) {
-                       $sep = ($osType=='WIN') ? ';' : ':';
-                       $envPath = t3lib_div::trimExplode($sep,$GLOBALS['_SERVER']['PATH'],1);
-                       reset($envPath);
-                       while(list(,$val)=each($envPath)) {
-                               $val = t3lib_exec::_fixPath($val);
-                               $sysPathArr[$val]=$val;
+               if (!$addInvalid) {
+                       foreach ($paths as $path => $validPath) {
+                               if (!$validPath) {
+                                       unset($paths[$path]);
+                               }
                        }
                }
-
-               if ($osType=='WIN') {
-#TODO: add the most common paths for WIN
-                       $sysPathArr = array_merge($sysPathArr, array (
-                               '/usr/bin/' => '/usr/bin/',
-                               '/perl/bin/' => '/perl/bin/',
-                       ));
-               } else { // UNIX
-                       $sysPathArr = array_merge($sysPathArr, array (
-                               '/usr/bin/' => '/usr/bin/',
-                               '/usr/local/bin/' => '/usr/local/bin/',
-                       ));
-               }
-
-#debug($pathsArr, '$pathsArr', __LINE__, __FILE__);
-#debug($GLOBALS['_SERVER']['PATH'], 'PATH', __LINE__, __FILE__);
-
-               $pathsArr = array_merge($pathsArr, $sysPathArr);
-               return $pathsArr;
+               return $paths;
        }
 
+
        /**
-        * init
+        * Initializes this class
         *
-        * @return      [type]          ...
-        * @internal
+        * @return      void
         */
-       function _init()        {
-               if (!$GLOBALS['t3lib_exec']['init']) {
-
-                       t3lib_exec::_initPaths();
-                       $GLOBALS['t3lib_exec']['apps'] = array();
-                       $GLOBALS['t3lib_exec']['init'] = true;
+       protected static function init() {
+               if ($GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function']) {
+                       return FALSE;
+               }
+               if (!self::$initialized) {
+                       self::initPaths();
+                       self::$applications = self::getConfiguredApps();
+                       self::$initialized = TRUE;
                }
+               return TRUE;
        }
 
+
        /**
-        * init and extend the preset paths with own
+        * Initializes and extends the preset paths with own
         *
-        * @param       string          comma seperated list of extra paths where a command should be searched. Relative paths (without leading "/") are prepend with site root path (PATH_site).
-        * @return      [type]          ...
-        * @internal
+        * @param       string          Comma seperated list of extra paths where a command should be searched. Relative paths (without leading "/") are prepend with site root path (PATH_site).
+        * @return      void
         */
-       function _initPaths($paths='')  {
-               $doCeck=false;
+       protected static function initPaths($paths = '') {
+               $doCheck = FALSE;
 
                        // init global paths array if not already done
-               if (!is_array($GLOBALS['t3lib_exec']['paths'])) {
-                       $GLOBALS['t3lib_exec']['paths'] = t3lib_exec::_getPaths();
-                       $doCeck=true;
+               if (!is_array(self::$paths)) {
+                       self::$paths = self::getPathsInternal();
+                       $doCheck = TRUE;
                }
                        // merge the submitted paths array to the global
                if ($paths) {
-                       $paths = t3lib_div::trimExplode(',',$paths,1);
+                       $paths = t3lib_div::trimExplode(',', $paths, 1);
                        if (is_array($paths)) {
-                               reset($paths);
-                               while(list(,$path)=each($paths)) {
+                               foreach ($paths as $path) {
                                                // make absolute path of relative
-                                       if (!preg_match('#^/#',$path)) {
-                                               $path = PATH_site.$path;
+                                       if (!preg_match('#^/#', $path)) {
+                                               $path = PATH_site . $path;
                                        }
-                                       if (!isset($GLOBALS['t3lib_exec']['paths'][$path])) {
+                                       if (!isset(self::$paths[$path])) {
                                                if (@is_dir($path)) {
-                                                       $GLOBALS['t3lib_exec']['paths'][$path] = $path;
-                                                       $GLOBALS['t3lib_exec']['allPaths'].=','.$path;
-                                                       // $doCeck=true; just done
+                                                       self::$paths[$path] = $path;
                                                } else {
-                                                       $GLOBALS['t3lib_exec']['paths'][$path] = false;
+                                                       self::$paths[$path] = FALSE;
                                                }
                                        }
                                }
                        }
                }
                        // check if new paths are invalid
-               if ($doCeck) {
-                       $GLOBALS['t3lib_exec']['allPaths']='';
-                       reset($GLOBALS['t3lib_exec']['paths']);
-                       while(list($path,$valid)=each($GLOBALS['t3lib_exec']['paths'])) {
-                                       // ignore invalid (false) paths
-#TODO: what's the idea not to remove invalid paths?
-                               if ($valid) {
-                                       if (!@is_dir($path)) {
-                                               $GLOBALS['t3lib_exec']['paths'][$path] = false;
-                                       }
-                               }
-                               if ($path = $GLOBALS['t3lib_exec']['paths'][$path]) {
-                                       $GLOBALS['t3lib_exec']['allPaths'].=','.$path;
+               if ($doCheck) {
+                       foreach (self::$paths as $path => $valid) {
+                                       // ignore invalid (FALSE) paths
+                               if ($valid AND !@is_dir($path)) {
+                                       self::$paths[$path] = FALSE;
                                }
                        }
                }
        }
 
+
        /**
-        * returns on which OS we're runing
+        * Processes and returns the paths from $GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']
         *
-        * @return      string          the OS type: "UNIX" or "WIN"
-        * @internal
+        * @return      array   Array of commands and path
         */
-       function _getOS()       {
-               return stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'UNIX';
+       protected static function getConfiguredApps() {
+               $cmdArr = array();
+
+               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']) {
+                       $pathSetup = preg_split('/[\n,]+/', $GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']);
+                       foreach ($pathSetup as $val) {
+                               list($cmd, $cmdPath) = t3lib_div::trimExplode('=', $val, 1);
+                               $cmdArr[$cmd]['app'] = basename($cmdPath);
+                               $cmdArr[$cmd]['path'] = dirname($cmdPath) . '/';
+                               $cmdArr[$cmd]['valid'] = TRUE;
+                       }
+               }
+
+               return $cmdArr;
        }
 
+
+       /**
+        * Sets the search paths from different sources, internal
+        *
+        * @return      array           Array of absolute paths (keys and values are equal)
+        */
+       protected static function getPathsInternal() {
+
+               $pathsArr = array();
+               $sysPathArr = array();
+
+                       // image magick paths first
+                       // im_path_lzw take precedence over im_path
+               if (($imPath = ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw'] : $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path']))) {
+                       $imPath = self::fixPath($imPath);
+                       $pathsArr[$imPath] = $imPath;
+               }
+
+                       // add configured paths
+               if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['binPath']) {
+                       $sysPath = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['binPath'], 1);
+                       foreach ($sysPath as $val) {
+                               $val = self::fixPath($val);
+                               $sysPathArr[$val] = $val;
+                       }
+               }
+
+
+                       // add path from environment
+                       // TODO: how does this work for WIN
+               if ($GLOBALS['_SERVER']['PATH']) {
+                       $sep = (TYPO3_OS == 'WIN' ? ';' : ':');
+                       $envPath = t3lib_div::trimExplode($sep, $GLOBALS['_SERVER']['PATH'], 1);
+                       foreach ($envPath as $val) {
+                               $val = self::fixPath($val);
+                               $sysPathArr[$val] = $val;
+                       }
+               }
+
+                       // Set common paths for Unix (only)
+               if (TYPO3_OS !== 'WIN') {
+                       $sysPathArr = array_merge($sysPathArr, array(
+                               '/usr/bin/' => '/usr/bin/',
+                               '/usr/local/bin/' => '/usr/local/bin/',
+                       ));
+               }
+
+               $pathsArr = array_merge($pathsArr, $sysPathArr);
+
+               return $pathsArr;
+       }
+
+
        /**
-        * set a path to the right format
+        * Set a path to the right format
         *
-        * @param       string          path
-        * @return      string          path
-        * @internal
+        * @param       string          Input path
+        * @return      string          Output path
         */
-       function _fixPath($path)        {
-               return str_replace ('//',"/",$path.'/');
+       protected static function fixPath($path) {
+               return str_replace('//', '/', $path . '/');
        }
 }
 
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php'])     {
-       include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php'])) {
+       include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
 }
 ?>
\ No newline at end of file