See changelog
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_exec.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2002-2004 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 find executables (programs) on unix and windows without knowing where they are
26 *
27 * $Id$
28 *
29 * @author René Fritz <r.fritz@colorcube.de>
30 */
31 /**
32 * [CLASS/FUNCTION INDEX of SCRIPT]
33 *
34 *
35 *
36 * 81: class t3lib_exec
37 * 91: function checkCommand($cmd, $handler='')
38 * 162: function getCommand($cmd, $handler='', $handlerOpt='')
39 * 191: function addPaths($paths)
40 * 201: function _getPaths()
41 * 269: function _init()
42 * 285: function _initPaths($paths='')
43 * 340: function _getOS()
44 * 351: function _fixPath($path)
45 *
46 * TOTAL FUNCTIONS: 8
47 * (This index is automatically created/updated by the extension "extdeveval")
48 *
49 */
50
51
52
53
54
55 /**
56 * returns exec command for a program
57 * or false
58 *
59 * This class is meant to be used without instance:
60 * $cmd = t3lib_exec::getCommand ('awstats','perl');
61 *
62 * The data of this class is hold in a global variable. Doing it this way the setup is cached.
63 * That means if a program is found once it don't have to be searched again.
64 *
65 * user functions:
66 *
67 * addPaths() could be used to extend the search paths
68 * getCommand() get a command string
69 * checkCommand() returns true if a command is available
70 *
71 * Search paths that are included:
72 * $TYPO3_CONF_VARS['GFX']['im_path_lzw'] or $TYPO3_CONF_VARS['GFX']['im_path']
73 * $TYPO3_CONF_VARS['SYS']['binPath']
74 * $GLOBALS['_SERVER']['PATH']
75 * '/usr/bin/,/usr/local/bin/' on Unix
76 *
77 * @author René Fritz <r.fritz@colorcube.de>
78 * @package TYPO3
79 * @subpackage t3lib
80 */
81 class t3lib_exec {
82
83 /**
84 * Checks if a command is valid or not
85 * updates global vars
86 *
87 * @param string the command that should be executed. eg: "convert"
88 * @param string executer for the command. eg: "perl"
89 * @return boolean false if cmd is not found, or -1 if the handler is not found
90 */
91 function checkCommand($cmd, $handler='') {
92
93 t3lib_exec::_init();
94 $osType = t3lib_exec::_getOS();
95
96
97 #debug($GLOBALS['t3lib_exec'], 't3lib_exec', __LINE__, __FILE__);
98
99 if ($handler && !t3lib_exec::checkCommand($handler)) {
100 return -1;
101 }
102 // already checked and valid
103 if ($GLOBALS['t3lib_exec']['apps'][$cmd]['valid']) {
104 return true;
105 }
106 // is set but was (above) not true
107 if (isset($GLOBALS['t3lib_exec']['apps'][$cmd]['valid'])) {
108 return false;
109 }
110
111 reset($GLOBALS['t3lib_exec']['paths']);
112 foreach($GLOBALS['t3lib_exec']['paths'] as $path => $validPath) {
113 // ignore invalid (false) paths
114 if ($validPath) {
115 if ($osType=='WIN') {
116 if (@is_file($path.$cmd)) {
117 $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
118 $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = $path;
119 $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
120 return true;
121 }
122 if (@is_file($path.$cmd.'.exe')) {
123 $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd.'.exe';
124 $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = $path;
125 $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
126 return true;
127 }
128 } else { // UNIX
129 if (@is_executable($path.$cmd)) {
130 $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
131 $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = $path;
132 $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
133 return true;
134 }
135 }
136 }
137 }
138
139 // try to get the executable with the command 'which'. It do the same like already done, but maybe on other paths??
140 if ($osType=='UNIX') {
141 $cmd = @exec ('which '.$val['cmd']);
142
143 if (@is_executable($cmd)) {
144 $GLOBALS['t3lib_exec']['apps'][$cmd]['app'] = $cmd;
145 $GLOBALS['t3lib_exec']['apps'][$cmd]['path'] = dirname($cmd).'/';
146 $GLOBALS['t3lib_exec']['apps'][$cmd]['valid'] = true;
147 return true;
148 }
149 }
150
151 return false;
152 }
153
154 /**
155 * Returns a command string for exec(), system()
156 *
157 * @param string the command that should be executed. eg: "convert"
158 * @param string handler (executor) for the command. eg: "perl"
159 * @param string options for the handler, like '-w' for "perl"
160 * @return mixed returns command string, or false if cmd is not found, or -1 if the handler is not found
161 */
162 function getCommand($cmd, $handler='', $handlerOpt='') {
163
164 t3lib_exec::_init();
165
166 // handler
167 if ($handler) {
168 $handler = t3lib_exec::getCommand($handler);
169
170 if (!$handler) {
171 return -1;
172 }
173 $handler .= ' '.$handlerOpt.' ';
174 }
175
176 // command
177 if (!t3lib_exec::checkCommand($cmd)) {
178 return false;
179 }
180 $cmd = $GLOBALS['t3lib_exec']['apps'][$cmd]['path'].$GLOBALS['t3lib_exec']['apps'][$cmd]['app'].' ';
181
182 return $handler.$cmd;
183 }
184
185 /**
186 * Extend the preset paths. This way an extension can install an executable and provide the path to t3lib_exec.
187 *
188 * @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).
189 * @return void
190 */
191 function addPaths($paths) {
192 t3lib_exec::_initPaths($paths);
193 }
194
195 /**
196 * Set the search paths from different sources
197 *
198 * @return array Array of absolute paths (keys and values are equal)
199 */
200 function _getPaths() {
201 global $TYPO3_CONF_VARS;
202
203 $pathsArr = array();
204 $sysPathArr = array();
205 $osType = t3lib_exec::_getOS();
206
207 // image magick paths first
208 // im_path_lzw take precedence over im_path
209 if ($imPath = ($TYPO3_CONF_VARS['GFX']['im_path_lzw'] ? $TYPO3_CONF_VARS['GFX']['im_path_lzw'] : $TYPO3_CONF_VARS['GFX']['im_path'])) {
210 $imPath = t3lib_exec::_fixPath($imPath);
211 $pathsArr[$imPath] = $imPath;
212 }
213
214 // add configured paths
215 if ($TYPO3_CONF_VARS['SYS']['binPath']) {
216 $sysPath = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['SYS']['binPath'],1);
217 reset($sysPath);
218 while(list(,$val)=each($sysPath)) {
219 $val = t3lib_exec::_fixPath($val);
220 $sysPathArr[$val]=$val;
221 }
222 }
223
224 # ???? t3lib_div::getIndpEnv('REQUEST_URI');
225
226 // add path from environment
227 #TODO: how does this work for WIN
228 if ($GLOBALS['_SERVER']['PATH']) {
229 $sep = ($osType=='WIN') ? ';' : ':';
230 $envPath = t3lib_div::trimExplode($sep,$GLOBALS['_SERVER']['PATH'],1);
231 reset($envPath);
232 while(list(,$val)=each($envPath)) {
233 $val = t3lib_exec::_fixPath($val);
234 $sysPathArr[$val]=$val;
235 }
236 }
237
238 if ($osType=='WIN') {
239 #TODO: add the most common paths for WIN
240 $sysPathArr = array_merge($sysPathArr, array (
241 '/usr/bin/' => '/usr/bin/',
242 '/perl/bin/' => '/perl/bin/',
243 ));
244 } else { // UNIX
245 $sysPathArr = array_merge($sysPathArr, array (
246 '/usr/bin/' => '/usr/bin/',
247 '/usr/local/bin/' => '/usr/local/bin/',
248 ));
249 }
250
251 #debug($pathsArr, '$pathsArr', __LINE__, __FILE__);
252 #debug($GLOBALS['_SERVER']['PATH'], 'PATH', __LINE__, __FILE__);
253
254 $pathsArr = array_merge($pathsArr, $sysPathArr);
255 return $pathsArr;
256 }
257
258 /**
259 * Initialization, internal
260 *
261 * @return void
262 * @internal
263 */
264 function _init() {
265 if (!$GLOBALS['t3lib_exec']['init']) {
266
267 t3lib_exec::_initPaths();
268 $GLOBALS['t3lib_exec']['apps'] = array();
269 $GLOBALS['t3lib_exec']['init'] = true;
270 }
271 }
272
273 /**
274 * Init and extend the preset paths with own
275 *
276 * @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).
277 * @return void
278 * @internal
279 */
280 function _initPaths($paths='') {
281 $doCeck=false;
282
283 // init global paths array if not already done
284 if (!is_array($GLOBALS['t3lib_exec']['paths'])) {
285 $GLOBALS['t3lib_exec']['paths'] = t3lib_exec::_getPaths();
286 $doCeck=true;
287 }
288 // merge the submitted paths array to the global
289 if ($paths) {
290 $paths = t3lib_div::trimExplode(',',$paths,1);
291 if (is_array($paths)) {
292 reset($paths);
293 while(list(,$path)=each($paths)) {
294 // make absolute path of relative
295 if (!preg_match('#^/#',$path)) {
296 $path = PATH_site.$path;
297 }
298 if (!isset($GLOBALS['t3lib_exec']['paths'][$path])) {
299 if (@is_dir($path)) {
300 $GLOBALS['t3lib_exec']['paths'][$path] = $path;
301 $GLOBALS['t3lib_exec']['allPaths'].=','.$path;
302 // $doCeck=true; just done
303 } else {
304 $GLOBALS['t3lib_exec']['paths'][$path] = false;
305 }
306 }
307 }
308 }
309 }
310 // check if new paths are invalid
311 if ($doCeck) {
312 $GLOBALS['t3lib_exec']['allPaths']='';
313 reset($GLOBALS['t3lib_exec']['paths']);
314 while(list($path,$valid)=each($GLOBALS['t3lib_exec']['paths'])) {
315 // ignore invalid (false) paths
316 #TODO: what's the idea not to remove invalid paths?
317 if ($valid) {
318 if (!@is_dir($path)) {
319 $GLOBALS['t3lib_exec']['paths'][$path] = false;
320 }
321 }
322 if ($path = $GLOBALS['t3lib_exec']['paths'][$path]) {
323 $GLOBALS['t3lib_exec']['allPaths'].=','.$path;
324 }
325 }
326 }
327 }
328
329 /**
330 * Returns on which OS we're runing
331 *
332 * @return string the OS type: "UNIX" or "WIN"
333 * @internal
334 */
335 function _getOS() {
336 return stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'UNIX';
337 }
338
339 /**
340 * Set a path to the right format
341 *
342 * @param string Input path
343 * @return string Output path
344 * @internal
345 */
346 function _fixPath($path) {
347 return str_replace ('//','/',$path.'/');
348 }
349 }
350
351 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']) {
352 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
353 }
354 ?>