class.t3lib_exec.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 2002-2010 René Fritz (r.fritz@colorcube.de)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the Typo3 project. The Typo3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *
00017 *  This script is distributed in the hope that it will be useful,
00018 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 *  GNU General Public License for more details.
00021 *
00022 *  This copyright notice MUST APPEAR in all copies of the script!
00023 ***************************************************************/
00024 /**
00025  * t3lib_exec finds executables (programs) on Unix and Windows without knowing where they are
00026  *
00027  * $Id: class.t3lib_exec.php 7905 2010-06-13 14:42:33Z ohader $
00028  *
00029  * @author  René Fritz <r.fritz@colorcube.de>
00030  */
00031 /**
00032  * [CLASS/FUNCTION INDEX of SCRIPT]
00033  *
00034  *
00035  *
00036  *   85: class t3lib_exec
00037  *   95:     function checkCommand($cmd, $handler='')
00038  *  166:     function getCommand($cmd, $handler='', $handlerOpt='')
00039  *  199:     function addPaths($paths)
00040  *  211:     function getPaths($addInvalid=false)
00041  *  237:     function _init()
00042  *  259:     function _initPaths($paths='')
00043  *  312:     function _getConfiguredApps()
00044  *  339:     function _getPaths()
00045  *  400:     function _fixPath($path)
00046  *
00047  * TOTAL FUNCTIONS: 9
00048  * (This index is automatically created/updated by the extension "extdeveval")
00049  *
00050  */
00051 
00052 
00053 
00054 
00055 
00056 /**
00057  * returns exec command for a program
00058  * or false
00059  *
00060  * This class is meant to be used without instance:
00061  * $cmd = t3lib_exec::getCommand ('awstats','perl');
00062  *
00063  * The data of this class is cached.
00064  * That means if a program is found once it don't have to be searched again.
00065  *
00066  * user functions:
00067  *
00068  * addPaths() could be used to extend the search paths
00069  * getCommand() get a command string
00070  * checkCommand() returns true if a command is available
00071  *
00072  * Search paths that are included:
00073  * $TYPO3_CONF_VARS['GFX']['im_path_lzw'] or $TYPO3_CONF_VARS['GFX']['im_path']
00074  * $TYPO3_CONF_VARS['SYS']['binPath']
00075  * $GLOBALS['_SERVER']['PATH']
00076  * '/usr/bin/,/usr/local/bin/' on Unix
00077  *
00078  * binaries can be preconfigured with
00079  * $TYPO3_CONF_VARS['SYS']['binSetup']
00080  *
00081  * @author      René Fritz <r.fritz@colorcube.de>
00082  * @package     TYPO3
00083  * @subpackage  t3lib
00084  */
00085 class t3lib_exec {
00086 
00087     /** Tells if object is already initialized */
00088     protected static $initialized = FALSE;
00089 
00090     /**
00091      * Contains application list. This is an array with the following structure:
00092      * - app => file name to the application (like 'tar' or 'bzip2')
00093      * - path => full path to the application without application name (like '/usr/bin/' for '/usr/bin/tar')
00094      * - valid => true or false
00095      * Array key is identical to 'app'.
00096      *
00097      * @var array
00098      */
00099     protected static $applications = array();
00100 
00101     /**
00102      * Paths where to search for applications
00103      *
00104      * @var array
00105      */
00106     protected static $paths = NULL;
00107 
00108     /**
00109      * Checks if a command is valid or not, updates global variables
00110      *
00111      * @param   string      the command that should be executed. eg: "convert"
00112      * @param   string      executer for the command. eg: "perl"
00113      * @return  boolean     false if cmd is not found, or -1 if the handler is not found
00114      */
00115     public static function checkCommand($cmd, $handler = '') {
00116         if (!self::init()) {
00117             return FALSE;
00118         }
00119 
00120         if ($handler && !self::checkCommand($handler)) {
00121             return -1;
00122         }
00123             // Already checked and valid
00124         if (self::$applications[$cmd]['valid']) {
00125             return TRUE;
00126         }
00127             // Is set but was (above) not true
00128         if (isset(self::$applications[$cmd]['valid'])) {
00129             return FALSE;
00130         }
00131 
00132         foreach (self::$paths as $path => $validPath) {
00133                 // Ignore invalid (false) paths
00134             if ($validPath) {
00135                 if (TYPO3_OS == 'WIN') {
00136                         // Windows OS
00137                         // TODO Why is_executable() is not called here?
00138                     if (@is_file($path . $cmd)) {
00139                         self::$applications[$cmd]['app'] = $cmd;
00140                         self::$applications[$cmd]['path'] = $path;
00141                         self::$applications[$cmd]['valid'] = TRUE;
00142                         return TRUE;
00143                     }
00144                     if (@is_file($path . $cmd . '.exe')) {
00145                         self::$applications[$cmd]['app'] = $cmd . '.exe';
00146                         self::$applications[$cmd]['path'] = $path;
00147                         self::$applications[$cmd]['valid'] = TRUE;
00148                         return TRUE;
00149                     }
00150                 } else {
00151                         // Unix-like OS
00152                     $filePath = realpath($path . $cmd);
00153                     if ($filePath && @is_executable($filePath)) {
00154                         self::$applications[$cmd]['app'] = $cmd;
00155                         self::$applications[$cmd]['path'] = $path;
00156                         self::$applications[$cmd]['valid'] = TRUE;
00157                         return TRUE;
00158                     }
00159                 }
00160             }
00161         }
00162 
00163             // Try to get the executable with the command 'which'.
00164             // It does the same like already done, but maybe on other paths
00165         if (TYPO3_OS != 'WIN') {
00166             $cmd = @exec('which ' . $cmd);
00167             if (@is_executable($cmd)) {
00168                 self::$applications[$cmd]['app'] = $cmd;
00169                 self::$applications[$cmd]['path'] = dirname($cmd) . '/';
00170                 self::$applications[$cmd]['valid'] = TRUE;
00171                 return TRUE;
00172             }
00173         }
00174 
00175         return FALSE;
00176     }
00177 
00178 
00179     /**
00180      * Returns a command string for exec(), system()
00181      *
00182      * @param   string      the command that should be executed. eg: "convert"
00183      * @param   string      handler (executor) for the command. eg: "perl"
00184      * @param   string      options for the handler, like '-w' for "perl"
00185      * @return  mixed       returns command string, or false if cmd is not found, or -1 if the handler is not found
00186      */
00187     public static function getCommand($cmd, $handler = '', $handlerOpt = '') {
00188         if (!self::init()) {
00189             return FALSE;
00190         }
00191 
00192             // handler
00193         if ($handler) {
00194             $handler = self::getCommand($handler);
00195 
00196             if (!$handler) {
00197                 return -1;
00198             }
00199             $handler .= ' ' . $handlerOpt . ' ';
00200         }
00201 
00202             // command
00203         if (!self::checkCommand($cmd)) {
00204             return FALSE;
00205         }
00206         $cmd = self::$applications[$cmd]['path'] . self::$applications[$cmd]['app'] . ' ';
00207 
00208         return trim($handler . $cmd);
00209     }
00210 
00211 
00212     /**
00213      * Extend the preset paths. This way an extension can install an executable and provide the path to t3lib_exec.
00214      *
00215      * @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).
00216      * @return  void
00217      */
00218     public static function addPaths($paths) {
00219         self::initPaths($paths);
00220     }
00221 
00222 
00223     /**
00224      * Returns an array of search paths
00225      *
00226      * @param   boolean     If set the array contains invalid path too. Then the key is the path and the value is empty
00227      * @return  array       Array of search paths (empty if exec is disabled)
00228      */
00229     public static function getPaths($addInvalid = FALSE) {
00230         if (!self::init()) {
00231             return array();
00232         }
00233 
00234         $paths = self::$paths;
00235 
00236         if (!$addInvalid) {
00237             foreach ($paths as $path => $validPath) {
00238                 if (!$validPath) {
00239                     unset($paths[$path]);
00240                 }
00241             }
00242         }
00243         return $paths;
00244     }
00245 
00246 
00247     /**
00248      * Initializes this class
00249      *
00250      * @return  void
00251      */
00252     protected static function init() {
00253         if ($GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function']) {
00254             return FALSE;
00255         }
00256         if (!self::$initialized) {
00257             self::initPaths();
00258             self::$applications = self::getConfiguredApps();
00259             self::$initialized = TRUE;
00260         }
00261         return TRUE;
00262     }
00263 
00264 
00265     /**
00266      * Initializes and extends the preset paths with own
00267      *
00268      * @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).
00269      * @return  void
00270      */
00271     protected static function initPaths($paths = '') {
00272         $doCheck = FALSE;
00273 
00274             // init global paths array if not already done
00275         if (!is_array(self::$paths)) {
00276             self::$paths = self::getPathsInternal();
00277             $doCheck = TRUE;
00278         }
00279             // merge the submitted paths array to the global
00280         if ($paths) {
00281             $paths = t3lib_div::trimExplode(',', $paths, 1);
00282             if (is_array($paths)) {
00283                 foreach ($paths as $path) {
00284                         // make absolute path of relative
00285                     if (!preg_match('#^/#', $path)) {
00286                         $path = PATH_site . $path;
00287                     }
00288                     if (!isset(self::$paths[$path])) {
00289                         if (@is_dir($path)) {
00290                             self::$paths[$path] = $path;
00291                         } else {
00292                             self::$paths[$path] = FALSE;
00293                         }
00294                     }
00295                 }
00296             }
00297         }
00298             // check if new paths are invalid
00299         if ($doCheck) {
00300             foreach (self::$paths as $path => $valid) {
00301                     // ignore invalid (false) paths
00302                 if ($valid AND !@is_dir($path)) {
00303                     self::$paths[$path] = FALSE;
00304                 }
00305             }
00306         }
00307     }
00308 
00309 
00310     /**
00311      * Processes and returns the paths from $GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']
00312      *
00313      * @return  array   Array of commands and path
00314      */
00315     protected static function getConfiguredApps() {
00316         $cmdArr = array();
00317 
00318         if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']) {
00319             $pathSetup = preg_split('/[\n,]+/', $GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']);
00320             foreach ($pathSetup as $val) {
00321                 list($cmd, $cmdPath) = t3lib_div::trimExplode('=', $val, 1);
00322                 $cmdArr[$cmd]['app'] = basename($cmdPath);
00323                 $cmdArr[$cmd]['path'] = dirname($cmdPath) . '/';
00324                 $cmdArr[$cmd]['valid'] = TRUE;
00325             }
00326         }
00327 
00328         return $cmdArr;
00329     }
00330 
00331 
00332     /**
00333      * Sets the search paths from different sources, internal
00334      *
00335      * @return  array       Array of absolute paths (keys and values are equal)
00336      */
00337     protected static function getPathsInternal() {
00338 
00339         $pathsArr = array();
00340         $sysPathArr = array();
00341 
00342             // image magick paths first
00343             // im_path_lzw take precedence over im_path
00344         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']))) {
00345             $imPath = self::fixPath($imPath);
00346             $pathsArr[$imPath] = $imPath;
00347         }
00348 
00349             // add configured paths
00350         if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['binPath']) {
00351             $sysPath = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['binPath'], 1);
00352             foreach ($sysPath as $val) {
00353                 $val = self::fixPath($val);
00354                 $sysPathArr[$val] = $val;
00355             }
00356         }
00357 
00358 
00359             // add path from environment
00360             // TODO: how does this work for WIN
00361         if ($GLOBALS['_SERVER']['PATH']) {
00362             $sep = (TYPO3_OS == 'WIN' ? ';' : ':');
00363             $envPath = t3lib_div::trimExplode($sep, $GLOBALS['_SERVER']['PATH'], 1);
00364             foreach ($envPath as $val) {
00365                 $val = self::fixPath($val);
00366                 $sysPathArr[$val] = $val;
00367             }
00368         }
00369 
00370             // Set common paths for Unix (only)
00371         if (TYPO3_OS !== 'WIN') {
00372             $sysPathArr = array_merge($sysPathArr, array(
00373                 '/usr/bin/' => '/usr/bin/',
00374                 '/usr/local/bin/' => '/usr/local/bin/',
00375             ));
00376         }
00377 
00378         $pathsArr = array_merge($pathsArr, $sysPathArr);
00379 
00380         return $pathsArr;
00381     }
00382 
00383 
00384     /**
00385      * Set a path to the right format
00386      *
00387      * @param   string      Input path
00388      * @return  string      Output path
00389      */
00390     protected static function fixPath($path) {
00391         return str_replace('//', '/', $path . '/');
00392     }
00393 }
00394 
00395 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php'])  {
00396     include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
00397 }
00398 ?>

Generated on Sat Jul 24 04:17:17 2010 for TYPO3 API by  doxygen 1.4.7