Beispiel #1
0
 /**
  * Parses input setup in constructor, and creates a parse tree.
  */
 function parse_input()
 {
     /*We need to break the $this->parsed_input[SECTION_COMMAND] up into several distinct parts:
     			- Command
     			- Options
     			- Parameters
     			- Extras (e.g. I/O redirection / pipes)
     		i.e.
     			chmod	-R	777		./foobar	>> output.txt
     			COMMAND	OPTION	PARAMETER	PARAMETER	EXTRA
     		*/
     /*Output redirection:
     			2&1> output.txt
     
     			2&1			>		output.txt
     			STREAM_IDENTIFIER	ASSIGNMENT	REDIRECT_IDENTIFIER
     		*/
     $this->parse_runtime['command_length'] = strlen($this->current_input);
     $this->parse_runtime['parse_position'] = 0;
     $this->parse_runtime['current_mode'] = MODE_NORMAL;
     $this->parse_runtime['escape_used'] = false;
     $this->parse_runtime['occle_command'] = COMMAND_NATIVE;
     $this->parsed_input[SECTION_COMMAND] = NULL;
     $this->parsed_input[SECTION_OPTIONS] = array();
     $this->parsed_input[SECTION_PARAMETERS] = array();
     $this->parsed_input[SECTION_EXTRAS] = array();
     $this->fs = object_factory('virtual_fs');
     //Start parsing with the command
     $this->_extract_command();
     if (trim($this->parsed_input[SECTION_COMMAND]) == '') {
         $this->output[STREAM_STDCOMMAND] = '';
         $this->output[STREAM_STDHTML] = '';
         $this->output[STREAM_STDOUT] = '';
         $this->output[STREAM_STDERR] = do_lang('NON_COMMAND');
         return;
     }
     if ($this->parse_runtime['occle_command'] == COMMAND_NATIVE) {
         //Options (it's an OcCLE command; not a PHP command)
         $this->_extract_options();
         $this->_extract_parameters();
     }
     //Extras
     $this->_extract_extras();
     //Pre-processing: follow any extras provided
     $i = 0;
     foreach ($this->parsed_input[SECTION_EXTRAS] as $extra) {
         if ($extra[ASSIGNMENT] == REDIRECT_PIPE || $extra[ASSIGNMENT] == REDIRECT_INPUT) {
             $replacements = 0;
             if ($extra[ASSIGNMENT] == REDIRECT_PIPE) {
                 if (!isset($extra[STREAM_IDENTIFIER][0])) {
                     $extra[STREAM_IDENTIFIER] = array(STREAM_STDOUT);
                 }
                 $virtual_bash = new virtual_bash($extra[REDIRECT_IDENTIFIER]);
                 $virtual_output = $virtual_bash->return_output();
                 $pertinant_output = $virtual_output[$extra[STREAM_IDENTIFIER][count($extra[STREAM_IDENTIFIER]) - 1]];
                 if ($virtual_output[STREAM_STDERR] != '') {
                     $this->output[STREAM_STDERR] = $virtual_output[STREAM_STDERR];
                 }
             } else {
                 $pertinant_output = $this->fs->read_file($this->fs->_pwd_to_array($extra[REDIRECT_IDENTIFIER]));
                 if ($pertinant_output === false) {
                     $pertinant_output = '';
                 }
             }
             foreach ($this->parsed_input[SECTION_PARAMETERS] as $param_no => $parameter) {
                 //Do we have any "{".$i."}" parameters?
                 if ($parameter == '{' . strval($i) . '}') {
                     //NOTE: Might want to change this somehow so that other streams can be put through
                     $this->parsed_input[SECTION_PARAMETERS][$param_no] = $pertinant_output;
                     $replacements++;
                 }
             }
             if ($replacements == 0) {
                 //Just tag the input onto the end of the parameters array
                 //NOTE: See above
                 $this->parsed_input[SECTION_PARAMETERS][] = $pertinant_output;
             }
             $i++;
         }
     }
     //Handle the command: load up the relevant hook
     if ($this->parse_runtime['occle_command'] == COMMAND_NATIVE) {
         //See if it's a lone command first
         $hooks = find_all_hooks('modules', 'admin_occle_commands');
         $hook_return = NULL;
         foreach (array_keys($hooks) as $hook) {
             if ($hook == $this->parsed_input[SECTION_COMMAND]) {
                 require_code('hooks/modules/admin_occle_commands/' . filter_naughty_harsh($hook));
                 $object = object_factory('Hook_' . filter_naughty_harsh($hook));
                 $hook_return = $object->run($this->parsed_input[SECTION_OPTIONS], $this->parsed_input[SECTION_PARAMETERS], $this->fs);
                 $this->parse_runtime['occle_command'] = COMMAND_LONE;
                 break;
             }
         }
         if (!is_null($hook_return)) {
             $this->output[STREAM_STDCOMMAND] = $hook_return[0];
             if (is_object($hook_return[1])) {
                 $this->output[STREAM_STDHTML] = $hook_return[1]->evaluate();
             } else {
                 $this->output[STREAM_STDHTML] = $hook_return[1];
             }
             $this->output[STREAM_STDOUT] = array_key_exists(2, $hook_return) ? $hook_return[2] : '';
             $this->output[STREAM_STDERR] = array_key_exists(2, $hook_return) ? $hook_return[3] : '';
         } else {
             //It's not a lone command; see if it's a script - check first in the main script dir
             if (file_exists(get_custom_file_base() . '/data/modules/admin_occle/' . filter_naughty_harsh($this->parsed_input[SECTION_COMMAND], true))) {
                 $script_file = get_custom_file_base() . '/data/modules/admin_occle/' . filter_naughty_harsh($this->parsed_input[SECTION_COMMAND]);
             } else {
                 $script_file = $this->_find_script_file($this->parsed_input[SECTION_COMMAND]);
             }
             //Exhaustive search
             if ($script_file !== false && is_readable($script_file)) {
                 //It *is* a script, so let's run it :)
                 $this->parse_runtime['occle_command'] = COMMAND_SCRIPT;
                 $script_contents = unixify_line_format(file_get_contents($script_file, FILE_TEXT));
                 $script_lines = explode("\n", $script_contents);
                 foreach ($script_lines as $script_line) {
                     if (strlen($script_line) > 0) {
                         $virtual_bash = new virtual_bash($script_line, $this->parsed_input[SECTION_PARAMETERS]);
                         $script_output = $virtual_bash->return_output();
                         $this->output = $this->_combine_streams($this->output, $script_output);
                     }
                 }
             } else {
                 //Give up: it's not a command
                 $this->output[STREAM_STDCOMMAND] = '';
                 $this->output[STREAM_STDHTML] = '';
                 $this->output[STREAM_STDOUT] = '';
                 $this->output[STREAM_STDERR] = do_lang('NON_COMMAND');
                 return;
             }
         }
     } elseif ($this->parse_runtime['occle_command'] == COMMAND_PHP) {
         //NOTE: This is done in a separate function to limit variable interaction (due to the PHP memory implemented)
         $this->_handle_php_command();
     } elseif ($this->parse_runtime['occle_command'] == COMMAND_SQL) {
         //SQL command
         $GLOBALS['NO_DB_SCOPE_CHECK'] = true;
         $occle_output = $GLOBALS['SITE_DB']->query($this->parsed_input[SECTION_COMMAND], NULL, NULL, true);
         $GLOBALS['NO_DB_SCOPE_CHECK'] = false;
         if (count($occle_output) > 100) {
             $occle_output = $GLOBALS['SITE_DB']->query($this->parsed_input[SECTION_COMMAND], 100, NULL, true);
             $occle_output[] = array('...' => '...');
         }
         $this->output[STREAM_STDCOMMAND] = '';
         $this->output[STREAM_STDHTML] = '';
         $this->output[STREAM_STDOUT] = '';
         $this->output[STREAM_STDERR] = '';
         if (is_null($occle_output)) {
             $this->output[STREAM_STDERR] = do_lang('NO_RESULTS');
         } else {
             $this->output[STREAM_STDHTML] = $this->_array_to_html($occle_output);
         }
     }
     //Post-processing: follow any extras provided
     $old_output = $this->output;
     foreach ($this->parsed_input[SECTION_EXTRAS] as $extra) {
         if (!isset($extra[STREAM_IDENTIFIER][0])) {
             $extra[STREAM_IDENTIFIER] = array(STREAM_STDOUT);
         }
         if (!isset($this->output[$extra[REDIRECT_IDENTIFIER]])) {
             // It's a file... so read in if it exists, else blank
             $this->output[$extra[REDIRECT_IDENTIFIER]] = $this->fs->read_file($this->fs->_pwd_to_array($extra[REDIRECT_IDENTIFIER]));
             if ($this->output[$extra[REDIRECT_IDENTIFIER]] === false) {
                 $this->output[$extra[REDIRECT_IDENTIFIER]] = '';
             }
         }
         $extra[ASSIGNMENT] = intval($extra[ASSIGNMENT]);
         foreach ($extra[STREAM_IDENTIFIER] as $stream_identifier) {
             if ($extra[ASSIGNMENT] == REDIRECT_OVERWRITE) {
                 $this->output[$stream_identifier] = '';
                 // Because it's been taken away from here
                 $this->output[$extra[REDIRECT_IDENTIFIER]] = $old_output[$stream_identifier];
             } elseif ($extra[ASSIGNMENT] == REDIRECT_APPEND) {
                 $this->output[$stream_identifier] = '';
                 // Because it's been taken away from here
                 if (is_object($this->output[$extra[REDIRECT_IDENTIFIER]]) && is_object($old_output[$stream_identifier])) {
                     $this->output[$extra[REDIRECT_IDENTIFIER]]->append($old_output[$stream_identifier]);
                 } elseif (!is_object($this->output[$extra[REDIRECT_IDENTIFIER]]) && is_object($old_output[$stream_identifier])) {
                     $this->output[$extra[REDIRECT_IDENTIFIER]] = make_string_tempcode($this->output[$extra[REDIRECT_IDENTIFIER]]);
                     $this->output[$extra[REDIRECT_IDENTIFIER]]->append($old_output[$stream_identifier]);
                     $this->output[$extra[REDIRECT_IDENTIFIER]] = $this->output[$extra[REDIRECT_IDENTIFIER]]->evaluate();
                 } elseif (is_object($this->output[$extra[REDIRECT_IDENTIFIER]]) && !is_object($old_output[$stream_identifier])) {
                     $old_output[$stream_identifier] = make_string_tempcode($old_output[$stream_identifier]);
                     $this->output[$extra[REDIRECT_IDENTIFIER]]->append($old_output[$stream_identifier]);
                 } else {
                     $this->output[$extra[REDIRECT_IDENTIFIER]] .= $old_output[$stream_identifier];
                 }
             }
         }
         if ($extra[ASSIGNMENT] == REDIRECT_OVERWRITE || $extra[ASSIGNMENT] == REDIRECT_APPEND) {
             if (is_object($this->output[$extra[REDIRECT_IDENTIFIER]])) {
                 $this->output[$extra[REDIRECT_IDENTIFIER]] = $this->output[$extra[REDIRECT_IDENTIFIER]]->evaluate();
             }
             $this->fs->write_file($this->fs->_pwd_to_array($extra[REDIRECT_IDENTIFIER]), $this->output[$extra[REDIRECT_IDENTIFIER]]);
         }
     }
 }