*** empty log message ***
[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 axecutable 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 [type] ...
190 */
191 function addPaths($paths) {
192 t3lib_exec::_initPaths($paths);
193 }
194
195 /**
196 * set the search paths from different sources
197 *
198 * @return [type] ...
199 * @internal
200 */
201 function _getPaths() {
202 global $TYPO3_CONF_VARS;
203
204 $pathsArr = array();
205 $sysPathArr = array();
206 $osType = t3lib_exec::_getOS();
207
208 // image magick paths first
209 // im_path_lzw take precedence over im_path
210 if ($imPath = ($TYPO3_CONF_VARS['GFX']['im_path_lzw'] ? $TYPO3_CONF_VARS['GFX']['im_path_lzw'] : $TYPO3_CONF_VARS['GFX']['im_path'])) {
211 $imPath = t3lib_exec::_fixPath($imPath);
212 $pathsArr[$imPath] = $imPath;
213 }
214
215 // add configured paths
216 if ($TYPO3_CONF_VARS['SYS']['binPath']) {
217 $sysPath = t3lib_div::trimExplode(',',$TYPO3_CONF_VARS['SYS']['binPath'],1);
218 reset($sysPath);
219 while(list(,$val)=each($sysPath)) {
220 $val = t3lib_exec::_fixPath($val);
221 $sysPathArr[$val]=$val;
222 }
223 }
224
225
226
227
228 # ???? t3lib_div::getIndpEnv('REQUEST_URI');
229
230
231 // add path from environment
232 #TODO: how does this work for WIN
233 if ($GLOBALS['_SERVER']['PATH']) {
234 $sep = ($osType=='WIN') ? ';' : ':';
235 $envPath = t3lib_div::trimExplode($sep,$GLOBALS['_SERVER']['PATH'],1);
236 reset($envPath);
237 while(list(,$val)=each($envPath)) {
238 $val = t3lib_exec::_fixPath($val);
239 $sysPathArr[$val]=$val;
240 }
241 }
242
243 if ($osType=='WIN') {
244 #TODO: add the most common paths for WIN
245 $sysPathArr = array_merge($sysPathArr, array (
246 '/usr/bin/' => '/usr/bin/',
247 '/perl/bin/' => '/perl/bin/',
248 ));
249 } else { // UNIX
250 $sysPathArr = array_merge($sysPathArr, array (
251 '/usr/bin/' => '/usr/bin/',
252 '/usr/local/bin/' => '/usr/local/bin/',
253 ));
254 }
255
256 #debug($pathsArr, '$pathsArr', __LINE__, __FILE__);
257 #debug($GLOBALS['_SERVER']['PATH'], 'PATH', __LINE__, __FILE__);
258
259 $pathsArr = array_merge($pathsArr, $sysPathArr);
260 return $pathsArr;
261 }
262
263 /**
264 * init
265 *
266 * @return [type] ...
267 * @internal
268 */
269 function _init() {
270 if (!$GLOBALS['t3lib_exec']['init']) {
271
272 t3lib_exec::_initPaths();
273 $GLOBALS['t3lib_exec']['apps'] = array();
274 $GLOBALS['t3lib_exec']['init'] = true;
275 }
276 }
277
278 /**
279 * init and extend the preset paths with own
280 *
281 * @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).
282 * @return [type] ...
283 * @internal
284 */
285 function _initPaths($paths='') {
286 $doCeck=false;
287
288 // init global paths array if not already done
289 if (!is_array($GLOBALS['t3lib_exec']['paths'])) {
290 $GLOBALS['t3lib_exec']['paths'] = t3lib_exec::_getPaths();
291 $doCeck=true;
292 }
293 // merge the submitted paths array to the global
294 if ($paths) {
295 $paths = t3lib_div::trimExplode(',',$paths,1);
296 if (is_array($paths)) {
297 reset($paths);
298 while(list(,$path)=each($paths)) {
299 // make absolute path of relative
300 if (!preg_match('#^/#',$path)) {
301 $path = PATH_site.$path;
302 }
303 if (!isset($GLOBALS['t3lib_exec']['paths'][$path])) {
304 if (@is_dir($path)) {
305 $GLOBALS['t3lib_exec']['paths'][$path] = $path;
306 $GLOBALS['t3lib_exec']['allPaths'].=','.$path;
307 // $doCeck=true; just done
308 } else {
309 $GLOBALS['t3lib_exec']['paths'][$path] = false;
310 }
311 }
312 }
313 }
314 }
315 // check if new paths are invalid
316 if ($doCeck) {
317 $GLOBALS['t3lib_exec']['allPaths']='';
318 reset($GLOBALS['t3lib_exec']['paths']);
319 while(list($path,$valid)=each($GLOBALS['t3lib_exec']['paths'])) {
320 // ignore invalid (false) paths
321 #TODO: what's the idea not to remove invalid paths?
322 if ($valid) {
323 if (!@is_dir($path)) {
324 $GLOBALS['t3lib_exec']['paths'][$path] = false;
325 }
326 }
327 if ($path = $GLOBALS['t3lib_exec']['paths'][$path]) {
328 $GLOBALS['t3lib_exec']['allPaths'].=','.$path;
329 }
330 }
331 }
332 }
333
334 /**
335 * returns on which OS we're runing
336 *
337 * @return string the OS type: "UNIX" or "WIN"
338 * @internal
339 */
340 function _getOS() {
341 return stristr(PHP_OS,'win')&&!stristr(PHP_OS,'darwin')?'WIN':'UNIX';
342 }
343
344 /**
345 * set a path to the right format
346 *
347 * @param string path
348 * @return string path
349 * @internal
350 */
351 function _fixPath($path) {
352 return str_replace ('//',"/",$path.'/');
353 }
354 }
355
356 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']) {
357 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_exec.php']);
358 }
359 ?>