]> git.openstreetmap.org Git - nominatim.git/blob - lib-php/Shell.php
Merge pull request #2390 from lonvia/responsible-disclosure
[nominatim.git] / lib-php / Shell.php
1 <?php
2
3 namespace Nominatim;
4
5 class Shell
6 {
7     public function __construct($sBaseCmd, ...$aParams)
8     {
9         if (!$sBaseCmd) {
10             throw new \Exception('Command missing in new() call');
11         }
12         $this->baseCmd = $sBaseCmd;
13         $this->aParams = array();
14         $this->aEnv = null; // null = use the same environment as the current PHP process
15
16         $this->stdoutString = null;
17
18         foreach ($aParams as $sParam) {
19             $this->addParams($sParam);
20         }
21     }
22
23     public function addParams(...$aParams)
24     {
25         foreach ($aParams as $sParam) {
26             if (isset($sParam) && $sParam !== null && $sParam !== '') {
27                 array_push($this->aParams, $sParam);
28             }
29         }
30         return $this;
31     }
32
33     public function addEnvPair($sKey, $sVal)
34     {
35         if (isset($sKey) && $sKey && isset($sVal)) {
36             if (!isset($this->aEnv)) $this->aEnv = $_ENV;
37             $this->aEnv = array_merge($this->aEnv, array($sKey => $sVal), $_ENV);
38         }
39         return $this;
40     }
41
42     public function escapedCmd()
43     {
44         $aEscaped = array_map(function ($sParam) {
45             return $this->escapeParam($sParam);
46         }, array_merge(array($this->baseCmd), $this->aParams));
47
48         return join(' ', $aEscaped);
49     }
50
51     public function run($bExitOnFail = false)
52     {
53         $sCmd = $this->escapedCmd();
54         // $aEnv does not need escaping, proc_open seems to handle it fine
55
56         $aFDs = array(
57                  0 => array('pipe', 'r'),
58                  1 => STDOUT,
59                  2 => STDERR
60                 );
61         $aPipes = null;
62         $hProc = @proc_open($sCmd, $aFDs, $aPipes, null, $this->aEnv);
63         if (!is_resource($hProc)) {
64             throw new \Exception('Unable to run command: ' . $sCmd);
65         }
66
67         fclose($aPipes[0]); // no stdin
68
69         $iStat = proc_close($hProc);
70
71         if ($iStat != 0 && $bExitOnFail) {
72             exit($iStat);
73         }
74
75         return $iStat;
76     }
77
78
79
80     private function escapeParam($sParam)
81     {
82         if (preg_match('/^-*\w+$/', $sParam)) return $sParam;
83         return escapeshellarg($sParam);
84     }
85 }