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