X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fpharext%2FCli%2FCommand.php;h=706cb850efd29c58510fc3d7916f43f4c7689fb4;hb=b3b7f2dddc97f6f6c2ca83f6a708fb09ae2ed64c;hp=0ec52fffea07b06b829ee4e3ccffd68a651c8a98;hpb=26683702fdc53d2431ae2bc5081439ac12685d1b;p=pharext%2Fpharext diff --git a/src/pharext/Cli/Command.php b/src/pharext/Cli/Command.php index 0ec52ff..706cb85 100644 --- a/src/pharext/Cli/Command.php +++ b/src/pharext/Cli/Command.php @@ -163,4 +163,74 @@ trait Command $this->error(null); } } + + /** + * Execute a program with escalated privileges handling interactive password prompt + * @param string $command + * @param string $output + * @return int + */ + private function sudo($command, &$output) { + if (!($proc = proc_open($command, [STDIN,["pipe","w"],["pipe","w"]], $pipes))) { + return -1; + } + $stdout = $pipes[1]; + $passwd = 0; + while (!feof($stdout)) { + $R = [$stdout]; $W = []; $E = []; + if (!stream_select($R, $W, $E, null)) { + continue; + } + $data = fread($stdout, 0x1000); + /* only check a few times */ + if ($passwd++ < 10) { + if (stristr($data, "password")) { + printf("\n%s", $data); + } + } + $output .= $data; + } + return proc_close($proc); + } + + /** + * Execute a system command + * @param string $name pretty name + * @param string $command command + * @param array $args command arguments + * @param bool $sudo whether the command may need escalated privileges + */ + private function exec($name, $command, array $args = null, $sudo = false) { + $exec = escapeshellcmd($command); + if ($args) { + $exec .= " ". implode(" ", array_map("escapeshellarg", (array) $args)); + } + + if ($this->args->verbose) { + $this->info("Running %s ...\n", $exec); + } else { + $this->info("Running %s ... ", $name); + } + + if ($sudo && isset($this->args->sudo)) { + $retval = $this->sudo(sprintf($this->args->sudo." 2>&1", $exec), $output); + } elseif ($this->args->verbose) { + passthru($exec ." 2>&1", $retval); + } else { + exec($exec ." 2>&1", $output, $retval); + $output = implode("\n", $output); + } + + if ($retval) { + $this->error("Command %s failed with (%s)\n", $command, $retval); + if (isset($output) && !$this->args->quiet) { + printf("%s\n", $output); + } + exit(2); + } + if (!$this->args->verbose) { + // we already have a bunch of output + $this->info("OK\n"); + } + } }