Drush: includes/backend.inc Source File

  1. 7.x doxygen/html/backend_8inc_source.html
  2. master doxygen/html/backend_8inc_source.html
Go to the documentation of this file.
1 <?php
2 
3 /**
4  * @file
5  * Drush backend API
6  *
7  * When a drush command is called with the --backend option,
8  * it will buffer all output, and instead return a JSON encoded
9  * string containing all relevant information on the command that
10  * was just executed.
11  *
12  * Through this mechanism, it is possible for Drush commands to
13  * invoke each other.
14  *
15  * There are many cases where a command might wish to call another
16  * command in its own process, to allow the calling command to
17  * intercept and act on any errors that may occur in the script that
18  * was called.
19  *
20  * A simple example is if there exists an 'update' command for running
21  * update.php on a specific site. The original command might download
22  * a newer version of a module for installation on a site, and then
23  * run the update script in a separate process, so that in the case
24  * of an error running a hook_update_n function, the module can revert
25  * to a previously made database backup, and the previously installed code.
26  *
27  * By calling the script in a separate process, the calling script is insulated
28  * from any error that occurs in the called script, to the level that if a
29  * php code error occurs (ie: misformed file, missing parenthesis, whatever),
30  * it is still able to reliably handle any problems that occur.
31  *
32  * This is nearly a RESTful API. @see http://en.wikipedia.org/wiki/REST
33  *
34  * Instead of :
35  * http://[server]/[apipath]/[command]?[arg1]=[value1],[arg2]=[value2]
36  *
37  * It will call :
38  * [apipath] [command] --[arg1]=[value1] --[arg2]=[value2] --backend
39  *
40  * [apipath] in this case will be the path to the drush.php file.
41  * [command] is the command you would call, for instance 'status'.
42  *
43  * GET parameters will be passed as options to the script.
44  * POST parameters will be passed to the script as a JSON encoded associative array over STDIN.
45  *
46  * Because of this standard interface, Drush commands can also be executed on
47  * external servers through SSH pipes, simply by prepending, 'ssh username@server.com'
48  * in front of the command.
49  *
50  * If the key-based ssh authentication has been set up between the servers,
51  * this will just work. By default, drush is configured to disallow password
52  * authentication; if you would like to enter a password for every connection,
53  * then in your drushrc.php file, set $options['ssh-options'] so that it does NOT
54  * include '-o PasswordAuthentication=no'. See examples/example.drushrc.php.
55  *
56  * The results from backend API calls can be fetched via a call to
58  */
59 
60 /**
61  * Identify the JSON encoded output from a command.
62  *
63  * Note that Drush now outputs a null ("\0") before the DRUSH_BACKEND_OUTPUT_DELIMITER,
64  * but this null occurs where this constant is output rather than being
65  * included in the define. This is done to maintain compatibility with
66  * older versions of Drush, so that Drush-6.x can correctly parse backend messages
67  * from calls made to Drush-5.x and earlier. The null is removed via trim().
68  */
69 define('DRUSH_BACKEND_OUTPUT_START', 'DRUSH_BACKEND_OUTPUT_START>>>');
70 define('DRUSH_BACKEND_OUTPUT_DELIMITER', DRUSH_BACKEND_OUTPUT_START . '%s<<<DRUSH_BACKEND_OUTPUT_END');
71 
72 /**
73  * Identify JSON encoded "packets" embedded inside of backend
74  * output; used to send out-of-band information durring a backend
75  * invoke call (currently only used for log and error messages).
76  */
77 define('DRUSH_BACKEND_PACKET_START', "DRUSH_BACKEND:");
78 define('DRUSH_BACKEND_PACKET_PATTERN', "\0" . DRUSH_BACKEND_PACKET_START . "%s\n\0");
79 
80 /**
81  * The backend result is the original PHP data structure (usually an array)
82  * used to generate the output for the current command.
83  */
84 function drush_backend_set_result($value) {
85  if (drush_get_context('DRUSH_BACKEND')) {
86  drush_set_context('BACKEND_RESULT', $value);
87  }
88 }
89 
90 /**
91  * Retrieves the results from the last call to backend_invoke.
92  *
93  * @returns array
94  * An associative array containing information from the last
95  * backend invoke. The keys in the array include:
96  *
97  * - output: This item contains the textual output of
98  * the command that was executed.
99  * - object: Contains the PHP object representation of the
100  * result of the command.
101  * - self: The self object contains the alias record that was
102  * used to select the bootstrapped site when the command was
103  * executed.
104  * - error_status: This item returns the error status for the
105  * command. Zero means "no error".
106  * - log: The log item contains an array of log messages from
107  * the command execution ordered chronologically. Each log
108  * entery is an associative array. A log entry contains
109  * following items:
110  * o type: The type of log entry, such as 'notice' or 'warning'
111  * o message: The log message
112  * o timestamp: The time that the message was logged
113  * o memory: Available memory at the time that the message was logged
114  * o error: The error code associated with the log message
115  * (only for log entries whose type is 'error')
116  * - error_log: The error_log item contains another representation
117  * of entries from the log. Only log entries whose 'error' item
118  * is set will appear in the error log. The error log is an
119  * associative array whose key is the error code, and whose value
120  * is an array of messages--one message for every log entry with
121  * the same error code.
122  * - context: The context item contains a representation of all option
123  * values that affected the operation of the command, including both
124  * the command line options, options set in a drushrc.php configuration
125  * files, and options set from the alias record used with the command.
126  */
128  return drush_get_context('BACKEND_RESULT');
129 }
130 
131 /**
132  * Print the json-encoded output of this command, including the
133  * encoded log records, context information, etc.
134  */
136  $data = array();
137 
138  if (drush_get_context('DRUSH_PIPE')) {
139  $pipe = drush_get_context('DRUSH_PIPE_BUFFER');
140  $data['output'] = $pipe; // print_r($pipe, TRUE);
141  }
142  else {
143  // Strip out backend commands.
144  $packet_regex = strtr(sprintf(DRUSH_BACKEND_PACKET_PATTERN, "([^\0]*)"), array("\0" => "\\0"));
145  $packet_regex = str_replace("\n", "", $packet_regex);
146  $data['output'] = preg_replace("/$packet_regex/s", '', drush_backend_output_collect(NULL));
147  }
148 
149  if (drush_get_context('DRUSH_QUIET', FALSE)) {
150  ob_end_clean();
151  }
152 
153  $result_object = drush_backend_get_result();
154  if (isset($result_object)) {
155  $data['object'] = $result_object;
156  }
157 
158  $error = drush_get_error();
159  $data['error_status'] = ($error) ? $error : DRUSH_SUCCESS;
160 
161  $data['log'] = drush_get_log(); // Append logging information
162  // The error log is a more specific version of the log, and may be used by calling
163  // scripts to check for specific errors that have occurred.
164  $data['error_log'] = drush_get_error_log();
165  // If there is a @self record, then include it in the result
166  $self_record = drush_sitealias_get_record('@self');
167  if (!empty($self_record)) {
168  $site_context = drush_get_context('site', array());
169  unset($site_context['config-file']);
170  unset($site_context['context-path']);
171  unset($self_record['loaded-config']);
172  unset($self_record['#name']);
173  $data['self'] = array_merge($site_context, $self_record);
174  }
175 
176  // Return the options that were set at the end of the process.
177  $data['context'] = drush_get_merged_options();
179 }
180 
181 /**
182  * Callback to collect backend command output.
183  */
184 function drush_backend_output_collect($string) {
185  static $output = '';
186  if (!isset($string)) {
187  return $output;
188  }
189 
190  $output .= $string;
191  return $string;
192 }
193 
194 /**
195  * Output buffer functions that discards all output but backend packets.
196  */
197 function drush_backend_output_discard($string) {
198  $packet_regex = strtr(sprintf(DRUSH_BACKEND_PACKET_PATTERN, "([^\0]*)"), array("\0" => "\\0"));
199  $packet_regex = str_replace("\n", "", $packet_regex);
200  if (preg_match_all("/$packet_regex/s", $string, $matches)) {
201  return implode('', $matches[0]);
202  }
203 }
204 
205 /**
206  * Output a backend packet if we're running as backend.
207  *
208  * @param packet
209  * The packet to send.
210  * @param data
211  * Data for the command.
212  *
213  * @return
214  * A boolean indicating whether the command was output.
215  */
216 function drush_backend_packet($packet, $data) {
217  if (drush_get_context('DRUSH_BACKEND')) {
218  $data['packet'] = $packet;
219  $data = json_encode($data);
220  // We use 'fwrite' instead of 'drush_print' here because
221  // this backend packet is out-of-band data.
223  return TRUE;
224  }
225 
226  return FALSE;
227 }
228 
229 /**
230  * Parse output returned from a Drush command.
231  *
232  * @param string
233  * The output of a drush command
234  * @param integrate
235  * Integrate the errors and log messages from the command into the current process.
236  * @param outputted
237  * Whether output has already been handled.
238  *
239  * @return
240  * An associative array containing the data from the external command, or the string parameter if it
241  * could not be parsed successfully.
242  */
243 function drush_backend_parse_output($string, $backend_options = array(), $outputted = FALSE) {
244  $regex = sprintf(DRUSH_BACKEND_OUTPUT_DELIMITER, '(.*)');
245 
246  preg_match("/$regex/s", $string, $match);
247 
248  if (!empty($match) && $match[1]) {
249  // we have our JSON encoded string
250  $output = $match[1];
251  // remove the match we just made and any non printing characters
252  $string = trim(str_replace(sprintf(DRUSH_BACKEND_OUTPUT_DELIMITER, $match[1]), '', $string));
253  }
254 
255  if (!empty($output)) {
256  $data = json_decode($output, TRUE);
257  if (is_array($data)) {
258  _drush_backend_integrate($data, $backend_options, $outputted);
259  return $data;
260  }
261  }
262  return $string;
263 }
264 
265 /**
266  * Integrate log messages and error statuses into the current
267  * process.
268  *
269  * Output produced by the called script will be printed if we didn't print it
270  * on the fly, errors will be set, and log messages will be logged locally, if
271  * not already logged.
272  *
273  * @param data
274  * The associative array returned from the external command.
275  * @param outputted
276  * Whether output has already been handled.
277  */
278 function _drush_backend_integrate($data, $backend_options, $outputted) {
279  // In 'integrate' mode, logs and errors have already been handled
280  // by drush_backend_packet (sender) drush_backend_parse_packets (receiver - us)
281  // during incremental output. We therefore do not need to call drush_set_error
282  // or drush_log here. The exception is if the sender is an older version of
283  // Drush (version 4.x) that does not send backend packets, then we will
284  // not have processed the log entries yet, and must print them here.
285  $received_packets = drush_get_context('DRUSH_RECEIVED_BACKEND_PACKETS', FALSE);
286  if (is_array($data['log']) && $backend_options['log'] && (!$received_packets)) {
287  foreach($data['log'] as $log) {
288  $message = is_array($log['message']) ? implode("\n", $log['message']) : $log['message'];
289  if (isset($backend_options['#output-label'])) {
290  $message = $backend_options['#output-label'] . $message;
291  }
292  if (isset($log['error']) && $backend_options['integrate']) {
293  drush_set_error($log['error'], $message);
294  }
295  elseif ($backend_options['integrate']) {
296  drush_log($message, $log['type']);
297  }
298  }
299  }
300  // Output will either be printed, or buffered to the drush_backend_output command.
301  // If the output has already been printed, then we do not need to show it again on a failure.
302  if (!$outputted) {
303  if (drush_cmp_error('DRUSH_APPLICATION_ERROR') && !empty($data['output'])) {
304  drush_set_error("DRUSH_APPLICATION_ERROR", dt("Output from failed command :\n !output", array('!output' => $data['output'])));
305  }
306  elseif ($backend_options['output']) {
307  _drush_backend_print_output($data['output'], $backend_options);
308  }
309  }
310 }
311 
312 /**
313  * Supress log message output during backend integrate.
314  */
316 }
317 
318 /**
319  * Call an external command using proc_open.
320  *
321  * @param cmds
322  * An array of records containing the following elements:
323  * 'cmd' - The command to execute, already properly escaped
324  * 'post-options' - An associative array that will be JSON encoded
325  * and passed to the script being called. Objects are not allowed,
326  * as they do not json_decode gracefully.
327  * 'backend-options' - Options that control the operation of the backend invoke
328  * - OR -
329  * An array of commands to execute. These commands already need to be properly escaped.
330  * In this case, post-options will default to empty, and a default output label will
331  * be generated.
332  * @param data
333  * An associative array that will be JSON encoded and passed to the script being called.
334  * Objects are not allowed, as they do not json_decode gracefully.
335  *
336  * @return
337  * False if the command could not be executed, or did not return any output.
338  * If it executed successfully, it returns an associative array containing the command
339  * called, the output of the command, and the error code of the command.
340  */
341 function _drush_backend_proc_open($cmds, $process_limit, $context = NULL) {
342  $descriptorspec = array(
343  0 => array("pipe", "r"), // stdin is a pipe that the child will read from
344  1 => array("pipe", "w"), // stdout is a pipe that the child will write to
345  );
346 
347  $open_processes = array();
348  $bucket = array();
349  $process_limit = max($process_limit, 1);
350  $is_windows = drush_is_windows();
351  // Loop through processes until they all close, having a nap as needed.
352  $nap_time = 0;
353  while (count($open_processes) || count($cmds)) {
354  $nap_time++;
355  if (count($cmds) && (count($open_processes) < $process_limit)) {
356  // Pop the site and command (key / value) from the cmds array
357  end($cmds);
358  list($site, $cmd) = each($cmds);
359  unset($cmds[$site]);
360 
361  if (is_array($cmd)) {
362  $c = $cmd['cmd'];
363  $post_options = $cmd['post-options'];
364  $backend_options = $cmd['backend-options'];
365  }
366  else {
367  $c = $cmd;
368  $post_options = array();
369  $backend_options = array();
370  }
371  $backend_options += array(
372  '#output-label' => '',
373  '#process-read-size' => 4096,
374  );
375  $process = array();
376  drush_log($backend_options['#output-label'] . $c);
377  $process['process'] = proc_open($c, $descriptorspec, $process['pipes'], null, null, array('context' => $context));
378  if (is_resource($process['process'])) {
379  if ($post_options) {
380  fwrite($process['pipes'][0], json_encode($post_options)); // pass the data array in a JSON encoded string
381  }
382  // If we do not close stdin here, then we cause a deadlock;
384  // If we reimplement interactive commands to also use
385  // _drush_proc_open, then clearly we would need to keep
386  // this open longer.
387  fclose($process['pipes'][0]);
388 
389  $process['info'] = stream_get_meta_data($process['pipes'][1]);
390  stream_set_blocking($process['pipes'][1], FALSE);
391  stream_set_timeout($process['pipes'][1], 1);
392  $bucket[$site]['cmd'] = $c;
393  $bucket[$site]['output'] = '';
394  $bucket[$site]['remainder'] = '';
395  $bucket[$site]['backend-options'] = $backend_options;
396  $bucket[$site]['end_of_output'] = FALSE;
397  $bucket[$site]['outputted'] = FALSE;
398  $open_processes[$site] = $process;
399  }
400  // Reset the $nap_time variable as there might be output to process next
401  // time around:
402  $nap_time = 0;
403  }
404  // Set up to call stream_select(). See:
406  // We can't use stream_select on Windows, because it doesn't work for
407  // streams returned by proc_open.
408  if (!$is_windows) {
409  $ss_result = 0;
410  $read_streams = array();
411  $write_streams = array();
412  $except_streams = array();
413  foreach ($open_processes as $site => &$current_process) {
414  if (isset($current_process['pipes'][1])) {
415  $read_streams[] = $current_process['pipes'][1];
416  }
417  }
418  // Wait up to 2s for data to become ready on one of the read streams.
419  if (count($read_streams)) {
420  $ss_result = stream_select($read_streams, $write_streams, $except_streams, 2);
421  // If stream_select returns a error, then fallback to using $nap_time.
422  if ($ss_result !== FALSE) {
423  $nap_time = 0;
424  }
425  }
426  }
427 
428  foreach ($open_processes as $site => &$current_process) {
429  if (isset($current_process['pipes'][1])) {
430  // Collect output from stdout
431  $bucket[$site][1] = '';
432  $info = stream_get_meta_data($current_process['pipes'][1]);
433 
434  if (!feof($current_process['pipes'][1]) && !$info['timed_out']) {
435  $string = $bucket[$site]['remainder'] . fread($current_process['pipes'][1], $backend_options['#process-read-size']);
436  $bucket[$site]['remainder'] = '';
437  $output_end_pos = strpos($string, DRUSH_BACKEND_OUTPUT_START);
438  if ($output_end_pos !== FALSE) {
439  $trailing_string = substr($string, 0, $output_end_pos);
440  $trailing_remainder = '';
441  // If there is any data in the trailing string (characters prior
442  // to the backend output start), then process any backend packets
443  // embedded inside.
444  if (strlen($trailing_string) > 0) {
445  drush_backend_parse_packets($trailing_string, $trailing_remainder, $bucket[$site]['backend-options']);
446  }
447  // If there is any data remaining in the trailing string after
448  // the backend packets are removed, then print it.
449  if (strlen($trailing_string) > 0) {
450  _drush_backend_print_output($trailing_string . $trailing_remainder, $bucket[$site]['backend-options']);
451  $bucket[$site]['outputted'] = TRUE;
452  }
453  $bucket[$site]['end_of_output'] = TRUE;
454  }
455  if (!$bucket[$site]['end_of_output']) {
456  drush_backend_parse_packets($string, $bucket[$site]['remainder'], $bucket[$site]['backend-options']);
457  // Pass output through.
458  _drush_backend_print_output($string, $bucket[$site]['backend-options']);
459  if (strlen($string) > 0) {
460  $bucket[$site]['outputted'] = TRUE;
461  }
462  }
463  $bucket[$site][1] .= $string;
464  $bucket[$site]['output'] .= $string;
465  $info = stream_get_meta_data($current_process['pipes'][1]);
466  flush();
467 
468  // Reset the $nap_time variable as there might be output to process
469  // next time around:
470  if (strlen($string) > 0) {
471  $nap_time = 0;
472  }
473  }
474  else {
475  fclose($current_process['pipes'][1]);
476  unset($current_process['pipes'][1]);
477  // close the pipe , set a marker
478 
479  // Reset the $nap_time variable as there might be output to process
480  // next time around:
481  $nap_time = 0;
482  }
483  }
484  else {
485  // if both pipes are closed for the process, remove it from active loop and add a new process to open.
486  $bucket[$site]['code'] = proc_close($current_process['process']);
487  unset($open_processes[$site]);
488 
489  // Reset the $nap_time variable as there might be output to process next
490  // time around:
491  $nap_time = 0;
492  }
493  }
494 
495  // We should sleep for a bit if we need to, up to a maximum of 1/10 of a
496  // second.
497  if ($nap_time > 0) {
498  usleep(max($nap_time * 500, 100000));
499  }
500  }
501  return $bucket;
502  // TODO: Handle bad proc handles
503  //}
504  //return FALSE;
505 }
506 
507 
508 
509 /**
510  * Print the output received from a call to backend invoke,
511  * adding the label to the head of each line if necessary.
512  */
513 function _drush_backend_print_output($output_string, $backend_options) {
514  if ($backend_options['output'] && !empty($output_string)) {
515  $output_label = array_key_exists('#output-label', $backend_options) ? $backend_options['#output-label'] : FALSE;
516  if (!empty($output_label)) {
517  // Remove one, and only one newline from the end of the
518  // string. Else we'll get an extra 'empty' line.
519  foreach (explode("\n", preg_replace('/\\n$/', '', $output_string)) as $line) {
520  fwrite(STDOUT, $output_label . rtrim($line) . "\n");
521  }
522  }
523  else {
524  fwrite(STDOUT, $output_string);
525  }
526  }
527 }
528 
529 /**
530  * Parse out and remove backend packet from the supplied string and
531  * invoke the commands.
532  */
533 function drush_backend_parse_packets(&$string, &$remainder, $backend_options) {
534  $remainder = '';
535  $packet_regex = strtr(sprintf(DRUSH_BACKEND_PACKET_PATTERN, "([^\0]*)"), array("\0" => "\\0"));
536  $packet_regex = str_replace("\n", "", $packet_regex);
537  if (preg_match_all("/$packet_regex/s", $string, $match, PREG_PATTERN_ORDER)) {
538  drush_set_context('DRUSH_RECEIVED_BACKEND_PACKETS', TRUE);
539  foreach ($match[1] as $packet_data) {
540  $entry = (array) json_decode($packet_data);
541  if (is_array($entry) && isset($entry['packet'])) {
542  $function = 'drush_backend_packet_' . $entry['packet'];
543  if (function_exists($function)) {
544  $function($entry, $backend_options);
545  }
546  else {
547  drush_log(dt("Unknown backend packet @packet", array('@packet' => $entry['packet'])), 'notice');
548  }
549  }
550  else {
551  drush_log(dt("Malformed backend packet"), 'error');
552  drush_log(dt("Bad packet: @packet", array('@packet' => print_r($entry, TRUE))), 'debug');
553  drush_log(dt("String is: @str", array('@str' => $packet_data), 'debug'));
554  }
555  }
556  $string = preg_replace("/$packet_regex/s", '', $string);
557  }
558  // Check to see if there is potentially a partial packet remaining.
559  // We only care about the last null; if there are any nulls prior
560  // to the last one, they would have been removed above if they were
561  // valid drush packets.
562  $embedded_null = strrpos($string, "\0");
563  if ($embedded_null !== FALSE) {
564  // We will consider everything after $embedded_null to be part of
565  // the $remainder string if:
566  // - the embedded null is less than strlen(DRUSH_BACKEND_OUTPUT_START)
567  // from the end of $string (that is, there might be a truncated
568  // backend packet header, or the truncated backend output start
569  // after the null)
570  // OR
571  // - the embedded null is followed by DRUSH_BACKEND_PACKET_START
572  // (that is, the terminating null for that packet has not been
573  // read into our buffer yet)
574  if (($embedded_null + strlen(DRUSH_BACKEND_OUTPUT_START) >= strlen($string)) || (substr($string, $embedded_null + 1, strlen(DRUSH_BACKEND_PACKET_START)) == DRUSH_BACKEND_PACKET_START)) {
575  $remainder = substr($string, $embedded_null);
576  $string = substr($string, 0, $embedded_null);
577  }
578  }
579 }
580 
581 /**
582  * Backend command for setting errors.
583  */
584 function drush_backend_packet_set_error($data, $backend_options) {
585  if (!$backend_options['integrate']) {
586  return;
587  }
588  $output_label = "";
589  if (array_key_exists('#output-label', $backend_options)) {
590  $output_label = $backend_options['#output-label'];
591  }
592  drush_set_error($data['error'], $data['message'], $output_label);
593 }
594 
595 /**
596  * Default options for backend_invoke commands.
597  */
598 function _drush_backend_adjust_options($site_record, $command, $command_options, $backend_options) {
599  // By default, if the caller does not specify a value for 'output', but does
600  // specify 'integrate' === FALSE, then we will set output to FALSE. Otherwise we
601  // will allow it to default to TRUE.
602  if ((array_key_exists('integrate', $backend_options)) && ($backend_options['integrate'] === FALSE) && (!array_key_exists('output', $backend_options))) {
603  $backend_options['output'] = FALSE;
604  }
605  $has_site_specification = array_key_exists('root', $site_record) || array_key_exists('uri', $site_record);
606  $result = $backend_options + array(
607  'method' => 'GET',
608  'output' => TRUE,
609  'log' => TRUE,
610  'integrate' => TRUE,
611  'backend' => TRUE,
612  'dispatch-using-alias' => !$has_site_specification,
613  );
614  // Convert '#integrate' et. al. into backend options
615  foreach ($command_options as $key => $value) {
616  if (substr($key,0,1) === '#') {
617  $result[substr($key,1)] = $value;
618  }
619  }
620  return $result;
621 }
622 
623 /**
624  * Execute a new local or remote command in a new process.
625  *
626  * n.b. Prefer drush_invoke_process() to this function.
627  *
628  * @param invocations
629  * An array of command records to exacute. Each record should contain:
630  * 'site':
631  * An array containing information used to generate the command.
632  * 'remote-host'
633  * Optional. A remote host to execute the drush command on.
634  * 'remote-user'
635  * Optional. Defaults to the current user. If you specify this, you can choose which module to send.
636  * 'ssh-options'
637  * Optional. Defaults to "-o PasswordAuthentication=no"
638  * 'path-aliases'
639  * Optional; contains paths to folders and executables useful to the command.
640  * '%drush-script'
641  * Optional. Defaults to the current drush.php file on the local machine, and
642  * to simply 'drush' (the drush script in the current PATH) on remote servers.
643  * You may also specify a different drush.php script explicitly. You will need
644  * to set this when calling drush on a remote server if 'drush' is not in the
645  * PATH on that machine.
646  * 'command':
647  * A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
648  * 'args':
649  * An array of arguments for the command.
650  * 'options'
651  * Optional. An array containing options to pass to the remote script.
652  * Array items with a numeric key are treated as optional arguments to the
653  * command.
654  * 'backend-options':
655  * Optional. Additional parameters that control the operation of the invoke.
656  * 'method'
657  * Optional. Defaults to 'GET'.
658  * If this parameter is set to 'POST', the $data array will be passed
659  * to the script being called as a JSON encoded string over the STDIN
660  * pipe of that process. This is preferable if you have to pass
661  * sensitive data such as passwords and the like.
662  * For any other value, the $data array will be collapsed down into a
663  * set of command line options to the script.
664  * 'integrate'
665  * Optional. Defaults to TRUE.
666  * If TRUE, any error statuses will be integrated into the current
667  * process. This might not be what you want, if you are writing a
668  * command that operates on multiple sites.
669  * 'log'
670  * Optional. Defaults to TRUE.
671  * If TRUE, any log messages will be integrated into the current
672  * process.
673  * 'output'
674  * Optional. Defaults to TRUE.
675  * If TRUE, output from the command will be synchronously printed to
676  * stdout.
677  * 'drush-script'
678  * Optional. Defaults to the current drush.php file on the local
679  * machine, and to simply 'drush' (the drush script in the current
680  * PATH) on remote servers. You may also specify a different drush.php
681  * script explicitly. You will need to set this when calling drush on
682  * a remote server if 'drush' is not in the PATH on that machine.
683  * 'dispatch-using-alias'
684  * Optional. Defaults to FALSE.
685  * If specified as a non-empty value the drush command will be
686  * dispatched using the alias name on the command line, instead of
687  * the options from the alias being added to the command line
688  * automatically.
689  * @param common_options
690  * Optional. Merged in with the options for each invocation.
691  * @param backend_options
692  * Optional. Merged in with the backend options for each invocation.
693  * @param default_command
694  * Optional. Used as the 'command' for any invocation that does not
695  * define a command explicitly.
696  * @param default_site
697  * Optional. Used as the 'site' for any invocation that does not
698  * define a site explicitly.
699  * @param context
700  * Optional. Passed in to proc_open if provided.
701  *
702  * @return
703  * If the command could not be completed successfully, FALSE.
704  * If the command was completed, this will return an associative array containing the data from drush_backend_output().
705  */
706 function drush_backend_invoke_concurrent($invocations, $common_options = array(), $common_backend_options = array(), $default_command = NULL, $default_site = NULL, $context = NULL) {
707  $index = 0;
708 
709  // Slice and dice our options in preparation to build a command string
710  $invocation_options = array();
711  foreach ($invocations as $invocation) {
712  $site_record = isset($invocation['site']) ? $invocation['site'] : $default_site;
713  // NULL is a synonym to '@self', although the latter is preferred.
714  if (!isset($site_record)) {
715  $site_record = '@self';
716  }
717  // If the first parameter is not a site alias record,
718  // then presume it is an alias name, and try to look up
719  // the alias record.
720  if (!is_array($site_record)) {
721  $site_record = drush_sitealias_get_record($site_record);
722  }
723  $command = isset($invocation['command']) ? $invocation['command'] : $default_command;
724  $args = isset($invocation['args']) ? $invocation['args'] : array();
725  $command_options = isset($invocation['options']) ? $invocation['options'] : array();
726  $backend_options = isset($invocation['backend-options']) ? $invocation['backend-options'] : array();
727  // If $backend_options is passed in as a bool, interpret that as the value for 'integrate'
728  if (!is_array($common_backend_options)) {
729  $integrate = (bool)$common_backend_options;
730  $common_backend_options = array('integrate' => $integrate);
731  }
732 
733  $command_options += $common_options;
734  $backend_options += $common_backend_options;
735 
736  $backend_options = _drush_backend_adjust_options($site_record, $command, $command_options, $backend_options);
737 
738  // Insure that contexts such as DRUSH_SIMULATE and NO_COLOR are included.
739  $command_options += _drush_backend_get_global_contexts($site_record);
740 
741  // Add in command-specific options as well
742  $command_options += drush_command_get_command_specific_options($site_record, $command);
743 
744  // If the caller has requested it, don't pull the options from the alias
745  // into the command line, but use the alias name for dispatching.
746  if (!empty($backend_options['dispatch-using-alias']) && isset($site_record['#name'])) {
747  list($post_options, $commandline_options, $drush_global_options) = _drush_backend_classify_options(array(), $command_options, $backend_options);
748  $site_record_to_dispatch = '@' . ltrim($site_record['#name'], '@');
749  }
750  else {
751  list($post_options, $commandline_options, $drush_global_options) = _drush_backend_classify_options($site_record, $command_options, $backend_options);
752  $site_record_to_dispatch = '';
753  }
754  if (array_key_exists('backend-simulate', $backend_options)) {
755  $commandline_options['simulate'] = TRUE;
756  }
757  $site_record += array('path-aliases' => array());
758  $site_record['path-aliases'] += array(
759  '%drush-script' => NULL,
760  );
761 
762  $site = (array_key_exists('#name', $site_record) && !array_key_exists($site_record['#name'], $invocation_options)) ? $site_record['#name'] : $index++;
763  $invocation_options[$site] = array(
764  'site-record' => $site_record,
765  'site-record-to-dispatch' => $site_record_to_dispatch,
766  'command' => $command,
767  'args' => $args,
768  'post-options' => $post_options,
769  'drush-global-options' => $drush_global_options,
770  'commandline-options' => $commandline_options,
771  'command-options' => $command_options,
772  'backend-options' => $backend_options,
773  );
774  }
775 
776  // Calculate the length of the longest output label
777  $max_name_length = 0;
778  $label_separator = '';
779  if (!array_key_exists('no-label', $common_options) && (count($invocation_options) > 1)) {
780  $label_separator = array_key_exists('label-separator', $common_options) ? $common_options['label-separator'] : ' >> ';
781  foreach ($invocation_options as $site => $item) {
782  $backend_options = $item['backend-options'];
783  if (!array_key_exists('#output-label', $backend_options)) {
784  if (is_numeric($site)) {
785  $backend_options['#output-label'] = ' * [@self.' . $site;
786  $label_separator = '] ';
787  }
788  else {
789  $backend_options['#output-label'] = $site;
790  }
791  $invocation_options[$site]['backend-options']['#output-label'] = $backend_options['#output-label'];
792  }
793  $name_len = strlen($backend_options['#output-label']);
794  if ($name_len > $max_name_length) {
795  $max_name_length = $name_len;
796  }
797  if (array_key_exists('#label-separator', $backend_options)) {
798  $label_separator = $backend_options['#label-separator'];
799  }
800  }
801  }
802  // Now pad out the output labels and add the label separator.
803  $reserve_margin = $max_name_length + strlen($label_separator);
804  foreach ($invocation_options as $site => $item) {
805  $backend_options = $item['backend-options'] + array('#output-label' => '');
806  $invocation_options[$site]['backend-options']['#output-label'] = str_pad($backend_options['#output-label'], $max_name_length, " ") . $label_separator;
807  if ($reserve_margin) {
808  $invocation_options[$site]['drush-global-options']['reserve-margin'] = $reserve_margin;
809  }
810  }
811 
812  // Now take our prepared options and generate the command strings
813  $cmds = array();
814  foreach ($invocation_options as $site => $item) {
815  $site_record = $item['site-record'];
816  $site_record_to_dispatch = $item['site-record-to-dispatch'];
817  $command = $item['command'];
818  $args = $item['args'];
819  $post_options = $item['post-options'];
820  $commandline_options = $item['commandline-options'];
821  $command_options = $item['command-options'];
822  $drush_global_options = $item['drush-global-options'];
823  $backend_options = $item['backend-options'];
824  $os = drush_os($site_record);
825  // If the caller did not pass in a specific path to drush, then we will
826  // use a default value. For commands that are being executed on the same
827  // machine, we will use DRUSH_COMMAND, which is the path to the drush.php
828  // that is running right now. For remote commands, we will run a wrapper
829  // script instead of drush.php -- drush.bat on Windows, or drush on Linux.
830  $drush_path = $site_record['path-aliases']['%drush-script'];
831  $php = array_key_exists('php', $site_record) ? $site_record['php'] : (array_key_exists('php', $command_options) ? $command_options['php'] : NULL);
832  $drush_command_path = drush_build_drush_command($drush_path, $php, $os, array_key_exists('remote-host', $site_record));
833  $cmd = _drush_backend_generate_command($site_record, $drush_command_path . " " . _drush_backend_argument_string($drush_global_options, $os) . " " . $site_record_to_dispatch . " " . $command, $args, $commandline_options, $backend_options) . ' 2>&1';
834  $cmds[$site] = array(
835  'cmd' => $cmd,
836  'post-options' => $post_options,
837  'backend-options' => $backend_options,
838  );
839  }
840 
841  return _drush_backend_invoke($cmds, $common_backend_options, $context);
842 }
843 
844 /**
845  * Find all of the drush contexts that are used to cache global values and
846  * return them in an associative array.
847  */
848 function _drush_backend_get_global_contexts($site_record) {
849  $result = array();
850  $global_option_list = drush_get_global_options(FALSE);
851  foreach ($global_option_list as $global_key => $global_metadata) {
852  if (is_array($global_metadata)) {
853  $value = '';
854  if (!array_key_exists('never-propagate', $global_metadata)) {
855  if ((array_key_exists('propagate-cli-value', $global_metadata))) {
856  $value = drush_get_option($global_key, '', 'cli');
857  }
858  elseif ((array_key_exists('context', $global_metadata))) {
859  // If the context is declared to be a 'local-context-only',
860  // then only put it in if this is a local dispatch.
861  if (!array_key_exists('local-context-only', $global_metadata) || !array_key_exists('remote-host', $site_record)) {
862  $value = drush_get_context($global_metadata['context'], array());
863  }
864  }
865  if (!empty($value)) {
866  $result[$global_key] = $value;
867  }
868  }
869  }
870  }
871  return $result;
872 }
873 
874 /**
875  * Take all of the values in the $command_options array, and place each of
876  * them into one of the following result arrays:
877  *
878  * - $post_options: options to be encoded as JSON and written to the
879  * standard input of the drush subprocess being executed.
880  * - $commandline_options: options to be placed on the command line of the drush
881  * subprocess.
882  * - $drush_global_options: the drush global options also go on the command
883  * line, but appear before the drush command name rather than after it.
884  *
885  * Also, this function may modify $backend_options.
886  */
887 function _drush_backend_classify_options($site_record, $command_options, &$backend_options) {
888  // In 'POST' mode (the default, remove everything (except the items marked 'never-post'
889  // in the global option list) from the commandline options and put them into the post options.
890  // The post options will be json-encoded and sent to the command via stdin
891  $global_option_list = drush_get_global_options(FALSE); // These should be in the command line.
892  $additional_global_options = array();
893  if (array_key_exists('additional-global-options', $backend_options)) {
894  $additional_global_options = $backend_options['additional-global-options'];
895  $command_options += $additional_global_options;
896  }
897  $method_post = ((!array_key_exists('method', $backend_options)) || ($backend_options['method'] == 'POST'));
898  $post_options = array();
899  $commandline_options = array();
900  $drush_global_options = array();
901  $drush_local_options = array();
902  $additional_backend_options = array();
903  foreach ($site_record as $key => $value) {
904  if (!in_array($key, drush_sitealias_site_selection_keys())) {
905  if ($key[0] == '#') {
906  $backend_options[$key] = $value;
907  }
908  if (!isset($command_options[$key])) {
909  if (array_key_exists($key, $global_option_list)) {
910  $command_options[$key] = $value;
911  }
912  }
913  }
914  }
915  if (array_key_exists('drush-local-options', $backend_options)) {
916  $drush_local_options = $backend_options['drush-local-options'];
917  $command_options += $drush_local_options;
918  }
919  if (!empty($backend_options['backend']) && empty($backend_options['interactive']) && empty($backend_options['fork'])) {
920  $drush_global_options['backend'] = '2';
921  }
922  foreach ($command_options as $key => $value) {
923  $global = array_key_exists($key, $global_option_list);
924  $propagate = TRUE;
925  $special = FALSE;
926  if ($global) {
927  $propagate = (!array_key_exists('never-propagate', $global_option_list[$key]));
928  $special = (array_key_exists('never-post', $global_option_list[$key]));
929  if ($propagate) {
930  // We will allow 'merge-pathlist' contexts to be propogated. Right now
931  // these are all 'local-context-only' options; if we allowed them to
932  // propogate remotely, then we would need to get the right path separator
933  // for the remote machine.
934  if (is_array($value) && array_key_exists('merge-pathlist', $global_option_list[$key])) {
935  $value = implode(PATH_SEPARATOR, $value);
936  }
937  }
938  }
939  // Just remove options that are designated as non-propagating
940  if ($propagate === TRUE) {
941  // In METHOD POST, move command options to post options
942  if ($method_post && ($special === FALSE)) {
943  $post_options[$key] = $value;
944  }
945  // In METHOD GET, ignore options with array values
946  elseif (!is_array($value)) {
947  if ($global || array_key_exists($key, $additional_global_options)) {
948  $drush_global_options[$key] = $value;
949  }
950  else {
951  $commandline_options[$key] = $value;
952  }
953  }
954  }
955  }
956  return array($post_options, $commandline_options, $drush_global_options, $additional_backend_options);
957 }
958 
959 /**
960  * Create a new pipe with proc_open, and attempt to parse the output.
961  *
962  * We use proc_open instead of exec or others because proc_open is best
963  * for doing bi-directional pipes, and we need to pass data over STDIN
964  * to the remote script.
965  *
966  * Exec also seems to exhibit some strangeness in keeping the returned
967  * data intact, in that it modifies the newline characters.
968  *
969  * @param cmd
970  * The complete command line call to use.
971  * @param post_options
972  * An associative array to json-encode and pass to the remote script on stdin.
973  * @param backend_options
974  * Options for the invocation.
975  *
976  * @return
977  * If the command could not be completed successfully, FALSE.
978  * If one command was executed, this will return an associative array containing
979  * the data from drush_backend_output().
980  * If multiple commands were executed, this will return an associative array
981  * containing one item, 'concurrent', which will contain a list of the different
982  * backend invoke results from each concurrent command.
983  */
984 function _drush_backend_invoke($cmds, $common_backend_options = array(), $context = NULL) {
985  if (drush_get_context('DRUSH_SIMULATE') && !array_key_exists('override-simulated', $common_backend_options) && !array_key_exists('backend-simulate', $common_backend_options)) {
986  foreach ($cmds as $cmd) {
987  drush_print(dt('Simulating backend invoke: !cmd', array('!cmd' => $cmd['cmd'])));
988  }
989  return FALSE;
990  }
991  foreach ($cmds as $cmd) {
992  drush_log(dt('Backend invoke: !cmd', array('!cmd' => $cmd['cmd'])), 'command');
993  }
994  if (array_key_exists('interactive', $common_backend_options) || array_key_exists('fork', $common_backend_options)) {
995  foreach ($cmds as $cmd) {
996  $exec_cmd = $cmd['cmd'];
997  if (array_key_exists('fork', $common_backend_options)) {
998  $exec_cmd .= ' --quiet &';
999  }
1000  $ret = drush_shell_proc_open($exec_cmd);
1001  }
1002  return $ret;
1003  }
1004  else {
1005  $process_limit = drush_get_option_override($common_backend_options, 'concurrency', 1);
1006  $procs = _drush_backend_proc_open($cmds, $process_limit, $context);
1007  $procs = is_array($procs) ? $procs : array($procs);
1008 
1009  $ret = array();
1010  foreach ($procs as $site => $proc) {
1011  if (($proc['code'] == DRUSH_APPLICATION_ERROR) && isset($common_backend_options['integrate'])) {
1012  drush_set_error('DRUSH_APPLICATION_ERROR', dt("The external command could not be executed due to an application error."));
1013  }
1014 
1015  if ($proc['output']) {
1016  $values = drush_backend_parse_output($proc['output'], $proc['backend-options'], $proc['outputted']);
1017  $values['site'] = $site;
1018  if (is_array($values)) {
1019  if (empty($ret)) {
1020  $ret = $values;
1021  }
1022  elseif (!array_key_exists('concurrent', $ret)) {
1023  $ret = array('concurrent' => array($ret, $values));
1024  }
1025  else {
1026  $ret['concurrent'][] = $values;
1027  }
1028  }
1029  else {
1030  $ret = drush_set_error('DRUSH_FRAMEWORK_ERROR', dt("The command could not be executed successfully (returned: !return, code: !code)", array("!return" => $proc['output'], "!code" => $proc['code'])));
1031  }
1032  }
1033  }
1034  }
1035  return empty($ret) ? FALSE : $ret;
1036 }
1037 
1038 /**
1039  * Helper function that generates an anonymous site alias specification for
1040  * the given parameters.
1041  */
1042 function drush_backend_generate_sitealias($backend_options) {
1043  // Ensure default values.
1044  $backend_options += array(
1045  'remote-host' => NULL,
1046  'remote-user' => NULL,
1047  'ssh-options' => NULL,
1048  'drush-script' => NULL,
1049  );
1050  return array(
1051  'remote-host' => $backend_options['remote-host'],
1052  'remote-user' => $backend_options['remote-user'],
1053  'ssh-options' => $backend_options['ssh-options'],
1054  'path-aliases' => array(
1055  '%drush-script' => $backend_options['drush-script'],
1056  ),
1057  );
1058 }
1059 
1060 /**
1061  * Generate a command to execute.
1062  *
1063  * @param site_record
1064  * An array containing information used to generate the command.
1065  * 'remote-host'
1066  * Optional. A remote host to execute the drush command on.
1067  * 'remote-user'
1068  * Optional. Defaults to the current user. If you specify this, you can choose which module to send.
1069  * 'ssh-options'
1070  * Optional. Defaults to "-o PasswordAuthentication=no"
1071  * 'path-aliases'
1072  * Optional; contains paths to folders and executables useful to the command.
1073  * '%drush-script'
1074  * Optional. Defaults to the current drush.php file on the local machine, and
1075  * to simply 'drush' (the drush script in the current PATH) on remote servers.
1076  * You may also specify a different drush.php script explicitly. You will need
1077  * to set this when calling drush on a remote server if 'drush' is not in the
1078  * PATH on that machine.
1079  * @param command
1080  * A defined drush command such as 'cron', 'status' or any of the available ones such as 'drush pm'.
1081  * @param args
1082  * An array of arguments for the command.
1083  * @param command_options
1084  * Optional. An array containing options to pass to the remote script.
1085  * Array items with a numeric key are treated as optional arguments to the
1086  * command. This parameter is a reference, as any options that have been
1087  * represented as either an option, or an argument will be removed. This
1088  * allows you to pass the left over options as a JSON encoded string,
1089  * without duplicating data.
1090  * @param backend_options
1091  * Optional. An array of options for the invocation.
1092  * @see drush_backend_invoke for documentation.
1093  *
1094  * @return
1095  * A text string representing a fully escaped command.
1096  */
1097 function _drush_backend_generate_command($site_record, $command, $args = array(), $command_options = array(), $backend_options = array()) {
1098  $site_record += array(
1099  'remote-host' => NULL,
1100  'remote-user' => NULL,
1101  'ssh-options' => NULL,
1102  'path-aliases' => array(),
1103  );
1104  $backend_options += array(
1105  '#tty' => FALSE,
1106  );
1107 
1108  $hostname = $site_record['remote-host'];
1109  $username = $site_record['remote-user'];
1110  $ssh_options = $site_record['ssh-options'];
1111  $os = drush_os($site_record);
1112 
1113  if (array_key_exists('#check-local', $site_record) && drush_is_local_host($hostname)) {
1114  $hostname = null;
1115  }
1116 
1117  foreach ($command_options as $key => $arg) {
1118  if (is_numeric($key)) {
1119  $args[] = $arg;
1120  unset($command_options[$key]);
1121  }
1122  }
1123 
1124  $cmd[] = $command;
1125  foreach ($args as $arg) {
1126  $cmd[] = drush_escapeshellarg($arg, $os);
1127  }
1128  $option_str = _drush_backend_argument_string($command_options, $os);
1129  if (!empty($option_str)) {
1130  $cmd[] = " " . $option_str;
1131  }
1132  $command = implode(' ', array_filter($cmd, 'strlen'));
1133  if (isset($hostname)) {
1134  if (drush_is_windows($os)) {
1135  if (isset($username)) {
1136  $username = " -u:" . drush_escapeshellarg($username, "LOCAL");
1137  if (array_key_exists('winrs-password', $site_record)) {
1138  $username .= " -p:" . drush_escapeshellarg($site_record['winrs-password'], "LOCAL");
1139  }
1140  }
1141  $command = "winrs" . $username . " -r:" . drush_escapeshellarg($hostname, "LOCAL") . " " . drush_escapeshellarg($command, "LOCAL");
1142  }
1143  else {
1144  $username = (isset($username)) ? drush_escapeshellarg($username, "LOCAL") . "@" : '';
1145  $ssh_options = $site_record['ssh-options'];
1146  $ssh_options = (isset($ssh_options)) ? $ssh_options : drush_get_option('ssh-options', "-o PasswordAuthentication=no");
1147 
1148  $ssh_cmd[] = "ssh";
1149  $ssh_cmd[] = $ssh_options;
1150  if ($backend_options['#tty']) {
1151  $ssh_cmd[] = '-t';
1152  }
1153  $ssh_cmd[] = $username . drush_escapeshellarg($hostname, "LOCAL");
1154  $ssh_cmd[] = drush_escapeshellarg($command . ' 2>&1', "LOCAL");
1155 
1156  // Remove NULLs and separate with spaces
1157  $command = implode(' ', array_filter($ssh_cmd, 'strlen'));
1158  }
1159  }
1160 
1161  return $command;
1162 }
1163 
1164 /**
1165  * Map the options to a string containing all the possible arguments and options.
1166  *
1167  * @param data
1168  * Optional. An array containing options to pass to the remote script.
1169  * Array items with a numeric key are treated as optional arguments to the command.
1170  * This parameter is a reference, as any options that have been represented as either an option, or an argument will be removed.
1171  * This allows you to pass the left over options as a JSON encoded string, without duplicating data.
1172  * @param method
1173  * Optional. Defaults to 'GET'.
1174  * If this parameter is set to 'POST', the $data array will be passed to the script being called as a JSON encoded string over
1175  * the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.
1176  * For any other value, the $data array will be collapsed down into a set of command line options to the script.
1177  * @return
1178  * A properly formatted and escaped set of arguments and options to append to the drush.php shell command.
1179  */
1180 function _drush_backend_argument_string($data, $os = NULL) {
1181  $options = array();
1182 
1183  foreach ($data as $key => $value) {
1184  if (!is_array($value) && !is_object($value) && isset($value)) {
1185  if (substr($key,0,1) != '#') {
1186  $options[$key] = $value;
1187  }
1188  }
1189  }
1190 
1191  $option_str = '';
1192  foreach ($options as $key => $value) {
1193  $option_str .= _drush_escape_option($key, $value, $os);
1194  }
1195 
1196  return $option_str;
1197 }
1198 
1199 /**
1200  * Return a properly formatted and escaped command line option
1201  *
1202  * @param key
1203  * The name of the option.
1204  * @param value
1205  * The value of the option.
1206  *
1207  * @return
1208  * If the value is set to TRUE, this function will return " --key"
1209  * In other cases it will return " --key='value'"
1210  */
1211 function _drush_escape_option($key, $value = TRUE, $os = NULL) {
1212  if ($value !== TRUE) {
1213  $option_str = " --$key=" . drush_escapeshellarg($value, $os);
1214  }
1215  else {
1216  $option_str = " --$key";
1217  }
1218  return $option_str;
1219 }
1220 
1221 /**
1222  * Read options fron STDIN during POST requests.
1223  *
1224  * This function will read any text from the STDIN pipe,
1225  * and attempts to generate an associative array if valid
1226  * JSON was received.
1227  *
1228  * @return
1229  * An associative array of options, if successfull. Otherwise FALSE.
1230  */
1232  $fp = fopen('php://stdin', 'r');
1233  // Windows workaround: we cannot count on stream_get_contents to
1234  // return if STDIN is reading from the keyboard. We will therefore
1235  // check to see if there are already characters waiting on the
1236  // stream (as there always should be, if this is a backend call),
1237  // and if there are not, then we will exit.
1238  // This code prevents drush from hanging forever when called with
1239  // --backend from the commandline; however, overall it is still
1240  // a futile effort, as it does not seem that backend invoke can
1241  // successfully write data to that this function can read,
1242  // so the argument list and command always come out empty. :(
1243  // Perhaps stream_get_contents is the problem, and we should use
1244  // the technique described here:
1246  // n.b. the code in that issue passes '0' for the timeout in stream_select
1247  // in a loop, which is not recommended.
1248  // Note that the following DOES work:
1249  // drush ev 'print(json_encode(array("test" => "XYZZY")));' | drush status --backend
1250  // So, redirecting input is okay, it is just the proc_open that is a problem.
1251  if (drush_is_windows()) {
1252  // Note that stream_select uses reference parameters, so we need variables (can't pass a constant NULL)
1253  $read = array($fp);
1254  $write = NULL;
1255  $except = NULL;
1256  // Question: might we need to wait a bit for STDIN to be ready,
1257  // even if the process that called us immediately writes our parameters?
1258  // Passing '100' for the timeout here causes us to hang indefinitely
1259  // when called from the shell.
1260  $changed_streams = stream_select($read, $write, $except, 0);
1261  // Return on error (FALSE) or no changed streams (0).
1263  // stream_select will return FALSE for streams returned by proc_open.
1264  // That is not applicable to us, is it? Our stream is connected to a stream
1265  // created by proc_open, but is not a stream returned by proc_open.
1266  if ($changed_streams < 1) {
1267  return FALSE;
1268  }
1269  }
1270  stream_set_blocking($fp, FALSE);
1271  $string = stream_get_contents($fp);
1272  fclose($fp);
1273  if (trim($string)) {
1274  return json_decode($string, TRUE);
1275  }
1276  return FALSE;
1277 }

File

doxygen/html/backend_8inc_source.html
View source
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>Drush: includes/backend.inc Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
  $(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">Drush
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.1.2 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
      </li>
    </ul>
  </div>
  <div id="navrow2" class="tabs2">
    <ul class="tablist">
      <li><a href="files.html"><span>File&#160;List</span></a></li>
      <li><a href="globals.html"><span>File&#160;Members</span></a></li>
    </ul>
  </div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Groups</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Pages</a></div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="dir_09e761304027c904456130627fd4dcf5.html">includes</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">backend.inc</div>  </div>
</div><!--header-->
<div class="contents">
<a href="backend_8inc.html">Go to the documentation of this file.</a><div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;&lt;?php</div>
<div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;<span class="comment"> * @file</span></div>
<div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;<span class="comment"> * Drush backend API</span></div>
<div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;<span class="comment"> * When a drush command is called with the --backend option,</span></div>
<div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;<span class="comment"> * it will buffer all output, and instead return a JSON encoded</span></div>
<div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;<span class="comment"> * string containing all relevant information on the command that</span></div>
<div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;<span class="comment"> * was just executed.</span></div>
<div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;<span class="comment"> * Through this mechanism, it is possible for Drush commands to</span></div>
<div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;<span class="comment"> * invoke each other.</span></div>
<div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;<span class="comment"> * There are many cases where a command might wish to call another</span></div>
<div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;<span class="comment"> * command in its own process, to allow the calling command to</span></div>
<div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;<span class="comment"> * intercept and act on any errors that may occur in the script that</span></div>
<div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;<span class="comment"> * was called.</span></div>
<div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;<span class="comment"> * A simple example is if there exists an &#39;update&#39; command for running</span></div>
<div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;<span class="comment"> * update.php on a specific site. The original command might download</span></div>
<div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;<span class="comment"> * a newer version of a module for installation on a site, and then</span></div>
<div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;<span class="comment"> * run the update script in a separate process, so that in the case</span></div>
<div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;<span class="comment"> * of an error running a hook_update_n function, the module can revert</span></div>
<div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;<span class="comment"> * to a previously made database backup, and the previously installed code.</span></div>
<div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;<span class="comment"> * By calling the script in a separate process, the calling script is insulated</span></div>
<div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;<span class="comment"> * from any error that occurs in the called script, to the level that if a</span></div>
<div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;<span class="comment"> * php code error occurs (ie: misformed file, missing parenthesis, whatever),</span></div>
<div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;<span class="comment"> * it is still able to reliably handle any problems that occur.</span></div>
<div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;<span class="comment"> * This is nearly a RESTful API. @see http://en.wikipedia.org/wiki/REST</span></div>
<div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;<span class="comment"> * Instead of :</span></div>
<div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;<span class="comment"> *   http://[server]/[apipath]/[command]?[arg1]=[value1],[arg2]=[value2]</span></div>
<div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;<span class="comment"> * It will call :</span></div>
<div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;<span class="comment"> *  [apipath] [command] --[arg1]=[value1] --[arg2]=[value2] --backend</span></div>
<div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;<span class="comment"> * [apipath] in this case will be the path to the drush.php file.</span></div>
<div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;<span class="comment"> * [command] is the command you would call, for instance &#39;status&#39;.</span></div>
<div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;<span class="comment"> * GET parameters will be passed as options to the script.</span></div>
<div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;<span class="comment"> * POST parameters will be passed to the script as a JSON encoded associative array over STDIN.</span></div>
<div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;<span class="comment"> * Because of this standard interface, Drush commands can also be executed on</span></div>
<div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;<span class="comment"> * external servers through SSH pipes, simply by prepending, &#39;ssh username@server.com&#39;</span></div>
<div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;<span class="comment"> * in front of the command.</span></div>
<div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;<span class="comment"> * If the key-based ssh authentication has been set up between the servers,</span></div>
<div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;<span class="comment"> * this will just work.  By default, drush is configured to disallow password</span></div>
<div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;<span class="comment"> * authentication; if you would like to enter a password for every connection,</span></div>
<div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;<span class="comment"> * then in your drushrc.php file, set $options[&#39;ssh-options&#39;] so that it does NOT</span></div>
<div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;<span class="comment"> * include &#39;-o PasswordAuthentication=no&#39;.  See examples/example.drushrc.php.</span></div>
<div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;<span class="comment"> * The results from backend API calls can be fetched via a call to</span></div>
<div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;<span class="comment"> * drush_backend_get_result().</span></div>
<div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;<span class="comment"> * Identify the JSON encoded output from a command.</span></div>
<div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;<span class="comment"> * Note that Drush now outputs a null (&quot;\0&quot;) before the DRUSH_BACKEND_OUTPUT_DELIMITER,</span></div>
<div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;<span class="comment"> * but this null occurs where this constant is output rather than being</span></div>
<div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;<span class="comment"> * included in the define.  This is done to maintain compatibility with</span></div>
<div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;<span class="comment"> * older versions of Drush, so that Drush-6.x can correctly parse backend messages</span></div>
<div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;<span class="comment"> * from calls made to Drush-5.x and earlier.  The null is removed via trim().</span></div>
<div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00069"></a><span class="lineno"><a class="code" href="backend_8inc.html#a99476b8812c9923e8706b076c50863c0">   69</a></span>&#160;define(<span class="stringliteral">&#39;DRUSH_BACKEND_OUTPUT_START&#39;</span>, <span class="stringliteral">&#39;DRUSH_BACKEND_OUTPUT_START&gt;&gt;&gt;&#39;</span>);</div>
<div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;define(<span class="stringliteral">&#39;DRUSH_BACKEND_OUTPUT_DELIMITER&#39;</span>, <a class="code" href="backend_8inc.html#a99476b8812c9923e8706b076c50863c0">DRUSH_BACKEND_OUTPUT_START</a> . <span class="stringliteral">&#39;%s&lt;&lt;&lt;DRUSH_BACKEND_OUTPUT_END&#39;</span>);</div>
<div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;<span class="comment"> * Identify JSON encoded &quot;packets&quot; embedded inside of backend</span></div>
<div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;<span class="comment"> * output; used to send out-of-band information durring a backend</span></div>
<div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;<span class="comment"> * invoke call (currently only used for log and error messages).</span></div>
<div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00077"></a><span class="lineno"><a class="code" href="backend_8inc.html#a9701b812e125509d248b2e4566a712e0">   77</a></span>&#160;define(<span class="stringliteral">&#39;DRUSH_BACKEND_PACKET_START&#39;</span>, <span class="stringliteral">&quot;DRUSH_BACKEND:&quot;</span>);</div>
<div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;define(<span class="stringliteral">&#39;DRUSH_BACKEND_PACKET_PATTERN&#39;</span>, <span class="stringliteral">&quot;\0&quot;</span> . <a class="code" href="backend_8inc.html#a9701b812e125509d248b2e4566a712e0">DRUSH_BACKEND_PACKET_START</a> . <span class="stringliteral">&quot;%s\n\0&quot;</span>);</div>
<div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;<span class="comment"> * The backend result is the original PHP data structure (usually an array)</span></div>
<div class="line"><a name="l00082"></a><span class="lineno">   82</span>&#160;<span class="comment"> * used to generate the output for the current command.</span></div>
<div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00084"></a><span class="lineno"><a class="code" href="backend_8inc.html#ad8040331b08464a2a48b7ac8a00ed13c">   84</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#ad8040331b08464a2a48b7ac8a00ed13c">drush_backend_set_result</a>($value) {</div>
<div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;  <span class="keywordflow">if</span> (<a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_BACKEND&#39;</span>)) {</div>
<div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;    <a class="code" href="context_8inc.html#af983acfe90e7d7bbdbd67c57f93708ba">drush_set_context</a>(<span class="stringliteral">&#39;BACKEND_RESULT&#39;</span>, $value);</div>
<div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;  }</div>
<div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;}</div>
<div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;<span class="comment"> * Retrieves the results from the last call to backend_invoke.</span></div>
<div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;<span class="comment"> * @returns array</span></div>
<div class="line"><a name="l00094"></a><span class="lineno">   94</span>&#160;<span class="comment"> *   An associative array containing information from the last</span></div>
<div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;<span class="comment"> *   backend invoke.  The keys in the array include:</span></div>
<div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;<span class="comment"> *     - output: This item contains the textual output of</span></div>
<div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;<span class="comment"> *       the command that was executed.</span></div>
<div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;<span class="comment"> *     - object: Contains the PHP object representation of the</span></div>
<div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;<span class="comment"> *       result of the command.</span></div>
<div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;<span class="comment"> *     - self: The self object contains the alias record that was</span></div>
<div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;<span class="comment"> *       used to select the bootstrapped site when the command was</span></div>
<div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;<span class="comment"> *       executed.</span></div>
<div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;<span class="comment"> *     - error_status: This item returns the error status for the</span></div>
<div class="line"><a name="l00105"></a><span class="lineno">  105</span>&#160;<span class="comment"> *       command.  Zero means &quot;no error&quot;.</span></div>
<div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;<span class="comment"> *     - log: The log item contains an array of log messages from</span></div>
<div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;<span class="comment"> *       the command execution ordered chronologically.  Each log</span></div>
<div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;<span class="comment"> *       entery is an associative array.  A log entry contains</span></div>
<div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;<span class="comment"> *       following items:</span></div>
<div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;<span class="comment"> *         o  type: The type of log entry, such as &#39;notice&#39; or &#39;warning&#39;</span></div>
<div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;<span class="comment"> *         o  message: The log message</span></div>
<div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;<span class="comment"> *         o  timestamp: The time that the message was logged</span></div>
<div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;<span class="comment"> *         o  memory: Available memory at the time that the message was logged</span></div>
<div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;<span class="comment"> *         o  error: The error code associated with the log message</span></div>
<div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;<span class="comment"> *            (only for log entries whose type is &#39;error&#39;)</span></div>
<div class="line"><a name="l00116"></a><span class="lineno">  116</span>&#160;<span class="comment"> *     - error_log: The error_log item contains another representation</span></div>
<div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;<span class="comment"> *       of entries from the log.  Only log entries whose &#39;error&#39; item</span></div>
<div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;<span class="comment"> *       is set will appear in the error log.  The error log is an</span></div>
<div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;<span class="comment"> *       associative array whose key is the error code, and whose value</span></div>
<div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;<span class="comment"> *       is an array of messages--one message for every log entry with</span></div>
<div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;<span class="comment"> *       the same error code.</span></div>
<div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;<span class="comment"> *     - context: The context item contains a representation of all option</span></div>
<div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;<span class="comment"> *       values that affected the operation of the command, including both</span></div>
<div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;<span class="comment"> *       the command line options, options set in a drushrc.php configuration</span></div>
<div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;<span class="comment"> *       files, and options set from the alias record used with the command.</span></div>
<div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00127"></a><span class="lineno"><a class="code" href="backend_8inc.html#ac295e52c1fa40b91d9100517ed8e76de">  127</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#ac295e52c1fa40b91d9100517ed8e76de">drush_backend_get_result</a>() {</div>
<div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;  <span class="keywordflow">return</span> <a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;BACKEND_RESULT&#39;</span>);</div>
<div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;}</div>
<div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00131"></a><span class="lineno">  131</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;<span class="comment"> * Print the json-encoded output of this command, including the</span></div>
<div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;<span class="comment"> * encoded log records, context information, etc.</span></div>
<div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00135"></a><span class="lineno"><a class="code" href="backend_8inc.html#a3d855df98e2c6cb0314a947058f92b99">  135</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a3d855df98e2c6cb0314a947058f92b99">drush_backend_output</a>() {</div>
<div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;  $data = array();</div>
<div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;</div>
<div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;  <span class="keywordflow">if</span> (<a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_PIPE&#39;</span>)) {</div>
<div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;    $pipe = <a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_PIPE_BUFFER&#39;</span>);</div>
<div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;    $data[<span class="stringliteral">&#39;output&#39;</span>] = $pipe; <span class="comment">// print_r($pipe, TRUE);</span></div>
<div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;  }</div>
<div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;  <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;    <span class="comment">// Strip out backend commands.</span></div>
<div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;    $packet_regex = strtr(sprintf(DRUSH_BACKEND_PACKET_PATTERN, <span class="stringliteral">&quot;([^\0]*)&quot;</span>), array(<span class="stringliteral">&quot;\0&quot;</span> =&gt; <span class="stringliteral">&quot;\\0&quot;</span>));</div>
<div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;    $packet_regex = str_replace(<span class="stringliteral">&quot;\n&quot;</span>, <span class="stringliteral">&quot;&quot;</span>, $packet_regex);</div>
<div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;    $data[<span class="stringliteral">&#39;output&#39;</span>] = preg_replace(<span class="stringliteral">&quot;/$packet_regex/s&quot;</span>, <span class="stringliteral">&#39;&#39;</span>, <a class="code" href="backend_8inc.html#a1602048b761aedfc875af8f6d55b5e51">drush_backend_output_collect</a>(NULL));</div>
<div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;  }</div>
<div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;</div>
<div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;  <span class="keywordflow">if</span> (<a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_QUIET&#39;</span>, FALSE)) {</div>
<div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;    ob_end_clean();</div>
<div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;  }</div>
<div class="line"><a name="l00152"></a><span class="lineno">  152</span>&#160;</div>
<div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;  $result_object = <a class="code" href="backend_8inc.html#ac295e52c1fa40b91d9100517ed8e76de">drush_backend_get_result</a>();</div>
<div class="line"><a name="l00154"></a><span class="lineno">  154</span>&#160;  <span class="keywordflow">if</span> (isset($result_object)) {</div>
<div class="line"><a name="l00155"></a><span class="lineno">  155</span>&#160;    $data[<span class="stringliteral">&#39;object&#39;</span>] = $result_object;</div>
<div class="line"><a name="l00156"></a><span class="lineno">  156</span>&#160;  }</div>
<div class="line"><a name="l00157"></a><span class="lineno">  157</span>&#160;</div>
<div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;  $error = <a class="code" href="group__errorhandling.html#ga33fe8456b3dc49a0e28e7f63692a0d44">drush_get_error</a>();</div>
<div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;  $data[<span class="stringliteral">&#39;error_status&#39;</span>] = ($error) ? $error : <a class="code" href="drush_8inc.html#af1fd588cf6b6a3d51e8055408ee86635">DRUSH_SUCCESS</a>;</div>
<div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;</div>
<div class="line"><a name="l00161"></a><span class="lineno">  161</span>&#160;  $data[<span class="stringliteral">&#39;log&#39;</span>] = <a class="code" href="group__logging.html#ga5258324e4f8b274b092f8ce17610619f">drush_get_log</a>(); <span class="comment">// Append logging information</span></div>
<div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;  <span class="comment">// The error log is a more specific version of the log, and may be used by calling</span></div>
<div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;  <span class="comment">// scripts to check for specific errors that have occurred.</span></div>
<div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;  $data[<span class="stringliteral">&#39;error_log&#39;</span>] = <a class="code" href="group__errorhandling.html#gaf64f258413d1fed041c634581e39bff0">drush_get_error_log</a>();</div>
<div class="line"><a name="l00165"></a><span class="lineno">  165</span>&#160;  <span class="comment">// If there is a @self record, then include it in the result</span></div>
<div class="line"><a name="l00166"></a><span class="lineno">  166</span>&#160;  $self_record = <a class="code" href="sitealias_8inc.html#ac2f57b80441374522c4e4cdc3b7e0c2b">drush_sitealias_get_record</a>(<span class="stringliteral">&#39;@self&#39;</span>);</div>
<div class="line"><a name="l00167"></a><span class="lineno">  167</span>&#160;  <span class="keywordflow">if</span> (!empty($self_record)) {</div>
<div class="line"><a name="l00168"></a><span class="lineno">  168</span>&#160;    $site_context = <a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;site&#39;</span>, array());</div>
<div class="line"><a name="l00169"></a><span class="lineno">  169</span>&#160;    unset($site_context[<span class="stringliteral">&#39;config-file&#39;</span>]);</div>
<div class="line"><a name="l00170"></a><span class="lineno">  170</span>&#160;    unset($site_context[<span class="stringliteral">&#39;context-path&#39;</span>]);</div>
<div class="line"><a name="l00171"></a><span class="lineno">  171</span>&#160;    unset($self_record[<span class="stringliteral">&#39;loaded-config&#39;</span>]);</div>
<div class="line"><a name="l00172"></a><span class="lineno">  172</span>&#160;    unset($self_record[<span class="stringliteral">&#39;#name&#39;</span>]);</div>
<div class="line"><a name="l00173"></a><span class="lineno">  173</span>&#160;    $data[<span class="stringliteral">&#39;self&#39;</span>] = array_merge($site_context, $self_record);</div>
<div class="line"><a name="l00174"></a><span class="lineno">  174</span>&#160;  }</div>
<div class="line"><a name="l00175"></a><span class="lineno">  175</span>&#160;</div>
<div class="line"><a name="l00176"></a><span class="lineno">  176</span>&#160;  <span class="comment">// Return the options that were set at the end of the process.</span></div>
<div class="line"><a name="l00177"></a><span class="lineno">  177</span>&#160;  $data[<span class="stringliteral">&#39;context&#39;</span>]  = <a class="code" href="context_8inc.html#a72dfb89d6a4ba0bb143e3256f997d2b8">drush_get_merged_options</a>();</div>
<div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;  printf(<span class="stringliteral">&quot;\0&quot;</span> . DRUSH_BACKEND_OUTPUT_DELIMITER, json_encode($data));</div>
<div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;}</div>
<div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00181"></a><span class="lineno">  181</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00182"></a><span class="lineno">  182</span>&#160;<span class="comment"> * Callback to collect backend command output.</span></div>
<div class="line"><a name="l00183"></a><span class="lineno">  183</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00184"></a><span class="lineno"><a class="code" href="backend_8inc.html#a1602048b761aedfc875af8f6d55b5e51">  184</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a1602048b761aedfc875af8f6d55b5e51">drush_backend_output_collect</a>($string) {</div>
<div class="line"><a name="l00185"></a><span class="lineno">  185</span>&#160;  <span class="keyword">static</span> $output = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;  <span class="keywordflow">if</span> (!isset($string)) {</div>
<div class="line"><a name="l00187"></a><span class="lineno">  187</span>&#160;    <span class="keywordflow">return</span> $output;</div>
<div class="line"><a name="l00188"></a><span class="lineno">  188</span>&#160;  }</div>
<div class="line"><a name="l00189"></a><span class="lineno">  189</span>&#160;</div>
<div class="line"><a name="l00190"></a><span class="lineno">  190</span>&#160;  $output .= $string;</div>
<div class="line"><a name="l00191"></a><span class="lineno">  191</span>&#160;  <span class="keywordflow">return</span> $string;</div>
<div class="line"><a name="l00192"></a><span class="lineno">  192</span>&#160;}</div>
<div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00194"></a><span class="lineno">  194</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;<span class="comment"> * Output buffer functions that discards all output but backend packets.</span></div>
<div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00197"></a><span class="lineno"><a class="code" href="backend_8inc.html#a24d07aa37634fa6ece1d8b36c6fdeb46">  197</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a24d07aa37634fa6ece1d8b36c6fdeb46">drush_backend_output_discard</a>($string) {</div>
<div class="line"><a name="l00198"></a><span class="lineno">  198</span>&#160;  $packet_regex = strtr(sprintf(DRUSH_BACKEND_PACKET_PATTERN, <span class="stringliteral">&quot;([^\0]*)&quot;</span>), array(<span class="stringliteral">&quot;\0&quot;</span> =&gt; <span class="stringliteral">&quot;\\0&quot;</span>));</div>
<div class="line"><a name="l00199"></a><span class="lineno">  199</span>&#160;  $packet_regex = str_replace(<span class="stringliteral">&quot;\n&quot;</span>, <span class="stringliteral">&quot;&quot;</span>, $packet_regex);</div>
<div class="line"><a name="l00200"></a><span class="lineno">  200</span>&#160;  <span class="keywordflow">if</span> (preg_match_all(<span class="stringliteral">&quot;/$packet_regex/s&quot;</span>, $string, $matches)) {</div>
<div class="line"><a name="l00201"></a><span class="lineno">  201</span>&#160;    <span class="keywordflow">return</span> implode(<span class="stringliteral">&#39;&#39;</span>, $matches[0]);</div>
<div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;  }</div>
<div class="line"><a name="l00203"></a><span class="lineno">  203</span>&#160;}</div>
<div class="line"><a name="l00204"></a><span class="lineno">  204</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00205"></a><span class="lineno">  205</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00206"></a><span class="lineno">  206</span>&#160;<span class="comment"> * Output a backend packet if we&#39;re running as backend.</span></div>
<div class="line"><a name="l00207"></a><span class="lineno">  207</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;<span class="comment"> * @param packet</span></div>
<div class="line"><a name="l00209"></a><span class="lineno">  209</span>&#160;<span class="comment"> *   The packet to send.</span></div>
<div class="line"><a name="l00210"></a><span class="lineno">  210</span>&#160;<span class="comment"> * @param data</span></div>
<div class="line"><a name="l00211"></a><span class="lineno">  211</span>&#160;<span class="comment"> *   Data for the command.</span></div>
<div class="line"><a name="l00212"></a><span class="lineno">  212</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00213"></a><span class="lineno">  213</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l00214"></a><span class="lineno">  214</span>&#160;<span class="comment"> *  A boolean indicating whether the command was output.</span></div>
<div class="line"><a name="l00215"></a><span class="lineno">  215</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00216"></a><span class="lineno"><a class="code" href="backend_8inc.html#a38490210d77373f3d8492caf4e9a3190">  216</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a38490210d77373f3d8492caf4e9a3190">drush_backend_packet</a>($packet, $data) {</div>
<div class="line"><a name="l00217"></a><span class="lineno">  217</span>&#160;  <span class="keywordflow">if</span> (<a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_BACKEND&#39;</span>)) {</div>
<div class="line"><a name="l00218"></a><span class="lineno">  218</span>&#160;    $data[<span class="stringliteral">&#39;packet&#39;</span>] = $packet;</div>
<div class="line"><a name="l00219"></a><span class="lineno">  219</span>&#160;    $data = json_encode($data);</div>
<div class="line"><a name="l00220"></a><span class="lineno">  220</span>&#160;    <span class="comment">// We use &#39;fwrite&#39; instead of &#39;drush_print&#39; here because</span></div>
<div class="line"><a name="l00221"></a><span class="lineno">  221</span>&#160;    <span class="comment">// this backend packet is out-of-band data.</span></div>
<div class="line"><a name="l00222"></a><span class="lineno">  222</span>&#160;    fwrite(STDERR, sprintf(DRUSH_BACKEND_PACKET_PATTERN, $data));</div>
<div class="line"><a name="l00223"></a><span class="lineno">  223</span>&#160;    <span class="keywordflow">return</span> TRUE;</div>
<div class="line"><a name="l00224"></a><span class="lineno">  224</span>&#160;  }</div>
<div class="line"><a name="l00225"></a><span class="lineno">  225</span>&#160;</div>
<div class="line"><a name="l00226"></a><span class="lineno">  226</span>&#160;  <span class="keywordflow">return</span> FALSE;</div>
<div class="line"><a name="l00227"></a><span class="lineno">  227</span>&#160;}</div>
<div class="line"><a name="l00228"></a><span class="lineno">  228</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00229"></a><span class="lineno">  229</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00230"></a><span class="lineno">  230</span>&#160;<span class="comment"> * Parse output returned from a Drush command.</span></div>
<div class="line"><a name="l00231"></a><span class="lineno">  231</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00232"></a><span class="lineno">  232</span>&#160;<span class="comment"> * @param string</span></div>
<div class="line"><a name="l00233"></a><span class="lineno">  233</span>&#160;<span class="comment"> *    The output of a drush command</span></div>
<div class="line"><a name="l00234"></a><span class="lineno">  234</span>&#160;<span class="comment"> * @param integrate</span></div>
<div class="line"><a name="l00235"></a><span class="lineno">  235</span>&#160;<span class="comment"> *    Integrate the errors and log messages from the command into the current process.</span></div>
<div class="line"><a name="l00236"></a><span class="lineno">  236</span>&#160;<span class="comment"> * @param outputted</span></div>
<div class="line"><a name="l00237"></a><span class="lineno">  237</span>&#160;<span class="comment"> *    Whether output has already been handled.</span></div>
<div class="line"><a name="l00238"></a><span class="lineno">  238</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00239"></a><span class="lineno">  239</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l00240"></a><span class="lineno">  240</span>&#160;<span class="comment"> *   An associative array containing the data from the external command, or the string parameter if it</span></div>
<div class="line"><a name="l00241"></a><span class="lineno">  241</span>&#160;<span class="comment"> *   could not be parsed successfully.</span></div>
<div class="line"><a name="l00242"></a><span class="lineno">  242</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00243"></a><span class="lineno"><a class="code" href="backend_8inc.html#a31be2d52e209d3e6ac359e971cf1fd7b">  243</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a31be2d52e209d3e6ac359e971cf1fd7b">drush_backend_parse_output</a>($string, $backend_options = array(), $outputted = FALSE) {</div>
<div class="line"><a name="l00244"></a><span class="lineno">  244</span>&#160;  $regex = sprintf(DRUSH_BACKEND_OUTPUT_DELIMITER, <span class="stringliteral">&#39;(.*)&#39;</span>);</div>
<div class="line"><a name="l00245"></a><span class="lineno">  245</span>&#160;</div>
<div class="line"><a name="l00246"></a><span class="lineno">  246</span>&#160;  preg_match(<span class="stringliteral">&quot;/$regex/s&quot;</span>, $string, $match);</div>
<div class="line"><a name="l00247"></a><span class="lineno">  247</span>&#160;</div>
<div class="line"><a name="l00248"></a><span class="lineno">  248</span>&#160;  <span class="keywordflow">if</span> (!empty($match) &amp;&amp; $match[1]) {</div>
<div class="line"><a name="l00249"></a><span class="lineno">  249</span>&#160;    <span class="comment">// we have our JSON encoded string</span></div>
<div class="line"><a name="l00250"></a><span class="lineno">  250</span>&#160;    $output = $match[1];</div>
<div class="line"><a name="l00251"></a><span class="lineno">  251</span>&#160;    <span class="comment">// remove the match we just made and any non printing characters</span></div>
<div class="line"><a name="l00252"></a><span class="lineno">  252</span>&#160;    $string = trim(str_replace(sprintf(DRUSH_BACKEND_OUTPUT_DELIMITER, $match[1]), <span class="stringliteral">&#39;&#39;</span>, $string));</div>
<div class="line"><a name="l00253"></a><span class="lineno">  253</span>&#160;  }</div>
<div class="line"><a name="l00254"></a><span class="lineno">  254</span>&#160;</div>
<div class="line"><a name="l00255"></a><span class="lineno">  255</span>&#160;  <span class="keywordflow">if</span> (!empty($output)) {</div>
<div class="line"><a name="l00256"></a><span class="lineno">  256</span>&#160;    $data = json_decode($output, TRUE);</div>
<div class="line"><a name="l00257"></a><span class="lineno">  257</span>&#160;    <span class="keywordflow">if</span> (is_array($data)) {</div>
<div class="line"><a name="l00258"></a><span class="lineno">  258</span>&#160;      <a class="code" href="backend_8inc.html#ae4fc02494df344445fa5f139fa843ac0">_drush_backend_integrate</a>($data, $backend_options, $outputted);</div>
<div class="line"><a name="l00259"></a><span class="lineno">  259</span>&#160;      <span class="keywordflow">return</span> $data;</div>
<div class="line"><a name="l00260"></a><span class="lineno">  260</span>&#160;    }</div>
<div class="line"><a name="l00261"></a><span class="lineno">  261</span>&#160;  }</div>
<div class="line"><a name="l00262"></a><span class="lineno">  262</span>&#160;  <span class="keywordflow">return</span> $string;</div>
<div class="line"><a name="l00263"></a><span class="lineno">  263</span>&#160;}</div>
<div class="line"><a name="l00264"></a><span class="lineno">  264</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00265"></a><span class="lineno">  265</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00266"></a><span class="lineno">  266</span>&#160;<span class="comment"> * Integrate log messages and error statuses into the current</span></div>
<div class="line"><a name="l00267"></a><span class="lineno">  267</span>&#160;<span class="comment"> * process.</span></div>
<div class="line"><a name="l00268"></a><span class="lineno">  268</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00269"></a><span class="lineno">  269</span>&#160;<span class="comment"> * Output produced by the called script will be printed if we didn&#39;t print it</span></div>
<div class="line"><a name="l00270"></a><span class="lineno">  270</span>&#160;<span class="comment"> * on the fly, errors will be set, and log messages will be logged locally, if</span></div>
<div class="line"><a name="l00271"></a><span class="lineno">  271</span>&#160;<span class="comment"> * not already logged.</span></div>
<div class="line"><a name="l00272"></a><span class="lineno">  272</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00273"></a><span class="lineno">  273</span>&#160;<span class="comment"> * @param data</span></div>
<div class="line"><a name="l00274"></a><span class="lineno">  274</span>&#160;<span class="comment"> *    The associative array returned from the external command.</span></div>
<div class="line"><a name="l00275"></a><span class="lineno">  275</span>&#160;<span class="comment"> * @param outputted</span></div>
<div class="line"><a name="l00276"></a><span class="lineno">  276</span>&#160;<span class="comment"> *    Whether output has already been handled.</span></div>
<div class="line"><a name="l00277"></a><span class="lineno">  277</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00278"></a><span class="lineno"><a class="code" href="backend_8inc.html#ae4fc02494df344445fa5f139fa843ac0">  278</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#ae4fc02494df344445fa5f139fa843ac0">_drush_backend_integrate</a>($data, $backend_options, $outputted) {</div>
<div class="line"><a name="l00279"></a><span class="lineno">  279</span>&#160;  <span class="comment">// In &#39;integrate&#39; mode, logs and errors have already been handled</span></div>
<div class="line"><a name="l00280"></a><span class="lineno">  280</span>&#160;  <span class="comment">// by drush_backend_packet (sender) drush_backend_parse_packets (receiver - us)</span></div>
<div class="line"><a name="l00281"></a><span class="lineno">  281</span>&#160;  <span class="comment">// during incremental output.  We therefore do not need to call drush_set_error</span></div>
<div class="line"><a name="l00282"></a><span class="lineno">  282</span>&#160;  <span class="comment">// or drush_log here.  The exception is if the sender is an older version of</span></div>
<div class="line"><a name="l00283"></a><span class="lineno">  283</span>&#160;  <span class="comment">// Drush (version 4.x) that does not send backend packets, then we will</span></div>
<div class="line"><a name="l00284"></a><span class="lineno">  284</span>&#160;  <span class="comment">// not have processed the log entries yet, and must print them here.</span></div>
<div class="line"><a name="l00285"></a><span class="lineno">  285</span>&#160;  $received_packets = <a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_RECEIVED_BACKEND_PACKETS&#39;</span>, FALSE);</div>
<div class="line"><a name="l00286"></a><span class="lineno">  286</span>&#160;  <span class="keywordflow">if</span> (is_array($data[<span class="stringliteral">&#39;log&#39;</span>]) &amp;&amp; $backend_options[<span class="stringliteral">&#39;log&#39;</span>] &amp;&amp; (!$received_packets)) {</div>
<div class="line"><a name="l00287"></a><span class="lineno">  287</span>&#160;    <span class="keywordflow">foreach</span>($data[<span class="stringliteral">&#39;log&#39;</span>] as $log) {</div>
<div class="line"><a name="l00288"></a><span class="lineno">  288</span>&#160;      $message = is_array($log[<span class="stringliteral">&#39;message&#39;</span>]) ? implode(<span class="stringliteral">&quot;\n&quot;</span>, $log[<span class="stringliteral">&#39;message&#39;</span>]) : $log[<span class="stringliteral">&#39;message&#39;</span>];</div>
<div class="line"><a name="l00289"></a><span class="lineno">  289</span>&#160;      <span class="keywordflow">if</span> (isset($backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>])) {</div>
<div class="line"><a name="l00290"></a><span class="lineno">  290</span>&#160;        $message = $backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>] . $message;</div>
<div class="line"><a name="l00291"></a><span class="lineno">  291</span>&#160;      }</div>
<div class="line"><a name="l00292"></a><span class="lineno">  292</span>&#160;      <span class="keywordflow">if</span> (isset($log[<span class="stringliteral">&#39;error&#39;</span>]) &amp;&amp; $backend_options[<span class="stringliteral">&#39;integrate&#39;</span>]) {</div>
<div class="line"><a name="l00293"></a><span class="lineno">  293</span>&#160;        <a class="code" href="group__errorhandling.html#ga23fe9e1e8c1e5ade39256106044b6da4">drush_set_error</a>($log[<span class="stringliteral">&#39;error&#39;</span>], $message);</div>
<div class="line"><a name="l00294"></a><span class="lineno">  294</span>&#160;      }</div>
<div class="line"><a name="l00295"></a><span class="lineno">  295</span>&#160;      elseif ($backend_options[<span class="stringliteral">&#39;integrate&#39;</span>]) {</div>
<div class="line"><a name="l00296"></a><span class="lineno">  296</span>&#160;        <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>($message, $log[<span class="stringliteral">&#39;type&#39;</span>]);</div>
<div class="line"><a name="l00297"></a><span class="lineno">  297</span>&#160;      }</div>
<div class="line"><a name="l00298"></a><span class="lineno">  298</span>&#160;    }</div>
<div class="line"><a name="l00299"></a><span class="lineno">  299</span>&#160;  }</div>
<div class="line"><a name="l00300"></a><span class="lineno">  300</span>&#160;  <span class="comment">// Output will either be printed, or buffered to the drush_backend_output command.</span></div>
<div class="line"><a name="l00301"></a><span class="lineno">  301</span>&#160;  <span class="comment">// If the output has already been printed, then we do not need to show it again on a failure.</span></div>
<div class="line"><a name="l00302"></a><span class="lineno">  302</span>&#160;  <span class="keywordflow">if</span> (!$outputted) {</div>
<div class="line"><a name="l00303"></a><span class="lineno">  303</span>&#160;    <span class="keywordflow">if</span> (<a class="code" href="group__errorhandling.html#gafaa8004ee101cc91df57fae59e5d8956">drush_cmp_error</a>(<span class="stringliteral">&#39;DRUSH_APPLICATION_ERROR&#39;</span>) &amp;&amp; !empty($data[<span class="stringliteral">&#39;output&#39;</span>])) {</div>
<div class="line"><a name="l00304"></a><span class="lineno">  304</span>&#160;      <a class="code" href="group__errorhandling.html#ga23fe9e1e8c1e5ade39256106044b6da4">drush_set_error</a>(<span class="stringliteral">&quot;DRUSH_APPLICATION_ERROR&quot;</span>, <a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;Output from failed command :\n !output&quot;</span>, array(<span class="stringliteral">&#39;!output&#39;</span> =&gt; $data[<span class="stringliteral">&#39;output&#39;</span>])));</div>
<div class="line"><a name="l00305"></a><span class="lineno">  305</span>&#160;    }</div>
<div class="line"><a name="l00306"></a><span class="lineno">  306</span>&#160;    elseif ($backend_options[<span class="stringliteral">&#39;output&#39;</span>]) {</div>
<div class="line"><a name="l00307"></a><span class="lineno">  307</span>&#160;      <a class="code" href="backend_8inc.html#aabec94a039db3602741bb3282fec0729">_drush_backend_print_output</a>($data[<span class="stringliteral">&#39;output&#39;</span>], $backend_options);</div>
<div class="line"><a name="l00308"></a><span class="lineno">  308</span>&#160;    }</div>
<div class="line"><a name="l00309"></a><span class="lineno">  309</span>&#160;  }</div>
<div class="line"><a name="l00310"></a><span class="lineno">  310</span>&#160;}</div>
<div class="line"><a name="l00311"></a><span class="lineno">  311</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00312"></a><span class="lineno">  312</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00313"></a><span class="lineno">  313</span>&#160;<span class="comment"> * Supress log message output during backend integrate.</span></div>
<div class="line"><a name="l00314"></a><span class="lineno">  314</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00315"></a><span class="lineno"><a class="code" href="backend_8inc.html#aa530f9f9b70006185389091b5d870995">  315</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#aa530f9f9b70006185389091b5d870995">_drush_backend_integrate_log</a>($entry) {</div>
<div class="line"><a name="l00316"></a><span class="lineno">  316</span>&#160;}</div>
<div class="line"><a name="l00317"></a><span class="lineno">  317</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00318"></a><span class="lineno">  318</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00319"></a><span class="lineno">  319</span>&#160;<span class="comment"> * Call an external command using proc_open.</span></div>
<div class="line"><a name="l00320"></a><span class="lineno">  320</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00321"></a><span class="lineno">  321</span>&#160;<span class="comment"> * @param cmds</span></div>
<div class="line"><a name="l00322"></a><span class="lineno">  322</span>&#160;<span class="comment"> *    An array of records containing the following elements:</span></div>
<div class="line"><a name="l00323"></a><span class="lineno">  323</span>&#160;<span class="comment"> *      &#39;cmd&#39; - The command to execute, already properly escaped</span></div>
<div class="line"><a name="l00324"></a><span class="lineno">  324</span>&#160;<span class="comment"> *      &#39;post-options&#39; - An associative array that will be JSON encoded</span></div>
<div class="line"><a name="l00325"></a><span class="lineno">  325</span>&#160;<span class="comment"> *        and passed to the script being called. Objects are not allowed,</span></div>
<div class="line"><a name="l00326"></a><span class="lineno">  326</span>&#160;<span class="comment"> *        as they do not json_decode gracefully.</span></div>
<div class="line"><a name="l00327"></a><span class="lineno">  327</span>&#160;<span class="comment"> *      &#39;backend-options&#39; - Options that control the operation of the backend invoke</span></div>
<div class="line"><a name="l00328"></a><span class="lineno">  328</span>&#160;<span class="comment"> *     - OR -</span></div>
<div class="line"><a name="l00329"></a><span class="lineno">  329</span>&#160;<span class="comment"> *    An array of commands to execute. These commands already need to be properly escaped.</span></div>
<div class="line"><a name="l00330"></a><span class="lineno">  330</span>&#160;<span class="comment"> *    In this case, post-options will default to empty, and a default output label will</span></div>
<div class="line"><a name="l00331"></a><span class="lineno">  331</span>&#160;<span class="comment"> *    be generated.</span></div>
<div class="line"><a name="l00332"></a><span class="lineno">  332</span>&#160;<span class="comment"> * @param data</span></div>
<div class="line"><a name="l00333"></a><span class="lineno">  333</span>&#160;<span class="comment"> *    An associative array that will be JSON encoded and passed to the script being called.</span></div>
<div class="line"><a name="l00334"></a><span class="lineno">  334</span>&#160;<span class="comment"> *    Objects are not allowed, as they do not json_decode gracefully.</span></div>
<div class="line"><a name="l00335"></a><span class="lineno">  335</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00336"></a><span class="lineno">  336</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l00337"></a><span class="lineno">  337</span>&#160;<span class="comment"> *   False if the command could not be executed, or did not return any output.</span></div>
<div class="line"><a name="l00338"></a><span class="lineno">  338</span>&#160;<span class="comment"> *   If it executed successfully, it returns an associative array containing the command</span></div>
<div class="line"><a name="l00339"></a><span class="lineno">  339</span>&#160;<span class="comment"> *   called, the output of the command, and the error code of the command.</span></div>
<div class="line"><a name="l00340"></a><span class="lineno">  340</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00341"></a><span class="lineno"><a class="code" href="backend_8inc.html#aad736c236f213abc274709f79e41edf7">  341</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#aad736c236f213abc274709f79e41edf7">_drush_backend_proc_open</a>($cmds, $process_limit, $context = NULL) {</div>
<div class="line"><a name="l00342"></a><span class="lineno">  342</span>&#160;  $descriptorspec = array(</div>
<div class="line"><a name="l00343"></a><span class="lineno">  343</span>&#160;    0 =&gt; array(<span class="stringliteral">&quot;pipe&quot;</span>, <span class="stringliteral">&quot;r&quot;</span>),  <span class="comment">// stdin is a pipe that the child will read from</span></div>
<div class="line"><a name="l00344"></a><span class="lineno">  344</span>&#160;    1 =&gt; array(<span class="stringliteral">&quot;pipe&quot;</span>, <span class="stringliteral">&quot;w&quot;</span>),  <span class="comment">// stdout is a pipe that the child will write to</span></div>
<div class="line"><a name="l00345"></a><span class="lineno">  345</span>&#160;  );</div>
<div class="line"><a name="l00346"></a><span class="lineno">  346</span>&#160;</div>
<div class="line"><a name="l00347"></a><span class="lineno">  347</span>&#160;  $open_processes = array();</div>
<div class="line"><a name="l00348"></a><span class="lineno">  348</span>&#160;  $bucket = array();</div>
<div class="line"><a name="l00349"></a><span class="lineno">  349</span>&#160;  $process_limit = max($process_limit, 1);</div>
<div class="line"><a name="l00350"></a><span class="lineno">  350</span>&#160;  $is_windows = <a class="code" href="includes_2environment_8inc.html#a88114295372bcb0ca8dbb5f10b36368e">drush_is_windows</a>();</div>
<div class="line"><a name="l00351"></a><span class="lineno">  351</span>&#160;  <span class="comment">// Loop through processes until they all close, having a nap as needed.</span></div>
<div class="line"><a name="l00352"></a><span class="lineno">  352</span>&#160;  $nap_time = 0;</div>
<div class="line"><a name="l00353"></a><span class="lineno">  353</span>&#160;  <span class="keywordflow">while</span> (count($open_processes) || count($cmds)) {</div>
<div class="line"><a name="l00354"></a><span class="lineno">  354</span>&#160;    $nap_time++;</div>
<div class="line"><a name="l00355"></a><span class="lineno">  355</span>&#160;    <span class="keywordflow">if</span> (count($cmds) &amp;&amp; (count($open_processes) &lt; $process_limit)) {</div>
<div class="line"><a name="l00356"></a><span class="lineno">  356</span>&#160;      <span class="comment">// Pop the site and command (key / value) from the cmds array</span></div>
<div class="line"><a name="l00357"></a><span class="lineno">  357</span>&#160;      end($cmds);</div>
<div class="line"><a name="l00358"></a><span class="lineno">  358</span>&#160;      list($site, $cmd) = each($cmds);</div>
<div class="line"><a name="l00359"></a><span class="lineno">  359</span>&#160;      unset($cmds[$site]);</div>
<div class="line"><a name="l00360"></a><span class="lineno">  360</span>&#160;</div>
<div class="line"><a name="l00361"></a><span class="lineno">  361</span>&#160;      <span class="keywordflow">if</span> (is_array($cmd)) {</div>
<div class="line"><a name="l00362"></a><span class="lineno">  362</span>&#160;        $c = $cmd[<span class="stringliteral">&#39;cmd&#39;</span>];</div>
<div class="line"><a name="l00363"></a><span class="lineno">  363</span>&#160;        $post_options = $cmd[<span class="stringliteral">&#39;post-options&#39;</span>];</div>
<div class="line"><a name="l00364"></a><span class="lineno">  364</span>&#160;        $backend_options = $cmd[<span class="stringliteral">&#39;backend-options&#39;</span>];</div>
<div class="line"><a name="l00365"></a><span class="lineno">  365</span>&#160;      }</div>
<div class="line"><a name="l00366"></a><span class="lineno">  366</span>&#160;      <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00367"></a><span class="lineno">  367</span>&#160;        $c = $cmd;</div>
<div class="line"><a name="l00368"></a><span class="lineno">  368</span>&#160;        $post_options = array();</div>
<div class="line"><a name="l00369"></a><span class="lineno">  369</span>&#160;        $backend_options = array();</div>
<div class="line"><a name="l00370"></a><span class="lineno">  370</span>&#160;      }</div>
<div class="line"><a name="l00371"></a><span class="lineno">  371</span>&#160;      $backend_options += array(</div>
<div class="line"><a name="l00372"></a><span class="lineno">  372</span>&#160;        <span class="stringliteral">&#39;#output-label&#39;</span> =&gt; <span class="stringliteral">&#39;&#39;</span>,</div>
<div class="line"><a name="l00373"></a><span class="lineno">  373</span>&#160;        <span class="stringliteral">&#39;#process-read-size&#39;</span> =&gt; 4096,</div>
<div class="line"><a name="l00374"></a><span class="lineno">  374</span>&#160;      );</div>
<div class="line"><a name="l00375"></a><span class="lineno">  375</span>&#160;      $process = array();</div>
<div class="line"><a name="l00376"></a><span class="lineno">  376</span>&#160;      <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>($backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>] . $c);</div>
<div class="line"><a name="l00377"></a><span class="lineno">  377</span>&#160;      $process[<span class="stringliteral">&#39;process&#39;</span>] = proc_open($c, $descriptorspec, $process[<span class="stringliteral">&#39;pipes&#39;</span>], null, null, array(<span class="stringliteral">&#39;context&#39;</span> =&gt; $context));</div>
<div class="line"><a name="l00378"></a><span class="lineno">  378</span>&#160;      <span class="keywordflow">if</span> (is_resource($process[<span class="stringliteral">&#39;process&#39;</span>])) {</div>
<div class="line"><a name="l00379"></a><span class="lineno">  379</span>&#160;        <span class="keywordflow">if</span> ($post_options) {</div>
<div class="line"><a name="l00380"></a><span class="lineno">  380</span>&#160;          fwrite($process[<span class="stringliteral">&#39;pipes&#39;</span>][0], json_encode($post_options)); <span class="comment">// pass the data array in a JSON encoded string</span></div>
<div class="line"><a name="l00381"></a><span class="lineno">  381</span>&#160;        }</div>
<div class="line"><a name="l00382"></a><span class="lineno">  382</span>&#160;        <span class="comment">// If we do not close stdin here, then we cause a deadlock;</span></div>
<div class="line"><a name="l00383"></a><span class="lineno">  383</span>&#160;        <span class="comment">// see: http://drupal.org/node/766080#comment-4309936</span></div>
<div class="line"><a name="l00384"></a><span class="lineno">  384</span>&#160;        <span class="comment">// If we reimplement interactive commands to also use</span></div>
<div class="line"><a name="l00385"></a><span class="lineno">  385</span>&#160;        <span class="comment">// _drush_proc_open, then clearly we would need to keep</span></div>
<div class="line"><a name="l00386"></a><span class="lineno">  386</span>&#160;        <span class="comment">// this open longer.</span></div>
<div class="line"><a name="l00387"></a><span class="lineno">  387</span>&#160;        fclose($process[<span class="stringliteral">&#39;pipes&#39;</span>][0]);</div>
<div class="line"><a name="l00388"></a><span class="lineno">  388</span>&#160;</div>
<div class="line"><a name="l00389"></a><span class="lineno">  389</span>&#160;        $process[<span class="stringliteral">&#39;info&#39;</span>] = stream_get_meta_data($process[<span class="stringliteral">&#39;pipes&#39;</span>][1]);</div>
<div class="line"><a name="l00390"></a><span class="lineno">  390</span>&#160;        stream_set_blocking($process[<span class="stringliteral">&#39;pipes&#39;</span>][1], FALSE);</div>
<div class="line"><a name="l00391"></a><span class="lineno">  391</span>&#160;        stream_set_timeout($process[<span class="stringliteral">&#39;pipes&#39;</span>][1], 1);</div>
<div class="line"><a name="l00392"></a><span class="lineno">  392</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;cmd&#39;</span>] = $c;</div>
<div class="line"><a name="l00393"></a><span class="lineno">  393</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;output&#39;</span>] = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00394"></a><span class="lineno">  394</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;remainder&#39;</span>] = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00395"></a><span class="lineno">  395</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;backend-options&#39;</span>] = $backend_options;</div>
<div class="line"><a name="l00396"></a><span class="lineno">  396</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;end_of_output&#39;</span>] = FALSE;</div>
<div class="line"><a name="l00397"></a><span class="lineno">  397</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;outputted&#39;</span>] = FALSE;</div>
<div class="line"><a name="l00398"></a><span class="lineno">  398</span>&#160;        $open_processes[$site] = $process;</div>
<div class="line"><a name="l00399"></a><span class="lineno">  399</span>&#160;      }</div>
<div class="line"><a name="l00400"></a><span class="lineno">  400</span>&#160;      <span class="comment">// Reset the $nap_time variable as there might be output to process next</span></div>
<div class="line"><a name="l00401"></a><span class="lineno">  401</span>&#160;      <span class="comment">// time around:</span></div>
<div class="line"><a name="l00402"></a><span class="lineno">  402</span>&#160;      $nap_time = 0;</div>
<div class="line"><a name="l00403"></a><span class="lineno">  403</span>&#160;    }</div>
<div class="line"><a name="l00404"></a><span class="lineno">  404</span>&#160;    <span class="comment">// Set up to call stream_select(). See:</span></div>
<div class="line"><a name="l00405"></a><span class="lineno">  405</span>&#160;    <span class="comment">// http://php.net/manual/en/function.stream-select.php</span></div>
<div class="line"><a name="l00406"></a><span class="lineno">  406</span>&#160;    <span class="comment">// We can&#39;t use stream_select on Windows, because it doesn&#39;t work for</span></div>
<div class="line"><a name="l00407"></a><span class="lineno">  407</span>&#160;    <span class="comment">// streams returned by proc_open.</span></div>
<div class="line"><a name="l00408"></a><span class="lineno">  408</span>&#160;    <span class="keywordflow">if</span> (!$is_windows) {</div>
<div class="line"><a name="l00409"></a><span class="lineno">  409</span>&#160;      $ss_result = 0;</div>
<div class="line"><a name="l00410"></a><span class="lineno">  410</span>&#160;      $read_streams = array();</div>
<div class="line"><a name="l00411"></a><span class="lineno">  411</span>&#160;      $write_streams = array();</div>
<div class="line"><a name="l00412"></a><span class="lineno">  412</span>&#160;      $except_streams = array();</div>
<div class="line"><a name="l00413"></a><span class="lineno">  413</span>&#160;      <span class="keywordflow">foreach</span> ($open_processes as $site =&gt; &amp;$current_process) {</div>
<div class="line"><a name="l00414"></a><span class="lineno">  414</span>&#160;        <span class="keywordflow">if</span> (isset($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1])) {</div>
<div class="line"><a name="l00415"></a><span class="lineno">  415</span>&#160;          $read_streams[] = $current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1];</div>
<div class="line"><a name="l00416"></a><span class="lineno">  416</span>&#160;        }</div>
<div class="line"><a name="l00417"></a><span class="lineno">  417</span>&#160;      }</div>
<div class="line"><a name="l00418"></a><span class="lineno">  418</span>&#160;      <span class="comment">// Wait up to 2s for data to become ready on one of the read streams.</span></div>
<div class="line"><a name="l00419"></a><span class="lineno">  419</span>&#160;      <span class="keywordflow">if</span> (count($read_streams)) {</div>
<div class="line"><a name="l00420"></a><span class="lineno">  420</span>&#160;        $ss_result = stream_select($read_streams, $write_streams, $except_streams, 2);</div>
<div class="line"><a name="l00421"></a><span class="lineno">  421</span>&#160;        <span class="comment">// If stream_select returns a error, then fallback to using $nap_time.</span></div>
<div class="line"><a name="l00422"></a><span class="lineno">  422</span>&#160;        <span class="keywordflow">if</span> ($ss_result !== FALSE) {</div>
<div class="line"><a name="l00423"></a><span class="lineno">  423</span>&#160;          $nap_time = 0;</div>
<div class="line"><a name="l00424"></a><span class="lineno">  424</span>&#160;        }</div>
<div class="line"><a name="l00425"></a><span class="lineno">  425</span>&#160;      }</div>
<div class="line"><a name="l00426"></a><span class="lineno">  426</span>&#160;    }</div>
<div class="line"><a name="l00427"></a><span class="lineno">  427</span>&#160;</div>
<div class="line"><a name="l00428"></a><span class="lineno">  428</span>&#160;    <span class="keywordflow">foreach</span> ($open_processes as $site =&gt; &amp;$current_process) {</div>
<div class="line"><a name="l00429"></a><span class="lineno">  429</span>&#160;      <span class="keywordflow">if</span> (isset($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1])) {</div>
<div class="line"><a name="l00430"></a><span class="lineno">  430</span>&#160;        <span class="comment">// Collect output from stdout</span></div>
<div class="line"><a name="l00431"></a><span class="lineno">  431</span>&#160;        $bucket[$site][1] = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00432"></a><span class="lineno">  432</span>&#160;        $info = stream_get_meta_data($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1]);</div>
<div class="line"><a name="l00433"></a><span class="lineno">  433</span>&#160;</div>
<div class="line"><a name="l00434"></a><span class="lineno">  434</span>&#160;        <span class="keywordflow">if</span> (!feof($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1]) &amp;&amp; !$info[<span class="stringliteral">&#39;timed_out&#39;</span>]) {</div>
<div class="line"><a name="l00435"></a><span class="lineno">  435</span>&#160;          $string = $bucket[$site][<span class="stringliteral">&#39;remainder&#39;</span>] . fread($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1], $backend_options[<span class="stringliteral">&#39;#process-read-size&#39;</span>]);</div>
<div class="line"><a name="l00436"></a><span class="lineno">  436</span>&#160;          $bucket[$site][<span class="stringliteral">&#39;remainder&#39;</span>] = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00437"></a><span class="lineno">  437</span>&#160;          $output_end_pos = strpos($string, <a class="code" href="backend_8inc.html#a99476b8812c9923e8706b076c50863c0">DRUSH_BACKEND_OUTPUT_START</a>);</div>
<div class="line"><a name="l00438"></a><span class="lineno">  438</span>&#160;          <span class="keywordflow">if</span> ($output_end_pos !== FALSE) {</div>
<div class="line"><a name="l00439"></a><span class="lineno">  439</span>&#160;            $trailing_string = substr($string, 0, $output_end_pos);</div>
<div class="line"><a name="l00440"></a><span class="lineno">  440</span>&#160;            $trailing_remainder = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00441"></a><span class="lineno">  441</span>&#160;            <span class="comment">// If there is any data in the trailing string (characters prior</span></div>
<div class="line"><a name="l00442"></a><span class="lineno">  442</span>&#160;            <span class="comment">// to the backend output start), then process any backend packets</span></div>
<div class="line"><a name="l00443"></a><span class="lineno">  443</span>&#160;            <span class="comment">// embedded inside.</span></div>
<div class="line"><a name="l00444"></a><span class="lineno">  444</span>&#160;            <span class="keywordflow">if</span> (strlen($trailing_string) &gt; 0) {</div>
<div class="line"><a name="l00445"></a><span class="lineno">  445</span>&#160;              <a class="code" href="backend_8inc.html#aab9943ccb47db227e2bcfce3c2b9a36a">drush_backend_parse_packets</a>($trailing_string, $trailing_remainder, $bucket[$site][<span class="stringliteral">&#39;backend-options&#39;</span>]);</div>
<div class="line"><a name="l00446"></a><span class="lineno">  446</span>&#160;            }</div>
<div class="line"><a name="l00447"></a><span class="lineno">  447</span>&#160;            <span class="comment">// If there is any data remaining in the trailing string after</span></div>
<div class="line"><a name="l00448"></a><span class="lineno">  448</span>&#160;            <span class="comment">// the backend packets are removed, then print it.</span></div>
<div class="line"><a name="l00449"></a><span class="lineno">  449</span>&#160;            <span class="keywordflow">if</span> (strlen($trailing_string) &gt; 0) {</div>
<div class="line"><a name="l00450"></a><span class="lineno">  450</span>&#160;              <a class="code" href="backend_8inc.html#aabec94a039db3602741bb3282fec0729">_drush_backend_print_output</a>($trailing_string . $trailing_remainder, $bucket[$site][<span class="stringliteral">&#39;backend-options&#39;</span>]);</div>
<div class="line"><a name="l00451"></a><span class="lineno">  451</span>&#160;              $bucket[$site][<span class="stringliteral">&#39;outputted&#39;</span>] = TRUE;</div>
<div class="line"><a name="l00452"></a><span class="lineno">  452</span>&#160;            }</div>
<div class="line"><a name="l00453"></a><span class="lineno">  453</span>&#160;            $bucket[$site][<span class="stringliteral">&#39;end_of_output&#39;</span>] = TRUE;</div>
<div class="line"><a name="l00454"></a><span class="lineno">  454</span>&#160;          }</div>
<div class="line"><a name="l00455"></a><span class="lineno">  455</span>&#160;          <span class="keywordflow">if</span> (!$bucket[$site][<span class="stringliteral">&#39;end_of_output&#39;</span>]) {</div>
<div class="line"><a name="l00456"></a><span class="lineno">  456</span>&#160;            <a class="code" href="backend_8inc.html#aab9943ccb47db227e2bcfce3c2b9a36a">drush_backend_parse_packets</a>($string, $bucket[$site][<span class="stringliteral">&#39;remainder&#39;</span>], $bucket[$site][<span class="stringliteral">&#39;backend-options&#39;</span>]);</div>
<div class="line"><a name="l00457"></a><span class="lineno">  457</span>&#160;            <span class="comment">// Pass output through.</span></div>
<div class="line"><a name="l00458"></a><span class="lineno">  458</span>&#160;            <a class="code" href="backend_8inc.html#aabec94a039db3602741bb3282fec0729">_drush_backend_print_output</a>($string, $bucket[$site][<span class="stringliteral">&#39;backend-options&#39;</span>]);</div>
<div class="line"><a name="l00459"></a><span class="lineno">  459</span>&#160;            <span class="keywordflow">if</span> (strlen($string) &gt; 0) {</div>
<div class="line"><a name="l00460"></a><span class="lineno">  460</span>&#160;              $bucket[$site][<span class="stringliteral">&#39;outputted&#39;</span>] = TRUE;</div>
<div class="line"><a name="l00461"></a><span class="lineno">  461</span>&#160;            }</div>
<div class="line"><a name="l00462"></a><span class="lineno">  462</span>&#160;          }</div>
<div class="line"><a name="l00463"></a><span class="lineno">  463</span>&#160;          $bucket[$site][1] .= $string;</div>
<div class="line"><a name="l00464"></a><span class="lineno">  464</span>&#160;          $bucket[$site][<span class="stringliteral">&#39;output&#39;</span>] .= $string;</div>
<div class="line"><a name="l00465"></a><span class="lineno">  465</span>&#160;          $info = stream_get_meta_data($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1]);</div>
<div class="line"><a name="l00466"></a><span class="lineno">  466</span>&#160;          flush();</div>
<div class="line"><a name="l00467"></a><span class="lineno">  467</span>&#160;</div>
<div class="line"><a name="l00468"></a><span class="lineno">  468</span>&#160;          <span class="comment">// Reset the $nap_time variable as there might be output to process</span></div>
<div class="line"><a name="l00469"></a><span class="lineno">  469</span>&#160;          <span class="comment">// next time around:</span></div>
<div class="line"><a name="l00470"></a><span class="lineno">  470</span>&#160;          <span class="keywordflow">if</span> (strlen($string) &gt; 0) {</div>
<div class="line"><a name="l00471"></a><span class="lineno">  471</span>&#160;            $nap_time = 0;</div>
<div class="line"><a name="l00472"></a><span class="lineno">  472</span>&#160;          }</div>
<div class="line"><a name="l00473"></a><span class="lineno">  473</span>&#160;        }</div>
<div class="line"><a name="l00474"></a><span class="lineno">  474</span>&#160;        <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00475"></a><span class="lineno">  475</span>&#160;          fclose($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1]);</div>
<div class="line"><a name="l00476"></a><span class="lineno">  476</span>&#160;          unset($current_process[<span class="stringliteral">&#39;pipes&#39;</span>][1]);</div>
<div class="line"><a name="l00477"></a><span class="lineno">  477</span>&#160;          <span class="comment">// close the pipe , set a marker</span></div>
<div class="line"><a name="l00478"></a><span class="lineno">  478</span>&#160;</div>
<div class="line"><a name="l00479"></a><span class="lineno">  479</span>&#160;          <span class="comment">// Reset the $nap_time variable as there might be output to process</span></div>
<div class="line"><a name="l00480"></a><span class="lineno">  480</span>&#160;          <span class="comment">// next time around:</span></div>
<div class="line"><a name="l00481"></a><span class="lineno">  481</span>&#160;          $nap_time = 0;</div>
<div class="line"><a name="l00482"></a><span class="lineno">  482</span>&#160;        }</div>
<div class="line"><a name="l00483"></a><span class="lineno">  483</span>&#160;      }</div>
<div class="line"><a name="l00484"></a><span class="lineno">  484</span>&#160;      <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00485"></a><span class="lineno">  485</span>&#160;        <span class="comment">// if both pipes are closed for the process, remove it from active loop and add a new process to open.</span></div>
<div class="line"><a name="l00486"></a><span class="lineno">  486</span>&#160;        $bucket[$site][<span class="stringliteral">&#39;code&#39;</span>] = proc_close($current_process[<span class="stringliteral">&#39;process&#39;</span>]);</div>
<div class="line"><a name="l00487"></a><span class="lineno">  487</span>&#160;        unset($open_processes[$site]);</div>
<div class="line"><a name="l00488"></a><span class="lineno">  488</span>&#160;</div>
<div class="line"><a name="l00489"></a><span class="lineno">  489</span>&#160;        <span class="comment">// Reset the $nap_time variable as there might be output to process next</span></div>
<div class="line"><a name="l00490"></a><span class="lineno">  490</span>&#160;        <span class="comment">// time around:</span></div>
<div class="line"><a name="l00491"></a><span class="lineno">  491</span>&#160;        $nap_time = 0;</div>
<div class="line"><a name="l00492"></a><span class="lineno">  492</span>&#160;      }</div>
<div class="line"><a name="l00493"></a><span class="lineno">  493</span>&#160;    }</div>
<div class="line"><a name="l00494"></a><span class="lineno">  494</span>&#160;</div>
<div class="line"><a name="l00495"></a><span class="lineno">  495</span>&#160;    <span class="comment">// We should sleep for a bit if we need to, up to a maximum of 1/10 of a</span></div>
<div class="line"><a name="l00496"></a><span class="lineno">  496</span>&#160;    <span class="comment">// second.</span></div>
<div class="line"><a name="l00497"></a><span class="lineno">  497</span>&#160;    <span class="keywordflow">if</span> ($nap_time &gt; 0) {</div>
<div class="line"><a name="l00498"></a><span class="lineno">  498</span>&#160;      usleep(max($nap_time * 500, 100000));</div>
<div class="line"><a name="l00499"></a><span class="lineno">  499</span>&#160;    }</div>
<div class="line"><a name="l00500"></a><span class="lineno">  500</span>&#160;  }</div>
<div class="line"><a name="l00501"></a><span class="lineno">  501</span>&#160;  <span class="keywordflow">return</span> $bucket;</div>
<div class="line"><a name="l00502"></a><span class="lineno">  502</span>&#160;  <span class="comment">// TODO: Handle bad proc handles</span></div>
<div class="line"><a name="l00503"></a><span class="lineno">  503</span>&#160;  <span class="comment">//}</span></div>
<div class="line"><a name="l00504"></a><span class="lineno">  504</span>&#160;  <span class="comment">//return FALSE;</span></div>
<div class="line"><a name="l00505"></a><span class="lineno">  505</span>&#160;}</div>
<div class="line"><a name="l00506"></a><span class="lineno">  506</span>&#160;</div>
<div class="line"><a name="l00507"></a><span class="lineno">  507</span>&#160;</div>
<div class="line"><a name="l00508"></a><span class="lineno">  508</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00509"></a><span class="lineno">  509</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00510"></a><span class="lineno">  510</span>&#160;<span class="comment"> * Print the output received from a call to backend invoke,</span></div>
<div class="line"><a name="l00511"></a><span class="lineno">  511</span>&#160;<span class="comment"> * adding the label to the head of each line if necessary.</span></div>
<div class="line"><a name="l00512"></a><span class="lineno">  512</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00513"></a><span class="lineno"><a class="code" href="backend_8inc.html#aabec94a039db3602741bb3282fec0729">  513</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#aabec94a039db3602741bb3282fec0729">_drush_backend_print_output</a>($output_string, $backend_options) {</div>
<div class="line"><a name="l00514"></a><span class="lineno">  514</span>&#160;  <span class="keywordflow">if</span> ($backend_options[<span class="stringliteral">&#39;output&#39;</span>] &amp;&amp; !empty($output_string)) {</div>
<div class="line"><a name="l00515"></a><span class="lineno">  515</span>&#160;    $output_label = array_key_exists(<span class="stringliteral">&#39;#output-label&#39;</span>, $backend_options) ? $backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>] : FALSE;</div>
<div class="line"><a name="l00516"></a><span class="lineno">  516</span>&#160;    <span class="keywordflow">if</span> (!empty($output_label)) {</div>
<div class="line"><a name="l00517"></a><span class="lineno">  517</span>&#160;      <span class="comment">// Remove one, and only one newline from the end of the</span></div>
<div class="line"><a name="l00518"></a><span class="lineno">  518</span>&#160;      <span class="comment">// string. Else we&#39;ll get an extra &#39;empty&#39; line.</span></div>
<div class="line"><a name="l00519"></a><span class="lineno">  519</span>&#160;      <span class="keywordflow">foreach</span> (explode(<span class="stringliteral">&quot;\n&quot;</span>, preg_replace(<span class="stringliteral">&#39;/\\n$/&#39;</span>, <span class="stringliteral">&#39;&#39;</span>, $output_string)) as $line) {</div>
<div class="line"><a name="l00520"></a><span class="lineno">  520</span>&#160;        fwrite(STDOUT, $output_label . rtrim($line) . <span class="stringliteral">&quot;\n&quot;</span>);</div>
<div class="line"><a name="l00521"></a><span class="lineno">  521</span>&#160;      }</div>
<div class="line"><a name="l00522"></a><span class="lineno">  522</span>&#160;    }</div>
<div class="line"><a name="l00523"></a><span class="lineno">  523</span>&#160;    <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00524"></a><span class="lineno">  524</span>&#160;      fwrite(STDOUT, $output_string);</div>
<div class="line"><a name="l00525"></a><span class="lineno">  525</span>&#160;    }</div>
<div class="line"><a name="l00526"></a><span class="lineno">  526</span>&#160;  }</div>
<div class="line"><a name="l00527"></a><span class="lineno">  527</span>&#160;}</div>
<div class="line"><a name="l00528"></a><span class="lineno">  528</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00529"></a><span class="lineno">  529</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00530"></a><span class="lineno">  530</span>&#160;<span class="comment"> * Parse out and remove backend packet from the supplied string and</span></div>
<div class="line"><a name="l00531"></a><span class="lineno">  531</span>&#160;<span class="comment"> * invoke the commands.</span></div>
<div class="line"><a name="l00532"></a><span class="lineno">  532</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00533"></a><span class="lineno"><a class="code" href="backend_8inc.html#aab9943ccb47db227e2bcfce3c2b9a36a">  533</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#aab9943ccb47db227e2bcfce3c2b9a36a">drush_backend_parse_packets</a>(&amp;$string, &amp;$remainder, $backend_options) {</div>
<div class="line"><a name="l00534"></a><span class="lineno">  534</span>&#160;  $remainder = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00535"></a><span class="lineno">  535</span>&#160;  $packet_regex = strtr(sprintf(DRUSH_BACKEND_PACKET_PATTERN, <span class="stringliteral">&quot;([^\0]*)&quot;</span>), array(<span class="stringliteral">&quot;\0&quot;</span> =&gt; <span class="stringliteral">&quot;\\0&quot;</span>));</div>
<div class="line"><a name="l00536"></a><span class="lineno">  536</span>&#160;  $packet_regex = str_replace(<span class="stringliteral">&quot;\n&quot;</span>, <span class="stringliteral">&quot;&quot;</span>, $packet_regex);</div>
<div class="line"><a name="l00537"></a><span class="lineno">  537</span>&#160;  <span class="keywordflow">if</span> (preg_match_all(<span class="stringliteral">&quot;/$packet_regex/s&quot;</span>, $string, $match, PREG_PATTERN_ORDER)) {</div>
<div class="line"><a name="l00538"></a><span class="lineno">  538</span>&#160;    <a class="code" href="context_8inc.html#af983acfe90e7d7bbdbd67c57f93708ba">drush_set_context</a>(<span class="stringliteral">&#39;DRUSH_RECEIVED_BACKEND_PACKETS&#39;</span>, TRUE);</div>
<div class="line"><a name="l00539"></a><span class="lineno">  539</span>&#160;    <span class="keywordflow">foreach</span> ($match[1] as $packet_data) {</div>
<div class="line"><a name="l00540"></a><span class="lineno">  540</span>&#160;      $entry = (array) json_decode($packet_data);</div>
<div class="line"><a name="l00541"></a><span class="lineno">  541</span>&#160;      <span class="keywordflow">if</span> (is_array($entry) &amp;&amp; isset($entry[<span class="stringliteral">&#39;packet&#39;</span>])) {</div>
<div class="line"><a name="l00542"></a><span class="lineno">  542</span>&#160;        $function = <span class="stringliteral">&#39;drush_backend_packet_&#39;</span> . $entry[<span class="stringliteral">&#39;packet&#39;</span>];</div>
<div class="line"><a name="l00543"></a><span class="lineno">  543</span>&#160;        <span class="keywordflow">if</span> (function_exists($function)) {</div>
<div class="line"><a name="l00544"></a><span class="lineno">  544</span>&#160;          $function($entry, $backend_options);</div>
<div class="line"><a name="l00545"></a><span class="lineno">  545</span>&#160;        }</div>
<div class="line"><a name="l00546"></a><span class="lineno">  546</span>&#160;        <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00547"></a><span class="lineno">  547</span>&#160;          <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>(<a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;Unknown backend packet @packet&quot;</span>, array(<span class="stringliteral">&#39;@packet&#39;</span> =&gt; $entry[<span class="stringliteral">&#39;packet&#39;</span>])), <span class="stringliteral">&#39;notice&#39;</span>);</div>
<div class="line"><a name="l00548"></a><span class="lineno">  548</span>&#160;        }</div>
<div class="line"><a name="l00549"></a><span class="lineno">  549</span>&#160;      }</div>
<div class="line"><a name="l00550"></a><span class="lineno">  550</span>&#160;      <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00551"></a><span class="lineno">  551</span>&#160;        <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>(<a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;Malformed backend packet&quot;</span>), <span class="stringliteral">&#39;error&#39;</span>);</div>
<div class="line"><a name="l00552"></a><span class="lineno">  552</span>&#160;        <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>(<a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;Bad packet: @packet&quot;</span>, array(<span class="stringliteral">&#39;@packet&#39;</span> =&gt; print_r($entry, TRUE))), <span class="stringliteral">&#39;debug&#39;</span>);</div>
<div class="line"><a name="l00553"></a><span class="lineno">  553</span>&#160;        <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>(<a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;String is: @str&quot;</span>, array(<span class="stringliteral">&#39;@str&#39;</span> =&gt; $packet_data), <span class="stringliteral">&#39;debug&#39;</span>));</div>
<div class="line"><a name="l00554"></a><span class="lineno">  554</span>&#160;      }</div>
<div class="line"><a name="l00555"></a><span class="lineno">  555</span>&#160;    }</div>
<div class="line"><a name="l00556"></a><span class="lineno">  556</span>&#160;    $string = preg_replace(<span class="stringliteral">&quot;/$packet_regex/s&quot;</span>, <span class="stringliteral">&#39;&#39;</span>, $string);</div>
<div class="line"><a name="l00557"></a><span class="lineno">  557</span>&#160;  }</div>
<div class="line"><a name="l00558"></a><span class="lineno">  558</span>&#160;  <span class="comment">// Check to see if there is potentially a partial packet remaining.</span></div>
<div class="line"><a name="l00559"></a><span class="lineno">  559</span>&#160;  <span class="comment">// We only care about the last null; if there are any nulls prior</span></div>
<div class="line"><a name="l00560"></a><span class="lineno">  560</span>&#160;  <span class="comment">// to the last one, they would have been removed above if they were</span></div>
<div class="line"><a name="l00561"></a><span class="lineno">  561</span>&#160;  <span class="comment">// valid drush packets.</span></div>
<div class="line"><a name="l00562"></a><span class="lineno">  562</span>&#160;  $embedded_null = strrpos($string, <span class="stringliteral">&quot;\0&quot;</span>);</div>
<div class="line"><a name="l00563"></a><span class="lineno">  563</span>&#160;  <span class="keywordflow">if</span> ($embedded_null !== FALSE) {</div>
<div class="line"><a name="l00564"></a><span class="lineno">  564</span>&#160;    <span class="comment">// We will consider everything after $embedded_null to be part of</span></div>
<div class="line"><a name="l00565"></a><span class="lineno">  565</span>&#160;    <span class="comment">// the $remainder string if:</span></div>
<div class="line"><a name="l00566"></a><span class="lineno">  566</span>&#160;    <span class="comment">//   - the embedded null is less than strlen(DRUSH_BACKEND_OUTPUT_START)</span></div>
<div class="line"><a name="l00567"></a><span class="lineno">  567</span>&#160;    <span class="comment">//     from the end of $string (that is, there might be a truncated</span></div>
<div class="line"><a name="l00568"></a><span class="lineno">  568</span>&#160;    <span class="comment">//     backend packet header, or the truncated backend output start</span></div>
<div class="line"><a name="l00569"></a><span class="lineno">  569</span>&#160;    <span class="comment">//     after the null)</span></div>
<div class="line"><a name="l00570"></a><span class="lineno">  570</span>&#160;    <span class="comment">//   OR</span></div>
<div class="line"><a name="l00571"></a><span class="lineno">  571</span>&#160;    <span class="comment">//   - the embedded null is followed by DRUSH_BACKEND_PACKET_START</span></div>
<div class="line"><a name="l00572"></a><span class="lineno">  572</span>&#160;    <span class="comment">//     (that is, the terminating null for that packet has not been</span></div>
<div class="line"><a name="l00573"></a><span class="lineno">  573</span>&#160;    <span class="comment">//     read into our buffer yet)</span></div>
<div class="line"><a name="l00574"></a><span class="lineno">  574</span>&#160;    <span class="keywordflow">if</span> (($embedded_null + strlen(<a class="code" href="backend_8inc.html#a99476b8812c9923e8706b076c50863c0">DRUSH_BACKEND_OUTPUT_START</a>) &gt;= strlen($string)) || (substr($string, $embedded_null + 1, strlen(<a class="code" href="backend_8inc.html#a9701b812e125509d248b2e4566a712e0">DRUSH_BACKEND_PACKET_START</a>)) == <a class="code" href="backend_8inc.html#a9701b812e125509d248b2e4566a712e0">DRUSH_BACKEND_PACKET_START</a>)) {</div>
<div class="line"><a name="l00575"></a><span class="lineno">  575</span>&#160;      $remainder = substr($string, $embedded_null);</div>
<div class="line"><a name="l00576"></a><span class="lineno">  576</span>&#160;      $string = substr($string, 0, $embedded_null);</div>
<div class="line"><a name="l00577"></a><span class="lineno">  577</span>&#160;    }</div>
<div class="line"><a name="l00578"></a><span class="lineno">  578</span>&#160;  }</div>
<div class="line"><a name="l00579"></a><span class="lineno">  579</span>&#160;}</div>
<div class="line"><a name="l00580"></a><span class="lineno">  580</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00581"></a><span class="lineno">  581</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00582"></a><span class="lineno">  582</span>&#160;<span class="comment"> * Backend command for setting errors.</span></div>
<div class="line"><a name="l00583"></a><span class="lineno">  583</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00584"></a><span class="lineno"><a class="code" href="backend_8inc.html#a76b06a559b58fba879ae74ff81a2fcb1">  584</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a76b06a559b58fba879ae74ff81a2fcb1">drush_backend_packet_set_error</a>($data, $backend_options) {</div>
<div class="line"><a name="l00585"></a><span class="lineno">  585</span>&#160;  <span class="keywordflow">if</span> (!$backend_options[<span class="stringliteral">&#39;integrate&#39;</span>]) {</div>
<div class="line"><a name="l00586"></a><span class="lineno">  586</span>&#160;    <span class="keywordflow">return</span>;</div>
<div class="line"><a name="l00587"></a><span class="lineno">  587</span>&#160;  }</div>
<div class="line"><a name="l00588"></a><span class="lineno">  588</span>&#160;  $output_label = <span class="stringliteral">&quot;&quot;</span>;</div>
<div class="line"><a name="l00589"></a><span class="lineno">  589</span>&#160;  <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;#output-label&#39;</span>, $backend_options)) {</div>
<div class="line"><a name="l00590"></a><span class="lineno">  590</span>&#160;    $output_label = $backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>];</div>
<div class="line"><a name="l00591"></a><span class="lineno">  591</span>&#160;  }</div>
<div class="line"><a name="l00592"></a><span class="lineno">  592</span>&#160;  <a class="code" href="group__errorhandling.html#ga23fe9e1e8c1e5ade39256106044b6da4">drush_set_error</a>($data[<span class="stringliteral">&#39;error&#39;</span>], $data[<span class="stringliteral">&#39;message&#39;</span>], $output_label);</div>
<div class="line"><a name="l00593"></a><span class="lineno">  593</span>&#160;}</div>
<div class="line"><a name="l00594"></a><span class="lineno">  594</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00595"></a><span class="lineno">  595</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00596"></a><span class="lineno">  596</span>&#160;<span class="comment"> * Default options for backend_invoke commands.</span></div>
<div class="line"><a name="l00597"></a><span class="lineno">  597</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00598"></a><span class="lineno"><a class="code" href="backend_8inc.html#a895f14d30af875ea1783a3de2355d095">  598</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a895f14d30af875ea1783a3de2355d095">_drush_backend_adjust_options</a>($site_record, $command, $command_options, $backend_options) {</div>
<div class="line"><a name="l00599"></a><span class="lineno">  599</span>&#160;  <span class="comment">// By default, if the caller does not specify a value for &#39;output&#39;, but does</span></div>
<div class="line"><a name="l00600"></a><span class="lineno">  600</span>&#160;  <span class="comment">// specify &#39;integrate&#39; === FALSE, then we will set output to FALSE.  Otherwise we</span></div>
<div class="line"><a name="l00601"></a><span class="lineno">  601</span>&#160;  <span class="comment">// will allow it to default to TRUE.</span></div>
<div class="line"><a name="l00602"></a><span class="lineno">  602</span>&#160;  <span class="keywordflow">if</span> ((array_key_exists(<span class="stringliteral">&#39;integrate&#39;</span>, $backend_options)) &amp;&amp; ($backend_options[<span class="stringliteral">&#39;integrate&#39;</span>] === FALSE) &amp;&amp; (!array_key_exists(<span class="stringliteral">&#39;output&#39;</span>, $backend_options))) {</div>
<div class="line"><a name="l00603"></a><span class="lineno">  603</span>&#160;    $backend_options[<span class="stringliteral">&#39;output&#39;</span>] = FALSE;</div>
<div class="line"><a name="l00604"></a><span class="lineno">  604</span>&#160;  }</div>
<div class="line"><a name="l00605"></a><span class="lineno">  605</span>&#160;  $has_site_specification = array_key_exists(<span class="stringliteral">&#39;root&#39;</span>, $site_record) || array_key_exists(<span class="stringliteral">&#39;uri&#39;</span>, $site_record);</div>
<div class="line"><a name="l00606"></a><span class="lineno">  606</span>&#160;  $result = $backend_options + array(</div>
<div class="line"><a name="l00607"></a><span class="lineno">  607</span>&#160;     <span class="stringliteral">&#39;method&#39;</span> =&gt; <span class="stringliteral">&#39;GET&#39;</span>,</div>
<div class="line"><a name="l00608"></a><span class="lineno">  608</span>&#160;     <span class="stringliteral">&#39;output&#39;</span> =&gt; TRUE,</div>
<div class="line"><a name="l00609"></a><span class="lineno">  609</span>&#160;     <span class="stringliteral">&#39;log&#39;</span> =&gt; TRUE,</div>
<div class="line"><a name="l00610"></a><span class="lineno">  610</span>&#160;     <span class="stringliteral">&#39;integrate&#39;</span> =&gt; TRUE,</div>
<div class="line"><a name="l00611"></a><span class="lineno">  611</span>&#160;     <span class="stringliteral">&#39;backend&#39;</span> =&gt; TRUE,</div>
<div class="line"><a name="l00612"></a><span class="lineno">  612</span>&#160;     <span class="stringliteral">&#39;dispatch-using-alias&#39;</span> =&gt; !$has_site_specification,</div>
<div class="line"><a name="l00613"></a><span class="lineno">  613</span>&#160;  );</div>
<div class="line"><a name="l00614"></a><span class="lineno">  614</span>&#160;  <span class="comment">// Convert &#39;#integrate&#39; et. al. into backend options</span></div>
<div class="line"><a name="l00615"></a><span class="lineno">  615</span>&#160;  <span class="keywordflow">foreach</span> ($command_options as $key =&gt; $value) {</div>
<div class="line"><a name="l00616"></a><span class="lineno">  616</span>&#160;    <span class="keywordflow">if</span> (substr($key,0,1) === <span class="charliteral">&#39;#&#39;</span>) {</div>
<div class="line"><a name="l00617"></a><span class="lineno">  617</span>&#160;      $result[substr($key,1)] = $value;</div>
<div class="line"><a name="l00618"></a><span class="lineno">  618</span>&#160;    }</div>
<div class="line"><a name="l00619"></a><span class="lineno">  619</span>&#160;  }</div>
<div class="line"><a name="l00620"></a><span class="lineno">  620</span>&#160;  <span class="keywordflow">return</span> $result;</div>
<div class="line"><a name="l00621"></a><span class="lineno">  621</span>&#160;}</div>
<div class="line"><a name="l00622"></a><span class="lineno">  622</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00623"></a><span class="lineno">  623</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00624"></a><span class="lineno">  624</span>&#160;<span class="comment"> * Execute a new local or remote command in a new process.</span></div>
<div class="line"><a name="l00625"></a><span class="lineno">  625</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00626"></a><span class="lineno">  626</span>&#160;<span class="comment"> * n.b. Prefer drush_invoke_process() to this function.</span></div>
<div class="line"><a name="l00627"></a><span class="lineno">  627</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00628"></a><span class="lineno">  628</span>&#160;<span class="comment"> * @param invocations</span></div>
<div class="line"><a name="l00629"></a><span class="lineno">  629</span>&#160;<span class="comment"> *   An array of command records to exacute. Each record should contain:</span></div>
<div class="line"><a name="l00630"></a><span class="lineno">  630</span>&#160;<span class="comment"> *     &#39;site&#39;:</span></div>
<div class="line"><a name="l00631"></a><span class="lineno">  631</span>&#160;<span class="comment"> *       An array containing information used to generate the command.</span></div>
<div class="line"><a name="l00632"></a><span class="lineno">  632</span>&#160;<span class="comment"> *         &#39;remote-host&#39;</span></div>
<div class="line"><a name="l00633"></a><span class="lineno">  633</span>&#160;<span class="comment"> *            Optional. A remote host to execute the drush command on.</span></div>
<div class="line"><a name="l00634"></a><span class="lineno">  634</span>&#160;<span class="comment"> *         &#39;remote-user&#39;</span></div>
<div class="line"><a name="l00635"></a><span class="lineno">  635</span>&#160;<span class="comment"> *            Optional. Defaults to the current user. If you specify this, you can choose which module to send.</span></div>
<div class="line"><a name="l00636"></a><span class="lineno">  636</span>&#160;<span class="comment"> *         &#39;ssh-options&#39;</span></div>
<div class="line"><a name="l00637"></a><span class="lineno">  637</span>&#160;<span class="comment"> *            Optional.  Defaults to &quot;-o PasswordAuthentication=no&quot;</span></div>
<div class="line"><a name="l00638"></a><span class="lineno">  638</span>&#160;<span class="comment"> *         &#39;path-aliases&#39;</span></div>
<div class="line"><a name="l00639"></a><span class="lineno">  639</span>&#160;<span class="comment"> *            Optional; contains paths to folders and executables useful to the command.</span></div>
<div class="line"><a name="l00640"></a><span class="lineno">  640</span>&#160;<span class="comment"> *         &#39;%drush-script&#39;</span></div>
<div class="line"><a name="l00641"></a><span class="lineno">  641</span>&#160;<span class="comment"> *            Optional. Defaults to the current drush.php file on the local machine, and</span></div>
<div class="line"><a name="l00642"></a><span class="lineno">  642</span>&#160;<span class="comment"> *            to simply &#39;drush&#39; (the drush script in the current PATH) on remote servers.</span></div>
<div class="line"><a name="l00643"></a><span class="lineno">  643</span>&#160;<span class="comment"> *            You may also specify a different drush.php script explicitly.  You will need</span></div>
<div class="line"><a name="l00644"></a><span class="lineno">  644</span>&#160;<span class="comment"> *            to set this when calling drush on a remote server if &#39;drush&#39; is not in the</span></div>
<div class="line"><a name="l00645"></a><span class="lineno">  645</span>&#160;<span class="comment"> *            PATH on that machine.</span></div>
<div class="line"><a name="l00646"></a><span class="lineno">  646</span>&#160;<span class="comment"> *     &#39;command&#39;:</span></div>
<div class="line"><a name="l00647"></a><span class="lineno">  647</span>&#160;<span class="comment"> *       A defined drush command such as &#39;cron&#39;, &#39;status&#39; or any of the available ones such as &#39;drush pm&#39;.</span></div>
<div class="line"><a name="l00648"></a><span class="lineno">  648</span>&#160;<span class="comment"> *     &#39;args&#39;:</span></div>
<div class="line"><a name="l00649"></a><span class="lineno">  649</span>&#160;<span class="comment"> *       An array of arguments for the command.</span></div>
<div class="line"><a name="l00650"></a><span class="lineno">  650</span>&#160;<span class="comment"> *     &#39;options&#39;</span></div>
<div class="line"><a name="l00651"></a><span class="lineno">  651</span>&#160;<span class="comment"> *       Optional. An array containing options to pass to the remote script.</span></div>
<div class="line"><a name="l00652"></a><span class="lineno">  652</span>&#160;<span class="comment"> *       Array items with a numeric key are treated as optional arguments to the</span></div>
<div class="line"><a name="l00653"></a><span class="lineno">  653</span>&#160;<span class="comment"> *       command.</span></div>
<div class="line"><a name="l00654"></a><span class="lineno">  654</span>&#160;<span class="comment"> *     &#39;backend-options&#39;:</span></div>
<div class="line"><a name="l00655"></a><span class="lineno">  655</span>&#160;<span class="comment"> *       Optional. Additional parameters that control the operation of the invoke.</span></div>
<div class="line"><a name="l00656"></a><span class="lineno">  656</span>&#160;<span class="comment"> *         &#39;method&#39;</span></div>
<div class="line"><a name="l00657"></a><span class="lineno">  657</span>&#160;<span class="comment"> *            Optional. Defaults to &#39;GET&#39;.</span></div>
<div class="line"><a name="l00658"></a><span class="lineno">  658</span>&#160;<span class="comment"> *            If this parameter is set to &#39;POST&#39;, the $data array will be passed</span></div>
<div class="line"><a name="l00659"></a><span class="lineno">  659</span>&#160;<span class="comment"> *            to the script being called as a JSON encoded string over the STDIN</span></div>
<div class="line"><a name="l00660"></a><span class="lineno">  660</span>&#160;<span class="comment"> *            pipe of that process. This is preferable if you have to pass</span></div>
<div class="line"><a name="l00661"></a><span class="lineno">  661</span>&#160;<span class="comment"> *            sensitive data such as passwords and the like.</span></div>
<div class="line"><a name="l00662"></a><span class="lineno">  662</span>&#160;<span class="comment"> *            For any other value, the $data array will be collapsed down into a</span></div>
<div class="line"><a name="l00663"></a><span class="lineno">  663</span>&#160;<span class="comment"> *            set of command line options to the script.</span></div>
<div class="line"><a name="l00664"></a><span class="lineno">  664</span>&#160;<span class="comment"> *         &#39;integrate&#39;</span></div>
<div class="line"><a name="l00665"></a><span class="lineno">  665</span>&#160;<span class="comment"> *            Optional. Defaults to TRUE.</span></div>
<div class="line"><a name="l00666"></a><span class="lineno">  666</span>&#160;<span class="comment"> *            If TRUE, any error statuses will be integrated into the current</span></div>
<div class="line"><a name="l00667"></a><span class="lineno">  667</span>&#160;<span class="comment"> *            process. This might not be what you want, if you are writing a</span></div>
<div class="line"><a name="l00668"></a><span class="lineno">  668</span>&#160;<span class="comment"> *            command that operates on multiple sites.</span></div>
<div class="line"><a name="l00669"></a><span class="lineno">  669</span>&#160;<span class="comment"> *         &#39;log&#39;</span></div>
<div class="line"><a name="l00670"></a><span class="lineno">  670</span>&#160;<span class="comment"> *            Optional. Defaults to TRUE.</span></div>
<div class="line"><a name="l00671"></a><span class="lineno">  671</span>&#160;<span class="comment"> *            If TRUE, any log messages will be integrated into the current</span></div>
<div class="line"><a name="l00672"></a><span class="lineno">  672</span>&#160;<span class="comment"> *            process.</span></div>
<div class="line"><a name="l00673"></a><span class="lineno">  673</span>&#160;<span class="comment"> *         &#39;output&#39;</span></div>
<div class="line"><a name="l00674"></a><span class="lineno">  674</span>&#160;<span class="comment"> *            Optional. Defaults to TRUE.</span></div>
<div class="line"><a name="l00675"></a><span class="lineno">  675</span>&#160;<span class="comment"> *            If TRUE, output from the command will be synchronously printed to</span></div>
<div class="line"><a name="l00676"></a><span class="lineno">  676</span>&#160;<span class="comment"> *            stdout.</span></div>
<div class="line"><a name="l00677"></a><span class="lineno">  677</span>&#160;<span class="comment"> *         &#39;drush-script&#39;</span></div>
<div class="line"><a name="l00678"></a><span class="lineno">  678</span>&#160;<span class="comment"> *            Optional. Defaults to the current drush.php file on the local</span></div>
<div class="line"><a name="l00679"></a><span class="lineno">  679</span>&#160;<span class="comment"> *            machine, and to simply &#39;drush&#39; (the drush script in the current</span></div>
<div class="line"><a name="l00680"></a><span class="lineno">  680</span>&#160;<span class="comment"> *            PATH) on remote servers.  You may also specify a different drush.php</span></div>
<div class="line"><a name="l00681"></a><span class="lineno">  681</span>&#160;<span class="comment"> *            script explicitly.  You will need to set this when calling drush on</span></div>
<div class="line"><a name="l00682"></a><span class="lineno">  682</span>&#160;<span class="comment"> *            a remote server if &#39;drush&#39; is not in the PATH on that machine.</span></div>
<div class="line"><a name="l00683"></a><span class="lineno">  683</span>&#160;<span class="comment"> *          &#39;dispatch-using-alias&#39;</span></div>
<div class="line"><a name="l00684"></a><span class="lineno">  684</span>&#160;<span class="comment"> *            Optional. Defaults to FALSE.</span></div>
<div class="line"><a name="l00685"></a><span class="lineno">  685</span>&#160;<span class="comment"> *            If specified as a non-empty value the drush command will be</span></div>
<div class="line"><a name="l00686"></a><span class="lineno">  686</span>&#160;<span class="comment"> *            dispatched using the alias name on the command line, instead of</span></div>
<div class="line"><a name="l00687"></a><span class="lineno">  687</span>&#160;<span class="comment"> *            the options from the alias being added to the command line</span></div>
<div class="line"><a name="l00688"></a><span class="lineno">  688</span>&#160;<span class="comment"> *            automatically.</span></div>
<div class="line"><a name="l00689"></a><span class="lineno">  689</span>&#160;<span class="comment"> * @param common_options</span></div>
<div class="line"><a name="l00690"></a><span class="lineno">  690</span>&#160;<span class="comment"> *    Optional. Merged in with the options for each invocation.</span></div>
<div class="line"><a name="l00691"></a><span class="lineno">  691</span>&#160;<span class="comment"> * @param backend_options</span></div>
<div class="line"><a name="l00692"></a><span class="lineno">  692</span>&#160;<span class="comment"> *    Optional. Merged in with the backend options for each invocation.</span></div>
<div class="line"><a name="l00693"></a><span class="lineno">  693</span>&#160;<span class="comment"> * @param default_command</span></div>
<div class="line"><a name="l00694"></a><span class="lineno">  694</span>&#160;<span class="comment"> *    Optional. Used as the &#39;command&#39; for any invocation that does not</span></div>
<div class="line"><a name="l00695"></a><span class="lineno">  695</span>&#160;<span class="comment"> *    define a command explicitly.</span></div>
<div class="line"><a name="l00696"></a><span class="lineno">  696</span>&#160;<span class="comment"> * @param default_site</span></div>
<div class="line"><a name="l00697"></a><span class="lineno">  697</span>&#160;<span class="comment"> *    Optional. Used as the &#39;site&#39; for any invocation that does not</span></div>
<div class="line"><a name="l00698"></a><span class="lineno">  698</span>&#160;<span class="comment"> *    define a site explicitly.</span></div>
<div class="line"><a name="l00699"></a><span class="lineno">  699</span>&#160;<span class="comment"> * @param context</span></div>
<div class="line"><a name="l00700"></a><span class="lineno">  700</span>&#160;<span class="comment"> *    Optional. Passed in to proc_open if provided.</span></div>
<div class="line"><a name="l00701"></a><span class="lineno">  701</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00702"></a><span class="lineno">  702</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l00703"></a><span class="lineno">  703</span>&#160;<span class="comment"> *   If the command could not be completed successfully, FALSE.</span></div>
<div class="line"><a name="l00704"></a><span class="lineno">  704</span>&#160;<span class="comment"> *   If the command was completed, this will return an associative array containing the data from drush_backend_output().</span></div>
<div class="line"><a name="l00705"></a><span class="lineno">  705</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00706"></a><span class="lineno"><a class="code" href="backend_8inc.html#a7852d5448cd4ee3a2082eccd24d690e7">  706</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a7852d5448cd4ee3a2082eccd24d690e7">drush_backend_invoke_concurrent</a>($invocations, $common_options = array(), $common_backend_options = array(), $default_command = NULL, $default_site = NULL, $context = NULL) {</div>
<div class="line"><a name="l00707"></a><span class="lineno">  707</span>&#160;  $index = 0;</div>
<div class="line"><a name="l00708"></a><span class="lineno">  708</span>&#160;</div>
<div class="line"><a name="l00709"></a><span class="lineno">  709</span>&#160;  <span class="comment">// Slice and dice our options in preparation to build a command string</span></div>
<div class="line"><a name="l00710"></a><span class="lineno">  710</span>&#160;  $invocation_options = array();</div>
<div class="line"><a name="l00711"></a><span class="lineno">  711</span>&#160;  <span class="keywordflow">foreach</span> ($invocations as $invocation)  {</div>
<div class="line"><a name="l00712"></a><span class="lineno">  712</span>&#160;    $site_record = isset($invocation[<span class="stringliteral">&#39;site&#39;</span>]) ? $invocation[<span class="stringliteral">&#39;site&#39;</span>] : $default_site;</div>
<div class="line"><a name="l00713"></a><span class="lineno">  713</span>&#160;    <span class="comment">// NULL is a synonym to &#39;@self&#39;, although the latter is preferred.</span></div>
<div class="line"><a name="l00714"></a><span class="lineno">  714</span>&#160;    <span class="keywordflow">if</span> (!isset($site_record)) {</div>
<div class="line"><a name="l00715"></a><span class="lineno">  715</span>&#160;      $site_record = <span class="stringliteral">&#39;@self&#39;</span>;</div>
<div class="line"><a name="l00716"></a><span class="lineno">  716</span>&#160;    }</div>
<div class="line"><a name="l00717"></a><span class="lineno">  717</span>&#160;    <span class="comment">// If the first parameter is not a site alias record,</span></div>
<div class="line"><a name="l00718"></a><span class="lineno">  718</span>&#160;    <span class="comment">// then presume it is an alias name, and try to look up</span></div>
<div class="line"><a name="l00719"></a><span class="lineno">  719</span>&#160;    <span class="comment">// the alias record.</span></div>
<div class="line"><a name="l00720"></a><span class="lineno">  720</span>&#160;    <span class="keywordflow">if</span> (!is_array($site_record)) {</div>
<div class="line"><a name="l00721"></a><span class="lineno">  721</span>&#160;      $site_record = <a class="code" href="sitealias_8inc.html#ac2f57b80441374522c4e4cdc3b7e0c2b">drush_sitealias_get_record</a>($site_record);</div>
<div class="line"><a name="l00722"></a><span class="lineno">  722</span>&#160;    }</div>
<div class="line"><a name="l00723"></a><span class="lineno">  723</span>&#160;    $command = isset($invocation[<span class="stringliteral">&#39;command&#39;</span>]) ? $invocation[<span class="stringliteral">&#39;command&#39;</span>] : $default_command;</div>
<div class="line"><a name="l00724"></a><span class="lineno">  724</span>&#160;    $args = isset($invocation[<span class="stringliteral">&#39;args&#39;</span>]) ? $invocation[<span class="stringliteral">&#39;args&#39;</span>] : array();</div>
<div class="line"><a name="l00725"></a><span class="lineno">  725</span>&#160;    $command_options = isset($invocation[<span class="stringliteral">&#39;options&#39;</span>]) ? $invocation[<span class="stringliteral">&#39;options&#39;</span>] : array();</div>
<div class="line"><a name="l00726"></a><span class="lineno">  726</span>&#160;    $backend_options = isset($invocation[<span class="stringliteral">&#39;backend-options&#39;</span>]) ? $invocation[<span class="stringliteral">&#39;backend-options&#39;</span>] : array();</div>
<div class="line"><a name="l00727"></a><span class="lineno">  727</span>&#160;    <span class="comment">// If $backend_options is passed in as a bool, interpret that as the value for &#39;integrate&#39;</span></div>
<div class="line"><a name="l00728"></a><span class="lineno">  728</span>&#160;    <span class="keywordflow">if</span> (!is_array($common_backend_options)) {</div>
<div class="line"><a name="l00729"></a><span class="lineno">  729</span>&#160;      $integrate = (bool)$common_backend_options;</div>
<div class="line"><a name="l00730"></a><span class="lineno">  730</span>&#160;      $common_backend_options = array(<span class="stringliteral">&#39;integrate&#39;</span> =&gt; $integrate);</div>
<div class="line"><a name="l00731"></a><span class="lineno">  731</span>&#160;    }</div>
<div class="line"><a name="l00732"></a><span class="lineno">  732</span>&#160;</div>
<div class="line"><a name="l00733"></a><span class="lineno">  733</span>&#160;    $command_options += $common_options;</div>
<div class="line"><a name="l00734"></a><span class="lineno">  734</span>&#160;    $backend_options += $common_backend_options;</div>
<div class="line"><a name="l00735"></a><span class="lineno">  735</span>&#160;</div>
<div class="line"><a name="l00736"></a><span class="lineno">  736</span>&#160;    $backend_options = <a class="code" href="backend_8inc.html#a895f14d30af875ea1783a3de2355d095">_drush_backend_adjust_options</a>($site_record, $command, $command_options, $backend_options);</div>
<div class="line"><a name="l00737"></a><span class="lineno">  737</span>&#160;</div>
<div class="line"><a name="l00738"></a><span class="lineno">  738</span>&#160;    <span class="comment">// Insure that contexts such as DRUSH_SIMULATE and NO_COLOR are included.</span></div>
<div class="line"><a name="l00739"></a><span class="lineno">  739</span>&#160;    $command_options += <a class="code" href="backend_8inc.html#aff4e2427168bc7585fcfa5eca6a94af0">_drush_backend_get_global_contexts</a>($site_record);</div>
<div class="line"><a name="l00740"></a><span class="lineno">  740</span>&#160;</div>
<div class="line"><a name="l00741"></a><span class="lineno">  741</span>&#160;    <span class="comment">// Add in command-specific options as well</span></div>
<div class="line"><a name="l00742"></a><span class="lineno">  742</span>&#160;    $command_options += <a class="code" href="includes_2command_8inc.html#aed341ec21a59c794b73f7ba031825632">drush_command_get_command_specific_options</a>($site_record, $command);</div>
<div class="line"><a name="l00743"></a><span class="lineno">  743</span>&#160;</div>
<div class="line"><a name="l00744"></a><span class="lineno">  744</span>&#160;    <span class="comment">// If the caller has requested it, don&#39;t pull the options from the alias</span></div>
<div class="line"><a name="l00745"></a><span class="lineno">  745</span>&#160;    <span class="comment">// into the command line, but use the alias name for dispatching.</span></div>
<div class="line"><a name="l00746"></a><span class="lineno">  746</span>&#160;    <span class="keywordflow">if</span> (!empty($backend_options[<span class="stringliteral">&#39;dispatch-using-alias&#39;</span>]) &amp;&amp; isset($site_record[<span class="stringliteral">&#39;#name&#39;</span>])) {</div>
<div class="line"><a name="l00747"></a><span class="lineno">  747</span>&#160;      list($post_options, $commandline_options, $drush_global_options) = <a class="code" href="backend_8inc.html#a20dd75d8a0d75a4e59db35c8918d1d8a">_drush_backend_classify_options</a>(array(), $command_options, $backend_options);</div>
<div class="line"><a name="l00748"></a><span class="lineno">  748</span>&#160;      $site_record_to_dispatch = <span class="charliteral">&#39;@&#39;</span> . ltrim($site_record[<span class="stringliteral">&#39;#name&#39;</span>], <span class="charliteral">&#39;@&#39;</span>);</div>
<div class="line"><a name="l00749"></a><span class="lineno">  749</span>&#160;    }</div>
<div class="line"><a name="l00750"></a><span class="lineno">  750</span>&#160;    <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00751"></a><span class="lineno">  751</span>&#160;      list($post_options, $commandline_options, $drush_global_options) = <a class="code" href="backend_8inc.html#a20dd75d8a0d75a4e59db35c8918d1d8a">_drush_backend_classify_options</a>($site_record, $command_options, $backend_options);</div>
<div class="line"><a name="l00752"></a><span class="lineno">  752</span>&#160;      $site_record_to_dispatch = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00753"></a><span class="lineno">  753</span>&#160;    }</div>
<div class="line"><a name="l00754"></a><span class="lineno">  754</span>&#160;    <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;backend-simulate&#39;</span>, $backend_options)) {</div>
<div class="line"><a name="l00755"></a><span class="lineno">  755</span>&#160;      $commandline_options[<span class="stringliteral">&#39;simulate&#39;</span>] = TRUE;</div>
<div class="line"><a name="l00756"></a><span class="lineno">  756</span>&#160;    }</div>
<div class="line"><a name="l00757"></a><span class="lineno">  757</span>&#160;    $site_record += array(<span class="stringliteral">&#39;path-aliases&#39;</span> =&gt; array());</div>
<div class="line"><a name="l00758"></a><span class="lineno">  758</span>&#160;    $site_record[<span class="stringliteral">&#39;path-aliases&#39;</span>] += array(</div>
<div class="line"><a name="l00759"></a><span class="lineno">  759</span>&#160;      <span class="stringliteral">&#39;%drush-script&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l00760"></a><span class="lineno">  760</span>&#160;    );</div>
<div class="line"><a name="l00761"></a><span class="lineno">  761</span>&#160;</div>
<div class="line"><a name="l00762"></a><span class="lineno">  762</span>&#160;    $site = (array_key_exists(<span class="stringliteral">&#39;#name&#39;</span>, $site_record) &amp;&amp; !array_key_exists($site_record[<span class="stringliteral">&#39;#name&#39;</span>], $invocation_options)) ? $site_record[<span class="stringliteral">&#39;#name&#39;</span>] : $index++;</div>
<div class="line"><a name="l00763"></a><span class="lineno">  763</span>&#160;    $invocation_options[$site] = array(</div>
<div class="line"><a name="l00764"></a><span class="lineno">  764</span>&#160;      <span class="stringliteral">&#39;site-record&#39;</span> =&gt; $site_record,</div>
<div class="line"><a name="l00765"></a><span class="lineno">  765</span>&#160;      <span class="stringliteral">&#39;site-record-to-dispatch&#39;</span> =&gt; $site_record_to_dispatch,</div>
<div class="line"><a name="l00766"></a><span class="lineno">  766</span>&#160;      <span class="stringliteral">&#39;command&#39;</span> =&gt; $command,</div>
<div class="line"><a name="l00767"></a><span class="lineno">  767</span>&#160;      <span class="stringliteral">&#39;args&#39;</span> =&gt; $args,</div>
<div class="line"><a name="l00768"></a><span class="lineno">  768</span>&#160;      <span class="stringliteral">&#39;post-options&#39;</span> =&gt; $post_options,</div>
<div class="line"><a name="l00769"></a><span class="lineno">  769</span>&#160;      <span class="stringliteral">&#39;drush-global-options&#39;</span> =&gt; $drush_global_options,</div>
<div class="line"><a name="l00770"></a><span class="lineno">  770</span>&#160;      <span class="stringliteral">&#39;commandline-options&#39;</span> =&gt; $commandline_options,</div>
<div class="line"><a name="l00771"></a><span class="lineno">  771</span>&#160;      <span class="stringliteral">&#39;command-options&#39;</span> =&gt; $command_options,</div>
<div class="line"><a name="l00772"></a><span class="lineno">  772</span>&#160;      <span class="stringliteral">&#39;backend-options&#39;</span> =&gt; $backend_options,</div>
<div class="line"><a name="l00773"></a><span class="lineno">  773</span>&#160;    );</div>
<div class="line"><a name="l00774"></a><span class="lineno">  774</span>&#160;  }</div>
<div class="line"><a name="l00775"></a><span class="lineno">  775</span>&#160;</div>
<div class="line"><a name="l00776"></a><span class="lineno">  776</span>&#160;  <span class="comment">// Calculate the length of the longest output label</span></div>
<div class="line"><a name="l00777"></a><span class="lineno">  777</span>&#160;  $max_name_length = 0;</div>
<div class="line"><a name="l00778"></a><span class="lineno">  778</span>&#160;  $label_separator = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00779"></a><span class="lineno">  779</span>&#160;  <span class="keywordflow">if</span> (!array_key_exists(<span class="stringliteral">&#39;no-label&#39;</span>, $common_options) &amp;&amp; (count($invocation_options) &gt; 1)) {</div>
<div class="line"><a name="l00780"></a><span class="lineno">  780</span>&#160;    $label_separator = array_key_exists(<span class="stringliteral">&#39;label-separator&#39;</span>, $common_options) ? $common_options[<span class="stringliteral">&#39;label-separator&#39;</span>] : <span class="stringliteral">&#39; &gt;&gt; &#39;</span>;</div>
<div class="line"><a name="l00781"></a><span class="lineno">  781</span>&#160;    <span class="keywordflow">foreach</span> ($invocation_options as $site =&gt; $item) {</div>
<div class="line"><a name="l00782"></a><span class="lineno">  782</span>&#160;      $backend_options = $item[<span class="stringliteral">&#39;backend-options&#39;</span>];</div>
<div class="line"><a name="l00783"></a><span class="lineno">  783</span>&#160;      <span class="keywordflow">if</span> (!array_key_exists(<span class="stringliteral">&#39;#output-label&#39;</span>, $backend_options)) {</div>
<div class="line"><a name="l00784"></a><span class="lineno">  784</span>&#160;        <span class="keywordflow">if</span> (is_numeric($site)) {</div>
<div class="line"><a name="l00785"></a><span class="lineno">  785</span>&#160;          $backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>] = <span class="stringliteral">&#39; * [@self.&#39;</span> . $site;</div>
<div class="line"><a name="l00786"></a><span class="lineno">  786</span>&#160;          $label_separator = <span class="stringliteral">&#39;] &#39;</span>;</div>
<div class="line"><a name="l00787"></a><span class="lineno">  787</span>&#160;        }</div>
<div class="line"><a name="l00788"></a><span class="lineno">  788</span>&#160;        <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00789"></a><span class="lineno">  789</span>&#160;          $backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>] = $site;</div>
<div class="line"><a name="l00790"></a><span class="lineno">  790</span>&#160;        }</div>
<div class="line"><a name="l00791"></a><span class="lineno">  791</span>&#160;        $invocation_options[$site][<span class="stringliteral">&#39;backend-options&#39;</span>][<span class="stringliteral">&#39;#output-label&#39;</span>] = $backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>];</div>
<div class="line"><a name="l00792"></a><span class="lineno">  792</span>&#160;      }</div>
<div class="line"><a name="l00793"></a><span class="lineno">  793</span>&#160;      $name_len = strlen($backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>]);</div>
<div class="line"><a name="l00794"></a><span class="lineno">  794</span>&#160;      <span class="keywordflow">if</span> ($name_len &gt; $max_name_length) {</div>
<div class="line"><a name="l00795"></a><span class="lineno">  795</span>&#160;        $max_name_length = $name_len;</div>
<div class="line"><a name="l00796"></a><span class="lineno">  796</span>&#160;      }</div>
<div class="line"><a name="l00797"></a><span class="lineno">  797</span>&#160;      <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;#label-separator&#39;</span>, $backend_options)) {</div>
<div class="line"><a name="l00798"></a><span class="lineno">  798</span>&#160;        $label_separator = $backend_options[<span class="stringliteral">&#39;#label-separator&#39;</span>];</div>
<div class="line"><a name="l00799"></a><span class="lineno">  799</span>&#160;      }</div>
<div class="line"><a name="l00800"></a><span class="lineno">  800</span>&#160;    }</div>
<div class="line"><a name="l00801"></a><span class="lineno">  801</span>&#160;  }</div>
<div class="line"><a name="l00802"></a><span class="lineno">  802</span>&#160;  <span class="comment">// Now pad out the output labels and add the label separator.</span></div>
<div class="line"><a name="l00803"></a><span class="lineno">  803</span>&#160;  $reserve_margin = $max_name_length + strlen($label_separator);</div>
<div class="line"><a name="l00804"></a><span class="lineno">  804</span>&#160;  <span class="keywordflow">foreach</span> ($invocation_options as $site =&gt; $item) {</div>
<div class="line"><a name="l00805"></a><span class="lineno">  805</span>&#160;    $backend_options = $item[<span class="stringliteral">&#39;backend-options&#39;</span>] + array(<span class="stringliteral">&#39;#output-label&#39;</span> =&gt; <span class="stringliteral">&#39;&#39;</span>);</div>
<div class="line"><a name="l00806"></a><span class="lineno">  806</span>&#160;    $invocation_options[$site][<span class="stringliteral">&#39;backend-options&#39;</span>][<span class="stringliteral">&#39;#output-label&#39;</span>] = str_pad($backend_options[<span class="stringliteral">&#39;#output-label&#39;</span>], $max_name_length, <span class="stringliteral">&quot; &quot;</span>) . $label_separator;</div>
<div class="line"><a name="l00807"></a><span class="lineno">  807</span>&#160;    <span class="keywordflow">if</span> ($reserve_margin) {</div>
<div class="line"><a name="l00808"></a><span class="lineno">  808</span>&#160;      $invocation_options[$site][<span class="stringliteral">&#39;drush-global-options&#39;</span>][<span class="stringliteral">&#39;reserve-margin&#39;</span>] = $reserve_margin;</div>
<div class="line"><a name="l00809"></a><span class="lineno">  809</span>&#160;    }</div>
<div class="line"><a name="l00810"></a><span class="lineno">  810</span>&#160;  }</div>
<div class="line"><a name="l00811"></a><span class="lineno">  811</span>&#160;</div>
<div class="line"><a name="l00812"></a><span class="lineno">  812</span>&#160;  <span class="comment">// Now take our prepared options and generate the command strings</span></div>
<div class="line"><a name="l00813"></a><span class="lineno">  813</span>&#160;  $cmds = array();</div>
<div class="line"><a name="l00814"></a><span class="lineno">  814</span>&#160;  <span class="keywordflow">foreach</span> ($invocation_options as $site =&gt; $item) {</div>
<div class="line"><a name="l00815"></a><span class="lineno">  815</span>&#160;    $site_record = $item[<span class="stringliteral">&#39;site-record&#39;</span>];</div>
<div class="line"><a name="l00816"></a><span class="lineno">  816</span>&#160;    $site_record_to_dispatch = $item[<span class="stringliteral">&#39;site-record-to-dispatch&#39;</span>];</div>
<div class="line"><a name="l00817"></a><span class="lineno">  817</span>&#160;    $command = $item[<span class="stringliteral">&#39;command&#39;</span>];</div>
<div class="line"><a name="l00818"></a><span class="lineno">  818</span>&#160;    $args = $item[<span class="stringliteral">&#39;args&#39;</span>];</div>
<div class="line"><a name="l00819"></a><span class="lineno">  819</span>&#160;    $post_options = $item[<span class="stringliteral">&#39;post-options&#39;</span>];</div>
<div class="line"><a name="l00820"></a><span class="lineno">  820</span>&#160;    $commandline_options = $item[<span class="stringliteral">&#39;commandline-options&#39;</span>];</div>
<div class="line"><a name="l00821"></a><span class="lineno">  821</span>&#160;    $command_options = $item[<span class="stringliteral">&#39;command-options&#39;</span>];</div>
<div class="line"><a name="l00822"></a><span class="lineno">  822</span>&#160;    $drush_global_options = $item[<span class="stringliteral">&#39;drush-global-options&#39;</span>];</div>
<div class="line"><a name="l00823"></a><span class="lineno">  823</span>&#160;    $backend_options = $item[<span class="stringliteral">&#39;backend-options&#39;</span>];</div>
<div class="line"><a name="l00824"></a><span class="lineno">  824</span>&#160;    $os = <a class="code" href="group__commandwrappers.html#ga1292121e5bdd4bf19ef4f944b16301ed">drush_os</a>($site_record);</div>
<div class="line"><a name="l00825"></a><span class="lineno">  825</span>&#160;    <span class="comment">// If the caller did not pass in a specific path to drush, then we will</span></div>
<div class="line"><a name="l00826"></a><span class="lineno">  826</span>&#160;    <span class="comment">// use a default value.  For commands that are being executed on the same</span></div>
<div class="line"><a name="l00827"></a><span class="lineno">  827</span>&#160;    <span class="comment">// machine, we will use DRUSH_COMMAND, which is the path to the drush.php</span></div>
<div class="line"><a name="l00828"></a><span class="lineno">  828</span>&#160;    <span class="comment">// that is running right now.  For remote commands, we will run a wrapper</span></div>
<div class="line"><a name="l00829"></a><span class="lineno">  829</span>&#160;    <span class="comment">// script instead of drush.php -- drush.bat on Windows, or drush on Linux.</span></div>
<div class="line"><a name="l00830"></a><span class="lineno">  830</span>&#160;    $drush_path = $site_record[<span class="stringliteral">&#39;path-aliases&#39;</span>][<span class="stringliteral">&#39;%drush-script&#39;</span>];</div>
<div class="line"><a name="l00831"></a><span class="lineno">  831</span>&#160;    $php = array_key_exists(<span class="stringliteral">&#39;php&#39;</span>, $site_record) ? $site_record[<span class="stringliteral">&#39;php&#39;</span>] : (array_key_exists(<span class="stringliteral">&#39;php&#39;</span>, $command_options) ? $command_options[<span class="stringliteral">&#39;php&#39;</span>] : NULL);</div>
<div class="line"><a name="l00832"></a><span class="lineno">  832</span>&#160;    $drush_command_path = <a class="code" href="includes_2environment_8inc.html#a8839a1aae14125ef4128d1477827ca0e">drush_build_drush_command</a>($drush_path, $php, $os, array_key_exists(<span class="stringliteral">&#39;remote-host&#39;</span>, $site_record));</div>
<div class="line"><a name="l00833"></a><span class="lineno">  833</span>&#160;    $cmd = <a class="code" href="backend_8inc.html#aa9bff3ffcd61a4dd945b567057a54e5d">_drush_backend_generate_command</a>($site_record, $drush_command_path . <span class="stringliteral">&quot; &quot;</span> . <a class="code" href="backend_8inc.html#ad19c067bfbd87dfc63c55659723aaf60">_drush_backend_argument_string</a>($drush_global_options, $os) . <span class="stringliteral">&quot; &quot;</span> . $site_record_to_dispatch . <span class="stringliteral">&quot; &quot;</span> . $command, $args, $commandline_options, $backend_options) . <span class="stringliteral">&#39; 2&gt;&amp;1&#39;</span>;</div>
<div class="line"><a name="l00834"></a><span class="lineno">  834</span>&#160;    $cmds[$site] = array(</div>
<div class="line"><a name="l00835"></a><span class="lineno">  835</span>&#160;      <span class="stringliteral">&#39;cmd&#39;</span> =&gt; $cmd,</div>
<div class="line"><a name="l00836"></a><span class="lineno">  836</span>&#160;      <span class="stringliteral">&#39;post-options&#39;</span> =&gt; $post_options,</div>
<div class="line"><a name="l00837"></a><span class="lineno">  837</span>&#160;      <span class="stringliteral">&#39;backend-options&#39;</span> =&gt; $backend_options,</div>
<div class="line"><a name="l00838"></a><span class="lineno">  838</span>&#160;    );</div>
<div class="line"><a name="l00839"></a><span class="lineno">  839</span>&#160;  }</div>
<div class="line"><a name="l00840"></a><span class="lineno">  840</span>&#160;</div>
<div class="line"><a name="l00841"></a><span class="lineno">  841</span>&#160;  <span class="keywordflow">return</span> <a class="code" href="backend_8inc.html#a1d3f3caae7e1300c53e2cc1fe4ffb932">_drush_backend_invoke</a>($cmds, $common_backend_options, $context);</div>
<div class="line"><a name="l00842"></a><span class="lineno">  842</span>&#160;}</div>
<div class="line"><a name="l00843"></a><span class="lineno">  843</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00844"></a><span class="lineno">  844</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00845"></a><span class="lineno">  845</span>&#160;<span class="comment"> * Find all of the drush contexts that are used to cache global values and</span></div>
<div class="line"><a name="l00846"></a><span class="lineno">  846</span>&#160;<span class="comment"> * return them in an associative array.</span></div>
<div class="line"><a name="l00847"></a><span class="lineno">  847</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00848"></a><span class="lineno"><a class="code" href="backend_8inc.html#aff4e2427168bc7585fcfa5eca6a94af0">  848</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#aff4e2427168bc7585fcfa5eca6a94af0">_drush_backend_get_global_contexts</a>($site_record) {</div>
<div class="line"><a name="l00849"></a><span class="lineno">  849</span>&#160;  $result = array();</div>
<div class="line"><a name="l00850"></a><span class="lineno">  850</span>&#160;  $global_option_list = <a class="code" href="drush_8inc.html#acb0a26e79bcbdd1152d59a6916a35aae">drush_get_global_options</a>(FALSE);</div>
<div class="line"><a name="l00851"></a><span class="lineno">  851</span>&#160;  <span class="keywordflow">foreach</span> ($global_option_list as $global_key =&gt; $global_metadata) {</div>
<div class="line"><a name="l00852"></a><span class="lineno">  852</span>&#160;    <span class="keywordflow">if</span> (is_array($global_metadata)) {</div>
<div class="line"><a name="l00853"></a><span class="lineno">  853</span>&#160;      $value = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l00854"></a><span class="lineno">  854</span>&#160;      <span class="keywordflow">if</span> (!array_key_exists(<span class="stringliteral">&#39;never-propagate&#39;</span>, $global_metadata)) {</div>
<div class="line"><a name="l00855"></a><span class="lineno">  855</span>&#160;        <span class="keywordflow">if</span> ((array_key_exists(<span class="stringliteral">&#39;propagate-cli-value&#39;</span>, $global_metadata))) {</div>
<div class="line"><a name="l00856"></a><span class="lineno">  856</span>&#160;          $value = <a class="code" href="context_8inc.html#afe91fb3e5219ecb2208c3b036b1f0cb8">drush_get_option</a>($global_key, <span class="stringliteral">&#39;&#39;</span>, <span class="stringliteral">&#39;cli&#39;</span>);</div>
<div class="line"><a name="l00857"></a><span class="lineno">  857</span>&#160;        }</div>
<div class="line"><a name="l00858"></a><span class="lineno">  858</span>&#160;        elseif ((array_key_exists(<span class="stringliteral">&#39;context&#39;</span>, $global_metadata))) {</div>
<div class="line"><a name="l00859"></a><span class="lineno">  859</span>&#160;          <span class="comment">// If the context is declared to be a &#39;local-context-only&#39;,</span></div>
<div class="line"><a name="l00860"></a><span class="lineno">  860</span>&#160;          <span class="comment">// then only put it in if this is a local dispatch.</span></div>
<div class="line"><a name="l00861"></a><span class="lineno">  861</span>&#160;          <span class="keywordflow">if</span> (!array_key_exists(<span class="stringliteral">&#39;local-context-only&#39;</span>, $global_metadata) || !array_key_exists(<span class="stringliteral">&#39;remote-host&#39;</span>, $site_record)) {</div>
<div class="line"><a name="l00862"></a><span class="lineno">  862</span>&#160;            $value = <a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>($global_metadata[<span class="stringliteral">&#39;context&#39;</span>], array());</div>
<div class="line"><a name="l00863"></a><span class="lineno">  863</span>&#160;          }</div>
<div class="line"><a name="l00864"></a><span class="lineno">  864</span>&#160;        }</div>
<div class="line"><a name="l00865"></a><span class="lineno">  865</span>&#160;        <span class="keywordflow">if</span> (!empty($value)) {</div>
<div class="line"><a name="l00866"></a><span class="lineno">  866</span>&#160;          $result[$global_key] = $value;</div>
<div class="line"><a name="l00867"></a><span class="lineno">  867</span>&#160;        }</div>
<div class="line"><a name="l00868"></a><span class="lineno">  868</span>&#160;      }</div>
<div class="line"><a name="l00869"></a><span class="lineno">  869</span>&#160;    }</div>
<div class="line"><a name="l00870"></a><span class="lineno">  870</span>&#160;  }</div>
<div class="line"><a name="l00871"></a><span class="lineno">  871</span>&#160;  <span class="keywordflow">return</span> $result;</div>
<div class="line"><a name="l00872"></a><span class="lineno">  872</span>&#160;}</div>
<div class="line"><a name="l00873"></a><span class="lineno">  873</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00874"></a><span class="lineno">  874</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00875"></a><span class="lineno">  875</span>&#160;<span class="comment"> * Take all of the values in the $command_options array, and place each of</span></div>
<div class="line"><a name="l00876"></a><span class="lineno">  876</span>&#160;<span class="comment"> * them into one of the following result arrays:</span></div>
<div class="line"><a name="l00877"></a><span class="lineno">  877</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00878"></a><span class="lineno">  878</span>&#160;<span class="comment"> *     - $post_options: options to be encoded as JSON and written to the</span></div>
<div class="line"><a name="l00879"></a><span class="lineno">  879</span>&#160;<span class="comment"> *       standard input of the drush subprocess being executed.</span></div>
<div class="line"><a name="l00880"></a><span class="lineno">  880</span>&#160;<span class="comment"> *     - $commandline_options: options to be placed on the command line of the drush</span></div>
<div class="line"><a name="l00881"></a><span class="lineno">  881</span>&#160;<span class="comment"> *       subprocess.</span></div>
<div class="line"><a name="l00882"></a><span class="lineno">  882</span>&#160;<span class="comment"> *     - $drush_global_options: the drush global options also go on the command</span></div>
<div class="line"><a name="l00883"></a><span class="lineno">  883</span>&#160;<span class="comment"> *       line, but appear before the drush command name rather than after it.</span></div>
<div class="line"><a name="l00884"></a><span class="lineno">  884</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00885"></a><span class="lineno">  885</span>&#160;<span class="comment"> * Also, this function may modify $backend_options.</span></div>
<div class="line"><a name="l00886"></a><span class="lineno">  886</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00887"></a><span class="lineno"><a class="code" href="backend_8inc.html#a20dd75d8a0d75a4e59db35c8918d1d8a">  887</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a20dd75d8a0d75a4e59db35c8918d1d8a">_drush_backend_classify_options</a>($site_record, $command_options, &amp;$backend_options) {</div>
<div class="line"><a name="l00888"></a><span class="lineno">  888</span>&#160;  <span class="comment">// In &#39;POST&#39; mode (the default, remove everything (except the items marked &#39;never-post&#39;</span></div>
<div class="line"><a name="l00889"></a><span class="lineno">  889</span>&#160;  <span class="comment">// in the global option list) from the commandline options and put them into the post options.</span></div>
<div class="line"><a name="l00890"></a><span class="lineno">  890</span>&#160;  <span class="comment">// The post options will be json-encoded and sent to the command via stdin</span></div>
<div class="line"><a name="l00891"></a><span class="lineno">  891</span>&#160;  $global_option_list = <a class="code" href="drush_8inc.html#acb0a26e79bcbdd1152d59a6916a35aae">drush_get_global_options</a>(FALSE); <span class="comment">// These should be in the command line.</span></div>
<div class="line"><a name="l00892"></a><span class="lineno">  892</span>&#160;  $additional_global_options = array();</div>
<div class="line"><a name="l00893"></a><span class="lineno">  893</span>&#160;  <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;additional-global-options&#39;</span>, $backend_options)) {</div>
<div class="line"><a name="l00894"></a><span class="lineno">  894</span>&#160;    $additional_global_options = $backend_options[<span class="stringliteral">&#39;additional-global-options&#39;</span>];</div>
<div class="line"><a name="l00895"></a><span class="lineno">  895</span>&#160;    $command_options += $additional_global_options;</div>
<div class="line"><a name="l00896"></a><span class="lineno">  896</span>&#160;  }</div>
<div class="line"><a name="l00897"></a><span class="lineno">  897</span>&#160;  $method_post = ((!array_key_exists(<span class="stringliteral">&#39;method&#39;</span>, $backend_options)) || ($backend_options[<span class="stringliteral">&#39;method&#39;</span>] == <span class="stringliteral">&#39;POST&#39;</span>));</div>
<div class="line"><a name="l00898"></a><span class="lineno">  898</span>&#160;  $post_options = array();</div>
<div class="line"><a name="l00899"></a><span class="lineno">  899</span>&#160;  $commandline_options = array();</div>
<div class="line"><a name="l00900"></a><span class="lineno">  900</span>&#160;  $drush_global_options = array();</div>
<div class="line"><a name="l00901"></a><span class="lineno">  901</span>&#160;  $drush_local_options = array();</div>
<div class="line"><a name="l00902"></a><span class="lineno">  902</span>&#160;  $additional_backend_options = array();</div>
<div class="line"><a name="l00903"></a><span class="lineno">  903</span>&#160;  <span class="keywordflow">foreach</span> ($site_record as $key =&gt; $value) {</div>
<div class="line"><a name="l00904"></a><span class="lineno">  904</span>&#160;    <span class="keywordflow">if</span> (!in_array($key, <a class="code" href="sitealias_8inc.html#a4345c09c2ecb4793246075f06c146fec">drush_sitealias_site_selection_keys</a>())) {</div>
<div class="line"><a name="l00905"></a><span class="lineno">  905</span>&#160;      <span class="keywordflow">if</span> ($key[0] == <span class="charliteral">&#39;#&#39;</span>) {</div>
<div class="line"><a name="l00906"></a><span class="lineno">  906</span>&#160;        $backend_options[$key] = $value;</div>
<div class="line"><a name="l00907"></a><span class="lineno">  907</span>&#160;      }</div>
<div class="line"><a name="l00908"></a><span class="lineno">  908</span>&#160;      <span class="keywordflow">if</span> (!isset($command_options[$key])) {</div>
<div class="line"><a name="l00909"></a><span class="lineno">  909</span>&#160;        <span class="keywordflow">if</span> (array_key_exists($key, $global_option_list)) {</div>
<div class="line"><a name="l00910"></a><span class="lineno">  910</span>&#160;          $command_options[$key] = $value;</div>
<div class="line"><a name="l00911"></a><span class="lineno">  911</span>&#160;        }</div>
<div class="line"><a name="l00912"></a><span class="lineno">  912</span>&#160;      }</div>
<div class="line"><a name="l00913"></a><span class="lineno">  913</span>&#160;    }</div>
<div class="line"><a name="l00914"></a><span class="lineno">  914</span>&#160;  }</div>
<div class="line"><a name="l00915"></a><span class="lineno">  915</span>&#160;  <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;drush-local-options&#39;</span>, $backend_options)) {</div>
<div class="line"><a name="l00916"></a><span class="lineno">  916</span>&#160;    $drush_local_options = $backend_options[<span class="stringliteral">&#39;drush-local-options&#39;</span>];</div>
<div class="line"><a name="l00917"></a><span class="lineno">  917</span>&#160;    $command_options += $drush_local_options;</div>
<div class="line"><a name="l00918"></a><span class="lineno">  918</span>&#160;  }</div>
<div class="line"><a name="l00919"></a><span class="lineno">  919</span>&#160;  <span class="keywordflow">if</span> (!empty($backend_options[<span class="stringliteral">&#39;backend&#39;</span>]) &amp;&amp; empty($backend_options[<span class="stringliteral">&#39;interactive&#39;</span>]) &amp;&amp; empty($backend_options[<span class="stringliteral">&#39;fork&#39;</span>])) {</div>
<div class="line"><a name="l00920"></a><span class="lineno">  920</span>&#160;    $drush_global_options[<span class="stringliteral">&#39;backend&#39;</span>] = <span class="charliteral">&#39;2&#39;</span>;</div>
<div class="line"><a name="l00921"></a><span class="lineno">  921</span>&#160;  }</div>
<div class="line"><a name="l00922"></a><span class="lineno">  922</span>&#160;  <span class="keywordflow">foreach</span> ($command_options as $key =&gt; $value) {</div>
<div class="line"><a name="l00923"></a><span class="lineno">  923</span>&#160;    $global = array_key_exists($key, $global_option_list);</div>
<div class="line"><a name="l00924"></a><span class="lineno">  924</span>&#160;    $propagate = TRUE;</div>
<div class="line"><a name="l00925"></a><span class="lineno">  925</span>&#160;    $special = FALSE;</div>
<div class="line"><a name="l00926"></a><span class="lineno">  926</span>&#160;    <span class="keywordflow">if</span> ($global) {</div>
<div class="line"><a name="l00927"></a><span class="lineno">  927</span>&#160;      $propagate = (!array_key_exists(<span class="stringliteral">&#39;never-propagate&#39;</span>, $global_option_list[$key]));</div>
<div class="line"><a name="l00928"></a><span class="lineno">  928</span>&#160;      $special = (array_key_exists(<span class="stringliteral">&#39;never-post&#39;</span>, $global_option_list[$key]));</div>
<div class="line"><a name="l00929"></a><span class="lineno">  929</span>&#160;      <span class="keywordflow">if</span> ($propagate) {</div>
<div class="line"><a name="l00930"></a><span class="lineno">  930</span>&#160;        <span class="comment">// We will allow &#39;merge-pathlist&#39; contexts to be propogated.  Right now</span></div>
<div class="line"><a name="l00931"></a><span class="lineno">  931</span>&#160;        <span class="comment">// these are all &#39;local-context-only&#39; options; if we allowed them to</span></div>
<div class="line"><a name="l00932"></a><span class="lineno">  932</span>&#160;        <span class="comment">// propogate remotely, then we would need to get the right path separator</span></div>
<div class="line"><a name="l00933"></a><span class="lineno">  933</span>&#160;        <span class="comment">// for the remote machine.</span></div>
<div class="line"><a name="l00934"></a><span class="lineno">  934</span>&#160;        <span class="keywordflow">if</span> (is_array($value) &amp;&amp; array_key_exists(<span class="stringliteral">&#39;merge-pathlist&#39;</span>, $global_option_list[$key])) {</div>
<div class="line"><a name="l00935"></a><span class="lineno">  935</span>&#160;          $value = implode(PATH_SEPARATOR, $value);</div>
<div class="line"><a name="l00936"></a><span class="lineno">  936</span>&#160;        }</div>
<div class="line"><a name="l00937"></a><span class="lineno">  937</span>&#160;      }</div>
<div class="line"><a name="l00938"></a><span class="lineno">  938</span>&#160;    }</div>
<div class="line"><a name="l00939"></a><span class="lineno">  939</span>&#160;    <span class="comment">// Just remove options that are designated as non-propagating</span></div>
<div class="line"><a name="l00940"></a><span class="lineno">  940</span>&#160;    <span class="keywordflow">if</span> ($propagate === TRUE) {</div>
<div class="line"><a name="l00941"></a><span class="lineno">  941</span>&#160;      <span class="comment">// In METHOD POST, move command options to post options</span></div>
<div class="line"><a name="l00942"></a><span class="lineno">  942</span>&#160;      <span class="keywordflow">if</span> ($method_post &amp;&amp; ($special === FALSE)) {</div>
<div class="line"><a name="l00943"></a><span class="lineno">  943</span>&#160;        $post_options[$key] = $value;</div>
<div class="line"><a name="l00944"></a><span class="lineno">  944</span>&#160;      }</div>
<div class="line"><a name="l00945"></a><span class="lineno">  945</span>&#160;      <span class="comment">// In METHOD GET, ignore options with array values</span></div>
<div class="line"><a name="l00946"></a><span class="lineno">  946</span>&#160;      elseif (!is_array($value)) {</div>
<div class="line"><a name="l00947"></a><span class="lineno">  947</span>&#160;        <span class="keywordflow">if</span> ($global || array_key_exists($key, $additional_global_options)) {</div>
<div class="line"><a name="l00948"></a><span class="lineno">  948</span>&#160;          $drush_global_options[$key] = $value;</div>
<div class="line"><a name="l00949"></a><span class="lineno">  949</span>&#160;        }</div>
<div class="line"><a name="l00950"></a><span class="lineno">  950</span>&#160;        <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l00951"></a><span class="lineno">  951</span>&#160;          $commandline_options[$key] = $value;</div>
<div class="line"><a name="l00952"></a><span class="lineno">  952</span>&#160;        }</div>
<div class="line"><a name="l00953"></a><span class="lineno">  953</span>&#160;      }</div>
<div class="line"><a name="l00954"></a><span class="lineno">  954</span>&#160;    }</div>
<div class="line"><a name="l00955"></a><span class="lineno">  955</span>&#160;  }</div>
<div class="line"><a name="l00956"></a><span class="lineno">  956</span>&#160;  <span class="keywordflow">return</span> array($post_options, $commandline_options, $drush_global_options, $additional_backend_options);</div>
<div class="line"><a name="l00957"></a><span class="lineno">  957</span>&#160;}</div>
<div class="line"><a name="l00958"></a><span class="lineno">  958</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l00959"></a><span class="lineno">  959</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l00960"></a><span class="lineno">  960</span>&#160;<span class="comment"> * Create a new pipe with proc_open, and attempt to parse the output.</span></div>
<div class="line"><a name="l00961"></a><span class="lineno">  961</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00962"></a><span class="lineno">  962</span>&#160;<span class="comment"> * We use proc_open instead of exec or others because proc_open is best</span></div>
<div class="line"><a name="l00963"></a><span class="lineno">  963</span>&#160;<span class="comment"> * for doing bi-directional pipes, and we need to pass data over STDIN</span></div>
<div class="line"><a name="l00964"></a><span class="lineno">  964</span>&#160;<span class="comment"> * to the remote script.</span></div>
<div class="line"><a name="l00965"></a><span class="lineno">  965</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00966"></a><span class="lineno">  966</span>&#160;<span class="comment"> * Exec also seems to exhibit some strangeness in keeping the returned</span></div>
<div class="line"><a name="l00967"></a><span class="lineno">  967</span>&#160;<span class="comment"> * data intact, in that it modifies the newline characters.</span></div>
<div class="line"><a name="l00968"></a><span class="lineno">  968</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00969"></a><span class="lineno">  969</span>&#160;<span class="comment"> * @param cmd</span></div>
<div class="line"><a name="l00970"></a><span class="lineno">  970</span>&#160;<span class="comment"> *   The complete command line call to use.</span></div>
<div class="line"><a name="l00971"></a><span class="lineno">  971</span>&#160;<span class="comment"> * @param post_options</span></div>
<div class="line"><a name="l00972"></a><span class="lineno">  972</span>&#160;<span class="comment"> *   An associative array to json-encode and pass to the remote script on stdin.</span></div>
<div class="line"><a name="l00973"></a><span class="lineno">  973</span>&#160;<span class="comment"> * @param backend_options</span></div>
<div class="line"><a name="l00974"></a><span class="lineno">  974</span>&#160;<span class="comment"> *   Options for the invocation.</span></div>
<div class="line"><a name="l00975"></a><span class="lineno">  975</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l00976"></a><span class="lineno">  976</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l00977"></a><span class="lineno">  977</span>&#160;<span class="comment"> *   If the command could not be completed successfully, FALSE.</span></div>
<div class="line"><a name="l00978"></a><span class="lineno">  978</span>&#160;<span class="comment"> *   If one command was executed, this will return an associative array containing</span></div>
<div class="line"><a name="l00979"></a><span class="lineno">  979</span>&#160;<span class="comment"> *   the data from drush_backend_output().</span></div>
<div class="line"><a name="l00980"></a><span class="lineno">  980</span>&#160;<span class="comment"> *   If multiple commands were executed, this will return an associative array</span></div>
<div class="line"><a name="l00981"></a><span class="lineno">  981</span>&#160;<span class="comment"> *   containing one item, &#39;concurrent&#39;, which will contain a list of the different</span></div>
<div class="line"><a name="l00982"></a><span class="lineno">  982</span>&#160;<span class="comment"> *   backend invoke results from each concurrent command.</span></div>
<div class="line"><a name="l00983"></a><span class="lineno">  983</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l00984"></a><span class="lineno"><a class="code" href="backend_8inc.html#a1d3f3caae7e1300c53e2cc1fe4ffb932">  984</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a1d3f3caae7e1300c53e2cc1fe4ffb932">_drush_backend_invoke</a>($cmds, $common_backend_options = array(), $context = NULL) {</div>
<div class="line"><a name="l00985"></a><span class="lineno">  985</span>&#160;  <span class="keywordflow">if</span> (<a class="code" href="context_8inc.html#ad25559f8d7d753f636fbeac347c29fc5">drush_get_context</a>(<span class="stringliteral">&#39;DRUSH_SIMULATE&#39;</span>) &amp;&amp; !array_key_exists(<span class="stringliteral">&#39;override-simulated&#39;</span>, $common_backend_options) &amp;&amp; !array_key_exists(<span class="stringliteral">&#39;backend-simulate&#39;</span>, $common_backend_options)) {</div>
<div class="line"><a name="l00986"></a><span class="lineno">  986</span>&#160;    <span class="keywordflow">foreach</span> ($cmds as $cmd) {</div>
<div class="line"><a name="l00987"></a><span class="lineno">  987</span>&#160;      <a class="code" href="group__outputfunctions.html#ga63acbb94925d6d2693e235e966bba740">drush_print</a>(<a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&#39;Simulating backend invoke: !cmd&#39;</span>, array(<span class="stringliteral">&#39;!cmd&#39;</span> =&gt; $cmd[<span class="stringliteral">&#39;cmd&#39;</span>])));</div>
<div class="line"><a name="l00988"></a><span class="lineno">  988</span>&#160;    }</div>
<div class="line"><a name="l00989"></a><span class="lineno">  989</span>&#160;    <span class="keywordflow">return</span> FALSE;</div>
<div class="line"><a name="l00990"></a><span class="lineno">  990</span>&#160;  }</div>
<div class="line"><a name="l00991"></a><span class="lineno">  991</span>&#160;  <span class="keywordflow">foreach</span> ($cmds as $cmd) {</div>
<div class="line"><a name="l00992"></a><span class="lineno">  992</span>&#160;    <a class="code" href="group__logging.html#gad820f489a93518301794ada4ff7816b6">drush_log</a>(<a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&#39;Backend invoke: !cmd&#39;</span>, array(<span class="stringliteral">&#39;!cmd&#39;</span> =&gt; $cmd[<span class="stringliteral">&#39;cmd&#39;</span>])), <span class="stringliteral">&#39;command&#39;</span>);</div>
<div class="line"><a name="l00993"></a><span class="lineno">  993</span>&#160;  }</div>
<div class="line"><a name="l00994"></a><span class="lineno">  994</span>&#160;  <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;interactive&#39;</span>, $common_backend_options) || array_key_exists(<span class="stringliteral">&#39;fork&#39;</span>, $common_backend_options)) {</div>
<div class="line"><a name="l00995"></a><span class="lineno">  995</span>&#160;    <span class="keywordflow">foreach</span> ($cmds as $cmd) {</div>
<div class="line"><a name="l00996"></a><span class="lineno">  996</span>&#160;      $exec_cmd = $cmd[<span class="stringliteral">&#39;cmd&#39;</span>];</div>
<div class="line"><a name="l00997"></a><span class="lineno">  997</span>&#160;      <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;fork&#39;</span>, $common_backend_options)) {</div>
<div class="line"><a name="l00998"></a><span class="lineno">  998</span>&#160;        $exec_cmd .= <span class="stringliteral">&#39; --quiet &amp;&#39;</span>;</div>
<div class="line"><a name="l00999"></a><span class="lineno">  999</span>&#160;      }</div>
<div class="line"><a name="l01000"></a><span class="lineno"> 1000</span>&#160;      $ret = <a class="code" href="group__commandwrappers.html#ga3a1bb3ae751f14749ce1dbe4ec9c3288">drush_shell_proc_open</a>($exec_cmd);</div>
<div class="line"><a name="l01001"></a><span class="lineno"> 1001</span>&#160;    }</div>
<div class="line"><a name="l01002"></a><span class="lineno"> 1002</span>&#160;    <span class="keywordflow">return</span> $ret;</div>
<div class="line"><a name="l01003"></a><span class="lineno"> 1003</span>&#160;  }</div>
<div class="line"><a name="l01004"></a><span class="lineno"> 1004</span>&#160;  <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l01005"></a><span class="lineno"> 1005</span>&#160;    $process_limit = <a class="code" href="context_8inc.html#a559008f6decb23108b83e704208e415e">drush_get_option_override</a>($common_backend_options, <span class="stringliteral">&#39;concurrency&#39;</span>, 1);</div>
<div class="line"><a name="l01006"></a><span class="lineno"> 1006</span>&#160;    $procs = <a class="code" href="backend_8inc.html#aad736c236f213abc274709f79e41edf7">_drush_backend_proc_open</a>($cmds, $process_limit, $context);</div>
<div class="line"><a name="l01007"></a><span class="lineno"> 1007</span>&#160;    $procs = is_array($procs) ? $procs : array($procs);</div>
<div class="line"><a name="l01008"></a><span class="lineno"> 1008</span>&#160;</div>
<div class="line"><a name="l01009"></a><span class="lineno"> 1009</span>&#160;    $ret = array();</div>
<div class="line"><a name="l01010"></a><span class="lineno"> 1010</span>&#160;    <span class="keywordflow">foreach</span> ($procs as $site =&gt; $proc) {</div>
<div class="line"><a name="l01011"></a><span class="lineno"> 1011</span>&#160;      <span class="keywordflow">if</span> (($proc[<span class="stringliteral">&#39;code&#39;</span>] == <a class="code" href="drush_8inc.html#ad2cac2311a09943e8f911c2d13167c4a">DRUSH_APPLICATION_ERROR</a>) &amp;&amp; isset($common_backend_options[<span class="stringliteral">&#39;integrate&#39;</span>])) {</div>
<div class="line"><a name="l01012"></a><span class="lineno"> 1012</span>&#160;        <a class="code" href="group__errorhandling.html#ga23fe9e1e8c1e5ade39256106044b6da4">drush_set_error</a>(<span class="stringliteral">&#39;DRUSH_APPLICATION_ERROR&#39;</span>, <a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;The external command could not be executed due to an application error.&quot;</span>));</div>
<div class="line"><a name="l01013"></a><span class="lineno"> 1013</span>&#160;      }</div>
<div class="line"><a name="l01014"></a><span class="lineno"> 1014</span>&#160;</div>
<div class="line"><a name="l01015"></a><span class="lineno"> 1015</span>&#160;      <span class="keywordflow">if</span> ($proc[<span class="stringliteral">&#39;output&#39;</span>]) {</div>
<div class="line"><a name="l01016"></a><span class="lineno"> 1016</span>&#160;        $values = <a class="code" href="backend_8inc.html#a31be2d52e209d3e6ac359e971cf1fd7b">drush_backend_parse_output</a>($proc[<span class="stringliteral">&#39;output&#39;</span>], $proc[<span class="stringliteral">&#39;backend-options&#39;</span>], $proc[<span class="stringliteral">&#39;outputted&#39;</span>]);</div>
<div class="line"><a name="l01017"></a><span class="lineno"> 1017</span>&#160;        $values[<span class="stringliteral">&#39;site&#39;</span>] = $site;</div>
<div class="line"><a name="l01018"></a><span class="lineno"> 1018</span>&#160;        <span class="keywordflow">if</span> (is_array($values)) {</div>
<div class="line"><a name="l01019"></a><span class="lineno"> 1019</span>&#160;          <span class="keywordflow">if</span> (empty($ret)) {</div>
<div class="line"><a name="l01020"></a><span class="lineno"> 1020</span>&#160;            $ret = $values;</div>
<div class="line"><a name="l01021"></a><span class="lineno"> 1021</span>&#160;          }</div>
<div class="line"><a name="l01022"></a><span class="lineno"> 1022</span>&#160;          elseif (!array_key_exists(<span class="stringliteral">&#39;concurrent&#39;</span>, $ret)) {</div>
<div class="line"><a name="l01023"></a><span class="lineno"> 1023</span>&#160;            $ret = array(<span class="stringliteral">&#39;concurrent&#39;</span> =&gt; array($ret, $values));</div>
<div class="line"><a name="l01024"></a><span class="lineno"> 1024</span>&#160;          }</div>
<div class="line"><a name="l01025"></a><span class="lineno"> 1025</span>&#160;          <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l01026"></a><span class="lineno"> 1026</span>&#160;            $ret[<span class="stringliteral">&#39;concurrent&#39;</span>][] = $values;</div>
<div class="line"><a name="l01027"></a><span class="lineno"> 1027</span>&#160;          }</div>
<div class="line"><a name="l01028"></a><span class="lineno"> 1028</span>&#160;        }</div>
<div class="line"><a name="l01029"></a><span class="lineno"> 1029</span>&#160;        <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l01030"></a><span class="lineno"> 1030</span>&#160;          $ret = <a class="code" href="group__errorhandling.html#ga23fe9e1e8c1e5ade39256106044b6da4">drush_set_error</a>(<span class="stringliteral">&#39;DRUSH_FRAMEWORK_ERROR&#39;</span>, <a class="code" href="group__outputfunctions.html#ga1218abcb1e27dd3bb412113d1e344d96">dt</a>(<span class="stringliteral">&quot;The command could not be executed successfully (returned: !return, code: !code)&quot;</span>, array(<span class="stringliteral">&quot;!return&quot;</span> =&gt; $proc[<span class="stringliteral">&#39;output&#39;</span>], <span class="stringliteral">&quot;!code&quot;</span> =&gt;  $proc[<span class="stringliteral">&#39;code&#39;</span>])));</div>
<div class="line"><a name="l01031"></a><span class="lineno"> 1031</span>&#160;        }</div>
<div class="line"><a name="l01032"></a><span class="lineno"> 1032</span>&#160;      }</div>
<div class="line"><a name="l01033"></a><span class="lineno"> 1033</span>&#160;    }</div>
<div class="line"><a name="l01034"></a><span class="lineno"> 1034</span>&#160;  }</div>
<div class="line"><a name="l01035"></a><span class="lineno"> 1035</span>&#160;  <span class="keywordflow">return</span> empty($ret) ? FALSE : $ret;</div>
<div class="line"><a name="l01036"></a><span class="lineno"> 1036</span>&#160;}</div>
<div class="line"><a name="l01037"></a><span class="lineno"> 1037</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l01038"></a><span class="lineno"> 1038</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l01039"></a><span class="lineno"> 1039</span>&#160;<span class="comment"> * Helper function that generates an anonymous site alias specification for</span></div>
<div class="line"><a name="l01040"></a><span class="lineno"> 1040</span>&#160;<span class="comment"> * the given parameters.</span></div>
<div class="line"><a name="l01041"></a><span class="lineno"> 1041</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l01042"></a><span class="lineno"><a class="code" href="backend_8inc.html#ae4c4323460af25cdfe11551030f76fce"> 1042</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#ae4c4323460af25cdfe11551030f76fce">drush_backend_generate_sitealias</a>($backend_options) {</div>
<div class="line"><a name="l01043"></a><span class="lineno"> 1043</span>&#160;  <span class="comment">// Ensure default values.</span></div>
<div class="line"><a name="l01044"></a><span class="lineno"> 1044</span>&#160;  $backend_options += array(</div>
<div class="line"><a name="l01045"></a><span class="lineno"> 1045</span>&#160;    <span class="stringliteral">&#39;remote-host&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01046"></a><span class="lineno"> 1046</span>&#160;    <span class="stringliteral">&#39;remote-user&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01047"></a><span class="lineno"> 1047</span>&#160;    <span class="stringliteral">&#39;ssh-options&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01048"></a><span class="lineno"> 1048</span>&#160;    <span class="stringliteral">&#39;drush-script&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01049"></a><span class="lineno"> 1049</span>&#160;  );</div>
<div class="line"><a name="l01050"></a><span class="lineno"> 1050</span>&#160;  <span class="keywordflow">return</span> array(</div>
<div class="line"><a name="l01051"></a><span class="lineno"> 1051</span>&#160;    <span class="stringliteral">&#39;remote-host&#39;</span> =&gt; $backend_options[<span class="stringliteral">&#39;remote-host&#39;</span>],</div>
<div class="line"><a name="l01052"></a><span class="lineno"> 1052</span>&#160;    <span class="stringliteral">&#39;remote-user&#39;</span> =&gt; $backend_options[<span class="stringliteral">&#39;remote-user&#39;</span>],</div>
<div class="line"><a name="l01053"></a><span class="lineno"> 1053</span>&#160;    <span class="stringliteral">&#39;ssh-options&#39;</span> =&gt; $backend_options[<span class="stringliteral">&#39;ssh-options&#39;</span>],</div>
<div class="line"><a name="l01054"></a><span class="lineno"> 1054</span>&#160;    <span class="stringliteral">&#39;path-aliases&#39;</span> =&gt; array(</div>
<div class="line"><a name="l01055"></a><span class="lineno"> 1055</span>&#160;      <span class="stringliteral">&#39;%drush-script&#39;</span> =&gt; $backend_options[<span class="stringliteral">&#39;drush-script&#39;</span>],</div>
<div class="line"><a name="l01056"></a><span class="lineno"> 1056</span>&#160;    ),</div>
<div class="line"><a name="l01057"></a><span class="lineno"> 1057</span>&#160;  );</div>
<div class="line"><a name="l01058"></a><span class="lineno"> 1058</span>&#160;}</div>
<div class="line"><a name="l01059"></a><span class="lineno"> 1059</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l01060"></a><span class="lineno"> 1060</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l01061"></a><span class="lineno"> 1061</span>&#160;<span class="comment"> * Generate a command to execute.</span></div>
<div class="line"><a name="l01062"></a><span class="lineno"> 1062</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01063"></a><span class="lineno"> 1063</span>&#160;<span class="comment"> * @param site_record</span></div>
<div class="line"><a name="l01064"></a><span class="lineno"> 1064</span>&#160;<span class="comment"> *   An array containing information used to generate the command.</span></div>
<div class="line"><a name="l01065"></a><span class="lineno"> 1065</span>&#160;<span class="comment"> *   &#39;remote-host&#39;</span></div>
<div class="line"><a name="l01066"></a><span class="lineno"> 1066</span>&#160;<span class="comment"> *      Optional. A remote host to execute the drush command on.</span></div>
<div class="line"><a name="l01067"></a><span class="lineno"> 1067</span>&#160;<span class="comment"> *   &#39;remote-user&#39;</span></div>
<div class="line"><a name="l01068"></a><span class="lineno"> 1068</span>&#160;<span class="comment"> *      Optional. Defaults to the current user. If you specify this, you can choose which module to send.</span></div>
<div class="line"><a name="l01069"></a><span class="lineno"> 1069</span>&#160;<span class="comment"> *   &#39;ssh-options&#39;</span></div>
<div class="line"><a name="l01070"></a><span class="lineno"> 1070</span>&#160;<span class="comment"> *      Optional.  Defaults to &quot;-o PasswordAuthentication=no&quot;</span></div>
<div class="line"><a name="l01071"></a><span class="lineno"> 1071</span>&#160;<span class="comment"> *   &#39;path-aliases&#39;</span></div>
<div class="line"><a name="l01072"></a><span class="lineno"> 1072</span>&#160;<span class="comment"> *      Optional; contains paths to folders and executables useful to the command.</span></div>
<div class="line"><a name="l01073"></a><span class="lineno"> 1073</span>&#160;<span class="comment"> *      &#39;%drush-script&#39;</span></div>
<div class="line"><a name="l01074"></a><span class="lineno"> 1074</span>&#160;<span class="comment"> *        Optional. Defaults to the current drush.php file on the local machine, and</span></div>
<div class="line"><a name="l01075"></a><span class="lineno"> 1075</span>&#160;<span class="comment"> *        to simply &#39;drush&#39; (the drush script in the current PATH) on remote servers.</span></div>
<div class="line"><a name="l01076"></a><span class="lineno"> 1076</span>&#160;<span class="comment"> *        You may also specify a different drush.php script explicitly.  You will need</span></div>
<div class="line"><a name="l01077"></a><span class="lineno"> 1077</span>&#160;<span class="comment"> *        to set this when calling drush on a remote server if &#39;drush&#39; is not in the</span></div>
<div class="line"><a name="l01078"></a><span class="lineno"> 1078</span>&#160;<span class="comment"> *        PATH on that machine.</span></div>
<div class="line"><a name="l01079"></a><span class="lineno"> 1079</span>&#160;<span class="comment"> * @param command</span></div>
<div class="line"><a name="l01080"></a><span class="lineno"> 1080</span>&#160;<span class="comment"> *    A defined drush command such as &#39;cron&#39;, &#39;status&#39; or any of the available ones such as &#39;drush pm&#39;.</span></div>
<div class="line"><a name="l01081"></a><span class="lineno"> 1081</span>&#160;<span class="comment"> * @param args</span></div>
<div class="line"><a name="l01082"></a><span class="lineno"> 1082</span>&#160;<span class="comment"> *    An array of arguments for the command.</span></div>
<div class="line"><a name="l01083"></a><span class="lineno"> 1083</span>&#160;<span class="comment"> * @param command_options</span></div>
<div class="line"><a name="l01084"></a><span class="lineno"> 1084</span>&#160;<span class="comment"> *    Optional. An array containing options to pass to the remote script.</span></div>
<div class="line"><a name="l01085"></a><span class="lineno"> 1085</span>&#160;<span class="comment"> *    Array items with a numeric key are treated as optional arguments to the</span></div>
<div class="line"><a name="l01086"></a><span class="lineno"> 1086</span>&#160;<span class="comment"> *    command.  This parameter is a reference, as any options that have been</span></div>
<div class="line"><a name="l01087"></a><span class="lineno"> 1087</span>&#160;<span class="comment"> *    represented as either an option, or an argument will be removed.  This</span></div>
<div class="line"><a name="l01088"></a><span class="lineno"> 1088</span>&#160;<span class="comment"> *    allows you to pass the left over options as a JSON encoded string,</span></div>
<div class="line"><a name="l01089"></a><span class="lineno"> 1089</span>&#160;<span class="comment"> *    without duplicating data.</span></div>
<div class="line"><a name="l01090"></a><span class="lineno"> 1090</span>&#160;<span class="comment"> * @param backend_options</span></div>
<div class="line"><a name="l01091"></a><span class="lineno"> 1091</span>&#160;<span class="comment"> *    Optional. An array of options for the invocation.</span></div>
<div class="line"><a name="l01092"></a><span class="lineno"> 1092</span>&#160;<span class="comment"> *    @see drush_backend_invoke for documentation.</span></div>
<div class="line"><a name="l01093"></a><span class="lineno"> 1093</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01094"></a><span class="lineno"> 1094</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l01095"></a><span class="lineno"> 1095</span>&#160;<span class="comment"> *   A text string representing a fully escaped command.</span></div>
<div class="line"><a name="l01096"></a><span class="lineno"> 1096</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l01097"></a><span class="lineno"><a class="code" href="backend_8inc.html#aa9bff3ffcd61a4dd945b567057a54e5d"> 1097</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#aa9bff3ffcd61a4dd945b567057a54e5d">_drush_backend_generate_command</a>($site_record, $command, $args = array(), $command_options = array(), $backend_options = array()) {</div>
<div class="line"><a name="l01098"></a><span class="lineno"> 1098</span>&#160;  $site_record += array(</div>
<div class="line"><a name="l01099"></a><span class="lineno"> 1099</span>&#160;    <span class="stringliteral">&#39;remote-host&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01100"></a><span class="lineno"> 1100</span>&#160;    <span class="stringliteral">&#39;remote-user&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01101"></a><span class="lineno"> 1101</span>&#160;    <span class="stringliteral">&#39;ssh-options&#39;</span> =&gt; NULL,</div>
<div class="line"><a name="l01102"></a><span class="lineno"> 1102</span>&#160;    <span class="stringliteral">&#39;path-aliases&#39;</span> =&gt; array(),</div>
<div class="line"><a name="l01103"></a><span class="lineno"> 1103</span>&#160;  );</div>
<div class="line"><a name="l01104"></a><span class="lineno"> 1104</span>&#160;  $backend_options += array(</div>
<div class="line"><a name="l01105"></a><span class="lineno"> 1105</span>&#160;    <span class="stringliteral">&#39;#tty&#39;</span> =&gt; FALSE,</div>
<div class="line"><a name="l01106"></a><span class="lineno"> 1106</span>&#160;  );</div>
<div class="line"><a name="l01107"></a><span class="lineno"> 1107</span>&#160;</div>
<div class="line"><a name="l01108"></a><span class="lineno"> 1108</span>&#160;  $hostname = $site_record[<span class="stringliteral">&#39;remote-host&#39;</span>];</div>
<div class="line"><a name="l01109"></a><span class="lineno"> 1109</span>&#160;  $username = $site_record[<span class="stringliteral">&#39;remote-user&#39;</span>];</div>
<div class="line"><a name="l01110"></a><span class="lineno"> 1110</span>&#160;  $ssh_options = $site_record[<span class="stringliteral">&#39;ssh-options&#39;</span>];</div>
<div class="line"><a name="l01111"></a><span class="lineno"> 1111</span>&#160;  $os = <a class="code" href="group__commandwrappers.html#ga1292121e5bdd4bf19ef4f944b16301ed">drush_os</a>($site_record);</div>
<div class="line"><a name="l01112"></a><span class="lineno"> 1112</span>&#160;</div>
<div class="line"><a name="l01113"></a><span class="lineno"> 1113</span>&#160;  <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;#check-local&#39;</span>, $site_record) &amp;&amp; <a class="code" href="includes_2environment_8inc.html#a395834ff6c51946c9c8a0953aa8f539f">drush_is_local_host</a>($hostname)) {</div>
<div class="line"><a name="l01114"></a><span class="lineno"> 1114</span>&#160;    $hostname = null;</div>
<div class="line"><a name="l01115"></a><span class="lineno"> 1115</span>&#160;  }</div>
<div class="line"><a name="l01116"></a><span class="lineno"> 1116</span>&#160;</div>
<div class="line"><a name="l01117"></a><span class="lineno"> 1117</span>&#160;  <span class="keywordflow">foreach</span> ($command_options as $key =&gt; $arg) {</div>
<div class="line"><a name="l01118"></a><span class="lineno"> 1118</span>&#160;    <span class="keywordflow">if</span> (is_numeric($key)) {</div>
<div class="line"><a name="l01119"></a><span class="lineno"> 1119</span>&#160;      $args[] = $arg;</div>
<div class="line"><a name="l01120"></a><span class="lineno"> 1120</span>&#160;      unset($command_options[$key]);</div>
<div class="line"><a name="l01121"></a><span class="lineno"> 1121</span>&#160;    }</div>
<div class="line"><a name="l01122"></a><span class="lineno"> 1122</span>&#160;  }</div>
<div class="line"><a name="l01123"></a><span class="lineno"> 1123</span>&#160;</div>
<div class="line"><a name="l01124"></a><span class="lineno"> 1124</span>&#160;  $cmd[] = $command;</div>
<div class="line"><a name="l01125"></a><span class="lineno"> 1125</span>&#160;  <span class="keywordflow">foreach</span> ($args as $arg) {</div>
<div class="line"><a name="l01126"></a><span class="lineno"> 1126</span>&#160;    $cmd[] = <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($arg, $os);</div>
<div class="line"><a name="l01127"></a><span class="lineno"> 1127</span>&#160;  }</div>
<div class="line"><a name="l01128"></a><span class="lineno"> 1128</span>&#160;  $option_str = <a class="code" href="backend_8inc.html#ad19c067bfbd87dfc63c55659723aaf60">_drush_backend_argument_string</a>($command_options, $os);</div>
<div class="line"><a name="l01129"></a><span class="lineno"> 1129</span>&#160;  <span class="keywordflow">if</span> (!empty($option_str)) {</div>
<div class="line"><a name="l01130"></a><span class="lineno"> 1130</span>&#160;    $cmd[] = <span class="stringliteral">&quot; &quot;</span> . $option_str;</div>
<div class="line"><a name="l01131"></a><span class="lineno"> 1131</span>&#160;  }</div>
<div class="line"><a name="l01132"></a><span class="lineno"> 1132</span>&#160;  $command = implode(<span class="charliteral">&#39; &#39;</span>, array_filter($cmd, <span class="stringliteral">&#39;strlen&#39;</span>));</div>
<div class="line"><a name="l01133"></a><span class="lineno"> 1133</span>&#160;  <span class="keywordflow">if</span> (isset($hostname)) {</div>
<div class="line"><a name="l01134"></a><span class="lineno"> 1134</span>&#160;    <span class="keywordflow">if</span> (<a class="code" href="includes_2environment_8inc.html#a88114295372bcb0ca8dbb5f10b36368e">drush_is_windows</a>($os)) {</div>
<div class="line"><a name="l01135"></a><span class="lineno"> 1135</span>&#160;      <span class="keywordflow">if</span> (isset($username)) {</div>
<div class="line"><a name="l01136"></a><span class="lineno"> 1136</span>&#160;        $username = <span class="stringliteral">&quot; -u:&quot;</span> . <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($username, <span class="stringliteral">&quot;LOCAL&quot;</span>);</div>
<div class="line"><a name="l01137"></a><span class="lineno"> 1137</span>&#160;        <span class="keywordflow">if</span> (array_key_exists(<span class="stringliteral">&#39;winrs-password&#39;</span>, $site_record)) {</div>
<div class="line"><a name="l01138"></a><span class="lineno"> 1138</span>&#160;          $username .= <span class="stringliteral">&quot; -p:&quot;</span> . <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($site_record[<span class="stringliteral">&#39;winrs-password&#39;</span>], <span class="stringliteral">&quot;LOCAL&quot;</span>);</div>
<div class="line"><a name="l01139"></a><span class="lineno"> 1139</span>&#160;        }</div>
<div class="line"><a name="l01140"></a><span class="lineno"> 1140</span>&#160;      }</div>
<div class="line"><a name="l01141"></a><span class="lineno"> 1141</span>&#160;      $command = <span class="stringliteral">&quot;winrs&quot;</span> . $username . <span class="stringliteral">&quot; -r:&quot;</span> . <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($hostname, <span class="stringliteral">&quot;LOCAL&quot;</span>) . <span class="stringliteral">&quot; &quot;</span> . <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($command, <span class="stringliteral">&quot;LOCAL&quot;</span>);</div>
<div class="line"><a name="l01142"></a><span class="lineno"> 1142</span>&#160;    }</div>
<div class="line"><a name="l01143"></a><span class="lineno"> 1143</span>&#160;    <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l01144"></a><span class="lineno"> 1144</span>&#160;      $username = (isset($username)) ? <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($username, <span class="stringliteral">&quot;LOCAL&quot;</span>) . <span class="stringliteral">&quot;@&quot;</span> : <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l01145"></a><span class="lineno"> 1145</span>&#160;      $ssh_options = $site_record[<span class="stringliteral">&#39;ssh-options&#39;</span>];</div>
<div class="line"><a name="l01146"></a><span class="lineno"> 1146</span>&#160;      $ssh_options = (isset($ssh_options)) ? $ssh_options : <a class="code" href="context_8inc.html#afe91fb3e5219ecb2208c3b036b1f0cb8">drush_get_option</a>(<span class="stringliteral">&#39;ssh-options&#39;</span>, <span class="stringliteral">&quot;-o PasswordAuthentication=no&quot;</span>);</div>
<div class="line"><a name="l01147"></a><span class="lineno"> 1147</span>&#160;</div>
<div class="line"><a name="l01148"></a><span class="lineno"> 1148</span>&#160;      $ssh_cmd[] = <span class="stringliteral">&quot;ssh&quot;</span>;</div>
<div class="line"><a name="l01149"></a><span class="lineno"> 1149</span>&#160;      $ssh_cmd[] = $ssh_options;</div>
<div class="line"><a name="l01150"></a><span class="lineno"> 1150</span>&#160;      <span class="keywordflow">if</span> ($backend_options[<span class="stringliteral">&#39;#tty&#39;</span>]) {</div>
<div class="line"><a name="l01151"></a><span class="lineno"> 1151</span>&#160;        $ssh_cmd[] = <span class="stringliteral">&#39;-t&#39;</span>;</div>
<div class="line"><a name="l01152"></a><span class="lineno"> 1152</span>&#160;      }</div>
<div class="line"><a name="l01153"></a><span class="lineno"> 1153</span>&#160;      $ssh_cmd[] = $username . <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($hostname, <span class="stringliteral">&quot;LOCAL&quot;</span>);</div>
<div class="line"><a name="l01154"></a><span class="lineno"> 1154</span>&#160;      $ssh_cmd[] = <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($command . <span class="stringliteral">&#39; 2&gt;&amp;1&#39;</span>, <span class="stringliteral">&quot;LOCAL&quot;</span>);</div>
<div class="line"><a name="l01155"></a><span class="lineno"> 1155</span>&#160;</div>
<div class="line"><a name="l01156"></a><span class="lineno"> 1156</span>&#160;      <span class="comment">// Remove NULLs and separate with spaces</span></div>
<div class="line"><a name="l01157"></a><span class="lineno"> 1157</span>&#160;      $command = implode(<span class="charliteral">&#39; &#39;</span>, array_filter($ssh_cmd, <span class="stringliteral">&#39;strlen&#39;</span>));</div>
<div class="line"><a name="l01158"></a><span class="lineno"> 1158</span>&#160;    }</div>
<div class="line"><a name="l01159"></a><span class="lineno"> 1159</span>&#160;  }</div>
<div class="line"><a name="l01160"></a><span class="lineno"> 1160</span>&#160;</div>
<div class="line"><a name="l01161"></a><span class="lineno"> 1161</span>&#160;  <span class="keywordflow">return</span> $command;</div>
<div class="line"><a name="l01162"></a><span class="lineno"> 1162</span>&#160;}</div>
<div class="line"><a name="l01163"></a><span class="lineno"> 1163</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l01164"></a><span class="lineno"> 1164</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l01165"></a><span class="lineno"> 1165</span>&#160;<span class="comment"> * Map the options to a string containing all the possible arguments and options.</span></div>
<div class="line"><a name="l01166"></a><span class="lineno"> 1166</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01167"></a><span class="lineno"> 1167</span>&#160;<span class="comment"> * @param data</span></div>
<div class="line"><a name="l01168"></a><span class="lineno"> 1168</span>&#160;<span class="comment"> *    Optional. An array containing options to pass to the remote script.</span></div>
<div class="line"><a name="l01169"></a><span class="lineno"> 1169</span>&#160;<span class="comment"> *    Array items with a numeric key are treated as optional arguments to the command.</span></div>
<div class="line"><a name="l01170"></a><span class="lineno"> 1170</span>&#160;<span class="comment"> *    This parameter is a reference, as any options that have been represented as either an option, or an argument will be removed.</span></div>
<div class="line"><a name="l01171"></a><span class="lineno"> 1171</span>&#160;<span class="comment"> *    This allows you to pass the left over options as a JSON encoded string, without duplicating data.</span></div>
<div class="line"><a name="l01172"></a><span class="lineno"> 1172</span>&#160;<span class="comment"> * @param method</span></div>
<div class="line"><a name="l01173"></a><span class="lineno"> 1173</span>&#160;<span class="comment"> *    Optional. Defaults to &#39;GET&#39;.</span></div>
<div class="line"><a name="l01174"></a><span class="lineno"> 1174</span>&#160;<span class="comment"> *    If this parameter is set to &#39;POST&#39;, the $data array will be passed to the script being called as a JSON encoded string over</span></div>
<div class="line"><a name="l01175"></a><span class="lineno"> 1175</span>&#160;<span class="comment"> *    the STDIN pipe of that process. This is preferable if you have to pass sensitive data such as passwords and the like.</span></div>
<div class="line"><a name="l01176"></a><span class="lineno"> 1176</span>&#160;<span class="comment"> *    For any other value, the $data array will be collapsed down into a set of command line options to the script.</span></div>
<div class="line"><a name="l01177"></a><span class="lineno"> 1177</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l01178"></a><span class="lineno"> 1178</span>&#160;<span class="comment"> *    A properly formatted and escaped set of arguments and options to append to the drush.php shell command.</span></div>
<div class="line"><a name="l01179"></a><span class="lineno"> 1179</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l01180"></a><span class="lineno"><a class="code" href="backend_8inc.html#ad19c067bfbd87dfc63c55659723aaf60"> 1180</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#ad19c067bfbd87dfc63c55659723aaf60">_drush_backend_argument_string</a>($data, $os = NULL) {</div>
<div class="line"><a name="l01181"></a><span class="lineno"> 1181</span>&#160;  $options = array();</div>
<div class="line"><a name="l01182"></a><span class="lineno"> 1182</span>&#160;</div>
<div class="line"><a name="l01183"></a><span class="lineno"> 1183</span>&#160;  <span class="keywordflow">foreach</span> ($data as $key =&gt; $value) {</div>
<div class="line"><a name="l01184"></a><span class="lineno"> 1184</span>&#160;    <span class="keywordflow">if</span> (!is_array($value) &amp;&amp; !is_object($value) &amp;&amp; isset($value)) {</div>
<div class="line"><a name="l01185"></a><span class="lineno"> 1185</span>&#160;      <span class="keywordflow">if</span> (substr($key,0,1) != <span class="charliteral">&#39;#&#39;</span>) {</div>
<div class="line"><a name="l01186"></a><span class="lineno"> 1186</span>&#160;        $options[$key] = $value;</div>
<div class="line"><a name="l01187"></a><span class="lineno"> 1187</span>&#160;      }</div>
<div class="line"><a name="l01188"></a><span class="lineno"> 1188</span>&#160;    }</div>
<div class="line"><a name="l01189"></a><span class="lineno"> 1189</span>&#160;  }</div>
<div class="line"><a name="l01190"></a><span class="lineno"> 1190</span>&#160;</div>
<div class="line"><a name="l01191"></a><span class="lineno"> 1191</span>&#160;  $option_str = <span class="stringliteral">&#39;&#39;</span>;</div>
<div class="line"><a name="l01192"></a><span class="lineno"> 1192</span>&#160;  <span class="keywordflow">foreach</span> ($options as $key =&gt; $value) {</div>
<div class="line"><a name="l01193"></a><span class="lineno"> 1193</span>&#160;    $option_str .= <a class="code" href="backend_8inc.html#a76fe1964075bf89898a79d07885dcacf">_drush_escape_option</a>($key, $value, $os);</div>
<div class="line"><a name="l01194"></a><span class="lineno"> 1194</span>&#160;  }</div>
<div class="line"><a name="l01195"></a><span class="lineno"> 1195</span>&#160;</div>
<div class="line"><a name="l01196"></a><span class="lineno"> 1196</span>&#160;  <span class="keywordflow">return</span> $option_str;</div>
<div class="line"><a name="l01197"></a><span class="lineno"> 1197</span>&#160;}</div>
<div class="line"><a name="l01198"></a><span class="lineno"> 1198</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l01199"></a><span class="lineno"> 1199</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l01200"></a><span class="lineno"> 1200</span>&#160;<span class="comment"> * Return a properly formatted and escaped command line option</span></div>
<div class="line"><a name="l01201"></a><span class="lineno"> 1201</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01202"></a><span class="lineno"> 1202</span>&#160;<span class="comment"> * @param key</span></div>
<div class="line"><a name="l01203"></a><span class="lineno"> 1203</span>&#160;<span class="comment"> *   The name of the option.</span></div>
<div class="line"><a name="l01204"></a><span class="lineno"> 1204</span>&#160;<span class="comment"> * @param value</span></div>
<div class="line"><a name="l01205"></a><span class="lineno"> 1205</span>&#160;<span class="comment"> *   The value of the option.</span></div>
<div class="line"><a name="l01206"></a><span class="lineno"> 1206</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01207"></a><span class="lineno"> 1207</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l01208"></a><span class="lineno"> 1208</span>&#160;<span class="comment"> *   If the value is set to TRUE, this function will return &quot; --key&quot;</span></div>
<div class="line"><a name="l01209"></a><span class="lineno"> 1209</span>&#160;<span class="comment"> *   In other cases it will return &quot; --key=&#39;value&#39;&quot;</span></div>
<div class="line"><a name="l01210"></a><span class="lineno"> 1210</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l01211"></a><span class="lineno"><a class="code" href="backend_8inc.html#a76fe1964075bf89898a79d07885dcacf"> 1211</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a76fe1964075bf89898a79d07885dcacf">_drush_escape_option</a>($key, $value = TRUE, $os = NULL) {</div>
<div class="line"><a name="l01212"></a><span class="lineno"> 1212</span>&#160;  <span class="keywordflow">if</span> ($value !== TRUE) {</div>
<div class="line"><a name="l01213"></a><span class="lineno"> 1213</span>&#160;    $option_str = <span class="stringliteral">&quot; --$key=&quot;</span> . <a class="code" href="group__commandwrappers.html#gafc52f7e769d935b4d2462467cdf8d5ee">drush_escapeshellarg</a>($value, $os);</div>
<div class="line"><a name="l01214"></a><span class="lineno"> 1214</span>&#160;  }</div>
<div class="line"><a name="l01215"></a><span class="lineno"> 1215</span>&#160;  <span class="keywordflow">else</span> {</div>
<div class="line"><a name="l01216"></a><span class="lineno"> 1216</span>&#160;    $option_str = <span class="stringliteral">&quot; --$key&quot;</span>;</div>
<div class="line"><a name="l01217"></a><span class="lineno"> 1217</span>&#160;  }</div>
<div class="line"><a name="l01218"></a><span class="lineno"> 1218</span>&#160;  <span class="keywordflow">return</span> $option_str;</div>
<div class="line"><a name="l01219"></a><span class="lineno"> 1219</span>&#160;}</div>
<div class="line"><a name="l01220"></a><span class="lineno"> 1220</span>&#160;<span class="comment"></span></div>
<div class="line"><a name="l01221"></a><span class="lineno"> 1221</span>&#160;<span class="comment">/**</span></div>
<div class="line"><a name="l01222"></a><span class="lineno"> 1222</span>&#160;<span class="comment"> * Read options fron STDIN during POST requests.</span></div>
<div class="line"><a name="l01223"></a><span class="lineno"> 1223</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01224"></a><span class="lineno"> 1224</span>&#160;<span class="comment"> * This function will read any text from the STDIN pipe,</span></div>
<div class="line"><a name="l01225"></a><span class="lineno"> 1225</span>&#160;<span class="comment"> * and attempts to generate an associative array if valid</span></div>
<div class="line"><a name="l01226"></a><span class="lineno"> 1226</span>&#160;<span class="comment"> * JSON was received.</span></div>
<div class="line"><a name="l01227"></a><span class="lineno"> 1227</span>&#160;<span class="comment"> *</span></div>
<div class="line"><a name="l01228"></a><span class="lineno"> 1228</span>&#160;<span class="comment"> * @return</span></div>
<div class="line"><a name="l01229"></a><span class="lineno"> 1229</span>&#160;<span class="comment"> *   An associative array of options, if successfull. Otherwise FALSE.</span></div>
<div class="line"><a name="l01230"></a><span class="lineno"> 1230</span>&#160;<span class="comment"> */</span></div>
<div class="line"><a name="l01231"></a><span class="lineno"><a class="code" href="backend_8inc.html#a4b057a86151c5b6ee4ca67022ee864e4"> 1231</a></span>&#160;<span class="keyword">function</span> <a class="code" href="backend_8inc.html#a4b057a86151c5b6ee4ca67022ee864e4">_drush_backend_get_stdin</a>() {</div>
<div class="line"><a name="l01232"></a><span class="lineno"> 1232</span>&#160;  $fp = fopen(<span class="stringliteral">&#39;php://stdin&#39;</span>, <span class="charliteral">&#39;r&#39;</span>);</div>
<div class="line"><a name="l01233"></a><span class="lineno"> 1233</span>&#160;  <span class="comment">// Windows workaround: we cannot count on stream_get_contents to</span></div>
<div class="line"><a name="l01234"></a><span class="lineno"> 1234</span>&#160;  <span class="comment">// return if STDIN is reading from the keyboard.  We will therefore</span></div>
<div class="line"><a name="l01235"></a><span class="lineno"> 1235</span>&#160;  <span class="comment">// check to see if there are already characters waiting on the</span></div>
<div class="line"><a name="l01236"></a><span class="lineno"> 1236</span>&#160;  <span class="comment">// stream (as there always should be, if this is a backend call),</span></div>
<div class="line"><a name="l01237"></a><span class="lineno"> 1237</span>&#160;  <span class="comment">// and if there are not, then we will exit.</span></div>
<div class="line"><a name="l01238"></a><span class="lineno"> 1238</span>&#160;  <span class="comment">// This code prevents drush from hanging forever when called with</span></div>
<div class="line"><a name="l01239"></a><span class="lineno"> 1239</span>&#160;  <span class="comment">// --backend from the commandline; however, overall it is still</span></div>
<div class="line"><a name="l01240"></a><span class="lineno"> 1240</span>&#160;  <span class="comment">// a futile effort, as it does not seem that backend invoke can</span></div>
<div class="line"><a name="l01241"></a><span class="lineno"> 1241</span>&#160;  <span class="comment">// successfully write data to that this function can read,</span></div>
<div class="line"><a name="l01242"></a><span class="lineno"> 1242</span>&#160;  <span class="comment">// so the argument list and command always come out empty. :(</span></div>
<div class="line"><a name="l01243"></a><span class="lineno"> 1243</span>&#160;  <span class="comment">// Perhaps stream_get_contents is the problem, and we should use</span></div>
<div class="line"><a name="l01244"></a><span class="lineno"> 1244</span>&#160;  <span class="comment">// the technique described here:</span></div>
<div class="line"><a name="l01245"></a><span class="lineno"> 1245</span>&#160;  <span class="comment">//   http://bugs.php.net/bug.php?id=30154</span></div>
<div class="line"><a name="l01246"></a><span class="lineno"> 1246</span>&#160;  <span class="comment">// n.b. the code in that issue passes &#39;0&#39; for the timeout in stream_select</span></div>
<div class="line"><a name="l01247"></a><span class="lineno"> 1247</span>&#160;  <span class="comment">// in a loop, which is not recommended.</span></div>
<div class="line"><a name="l01248"></a><span class="lineno"> 1248</span>&#160;  <span class="comment">// Note that the following DOES work:</span></div>
<div class="line"><a name="l01249"></a><span class="lineno"> 1249</span>&#160;  <span class="comment">//   drush ev &#39;print(json_encode(array(&quot;test&quot; =&gt; &quot;XYZZY&quot;)));&#39; | drush status --backend</span></div>
<div class="line"><a name="l01250"></a><span class="lineno"> 1250</span>&#160;  <span class="comment">// So, redirecting input is okay, it is just the proc_open that is a problem.</span></div>
<div class="line"><a name="l01251"></a><span class="lineno"> 1251</span>&#160;  <span class="keywordflow">if</span> (<a class="code" href="includes_2environment_8inc.html#a88114295372bcb0ca8dbb5f10b36368e">drush_is_windows</a>()) {</div>
<div class="line"><a name="l01252"></a><span class="lineno"> 1252</span>&#160;    <span class="comment">// Note that stream_select uses reference parameters, so we need variables (can&#39;t pass a constant NULL)</span></div>
<div class="line"><a name="l01253"></a><span class="lineno"> 1253</span>&#160;    $read = array($fp);</div>
<div class="line"><a name="l01254"></a><span class="lineno"> 1254</span>&#160;    $write = NULL;</div>
<div class="line"><a name="l01255"></a><span class="lineno"> 1255</span>&#160;    $except = NULL;</div>
<div class="line"><a name="l01256"></a><span class="lineno"> 1256</span>&#160;    <span class="comment">// Question: might we need to wait a bit for STDIN to be ready,</span></div>
<div class="line"><a name="l01257"></a><span class="lineno"> 1257</span>&#160;    <span class="comment">// even if the process that called us immediately writes our parameters?</span></div>
<div class="line"><a name="l01258"></a><span class="lineno"> 1258</span>&#160;    <span class="comment">// Passing &#39;100&#39; for the timeout here causes us to hang indefinitely</span></div>
<div class="line"><a name="l01259"></a><span class="lineno"> 1259</span>&#160;    <span class="comment">// when called from the shell.</span></div>
<div class="line"><a name="l01260"></a><span class="lineno"> 1260</span>&#160;    $changed_streams = stream_select($read, $write, $except, 0);</div>
<div class="line"><a name="l01261"></a><span class="lineno"> 1261</span>&#160;    <span class="comment">// Return on error (FALSE) or no changed streams (0).</span></div>
<div class="line"><a name="l01262"></a><span class="lineno"> 1262</span>&#160;    <span class="comment">// Oh, according to http://php.net/manual/en/function.stream-select.php,</span></div>
<div class="line"><a name="l01263"></a><span class="lineno"> 1263</span>&#160;    <span class="comment">// stream_select will return FALSE for streams returned by proc_open.</span></div>
<div class="line"><a name="l01264"></a><span class="lineno"> 1264</span>&#160;    <span class="comment">// That is not applicable to us, is it? Our stream is connected to a stream</span></div>
<div class="line"><a name="l01265"></a><span class="lineno"> 1265</span>&#160;    <span class="comment">// created by proc_open, but is not a stream returned by proc_open.</span></div>
<div class="line"><a name="l01266"></a><span class="lineno"> 1266</span>&#160;    <span class="keywordflow">if</span> ($changed_streams &lt; 1) {</div>
<div class="line"><a name="l01267"></a><span class="lineno"> 1267</span>&#160;      <span class="keywordflow">return</span> FALSE;</div>
<div class="line"><a name="l01268"></a><span class="lineno"> 1268</span>&#160;    }</div>
<div class="line"><a name="l01269"></a><span class="lineno"> 1269</span>&#160;  }</div>
<div class="line"><a name="l01270"></a><span class="lineno"> 1270</span>&#160;  stream_set_blocking($fp, FALSE);</div>
<div class="line"><a name="l01271"></a><span class="lineno"> 1271</span>&#160;  $string = stream_get_contents($fp);</div>
<div class="line"><a name="l01272"></a><span class="lineno"> 1272</span>&#160;  fclose($fp);</div>
<div class="line"><a name="l01273"></a><span class="lineno"> 1273</span>&#160;  <span class="keywordflow">if</span> (trim($string)) {</div>
<div class="line"><a name="l01274"></a><span class="lineno"> 1274</span>&#160;    <span class="keywordflow">return</span> json_decode($string, TRUE);</div>
<div class="line"><a name="l01275"></a><span class="lineno"> 1275</span>&#160;  }</div>
<div class="line"><a name="l01276"></a><span class="lineno"> 1276</span>&#160;  <span class="keywordflow">return</span> FALSE;</div>
<div class="line"><a name="l01277"></a><span class="lineno"> 1277</span>&#160;}</div>
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Wed Oct 8 2014 09:04:54 for Drush by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.1.2
</small></address>
</body>
</html>