[TASK] Change "true" into "TRUE"
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_exec.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2002-2011 René Fritz (r.fritz@colorcube.de)
6 * All rights reserved
7 *
8 * This script is part of the Typo3 project. The Typo3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24 /**
25 * t3lib_exec finds executables (programs) on Unix and Windows without knowing where they are
26 *
27 * @author René Fritz <r.fritz@colorcube.de>
28 */
29 /**
30 * [CLASS/FUNCTION INDEX of SCRIPT]
31 *
32 *
33 *
34 * 85: class t3lib_exec
35 * 95: function checkCommand($cmd, $handler='')
36 * 166: function getCommand($cmd, $handler='', $handlerOpt='')
37 * 199: function addPaths($paths)
38 * 211: function getPaths($addInvalid=false)
39 * 237: function _init()
40 * 259: function _initPaths($paths='')
41 * 312: function _getConfiguredApps()
42 * 339: function _getPaths()
43 * 400: function _fixPath($path)
44 *
45 * TOTAL FUNCTIONS: 9
46 * (This index is automatically created/updated by the extension "extdeveval")
47 *
48 */
49
50
51 /**
52 * returns exec command for a program
53 * or false
54 *
55 * This class is meant to be used without instance:
56 * $cmd = t3lib_exec::getCommand ('awstats','perl');
57 *
58 * The data of this class is cached.
59 * That means if a program is found once it don't have to be searched again.
60 *
61 * user functions:
62 *
63 * addPaths() could be used to extend the search paths
64 * getCommand() get a command string
65 * checkCommand() returns TRUE if a command is available
66 *
67 * Search paths that are included:
68 * $TYPO3_CONF_VARS['GFX']['im_path_lzw'] or $TYPO3_CONF_VARS['GFX']['im_path']
69 * $TYPO3_CONF_VARS['SYS']['binPath']
70 * $GLOBALS['_SERVER']['PATH']
71 * '/usr/bin/,/usr/local/bin/' on Unix
72 *
73 * binaries can be preconfigured with
74 * $TYPO3_CONF_VARS['SYS']['binSetup']
75 *
76 * @author René Fritz <r.fritz@colorcube.de>
77 * @package TYPO3
78 * @subpackage t3lib
79 */
80 class t3lib_exec {
81
82 /** Tells if object is already initialized */
83 protected static $initialized = FALSE;
84
85 /**
86 * Contains application list. This is an array with the following structure:
87 * - app => file name to the application (like 'tar' or 'bzip2')
88 * - path => full path to the application without application name (like '/usr/bin/' for '/usr/bin/tar')
89 * - valid => TRUE or false
90 * Array key is identical to 'app'.
91 *
92 * @var array
93 */
94 protected static $applications = array();
95
96 /**
97 * Paths where to search for applications
98 *
99 * @var array
100 */
101 protected static $paths = NULL;
102
103 /**
104 * Checks if a command is valid or not, updates global variables
105 *
106 * @param string the command that should be executed. eg: "convert"
107 * @param string executer for the command. eg: "perl"
108 * @return boolean false if cmd is not found, or -1 if the handler is not found
109 */
110 public static function checkCommand($cmd, $handler = '') {
111 if (!self::init()) {
112 return FALSE;
113 }
114
115 if ($handler && !self::checkCommand($handler)) {
116 return -1;
117 }
118 // Already checked and valid
119 if (self::$applications[$cmd]['valid']) {
120 return TRUE;
121 }
122 // Is set but was (above) not TRUE
123 if (isset(self::$applications[$cmd]['valid'])) {
124 return FALSE;
125 }
126
127 foreach (self::$paths as $path => $validPath) {
128 // Ignore invalid (false) paths
129 if ($validPath) {
130 if (TYPO3_OS == 'WIN') {
131 // Windows OS
132 // TODO Why is_executable() is not called here?
133 if (@is_file($path . $cmd)) {
134 self::$applications[$cmd]['app'] = $cmd;
135 self::$applications[$cmd]['path'] = $path;
136 self::$applications[$cmd]['valid'] = TRUE;
137 return TRUE;
138 }
139 if (@is_file($path . $cmd . '.exe')) {
140 self::$applications[$cmd]['app'] = $cmd . '.exe';
141 self::$applications[$cmd]['path'] = $path;
142 self::$applications[$cmd]['valid'] = TRUE;
143 return TRUE;
144 }
145 } else {
146 // Unix-like OS
147 $filePath = realpath($path . $cmd);
148 if ($filePath && @is_executable($filePath)) {
149 self::$applications[$cmd]['app'] = $cmd;
150 self::$applications[$cmd]['path'] = $path;
151 self::$applications[$cmd]['valid'] = TRUE;
152 return TRUE;
153 }
154 }
155 }
156 }
157
158 // Try to get the executable with the command 'which'.
159 // It does the same like already done, but maybe on other paths
160 if (TYPO3_OS != 'WIN') {
161 $cmd = @t3lib_utility_Command::exec('which ' . $cmd);
162 if (@is_executable($cmd)) {
163 self::$applications[$cmd]['app'] = $cmd;
164 self::$applications[$cmd]['path'] = dirname($cmd) . '/';
165 self::$applications[$cmd]['valid'] = TRUE;
166 return TRUE;
167 }
168 }
169
170 return FALSE;
171 }
172
173
174 /**
175 * Returns a command string for exec(), system()
176 *
177 * @param string the command that should be executed. eg: "convert"
178 * @param string handler (executor) for the command. eg: "perl"
179 * @param string options for the handler, like '-w' for "perl"
180 * @return mixed returns command string, or false if cmd is not found, or -1 if the handler is not found
181 */
182 public static function getCommand($cmd, $handler = '', $handlerOpt = '') {
183 if (!self::init()) {
184 return FALSE;
185 }
186
187 // handler
188 if ($handler) {
189 $handler = self::getCommand($handler);
190
191 if (!$handler) {
192 return -1;
193 }
194 $handler .= ' ' . $handlerOpt . ' ';
195 }
196
197 // command
198 if (!self::checkCommand($cmd)) {
199 return FALSE;
200 }
201 $cmd = self::$applications[$cmd]['path'] . self::$applications[$cmd]['app'] . ' ';
202
203 return trim($handler . $cmd);
204 }
205
206
207 /**
208 * Extend the preset paths. This way an extension can install an executable and provide the path to t3lib_exec.
209 *
210 * @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).
211 * @return void
212 */
213 public static function addPaths($paths) {
214 self::initPaths($paths);
215 }
216
217
218 /**
219 * Returns an array of search paths
220 *
221 * @param boolean If set the array contains invalid path too. Then the key is the path and the value is empty
222 * @return array Array of search paths (empty if exec is disabled)
223 */
224 public static function getPaths($addInvalid = FALSE) {
225 if (!self::init()) {
226 return array();
227 }
228
229 $paths = self::$paths;
230
231 if (!$addInvalid) {
232 foreach ($paths as $path => $validPath) {
233 if (!$validPath) {
234 unset($paths[$path]);
235 }
236 }
237 }
238 return $paths;
239 }
240
241
242 /**
243 * Initializes this class
244 *
245 * @return void
246 */
247 protected static function init() {
248 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['disable_exec_function']) {
249 return FALSE;
250 }
251 if (!self::$initialized) {
252 self::initPaths();
253 self::$applications = self::getConfiguredApps();
254 self::$initialized = TRUE;
255 }
256 return TRUE;
257 }
258
259
260 /**
261 * Initializes and extends the preset paths with own
262 *
263 * @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).
264 * @return void
265 */
266 protected static function initPaths($paths = '') {
267 $doCheck = FALSE;
268
269 // init global paths array if not already done
270 if (!is_array(self::$paths)) {
271 self::$paths = self::getPathsInternal();
272 $doCheck = TRUE;
273 }
274 // merge the submitted paths array to the global
275 if ($paths) {
276 $paths = t3lib_div::trimExplode(',', $paths, 1);
277 if (is_array($paths)) {
278 foreach ($paths as $path) {
279 // make absolute path of relative
280 if (!preg_match('#^/#', $path)) {
281 $path = PATH_site . $path;
282 }
283 if (!isset(self::$paths[$path])) {
284 if (@is_dir($path)) {
285 self::$paths[$path] = $path;
286 } else {
287 self::$paths[$path] = FALSE;
288 }
289 }
290 }
291 }
292 }
293 // check if new paths are invalid
294 if ($doCheck) {
295 foreach (self::$paths as $path => $valid) {
296 // ignore invalid (false) paths
297 if ($valid AND !@is_dir($path)) {
298 self::$paths[$path] = FALSE;
299 }
300 }
301 }
302 }
303
304
305 /**
306 * Processes and returns the paths from $GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']
307 *
308 * @return array Array of commands and path
309 */
310 protected static function getConfiguredApps() {
311 $cmdArr = array();
312
313 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']) {
314 $pathSetup = preg_split('/[\n,]+/', $GLOBALS['TYPO3_CONF_VARS']['SYS']['binSetup']);
315 foreach ($pathSetup as $val) {
316 list($cmd, $cmdPath) = t3lib_div::trimExplode('=', $val, 1);
317 $cmdArr[$cmd]['app'] = basename($cmdPath);
318 $cmdArr[$cmd]['path'] = dirname($cmdPath) . '/';
319 $cmdArr[$cmd]['valid'] = TRUE;
320 }
321 }
322
323 return $cmdArr;
324 }
325
326
327 /**
328 * Sets the search paths from different sources, internal
329 *
330 * @return array Array of absolute paths (keys and values are equal)
331 */
332 protected static function getPathsInternal() {
333
334 $pathsArr = array();
335 $sysPathArr = array();
336
337 // image magick paths first
338 // im_path_lzw take precedence over im_path
339 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']))) {
340 $imPath = self::fixPath($imPath);
341 $pathsArr[$imPath] = $imPath;
342 }
343
344 // add configured paths
345 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['binPath']) {
346 $sysPath = t3lib_div::trimExplode(',', $GLOBALS['TYPO3_CONF_VARS']['SYS']['binPath'], 1);
347 foreach ($sysPath as $val) {
348 $val = self::fixPath($val);
349 $sysPathArr[$val] = $val;
350 }
351 }
352
353
354 // add path from environment
355 // TODO: how does this work for WIN
356 if ($GLOBALS['_SERVER']['PATH']) {
357 $sep = (TYPO3_OS == 'WIN' ? ';' : ':');
358 $envPath = t3lib_div::trimExplode($sep, $GLOBALS['_SERVER']['PATH'], 1);
359 foreach ($envPath as $val) {
360 $val = self::fixPath($val);
361 $sysPathArr[$val] = $val;
362 }
363 }
364
365 // Set common paths for Unix (only)
366 if (TYPO3_OS !== 'WIN') {
367 $sysPathArr = array_merge($sysPathArr, array(
368 '/usr/bin/' => '/usr/bin/',
369 '/usr/local/bin/' => '/usr/local/bin/',
370 ));
371 }
372
373 $pathsArr = array_merge($pathsArr, $sysPathArr);
374
375 return $pathsArr;
376 }
377
378
379 /**
380 * Set a path to the right format
381 *
382 * @param string Input path
383 * @return string Output path
384 */
385 protected static function fixPath($path) {
386 return str_replace('//', '/', $path . '/');
387 }
388 }
389
390 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php'])) {
391 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
392 }
393 ?>