1<?php
2require_once 'PEAR.php';
3require_once 'System.php';
4require_once 'PEAR/Config.php';
5require_once 'PEAR/Command.php';
6require_once 'PEAR/Common.php';
7class PEAR_Start extends PEAR
8{
9    var $bin_dir;
10    var $data_dir;
11    var $cfg_dir;
12    var $www_dir;
13    var $man_dir;
14    var $install_pfc;
15    var $corePackages =
16        array(
17            'Archive_Tar',
18            'Console_Getopt',
19            'PEAR',
20            'Structures_Graph',
21            'XML_Util',
22        );
23    var $local_dir = array();
24    var $origpwd;
25    var $pfc_packages = array(
26            'DB',
27            'Net_Socket',
28            'Net_SMTP',
29            'Mail',
30            'XML_Parser',
31            'XML_RPC',
32            'PHPUnit'
33        );
34    var $php_dir;
35    var $php_bin;
36    var $pear_conf;
37    var $validPHPBin = false;
38    var $test_dir;
39    var $download_dir;
40    var $temp_dir;
41    var $config =
42        array(
43            'prefix',
44            'bin_dir',
45            'php_dir',
46            'doc_dir',
47            'data_dir',
48            'cfg_dir',
49            'www_dir',
50            'man_dir',
51            'test_dir',
52            'temp_dir',
53            'download_dir',
54            'pear_conf',
55        );
56    var $prefix;
57    var $progress = 0;
58    var $configPrompt =
59        array(
60            'prefix' => 'Installation base ($prefix)',
61            'temp_dir' => 'Temporary directory for processing',
62            'download_dir' => 'Temporary directory for downloads',
63            'bin_dir' => 'Binaries directory',
64            'php_dir' => 'PHP code directory ($php_dir)',
65            'doc_dir' => 'Documentation directory',
66            'data_dir' => 'Data directory',
67            'cfg_dir' => 'User-modifiable configuration files directory',
68            'www_dir' => 'Public Web Files directory',
69            'man_dir' => 'System manual pages directory',
70            'test_dir' => 'Tests directory',
71            'pear_conf' => 'Name of configuration file',
72        );
73
74    var $localInstall;
75    var $PEARConfig;
76    var $tarball = array();
77    var $ptmp;
78
79    function __construct()
80    {
81        parent::__construct();
82        if (OS_WINDOWS) {
83            $this->configPrompt['php_bin'] = 'Path to CLI php.exe';
84            $this->config[] = 'php_bin';
85            $this->prefix = getcwd();
86
87            if (!@is_dir($this->prefix)) {
88                if (@is_dir('c:\php5')) {
89                    $this->prefix = 'c:\php5';
90                } elseif (@is_dir('c:\php4')) {
91                    $this->prefix = 'c:\php4';
92                } elseif (@is_dir('c:\php')) {
93                    $this->prefix = 'c:\php';
94                }
95            }
96
97            $slash = "\\";
98            if (strrpos($this->prefix, '\\') === (strlen($this->prefix) - 1)) {
99                $slash = '';
100            }
101
102            $this->localInstall = false;
103            $this->bin_dir   = '$prefix';
104            $this->temp_dir   = '$prefix' . $slash . 'tmp';
105            $this->download_dir   = '$prefix' . $slash . 'tmp';
106            $this->php_dir   = '$prefix' . $slash . 'pear';
107            $this->doc_dir   = '$prefix' . $slash . 'docs';
108            $this->data_dir  = '$prefix' . $slash . 'data';
109            $this->test_dir  = '$prefix' . $slash . 'tests';
110            $this->www_dir  = '$prefix' . $slash . 'www';
111            $this->man_dir  = '$prefix' . $slash . 'man';
112            $this->cfg_dir  = '$prefix' . $slash . 'cfg';
113            $this->pear_conf = PEAR_CONFIG_SYSCONFDIR . '\\pear.ini';
114            /*
115             * Detects php.exe
116             */
117            $this->validPHPBin = true;
118            if ($t = $this->safeGetenv('PHP_PEAR_PHP_BIN')) {
119                $this->php_bin   = dirname($t);
120            } elseif ($t = $this->safeGetenv('PHP_BIN')) {
121                $this->php_bin   = dirname($t);
122            } elseif ($t = System::which('php')) {
123                $this->php_bin = dirname($t);
124            } elseif (is_file($this->prefix . '\cli\php.exe')) {
125                $this->php_bin = $this->prefix . '\cli';
126            } elseif (is_file($this->prefix . '\php.exe')) {
127                $this->php_bin = $this->prefix;
128            }
129            $phpexe = OS_WINDOWS ? '\\php.exe' : '/php';
130            if ($this->php_bin && !is_file($this->php_bin . $phpexe)) {
131                $this->php_bin = '';
132            } else {
133                if (strpos($this->php_bin, ':') === 0) {
134                    $this->php_bin = getcwd() . DIRECTORY_SEPARATOR . $this->php_bin;
135                }
136            }
137            if (!is_file($this->php_bin . $phpexe)) {
138                if (is_file('c:/php/cli/php.exe')) {
139                    $this->php_bin = 'c"\\php\\cli';
140                } elseif (is_file('c:/php5/php.exe')) {
141                    $this->php_bin = 'c:\\php5';
142                } elseif (is_file('c:/php4/cli/php.exe')) {
143                    $this->php_bin = 'c:\\php4\\cli';
144                } else {
145                    $this->validPHPBin = false;
146                }
147            }
148        } else {
149            $this->prefix = dirname(PHP_BINDIR);
150            $this->pear_conf = PEAR_CONFIG_SYSCONFDIR . '/pear.conf';
151            if ($this->getCurrentUser() != 'root') {
152                $this->prefix = $this->safeGetenv('HOME') . '/pear';
153                $this->pear_conf = $this->safeGetenv('HOME') . '.pearrc';
154            }
155            $this->bin_dir   = '$prefix/bin';
156            $this->php_dir   = '$prefix/share/pear';
157            $this->temp_dir  = '/tmp/pear/install';
158            $this->download_dir  = '/tmp/pear/install';
159            $this->doc_dir   = '$prefix/docs';
160            $this->www_dir   = '$prefix/www';
161            $this->cfg_dir   = '$prefix/cfg';
162            $this->data_dir  = '$prefix/data';
163            $this->test_dir  = '$prefix/tests';
164            $this->man_dir  = '$prefix/man';
165            // check if the user has installed PHP with PHP or GNU layout
166            if (@is_dir("$this->prefix/lib/php/.registry")) {
167                $this->php_dir = '$prefix/lib/php';
168            } elseif (@is_dir("$this->prefix/share/pear/lib/.registry")) {
169                $this->php_dir = '$prefix/share/pear/lib';
170                $this->doc_dir   = '$prefix/share/pear/docs';
171                $this->data_dir  = '$prefix/share/pear/data';
172                $this->test_dir  = '$prefix/share/pear/tests';
173            } elseif (@is_dir("$this->prefix/share/php/.registry")) {
174                $this->php_dir = '$prefix/share/php';
175            }
176        }
177    }
178
179    /**
180     * Get the name of the user running the script.
181     * Only needed on unix for now.
182     *
183     * @return string Name of the user ("root", "cweiske")
184     */
185    function getCurrentUser()
186    {
187        if (isset($_ENV['USER'])) {
188            return $_ENV['USER'];
189        } else {
190            return trim(`whoami`);
191        }
192    }
193
194    function safeGetenv($var)
195    {
196        if (is_array($_ENV) && isset($_ENV[$var])) {
197            return $_ENV[$var];
198        }
199
200        return getenv($var);
201    }
202
203    function show($stuff)
204    {
205        print $stuff;
206    }
207
208    function locatePackagesToInstall()
209    {
210        $dp = @opendir(dirname(__FILE__) . '/go-pear-tarballs');
211        if (empty($dp)) {
212            return PEAR::raiseError("while locating packages to install: opendir('" .
213                dirname(__FILE__) . "/go-pear-tarballs') failed");
214        }
215
216        $potentials = array();
217        while (false !== ($entry = readdir($dp))) {
218            if ($entry{0} == '.' || !in_array(substr($entry, -4), array('.tar', '.tgz'))) {
219                continue;
220            }
221            $potentials[] = $entry;
222        }
223
224        closedir($dp);
225        $notfound = array();
226        foreach ($this->corePackages as $package) {
227            foreach ($potentials as $i => $candidate) {
228                if (preg_match('/^' . $package . '-' . _PEAR_COMMON_PACKAGE_VERSION_PREG
229                      . '\.(tar|tgz)\\z/', $candidate)) {
230                    $this->tarball[$package] = dirname(__FILE__) . '/go-pear-tarballs/' . $candidate;
231                    unset($potentials[$i]);
232                    continue 2;
233                }
234            }
235
236            $notfound[] = $package;
237        }
238
239        if (count($notfound)) {
240            return PEAR::raiseError("No tarballs found for core packages: " .
241                    implode(', ', $notfound));
242        }
243
244        $this->tarball = array_merge($this->tarball, $potentials);
245    }
246
247    function setupTempStuff()
248    {
249        if (!($this->ptmp = System::mktemp(array('-d')))) {
250            $this->show("System's Tempdir failed, trying to use \$prefix/tmp ...");
251            $res = System::mkDir(array($this->prefix . '/tmp'));
252            if (!$res) {
253                return PEAR::raiseError('mkdir ' . $this->prefix . '/tmp ... failed');
254            }
255
256            $_temp = tempnam($this->prefix . '/tmp', 'gope');
257            System::rm(array('-rf', $_temp));
258            System::mkdir(array('-p','-m', '0700', $_temp));
259            $this->ptmp = $this->prefix . '/tmp';
260            $ok = @chdir($this->ptmp);
261
262            if (!$ok) { // This should not happen, really ;)
263                $this->bail('chdir ' . $this->ptmp . ' ... failed');
264            }
265
266            print "ok\n";
267
268            // Adjust TEMPDIR envvars
269            if (!isset($_ENV)) {
270                $_ENV = array();
271            };
272            $_ENV['TMPDIR'] = $_ENV['TEMP'] = $this->prefix . '/tmp';
273        }
274
275        return @chdir($this->ptmp);
276    }
277
278    /**
279     * Try to detect the kind of SAPI used by the
280     * the given php.exe.
281     * @author Pierrre-Alain Joye
282     */
283    function win32DetectPHPSAPI()
284    {
285        if ($this->php_bin != '') {
286            if (OS_WINDOWS) {
287                exec('"' . $this->php_bin . '\\php.exe" -v', $res);
288            } else {
289                exec('"' . $this->php_bin . '/php" -v', $res);
290            }
291
292            if (is_array($res)) {
293                if (isset($res[0]) && strpos($res[0],"(cli)")) {
294                    return 'cli';
295                }
296
297                if (isset($res[0]) && strpos($res[0],"cgi")) {
298                    return 'cgi';
299                }
300
301                if (isset($res[0]) && strpos($res[0],"cgi-fcgi")) {
302                    return 'cgi';
303                }
304
305                return 'unknown';
306            }
307        }
308
309        return 'unknown';
310    }
311
312    function doInstall()
313    {
314        print "Beginning install...\n";
315        // finish php_bin config
316        if (OS_WINDOWS) {
317            $this->php_bin .= '\\php.exe';
318        } else {
319            $this->php_bin .= '/php';
320        }
321        $this->PEARConfig = &PEAR_Config::singleton($this->pear_conf, $this->pear_conf);
322        $this->PEARConfig->set('preferred_state', 'stable');
323        foreach ($this->config as $var) {
324            if ($var == 'pear_conf' || $var == 'prefix') {
325                continue;
326            }
327            $this->PEARConfig->set($var, $this->$var);
328        }
329
330        $this->PEARConfig->store();
331//       $this->PEARConfig->set('verbose', 6);
332        print "Configuration written to $this->pear_conf...\n";
333        $this->registry = &$this->PEARConfig->getRegistry();
334        print "Initialized registry...\n";
335        $install = &PEAR_Command::factory('install', $this->PEARConfig);
336        print "Preparing to install...\n";
337        $options = array(
338            'nodeps' => true,
339            'force' => true,
340            'upgrade' => true,
341            );
342        foreach ($this->tarball as $pkg => $src) {
343            print "installing $src...\n";
344        }
345        $install->run('install', $options, array_values($this->tarball));
346    }
347
348    function postProcessConfigVars()
349    {
350        foreach ($this->config as $n => $var) {
351            for ($m = 1; $m <= count($this->config); $m++) {
352                $var2 = $this->config[$m];
353                $this->$var = str_replace('$'.$var2, $this->$var2, $this->$var);
354            }
355        }
356
357        foreach ($this->config as $var) {
358            $dir = $this->$var;
359
360            if (!preg_match('/_dir\\z/', $var)) {
361                continue;
362            }
363
364            if (!@is_dir($dir)) {
365                if (!System::mkDir(array('-p', $dir))) {
366                    $root = OS_WINDOWS ? 'administrator' : 'root';
367                    return PEAR::raiseError("Unable to create {$this->configPrompt[$var]} $dir.
368Run this script as $root or pick another location.\n");
369                }
370            }
371        }
372    }
373
374    /**
375     * Get the php.ini file used with the current
376     * process or with the given php.exe
377     *
378     * Horrible hack, but well ;)
379     *
380     * Not used yet, will add the support later
381     * @author Pierre-Alain Joye <paj@pearfr.org>
382     */
383    function getPhpiniPath()
384    {
385        $pathIni = get_cfg_var('cfg_file_path');
386        if ($pathIni && is_file($pathIni)) {
387            return $pathIni;
388        }
389
390        // Oh well, we can keep this too :)
391        // I dunno if get_cfg_var() is safe on every OS
392        if (OS_WINDOWS) {
393            // on Windows, we can be pretty sure that there is a php.ini
394            // file somewhere
395            do {
396                $php_ini = PHP_CONFIG_FILE_PATH . DIRECTORY_SEPARATOR . 'php.ini';
397                if (@file_exists($php_ini)) {
398                    break;
399                }
400                $php_ini = 'c:\winnt\php.ini';
401                if (@file_exists($php_ini)) {
402                    break;
403                }
404                $php_ini = 'c:\windows\php.ini';
405            } while (false);
406        } else {
407            $php_ini = PHP_CONFIG_FILE_PATH . DIRECTORY_SEPARATOR . 'php.ini';
408        }
409
410        if (@is_file($php_ini)) {
411            return $php_ini;
412        }
413
414        // We re running in hackz&troubles :)
415        ob_implicit_flush(false);
416        ob_start();
417        phpinfo(INFO_GENERAL);
418        $strInfo = ob_get_contents();
419        ob_end_clean();
420        ob_implicit_flush(true);
421
422        if (php_sapi_name() != 'cli') {
423            $strInfo = strip_tags($strInfo,'<td>');
424            $arrayInfo = explode("</td>", $strInfo );
425            $cli = false;
426        } else {
427            $arrayInfo = explode("\n", $strInfo);
428            $cli = true;
429        }
430
431        foreach ($arrayInfo as $val) {
432            if (strpos($val,"php.ini")) {
433                if ($cli) {
434                    list(,$pathIni) = explode('=>', $val);
435                } else {
436                    $pathIni = strip_tags(trim($val));
437                }
438                $pathIni = trim($pathIni);
439                if (is_file($pathIni)) {
440                    return $pathIni;
441                }
442            }
443        }
444
445        return false;
446    }
447}
448?>
449