Source of file phpsh.php
Size: 8,804 Bytes - Last Modified: 2021-12-23T10:34:07+00:00
/var/www/docs.ssmods.com/process/src/thirdparty/phpsh/phpsh.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 | #!/usr/bin/env php -q <?php // this is used by phpsh.py to exec php commands and maintain state // @author ccheever <Charlie Cheever> // @author dcorson <Dan Corson> // @contributor warman <Jon Warman> (added multiline input support \ing) // @date Thu Jun 15 22:27:46 PDT 2006 // // @usage ./phpsh.php [filename1 [filename2 ...]] // there are some special things we need to for php versions that are pre-5 if (version_compare(PHP_VERSION, '5') == -1) { define('STDIN', fopen('php://stdin', 'r')); } // plain text errors, not HTML @ini_set('html_errors', false); // we buffer the output on includes so that output that gets generated by includes // doesn't interfere with the secret messages we pass between php and python // we'll capture any output and show it when we construct the shell object ob_start(); // An optional include file if (file_exists('phpsh_includes.php')) { require_once 'phpsh_includes.php'; } $___phpsh___do_color = true; $___phpsh___options_possible = true; foreach (array_slice($GLOBALS['argv'], 1) as $___phpsh___arg) { $___phpsh___did_arg = false; if ($___phpsh___options_possible) { switch ($___phpsh___arg) { case '-c': $___phpsh___do_color = false; $___phpsh___did_arg = true; break; case '--': $___phpsh___options_possible = false; $___phpsh___did_arg = true; break; } if ($___phpsh___did_arg) { continue; } } require_once $___phpsh___arg; } $___phpsh___output_from_includes = ob_get_contents(); ob_end_clean(); // unset all the variables we don't absolutely need unset($___phpsh___arg); unset($___phpsh___did_arg); unset($___phpsh___options_possible); $___phpsh___ = new ___PHPShell___($___phpsh___output_from_includes, $argv[0] == '-c'); /** * An instance of a phpsh interactive loop * * @author ccheever * @author dcorson * * This class mostly exists as a proxy for a namespace */ class ___PHPShell___ { var $_cmd_line_ready_string = 'phpCommandLineReadyToGo'; var $_handle = STDIN; var $_MAX_LINE_SIZE = 262144; /** * Constructor - actually runs the interactive loop so that all we have to do is construct it to run * @param list $extra_include Extra files that we want to include * * @author ccheever * @author dcorson */ // For PHP4 compatibility... function ___PHPShell___($output_from_includes='', $___phpsh___do_color) { if (version_compare(PHP_VERSION, '5') == -1) { $this->__construct($output_from_includes, $___phpsh___do_color); } } function __construct($___phpsh___output_from_includes='', $___phpsh___do_color) { $this->__send_autocomplete_identifiers(); // now it's safe to send any output the includes generated print $___phpsh___output_from_includes; $this->_interactive_loop($___phpsh___do_color); } /** * Destructor - just closes the handle to STDIN * * @author ccheever */ function __destruct() { fclose($this->_handle); } /** * A function that escapes the weird case where the user sends our long and arbitrary cmd_line_ready_string as output * @param string $s * @return escaped string * * @author dcorson */ function php_escape($s) { $___phpsh___clrp = $this->_cmd_line_ready_string . '>'; return str_replace($___phpsh___clrp, "$___phpsh___clrp$___phpsh___clrp", $s); } /** * Sends the list of identifiers that phpsh should know to tab-complete to python * * @author ccheever */ function __send_autocomplete_identifiers() { // send special string to signal that we're sending the autocomplete identifiers print "#start_autocomplete_identifiers\n"; // send function names -- both user defined and built-in // globals, constants, classes, interfaces $defined_functions = get_defined_functions(); $___phpsh___methods = array(); foreach (($___phpsh___classes = get_declared_classes()) as $___phpsh___class) { $___phpsh___methods = array_merge($___phpsh___methods, get_class_methods($___phpsh___class)); } // interfaces only exist in PHP5 // We'll check to see if the function exists instead of // checking the version of PHP though if (function_exists('get_declared_interfaces')) { $___phpsh___interfaces = get_declared_interfaces(); } else { $___phpsh___interfaces = array(); } foreach (array_merge($defined_functions['user'], $defined_functions['internal'], array_keys($GLOBALS), array_keys(get_defined_constants()), $___phpsh___classes, $___phpsh___interfaces, $___phpsh___methods, array('instanceof')) as $___phpsh___identifier) { // exclude the phpsh internal variables from the autocomplete list if ((!preg_match("/^___phpsh___/", $___phpsh___identifier)) && ($___phpsh___identifier != '___PHPShell___')) { print "$___phpsh___identifier\n"; } else { unset($$___phpsh___identifier); } } // string signalling the end of autocmplete identifiers print "#end_autocomplete_identifiers\n"; } /** * The main interactive loop * * @author ccheever * @author dcorson * * We prefix our vars here to prevent accidental name collisions :( */ function _interactive_loop($___phpsh___do_color) { $___phpsh___append_input = false; $___phpsh___buf_len = 0; while (!feof($this->_handle)) { // this string, not duplicated (escaped), indicates to phpsh.php // that we are ready for more input // and it needs a new line since output is line buffered print $this->_cmd_line_ready_string . "\n"; if ($___phpsh___append_input) { // user ended last line with backslash $___phpsh___buffer .= fgets($this->_handle, $this->_MAX_LINE_SIZE - $___phpsh___buf_len); $___phpsh___append_input = false; } else { $___phpsh___buffer = fgets($this->_handle, $this->_MAX_LINE_SIZE); } $___phpsh___buf_len = strlen($___phpsh___buffer); // user ended this line with backslash if (($___phpsh___buf_len > 1) && ($___phpsh___buffer[$___phpsh___buf_len - 2] == '\\')) { $___phpsh___buffer[$___phpsh___buf_len - 2] = ' '; $___phpsh___buffer[$___phpsh___buf_len - 1] = ' '; $___phpsh___append_input = true; // don't eval yet. append next input line. continue; } // strip leading whitespace $___phpsh___buffer = ltrim($___phpsh___buffer); // use = as syntacic sugar for return if ($___phpsh___buffer && ($___phpsh___buffer[0] == '=')) { $___phpsh___buffer = 'return ' . substr($___phpsh___buffer, 1); } // add semicolon ; if user hasn't if (($___phpsh___buf_len > 1) && ($___phpsh___buffer[$___phpsh___buf_len - 2] != ';')) { $___phpsh___buffer .= ';'; } // now evaluate what the user's entered and capture the output ob_start(); // If we're running PHP5 then we want to catch exceptions, // but try-catch is not implemented in PHP4 and so we have to // special case if (version_compare(PHP_VERSION, '5') == -1) { // PHP4 - No exception handling $___phpsh___evalue = eval($___phpsh___buffer); } else { // PHP5 - exception handling // PHP4 won't even be able to try { $___phpsh___evalue = eval($___phpsh___buffer); } catch (Exception $___phpsh___exception) { // unfortunately, almost all exceptions not explicitly thrown // by users are uncatchable fwrite(STDERR, 'Uncaught exception: ' . get_class($___phpsh___exception) . ': ' . $___phpsh___exception->getMessage() . "\n" . $___phpsh___exception->getTraceAsString()); $___phpsh___evalue = null; } } $___phpsh___out = ob_get_contents(); ob_end_clean(); // we escape on the unlikely possibility we actually want to print // $phpCommReadyStr at the end of a line. we are that serious. if ($___phpsh___out !== null) { if ($___phpsh___do_color) { print "\033[1m"; // bold } print($this->php_escape($___phpsh___out)); if ($___phpsh___do_color) { print "\033[0m"; // normal } } // if any value was returned by the evaluated code, print it if (isset($___phpsh___evalue)) { print($this->php_escape(print_r($___phpsh___evalue, true))); // set $_ to be the value of the last evaluated expression $_ = $___phpsh___evalue; // we also set $_ans to be the last evaluated value since $ // $_ is reserved for the script name in php4 $_ans = $___phpsh___evalue; } } // newline so we end cleanly print "\n"; } } |