root/sapi/cli/php_cli.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_cli_get_shell_callbacks
  2. print_module_info
  3. module_name_cmp
  4. print_modules
  5. print_extension_info
  6. extension_name_cmp
  7. print_extensions
  8. sapi_cli_select
  9. sapi_cli_single_write
  10. sapi_cli_ub_write
  11. sapi_cli_flush
  12. sapi_cli_register_variables
  13. sapi_cli_log_message
  14. sapi_cli_deactivate
  15. sapi_cli_read_cookies
  16. sapi_cli_header_handler
  17. sapi_cli_send_headers
  18. sapi_cli_send_header
  19. php_cli_startup
  20. sapi_cli_ini_defaults
  21. php_cli_usage
  22. cli_register_file_handles
  23. cli_seek_file_begin
  24. do_cli
  25. WinMain

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 The PHP Group                                |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 3.01 of the PHP license,      |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.php.net/license/3_01.txt                                  |
  11    | If you did not receive a copy of the PHP license and are unable to   |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@php.net so we can mail you a copy immediately.               |
  14    +----------------------------------------------------------------------+
  15    | Author: Edin Kadribasic <edink@php.net>                              |
  16    |         Marcus Boerger <helly@php.net>                               |
  17    |         Johannes Schlueter <johannes@php.net>                        |
  18    |         Parts based on CGI SAPI Module by                            |
  19    |         Rasmus Lerdorf, Stig Bakken and Zeev Suraski                 |
  20    +----------------------------------------------------------------------+
  21 */
  22 
  23 /* $Id$ */
  24 
  25 #include "php.h"
  26 #include "php_globals.h"
  27 #include "php_variables.h"
  28 #include "zend_hash.h"
  29 #include "zend_modules.h"
  30 #include "zend_interfaces.h"
  31 
  32 #include "ext/reflection/php_reflection.h"
  33 
  34 #include "SAPI.h"
  35 
  36 #include <stdio.h>
  37 #include "php.h"
  38 #ifdef PHP_WIN32
  39 #include "win32/time.h"
  40 #include "win32/signal.h"
  41 #include <process.h>
  42 #endif
  43 #if HAVE_SYS_TIME_H
  44 #include <sys/time.h>
  45 #endif
  46 #if HAVE_UNISTD_H
  47 #include <unistd.h>
  48 #endif
  49 #if HAVE_SIGNAL_H
  50 #include <signal.h>
  51 #endif
  52 #if HAVE_SETLOCALE
  53 #include <locale.h>
  54 #endif
  55 #include "zend.h"
  56 #include "zend_extensions.h"
  57 #include "php_ini.h"
  58 #include "php_globals.h"
  59 #include "php_main.h"
  60 #include "fopen_wrappers.h"
  61 #include "ext/standard/php_standard.h"
  62 #include "cli.h"
  63 #ifdef PHP_WIN32
  64 #include <io.h>
  65 #include <fcntl.h>
  66 #include "win32/php_registry.h"
  67 #endif
  68 
  69 #if HAVE_SIGNAL_H
  70 #include <signal.h>
  71 #endif
  72 
  73 #ifdef __riscos__
  74 #include <unixlib/local.h>
  75 #endif
  76 
  77 #include "zend_compile.h"
  78 #include "zend_execute.h"
  79 #include "zend_highlight.h"
  80 #include "zend_exceptions.h"
  81 
  82 #include "php_getopt.h"
  83 
  84 #ifndef PHP_CLI_WIN32_NO_CONSOLE
  85 #include "php_cli_server.h"
  86 #endif
  87 
  88 #include "ps_title.h"
  89 #include "php_cli_process_title.h"
  90 
  91 #ifndef PHP_WIN32
  92 # define php_select(m, r, w, e, t)      select(m, r, w, e, t)
  93 #else
  94 # include "win32/select.h"
  95 #endif
  96 
  97 #if defined(PHP_WIN32) && defined(HAVE_OPENSSL)
  98 # include "openssl/applink.c"
  99 #endif
 100 
 101 PHPAPI extern char *php_ini_opened_path;
 102 PHPAPI extern char *php_ini_scanned_path;
 103 PHPAPI extern char *php_ini_scanned_files;
 104 
 105 #if defined(PHP_WIN32) && defined(ZTS)
 106 ZEND_TSRMLS_CACHE_DEFINE()
 107 #endif
 108 
 109 #ifndef O_BINARY
 110 #define O_BINARY 0
 111 #endif
 112 
 113 #define PHP_MODE_STANDARD      1
 114 #define PHP_MODE_HIGHLIGHT     2
 115 #define PHP_MODE_LINT          4
 116 #define PHP_MODE_STRIP         5
 117 #define PHP_MODE_CLI_DIRECT    6
 118 #define PHP_MODE_PROCESS_STDIN 7
 119 #define PHP_MODE_REFLECTION_FUNCTION    8
 120 #define PHP_MODE_REFLECTION_CLASS       9
 121 #define PHP_MODE_REFLECTION_EXTENSION   10
 122 #define PHP_MODE_REFLECTION_EXT_INFO    11
 123 #define PHP_MODE_REFLECTION_ZEND_EXTENSION 12
 124 #define PHP_MODE_SHOW_INI_CONFIG        13
 125 
 126 cli_shell_callbacks_t cli_shell_callbacks = { NULL, NULL, NULL };
 127 PHP_CLI_API cli_shell_callbacks_t *php_cli_get_shell_callbacks()
 128 {
 129         return &cli_shell_callbacks;
 130 }
 131 
 132 const char HARDCODED_INI[] =
 133         "html_errors=0\n"
 134         "register_argc_argv=1\n"
 135         "implicit_flush=1\n"
 136         "output_buffering=0\n"
 137         "max_execution_time=0\n"
 138         "max_input_time=-1\n\0";
 139 
 140 
 141 const opt_struct OPTIONS[] = {
 142         {'a', 0, "interactive"},
 143         {'B', 1, "process-begin"},
 144         {'C', 0, "no-chdir"}, /* for compatibility with CGI (do not chdir to script directory) */
 145         {'c', 1, "php-ini"},
 146         {'d', 1, "define"},
 147         {'E', 1, "process-end"},
 148         {'e', 0, "profile-info"},
 149         {'F', 1, "process-file"},
 150         {'f', 1, "file"},
 151         {'h', 0, "help"},
 152         {'i', 0, "info"},
 153         {'l', 0, "syntax-check"},
 154         {'m', 0, "modules"},
 155         {'n', 0, "no-php-ini"},
 156         {'q', 0, "no-header"}, /* for compatibility with CGI (do not generate HTTP headers) */
 157         {'R', 1, "process-code"},
 158         {'H', 0, "hide-args"},
 159         {'r', 1, "run"},
 160         {'s', 0, "syntax-highlight"},
 161         {'s', 0, "syntax-highlighting"},
 162         {'S', 1, "server"},
 163         {'t', 1, "docroot"},
 164         {'w', 0, "strip"},
 165         {'?', 0, "usage"},/* help alias (both '?' and 'usage') */
 166         {'v', 0, "version"},
 167         {'z', 1, "zend-extension"},
 168         {10,  1, "rf"},
 169         {10,  1, "rfunction"},
 170         {11,  1, "rc"},
 171         {11,  1, "rclass"},
 172         {12,  1, "re"},
 173         {12,  1, "rextension"},
 174         {13,  1, "rz"},
 175         {13,  1, "rzendextension"},
 176         {14,  1, "ri"},
 177         {14,  1, "rextinfo"},
 178         {15,  0, "ini"},
 179         {'-', 0, NULL} /* end of args */
 180 };
 181 
 182 static int print_module_info(zval *element) /* {{{ */
 183 {
 184         zend_module_entry *module = (zend_module_entry*)Z_PTR_P(element);
 185         php_printf("%s\n", module->name);
 186         return ZEND_HASH_APPLY_KEEP;
 187 }
 188 /* }}} */
 189 
 190 static int module_name_cmp(const void *a, const void *b) /* {{{ */
 191 {
 192         Bucket *f = (Bucket *) a;
 193         Bucket *s = (Bucket *) b;
 194 
 195         return strcasecmp(((zend_module_entry *)Z_PTR(f->val))->name,
 196                                   ((zend_module_entry *)Z_PTR(s->val))->name);
 197 }
 198 /* }}} */
 199 
 200 static void print_modules(void) /* {{{ */
 201 {
 202         HashTable sorted_registry;
 203 
 204         zend_hash_init(&sorted_registry, 50, NULL, NULL, 0);
 205         zend_hash_copy(&sorted_registry, &module_registry, NULL);
 206         zend_hash_sort(&sorted_registry, module_name_cmp, 0);
 207         zend_hash_apply(&sorted_registry, print_module_info);
 208         zend_hash_destroy(&sorted_registry);
 209 }
 210 /* }}} */
 211 
 212 static int print_extension_info(zend_extension *ext, void *arg) /* {{{ */
 213 {
 214         php_printf("%s\n", ext->name);
 215         return ZEND_HASH_APPLY_KEEP;
 216 }
 217 /* }}} */
 218 
 219 static int extension_name_cmp(const zend_llist_element **f, const zend_llist_element **s) /* {{{ */
 220 {
 221         return strcmp(((zend_extension *)(*f)->data)->name,
 222                                   ((zend_extension *)(*s)->data)->name);
 223 }
 224 /* }}} */
 225 
 226 static void print_extensions(void) /* {{{ */
 227 {
 228         zend_llist sorted_exts;
 229 
 230         zend_llist_copy(&sorted_exts, &zend_extensions);
 231         sorted_exts.dtor = NULL;
 232         zend_llist_sort(&sorted_exts, extension_name_cmp);
 233         zend_llist_apply(&sorted_exts, (llist_apply_func_t) print_extension_info);
 234         zend_llist_destroy(&sorted_exts);
 235 }
 236 /* }}} */
 237 
 238 #ifndef STDOUT_FILENO
 239 #define STDOUT_FILENO 1
 240 #endif
 241 
 242 static inline int sapi_cli_select(int fd)
 243 {
 244         fd_set wfd, dfd;
 245         struct timeval tv;
 246         int ret;
 247 
 248         FD_ZERO(&wfd);
 249         FD_ZERO(&dfd);
 250 
 251         PHP_SAFE_FD_SET(fd, &wfd);
 252 
 253         tv.tv_sec = (long)FG(default_socket_timeout);
 254         tv.tv_usec = 0;
 255 
 256         ret = php_select(fd+1, &dfd, &wfd, &dfd, &tv);
 257 
 258         return ret != -1;
 259 }
 260 
 261 PHP_CLI_API size_t sapi_cli_single_write(const char *str, size_t str_length) /* {{{ */
 262 {
 263 #ifdef PHP_WRITE_STDOUT
 264         zend_long ret;
 265 #else
 266         size_t ret;
 267 #endif
 268 
 269         if (cli_shell_callbacks.cli_shell_write) {
 270                 size_t shell_wrote;
 271                 shell_wrote = cli_shell_callbacks.cli_shell_write(str, str_length);
 272                 if (shell_wrote > -1) {
 273                         return shell_wrote;
 274                 }
 275         }
 276 
 277 #ifdef PHP_WRITE_STDOUT
 278         do {
 279                 ret = write(STDOUT_FILENO, str, str_length);
 280         } while (ret <= 0 && errno == EAGAIN && sapi_cli_select(STDOUT_FILENO));
 281 
 282         if (ret <= 0) {
 283                 return 0;
 284         }
 285 
 286         return ret;
 287 #else
 288         ret = fwrite(str, 1, MIN(str_length, 16384), stdout);
 289         return ret;
 290 #endif
 291 }
 292 /* }}} */
 293 
 294 static size_t sapi_cli_ub_write(const char *str, size_t str_length) /* {{{ */
 295 {
 296         const char *ptr = str;
 297         size_t remaining = str_length;
 298         size_t ret;
 299 
 300         if (!str_length) {
 301                 return 0;
 302         }
 303 
 304         if (cli_shell_callbacks.cli_shell_ub_write) {
 305                 size_t ub_wrote;
 306                 ub_wrote = cli_shell_callbacks.cli_shell_ub_write(str, str_length);
 307                 if (ub_wrote > -1) {
 308                         return ub_wrote;
 309                 }
 310         }
 311 
 312         while (remaining > 0)
 313         {
 314                 ret = sapi_cli_single_write(ptr, remaining);
 315                 if (!ret) {
 316 #ifndef PHP_CLI_WIN32_NO_CONSOLE
 317                         php_handle_aborted_connection();
 318 #endif
 319                         break;
 320                 }
 321                 ptr += ret;
 322                 remaining -= ret;
 323         }
 324 
 325         return (ptr - str);
 326 }
 327 /* }}} */
 328 
 329 static void sapi_cli_flush(void *server_context) /* {{{ */
 330 {
 331         /* Ignore EBADF here, it's caused by the fact that STDIN/STDOUT/STDERR streams
 332          * are/could be closed before fflush() is called.
 333          */
 334         if (fflush(stdout)==EOF && errno!=EBADF) {
 335 #ifndef PHP_CLI_WIN32_NO_CONSOLE
 336                 php_handle_aborted_connection();
 337 #endif
 338         }
 339 }
 340 /* }}} */
 341 
 342 static char *php_self = "";
 343 static char *script_filename = "";
 344 
 345 static void sapi_cli_register_variables(zval *track_vars_array) /* {{{ */
 346 {
 347         size_t len;
 348         char   *docroot = "";
 349 
 350         /* In CGI mode, we consider the environment to be a part of the server
 351          * variables
 352          */
 353         php_import_environment_variables(track_vars_array);
 354 
 355         /* Build the special-case PHP_SELF variable for the CLI version */
 356         len = strlen(php_self);
 357         if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, len, &len)) {
 358                 php_register_variable("PHP_SELF", php_self, track_vars_array);
 359         }
 360         if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &php_self, len, &len)) {
 361                 php_register_variable("SCRIPT_NAME", php_self, track_vars_array);
 362         }
 363         /* filenames are empty for stdin */
 364         len = strlen(script_filename);
 365         if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &script_filename, len, &len)) {
 366                 php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array);
 367         }
 368         if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &script_filename, len, &len)) {
 369                 php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array);
 370         }
 371         /* just make it available */
 372         len = 0U;
 373         if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len, &len)) {
 374                 php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array);
 375         }
 376 }
 377 /* }}} */
 378 
 379 static void sapi_cli_log_message(char *message) /* {{{ */
 380 {
 381         fprintf(stderr, "%s\n", message);
 382 }
 383 /* }}} */
 384 
 385 static int sapi_cli_deactivate(void) /* {{{ */
 386 {
 387         fflush(stdout);
 388         if(SG(request_info).argv0) {
 389                 free(SG(request_info).argv0);
 390                 SG(request_info).argv0 = NULL;
 391         }
 392         return SUCCESS;
 393 }
 394 /* }}} */
 395 
 396 static char* sapi_cli_read_cookies(void) /* {{{ */
 397 {
 398         return NULL;
 399 }
 400 /* }}} */
 401 
 402 static int sapi_cli_header_handler(sapi_header_struct *h, sapi_header_op_enum op, sapi_headers_struct *s) /* {{{ */
 403 {
 404         return 0;
 405 }
 406 /* }}} */
 407 
 408 static int sapi_cli_send_headers(sapi_headers_struct *sapi_headers) /* {{{ */
 409 {
 410         /* We do nothing here, this function is needed to prevent that the fallback
 411          * header handling is called. */
 412         return SAPI_HEADER_SENT_SUCCESSFULLY;
 413 }
 414 /* }}} */
 415 
 416 static void sapi_cli_send_header(sapi_header_struct *sapi_header, void *server_context) /* {{{ */
 417 {
 418 }
 419 /* }}} */
 420 
 421 static int php_cli_startup(sapi_module_struct *sapi_module) /* {{{ */
 422 {
 423         if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
 424                 return FAILURE;
 425         }
 426         return SUCCESS;
 427 }
 428 /* }}} */
 429 
 430 /* {{{ sapi_cli_ini_defaults */
 431 
 432 /* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */
 433 #define INI_DEFAULT(name,value)\
 434         ZVAL_NEW_STR(&tmp, zend_string_init(value, sizeof(value)-1, 1));\
 435         zend_hash_str_update(configuration_hash, name, sizeof(name)-1, &tmp);\
 436 
 437 static void sapi_cli_ini_defaults(HashTable *configuration_hash)
 438 {
 439         zval tmp;
 440         INI_DEFAULT("report_zend_debug", "0");
 441         INI_DEFAULT("display_errors", "1");
 442 }
 443 /* }}} */
 444 
 445 /* {{{ sapi_module_struct cli_sapi_module
 446  */
 447 static sapi_module_struct cli_sapi_module = {
 448         "cli",                                                  /* name */
 449         "Command Line Interface",       /* pretty name */
 450 
 451         php_cli_startup,                                /* startup */
 452         php_module_shutdown_wrapper,    /* shutdown */
 453 
 454         NULL,                                                   /* activate */
 455         sapi_cli_deactivate,                    /* deactivate */
 456 
 457         sapi_cli_ub_write,                      /* unbuffered write */
 458         sapi_cli_flush,                             /* flush */
 459         NULL,                                                   /* get uid */
 460         NULL,                                                   /* getenv */
 461 
 462         php_error,                                              /* error handler */
 463 
 464         sapi_cli_header_handler,                /* header handler */
 465         sapi_cli_send_headers,                  /* send headers handler */
 466         sapi_cli_send_header,                   /* send header handler */
 467 
 468         NULL,                                       /* read POST data */
 469         sapi_cli_read_cookies,          /* read Cookies */
 470 
 471         sapi_cli_register_variables,    /* register server variables */
 472         sapi_cli_log_message,                   /* Log message */
 473         NULL,                                                   /* Get request time */
 474         NULL,                                                   /* Child terminate */
 475 
 476         STANDARD_SAPI_MODULE_PROPERTIES
 477 };
 478 /* }}} */
 479 
 480 /* {{{ arginfo ext/standard/dl.c */
 481 ZEND_BEGIN_ARG_INFO(arginfo_dl, 0)
 482         ZEND_ARG_INFO(0, extension_filename)
 483 ZEND_END_ARG_INFO()
 484 /* }}} */
 485 
 486 static const zend_function_entry additional_functions[] = {
 487         ZEND_FE(dl, arginfo_dl)
 488         PHP_FE(cli_set_process_title,        arginfo_cli_set_process_title)
 489         PHP_FE(cli_get_process_title,        arginfo_cli_get_process_title)
 490         {NULL, NULL, NULL}
 491 };
 492 
 493 /* {{{ php_cli_usage
 494  */
 495 static void php_cli_usage(char *argv0)
 496 {
 497         char *prog;
 498 
 499         prog = strrchr(argv0, '/');
 500         if (prog) {
 501                 prog++;
 502         } else {
 503                 prog = "php";
 504         }
 505 
 506         printf( "Usage: %s [options] [-f] <file> [--] [args...]\n"
 507                                 "   %s [options] -r <code> [--] [args...]\n"
 508                                 "   %s [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]\n"
 509                                 "   %s [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]\n"
 510                                 "   %s [options] -S <addr>:<port> [-t docroot]\n"
 511                                 "   %s [options] -- [args...]\n"
 512                                 "   %s [options] -a\n"
 513                                 "\n"
 514 #if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE)
 515                                 "  -a               Run as interactive shell\n"
 516 #else
 517                                 "  -a               Run interactively\n"
 518 #endif
 519                                 "  -c <path>|<file> Look for php.ini file in this directory\n"
 520                                 "  -n               No configuration (ini) files will be used\n"
 521                                 "  -d foo[=bar]     Define INI entry foo with value 'bar'\n"
 522                                 "  -e               Generate extended information for debugger/profiler\n"
 523                                 "  -f <file>        Parse and execute <file>.\n"
 524                                 "  -h               This help\n"
 525                                 "  -i               PHP information\n"
 526                                 "  -l               Syntax check only (lint)\n"
 527                                 "  -m               Show compiled in modules\n"
 528                                 "  -r <code>        Run PHP <code> without using script tags <?..?>\n"
 529                                 "  -B <begin_code>  Run PHP <begin_code> before processing input lines\n"
 530                                 "  -R <code>        Run PHP <code> for every input line\n"
 531                                 "  -F <file>        Parse and execute <file> for every input line\n"
 532                                 "  -E <end_code>    Run PHP <end_code> after processing all input lines\n"
 533                                 "  -H               Hide any passed arguments from external tools.\n"
 534                                 "  -S <addr>:<port> Run with built-in web server.\n"
 535                                 "  -t <docroot>     Specify document root <docroot> for built-in web server.\n"
 536                                 "  -s               Output HTML syntax highlighted source.\n"
 537                                 "  -v               Version number\n"
 538                                 "  -w               Output source with stripped comments and whitespace.\n"
 539                                 "  -z <file>        Load Zend extension <file>.\n"
 540                                 "\n"
 541                                 "  args...          Arguments passed to script. Use -- args when first argument\n"
 542                                 "                   starts with - or script is read from stdin\n"
 543                                 "\n"
 544                                 "  --ini            Show configuration file names\n"
 545                                 "\n"
 546                                 "  --rf <name>      Show information about function <name>.\n"
 547                                 "  --rc <name>      Show information about class <name>.\n"
 548                                 "  --re <name>      Show information about extension <name>.\n"
 549                                 "  --rz <name>      Show information about Zend extension <name>.\n"
 550                                 "  --ri <name>      Show configuration for extension <name>.\n"
 551                                 "\n"
 552                                 , prog, prog, prog, prog, prog, prog, prog);
 553 }
 554 /* }}} */
 555 
 556 static php_stream *s_in_process = NULL;
 557 
 558 static void cli_register_file_handles(void) /* {{{ */
 559 {
 560         zval zin, zout, zerr;
 561         php_stream *s_in, *s_out, *s_err;
 562         php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
 563         zend_constant ic, oc, ec;
 564 
 565         s_in  = php_stream_open_wrapper_ex("php://stdin",  "rb", 0, NULL, sc_in);
 566         s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
 567         s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
 568 
 569         if (s_in==NULL || s_out==NULL || s_err==NULL) {
 570                 if (s_in) php_stream_close(s_in);
 571                 if (s_out) php_stream_close(s_out);
 572                 if (s_err) php_stream_close(s_err);
 573                 return;
 574         }
 575 
 576 #if PHP_DEBUG
 577         /* do not close stdout and stderr */
 578         s_out->flags |= PHP_STREAM_FLAG_NO_CLOSE;
 579         s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
 580 #endif
 581 
 582         s_in_process = s_in;
 583 
 584         php_stream_to_zval(s_in,  &zin);
 585         php_stream_to_zval(s_out, &zout);
 586         php_stream_to_zval(s_err, &zerr);
 587 
 588         ZVAL_COPY_VALUE(&ic.value, &zin);
 589         ic.flags = CONST_CS;
 590         ic.name = zend_string_init("STDIN", sizeof("STDIN")-1, 1);
 591         ic.module_number = 0;
 592         zend_register_constant(&ic);
 593 
 594         ZVAL_COPY_VALUE(&oc.value, &zout);
 595         oc.flags = CONST_CS;
 596         oc.name = zend_string_init("STDOUT", sizeof("STDOUT")-1, 1);
 597         oc.module_number = 0;
 598         zend_register_constant(&oc);
 599 
 600         ZVAL_COPY_VALUE(&ec.value, &zerr);
 601         ec.flags = CONST_CS;
 602         ec.name = zend_string_init("STDERR", sizeof("STDERR")-1, 1);
 603         ec.module_number = 0;
 604         zend_register_constant(&ec);
 605 }
 606 /* }}} */
 607 
 608 static const char *param_mode_conflict = "Either execute direct code, process stdin or use a file.\n";
 609 
 610 /* {{{ cli_seek_file_begin
 611  */
 612 static int cli_seek_file_begin(zend_file_handle *file_handle, char *script_file, int *lineno)
 613 {
 614         int c;
 615 
 616         *lineno = 1;
 617 
 618         file_handle->type = ZEND_HANDLE_FP;
 619         file_handle->opened_path = NULL;
 620         file_handle->free_filename = 0;
 621         if (!(file_handle->handle.fp = VCWD_FOPEN(script_file, "rb"))) {
 622                 php_printf("Could not open input file: %s\n", script_file);
 623                 return FAILURE;
 624         }
 625         file_handle->filename = script_file;
 626 
 627         /* #!php support */
 628         c = fgetc(file_handle->handle.fp);
 629         if (c == '#' && (c = fgetc(file_handle->handle.fp)) == '!') {
 630                 while (c != '\n' && c != '\r' && c != EOF) {
 631                         c = fgetc(file_handle->handle.fp);      /* skip to end of line */
 632                 }
 633                 /* handle situations where line is terminated by \r\n */
 634                 if (c == '\r') {
 635                         if (fgetc(file_handle->handle.fp) != '\n') {
 636                                 zend_long pos = zend_ftell(file_handle->handle.fp);
 637                                 zend_fseek(file_handle->handle.fp, pos - 1, SEEK_SET);
 638                         }
 639                 }
 640                 *lineno = 2;
 641         } else {
 642                 rewind(file_handle->handle.fp);
 643         }
 644 
 645         return SUCCESS;
 646 }
 647 /* }}} */
 648 
 649 static int do_cli(int argc, char **argv) /* {{{ */
 650 {
 651         int c;
 652         zend_file_handle file_handle;
 653         int behavior = PHP_MODE_STANDARD;
 654         char *reflection_what = NULL;
 655         volatile int request_started = 0;
 656         volatile int exit_status = 0;
 657         char *php_optarg = NULL, *orig_optarg = NULL;
 658         int php_optind = 1, orig_optind = 1;
 659         char *exec_direct=NULL, *exec_run=NULL, *exec_begin=NULL, *exec_end=NULL;
 660         char *arg_free=NULL, **arg_excp=&arg_free;
 661         char *script_file=NULL, *translated_path = NULL;
 662         int interactive=0;
 663         int lineno = 0;
 664         const char *param_error=NULL;
 665         int hide_argv = 0;
 666 
 667         zend_try {
 668 
 669                 CG(in_compilation) = 0; /* not initialized but needed for several options */
 670 
 671                 while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
 672                         switch (c) {
 673 
 674                         case 'i': /* php info & quit */
 675                                 if (php_request_startup()==FAILURE) {
 676                                         goto err;
 677                                 }
 678                                 request_started = 1;
 679                                 php_print_info(0xFFFFFFFF);
 680                                 php_output_end_all();
 681                                 exit_status = (c == '?' && argc > 1 && !strchr(argv[1],  c));
 682                                 goto out;
 683 
 684                         case 'v': /* show php version & quit */
 685                                 php_printf("PHP %s (%s) (built: %s %s) ( %s)\nCopyright (c) 1997-2016 The PHP Group\n%s",
 686                                         PHP_VERSION, cli_sapi_module.name, __DATE__, __TIME__,
 687 #if ZTS
 688                                         "ZTS "
 689 #else
 690                                         "NTS "
 691 #endif
 692 #if ZEND_DEBUG
 693                                         "DEBUG "
 694 #endif
 695 #ifdef HAVE_GCOV
 696                                         "GCOV "
 697 #endif
 698                                         ,
 699                                         get_zend_version()
 700                                 );
 701                                 sapi_deactivate();
 702                                 goto out;
 703 
 704                         case 'm': /* list compiled in modules */
 705                                 if (php_request_startup()==FAILURE) {
 706                                         goto err;
 707                                 }
 708                                 request_started = 1;
 709                                 php_printf("[PHP Modules]\n");
 710                                 print_modules();
 711                                 php_printf("\n[Zend Modules]\n");
 712                                 print_extensions();
 713                                 php_printf("\n");
 714                                 php_output_end_all();
 715                                 exit_status=0;
 716                                 goto out;
 717 
 718                         default:
 719                                 break;
 720                         }
 721                 }
 722 
 723                 /* Set some CLI defaults */
 724                 SG(options) |= SAPI_OPTION_NO_CHDIR;
 725 
 726                 php_optind = orig_optind;
 727                 php_optarg = orig_optarg;
 728                 while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
 729                         switch (c) {
 730 
 731                         case 'a':       /* interactive mode */
 732                                 if (!interactive) {
 733                                         if (behavior != PHP_MODE_STANDARD) {
 734                                                 param_error = param_mode_conflict;
 735                                                 break;
 736                                         }
 737 
 738                                         interactive=1;
 739                                 }
 740                                 break;
 741 
 742                         case 'C': /* don't chdir to the script directory */
 743                                 /* This is default so NOP */
 744                                 break;
 745 
 746                         case 'F':
 747                                 if (behavior == PHP_MODE_PROCESS_STDIN) {
 748                                         if (exec_run || script_file) {
 749                                                 param_error = "You can use -R or -F only once.\n";
 750                                                 break;
 751                                         }
 752                                 } else if (behavior != PHP_MODE_STANDARD) {
 753                                         param_error = param_mode_conflict;
 754                                         break;
 755                                 }
 756                                 behavior=PHP_MODE_PROCESS_STDIN;
 757                                 script_file = php_optarg;
 758                                 break;
 759 
 760                         case 'f': /* parse file */
 761                                 if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) {
 762                                         param_error = param_mode_conflict;
 763                                         break;
 764                                 } else if (script_file) {
 765                                         param_error = "You can use -f only once.\n";
 766                                         break;
 767                                 }
 768                                 script_file = php_optarg;
 769                                 break;
 770 
 771                         case 'l': /* syntax check mode */
 772                                 if (behavior != PHP_MODE_STANDARD) {
 773                                         break;
 774                                 }
 775                                 behavior=PHP_MODE_LINT;
 776                                 break;
 777 
 778                         case 'q': /* do not generate HTTP headers */
 779                                 /* This is default so NOP */
 780                                 break;
 781 
 782                         case 'r': /* run code from command line */
 783                                 if (behavior == PHP_MODE_CLI_DIRECT) {
 784                                         if (exec_direct || script_file) {
 785                                                 param_error = "You can use -r only once.\n";
 786                                                 break;
 787                                         }
 788                                 } else if (behavior != PHP_MODE_STANDARD || interactive) {
 789                                         param_error = param_mode_conflict;
 790                                         break;
 791                                 }
 792                                 behavior=PHP_MODE_CLI_DIRECT;
 793                                 exec_direct=php_optarg;
 794                                 break;
 795 
 796                         case 'R':
 797                                 if (behavior == PHP_MODE_PROCESS_STDIN) {
 798                                         if (exec_run || script_file) {
 799                                                 param_error = "You can use -R or -F only once.\n";
 800                                                 break;
 801                                         }
 802                                 } else if (behavior != PHP_MODE_STANDARD) {
 803                                         param_error = param_mode_conflict;
 804                                         break;
 805                                 }
 806                                 behavior=PHP_MODE_PROCESS_STDIN;
 807                                 exec_run=php_optarg;
 808                                 break;
 809 
 810                         case 'B':
 811                                 if (behavior == PHP_MODE_PROCESS_STDIN) {
 812                                         if (exec_begin) {
 813                                                 param_error = "You can use -B only once.\n";
 814                                                 break;
 815                                         }
 816                                 } else if (behavior != PHP_MODE_STANDARD || interactive) {
 817                                         param_error = param_mode_conflict;
 818                                         break;
 819                                 }
 820                                 behavior=PHP_MODE_PROCESS_STDIN;
 821                                 exec_begin=php_optarg;
 822                                 break;
 823 
 824                         case 'E':
 825                                 if (behavior == PHP_MODE_PROCESS_STDIN) {
 826                                         if (exec_end) {
 827                                                 param_error = "You can use -E only once.\n";
 828                                                 break;
 829                                         }
 830                                 } else if (behavior != PHP_MODE_STANDARD || interactive) {
 831                                         param_error = param_mode_conflict;
 832                                         break;
 833                                 }
 834                                 behavior=PHP_MODE_PROCESS_STDIN;
 835                                 exec_end=php_optarg;
 836                                 break;
 837 
 838                         case 's': /* generate highlighted HTML from source */
 839                                 if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) {
 840                                         param_error = "Source highlighting only works for files.\n";
 841                                         break;
 842                                 }
 843                                 behavior=PHP_MODE_HIGHLIGHT;
 844                                 break;
 845 
 846                         case 'w':
 847                                 if (behavior == PHP_MODE_CLI_DIRECT || behavior == PHP_MODE_PROCESS_STDIN) {
 848                                         param_error = "Source stripping only works for files.\n";
 849                                         break;
 850                                 }
 851                                 behavior=PHP_MODE_STRIP;
 852                                 break;
 853 
 854                         case 'z': /* load extension file */
 855                                 zend_load_extension(php_optarg);
 856                                 break;
 857                         case 'H':
 858                                 hide_argv = 1;
 859                                 break;
 860                         case 10:
 861                                 behavior=PHP_MODE_REFLECTION_FUNCTION;
 862                                 reflection_what = php_optarg;
 863                                 break;
 864                         case 11:
 865                                 behavior=PHP_MODE_REFLECTION_CLASS;
 866                                 reflection_what = php_optarg;
 867                                 break;
 868                         case 12:
 869                                 behavior=PHP_MODE_REFLECTION_EXTENSION;
 870                                 reflection_what = php_optarg;
 871                                 break;
 872                         case 13:
 873                                 behavior=PHP_MODE_REFLECTION_ZEND_EXTENSION;
 874                                 reflection_what = php_optarg;
 875                                 break;
 876                         case 14:
 877                                 behavior=PHP_MODE_REFLECTION_EXT_INFO;
 878                                 reflection_what = php_optarg;
 879                                 break;
 880                         case 15:
 881                                 behavior = PHP_MODE_SHOW_INI_CONFIG;
 882                                 break;
 883                         default:
 884                                 break;
 885                         }
 886                 }
 887 
 888                 if (param_error) {
 889                         PUTS(param_error);
 890                         exit_status=1;
 891                         goto err;
 892                 }
 893 
 894                 if (interactive) {
 895 #if (HAVE_LIBREADLINE || HAVE_LIBEDIT) && !defined(COMPILE_DL_READLINE)
 896                         printf("Interactive shell\n\n");
 897 #else
 898                         printf("Interactive mode enabled\n\n");
 899 #endif
 900                         fflush(stdout);
 901                 }
 902 
 903                 /* only set script_file if not set already and not in direct mode and not at end of parameter list */
 904                 if (argc > php_optind
 905                   && !script_file
 906                   && behavior!=PHP_MODE_CLI_DIRECT
 907                   && behavior!=PHP_MODE_PROCESS_STDIN
 908                   && strcmp(argv[php_optind-1],"--"))
 909                 {
 910                         script_file=argv[php_optind];
 911                         php_optind++;
 912                 }
 913                 if (script_file) {
 914                         if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS) {
 915                                 goto err;
 916                         } else {
 917                                 char real_path[MAXPATHLEN];
 918                                 if (VCWD_REALPATH(script_file, real_path)) {
 919                                         translated_path = strdup(real_path);
 920                                 }
 921                                 script_filename = script_file;
 922                         }
 923                 } else {
 924                         /* We could handle PHP_MODE_PROCESS_STDIN in a different manner  */
 925                         /* here but this would make things only more complicated. And it */
 926                         /* is consitent with the way -R works where the stdin file handle*/
 927                         /* is also accessible. */
 928                         file_handle.filename = "-";
 929                         file_handle.handle.fp = stdin;
 930                 }
 931                 file_handle.type = ZEND_HANDLE_FP;
 932                 file_handle.opened_path = NULL;
 933                 file_handle.free_filename = 0;
 934                 php_self = (char*)file_handle.filename;
 935 
 936                 /* before registering argv to module exchange the *new* argv[0] */
 937                 /* we can achieve this without allocating more memory */
 938                 SG(request_info).argc=argc-php_optind+1;
 939                 arg_excp = argv+php_optind-1;
 940                 arg_free = argv[php_optind-1];
 941                 SG(request_info).path_translated = translated_path? translated_path: (char*)file_handle.filename;
 942                 argv[php_optind-1] = (char*)file_handle.filename;
 943                 SG(request_info).argv=argv+php_optind-1;
 944 
 945                 if (php_request_startup()==FAILURE) {
 946                         *arg_excp = arg_free;
 947                         fclose(file_handle.handle.fp);
 948                         PUTS("Could not startup.\n");
 949                         goto err;
 950                 }
 951                 request_started = 1;
 952                 CG(start_lineno) = lineno;
 953                 *arg_excp = arg_free; /* reconstuct argv */
 954 
 955                 if (hide_argv) {
 956                         int i;
 957                         for (i = 1; i < argc; i++) {
 958                                 memset(argv[i], 0, strlen(argv[i]));
 959                         }
 960                 }
 961 
 962                 zend_is_auto_global_str(ZEND_STRL("_SERVER"));
 963 
 964                 PG(during_request_startup) = 0;
 965                 switch (behavior) {
 966                 case PHP_MODE_STANDARD:
 967                         if (strcmp(file_handle.filename, "-")) {
 968                                 cli_register_file_handles();
 969                         }
 970 
 971                         if (interactive && cli_shell_callbacks.cli_shell_run) {
 972                                 exit_status = cli_shell_callbacks.cli_shell_run();
 973                         } else {
 974                                 php_execute_script(&file_handle);
 975                                 exit_status = EG(exit_status);
 976                         }
 977                         break;
 978                 case PHP_MODE_LINT:
 979                         exit_status = php_lint_script(&file_handle);
 980                         if (exit_status==SUCCESS) {
 981                                 zend_printf("No syntax errors detected in %s\n", file_handle.filename);
 982                         } else {
 983                                 zend_printf("Errors parsing %s\n", file_handle.filename);
 984                         }
 985                         break;
 986                 case PHP_MODE_STRIP:
 987                         if (open_file_for_scanning(&file_handle)==SUCCESS) {
 988                                 zend_strip();
 989                         }
 990                         goto out;
 991                         break;
 992                 case PHP_MODE_HIGHLIGHT:
 993                         {
 994                                 zend_syntax_highlighter_ini syntax_highlighter_ini;
 995 
 996                                 if (open_file_for_scanning(&file_handle)==SUCCESS) {
 997                                         php_get_highlight_struct(&syntax_highlighter_ini);
 998                                         zend_highlight(&syntax_highlighter_ini);
 999                                 }
1000                                 goto out;
1001                         }
1002                         break;
1003                 case PHP_MODE_CLI_DIRECT:
1004                         cli_register_file_handles();
1005                         if (zend_eval_string_ex(exec_direct, NULL, "Command line code", 1) == FAILURE) {
1006                                 exit_status=254;
1007                         }
1008                         break;
1009 
1010                 case PHP_MODE_PROCESS_STDIN:
1011                         {
1012                                 char *input;
1013                                 size_t len, index = 0;
1014                                 zval argn, argi;
1015 
1016                                 cli_register_file_handles();
1017 
1018                                 if (exec_begin && zend_eval_string_ex(exec_begin, NULL, "Command line begin code", 1) == FAILURE) {
1019                                         exit_status=254;
1020                                 }
1021                                 while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
1022                                         len = strlen(input);
1023                                         while (len > 0 && len-- && (input[len]=='\n' || input[len]=='\r')) {
1024                                                 input[len] = '\0';
1025                                         }
1026                                         ZVAL_STRINGL(&argn, input, len + 1);
1027                                         zend_hash_str_update(&EG(symbol_table), "argn", sizeof("argn")-1, &argn);
1028                                         ZVAL_LONG(&argi, ++index);
1029                                         zend_hash_str_update(&EG(symbol_table), "argi", sizeof("argi")-1, &argi);
1030                                         if (exec_run) {
1031                                                 if (zend_eval_string_ex(exec_run, NULL, "Command line run code", 1) == FAILURE) {
1032                                                         exit_status=254;
1033                                                 }
1034                                         } else {
1035                                                 if (script_file) {
1036                                                         if (cli_seek_file_begin(&file_handle, script_file, &lineno) != SUCCESS) {
1037                                                                 exit_status = 1;
1038                                                         } else {
1039                                                                 CG(start_lineno) = lineno;
1040                                                                 php_execute_script(&file_handle);
1041                                                                 exit_status = EG(exit_status);
1042                                                         }
1043                                                 }
1044                                         }
1045                                         efree(input);
1046                                 }
1047                                 if (exec_end && zend_eval_string_ex(exec_end, NULL, "Command line end code", 1) == FAILURE) {
1048                                         exit_status=254;
1049                                 }
1050 
1051                                 break;
1052                         }
1053 
1054                         case PHP_MODE_REFLECTION_FUNCTION:
1055                         case PHP_MODE_REFLECTION_CLASS:
1056                         case PHP_MODE_REFLECTION_EXTENSION:
1057                         case PHP_MODE_REFLECTION_ZEND_EXTENSION:
1058                                 {
1059                                         zend_class_entry *pce = NULL;
1060                                         zval arg, ref;
1061                                         zend_execute_data execute_data;
1062 
1063                                         switch (behavior) {
1064                                                 default:
1065                                                         break;
1066                                                 case PHP_MODE_REFLECTION_FUNCTION:
1067                                                         if (strstr(reflection_what, "::")) {
1068                                                                 pce = reflection_method_ptr;
1069                                                         } else {
1070                                                                 pce = reflection_function_ptr;
1071                                                         }
1072                                                         break;
1073                                                 case PHP_MODE_REFLECTION_CLASS:
1074                                                         pce = reflection_class_ptr;
1075                                                         break;
1076                                                 case PHP_MODE_REFLECTION_EXTENSION:
1077                                                         pce = reflection_extension_ptr;
1078                                                         break;
1079                                                 case PHP_MODE_REFLECTION_ZEND_EXTENSION:
1080                                                         pce = reflection_zend_extension_ptr;
1081                                                         break;
1082                                         }
1083 
1084                                         ZVAL_STRING(&arg, reflection_what);
1085                                         object_init_ex(&ref, pce);
1086 
1087                                         memset(&execute_data, 0, sizeof(zend_execute_data));
1088                                         EG(current_execute_data) = &execute_data;
1089                                         zend_call_method_with_1_params(&ref, pce, &pce->constructor, "__construct", NULL, &arg);
1090 
1091                                         if (EG(exception)) {
1092                                                 zval tmp, *msg, rv;
1093 
1094                                                 ZVAL_OBJ(&tmp, EG(exception));
1095                                                 msg = zend_read_property(zend_ce_exception, &tmp, "message", sizeof("message")-1, 0, &rv);
1096                                                 zend_printf("Exception: %s\n", Z_STRVAL_P(msg));
1097                                                 zval_ptr_dtor(&tmp);
1098                                                 EG(exception) = NULL;
1099                                         } else {
1100                                                 zend_call_method_with_1_params(NULL, reflection_ptr, NULL, "export", NULL, &ref);
1101                                         }
1102                                         zval_ptr_dtor(&ref);
1103                                         zval_ptr_dtor(&arg);
1104 
1105                                         break;
1106                                 }
1107                         case PHP_MODE_REFLECTION_EXT_INFO:
1108                                 {
1109                                         int len = (int)strlen(reflection_what);
1110                                         char *lcname = zend_str_tolower_dup(reflection_what, len);
1111                                         zend_module_entry *module;
1112 
1113                                         if ((module = zend_hash_str_find_ptr(&module_registry, lcname, len)) == NULL) {
1114                                                 if (!strcmp(reflection_what, "main")) {
1115                                                         display_ini_entries(NULL);
1116                                                 } else {
1117                                                         zend_printf("Extension '%s' not present.\n", reflection_what);
1118                                                         exit_status = 1;
1119                                                 }
1120                                         } else {
1121                                                 php_info_print_module(module);
1122                                         }
1123 
1124                                         efree(lcname);
1125                                         break;
1126                                 }
1127 
1128                         case PHP_MODE_SHOW_INI_CONFIG:
1129                                 {
1130                                         zend_printf("Configuration File (php.ini) Path: %s\n", PHP_CONFIG_FILE_PATH);
1131                                         zend_printf("Loaded Configuration File:         %s\n", php_ini_opened_path ? php_ini_opened_path : "(none)");
1132                                         zend_printf("Scan for additional .ini files in: %s\n", php_ini_scanned_path  ? php_ini_scanned_path : "(none)");
1133                                         zend_printf("Additional .ini files parsed:      %s\n", php_ini_scanned_files ? php_ini_scanned_files : "(none)");
1134                                         break;
1135                                 }
1136                 }
1137         } zend_end_try();
1138 
1139 out:
1140         if (request_started) {
1141                 php_request_shutdown((void *) 0);
1142         }
1143         if (translated_path) {
1144                 free(translated_path);
1145         }
1146         if (exit_status == 0) {
1147                 exit_status = EG(exit_status);
1148         }
1149         return exit_status;
1150 err:
1151         sapi_deactivate();
1152         zend_ini_deactivate();
1153         exit_status = 1;
1154         goto out;
1155 }
1156 /* }}} */
1157 
1158 /* {{{ main
1159  */
1160 #ifdef PHP_CLI_WIN32_NO_CONSOLE
1161 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
1162 #else
1163 int main(int argc, char *argv[])
1164 #endif
1165 {
1166 #ifdef PHP_CLI_WIN32_NO_CONSOLE
1167         int argc = __argc;
1168         char **argv = __argv;
1169 #endif
1170 
1171         int c;
1172         int exit_status = SUCCESS;
1173         int module_started = 0, sapi_started = 0;
1174         char *php_optarg = NULL;
1175         int php_optind = 1, use_extended_info = 0;
1176         char *ini_path_override = NULL;
1177         char *ini_entries = NULL;
1178         int ini_entries_len = 0;
1179         int ini_ignore = 0;
1180         sapi_module_struct *sapi_module = &cli_sapi_module;
1181 
1182         /*
1183          * Do not move this initialization. It needs to happen before argv is used
1184          * in any way.
1185          */
1186         argv = save_ps_args(argc, argv);
1187 
1188         cli_sapi_module.additional_functions = additional_functions;
1189 
1190 #if defined(PHP_WIN32) && defined(_DEBUG) && defined(PHP_WIN32_DEBUG_HEAP)
1191         {
1192                 int tmp_flag;
1193                 _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
1194                 _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
1195                 _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
1196                 _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
1197                 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
1198                 _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
1199                 tmp_flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
1200                 tmp_flag |= _CRTDBG_DELAY_FREE_MEM_DF;
1201                 tmp_flag |= _CRTDBG_LEAK_CHECK_DF;
1202 
1203                 _CrtSetDbgFlag(tmp_flag);
1204         }
1205 #endif
1206 
1207 #ifdef HAVE_SIGNAL_H
1208 #if defined(SIGPIPE) && defined(SIG_IGN)
1209         signal(SIGPIPE, SIG_IGN); /* ignore SIGPIPE in standalone mode so
1210                                                                 that sockets created via fsockopen()
1211                                                                 don't kill PHP if the remote site
1212                                                                 closes it.  in apache|apxs mode apache
1213                                                                 does that for us!  thies@thieso.net
1214                                                                 20000419 */
1215 #endif
1216 #endif
1217 
1218 
1219 #ifdef ZTS
1220         tsrm_startup(1, 1, 0, NULL);
1221         (void)ts_resource(0);
1222         ZEND_TSRMLS_CACHE_UPDATE();
1223 #endif
1224 
1225 #ifdef ZEND_SIGNALS
1226         zend_signal_startup();
1227 #endif
1228 
1229 #ifdef PHP_WIN32
1230         _fmode = _O_BINARY;                     /*sets default for file streams to binary */
1231         setmode(_fileno(stdin), O_BINARY);              /* make the stdio mode be binary */
1232         setmode(_fileno(stdout), O_BINARY);             /* make the stdio mode be binary */
1233         setmode(_fileno(stderr), O_BINARY);             /* make the stdio mode be binary */
1234 #endif
1235 
1236         while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2))!=-1) {
1237                 switch (c) {
1238                         case 'c':
1239                                 if (ini_path_override) {
1240                                         free(ini_path_override);
1241                                 }
1242                                 ini_path_override = strdup(php_optarg);
1243                                 break;
1244                         case 'n':
1245                                 ini_ignore = 1;
1246                                 break;
1247                         case 'd': {
1248                                 /* define ini entries on command line */
1249                                 int len = (int)strlen(php_optarg);
1250                                 char *val;
1251 
1252                                 if ((val = strchr(php_optarg, '='))) {
1253                                         val++;
1254                                         if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') {
1255                                                 ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0"));
1256                                                 memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg));
1257                                                 ini_entries_len += (int)(val - php_optarg);
1258                                                 memcpy(ini_entries + ini_entries_len, "\"", 1);
1259                                                 ini_entries_len++;
1260                                                 memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg));
1261                                                 ini_entries_len += len - (int)(val - php_optarg);
1262                                                 memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0"));
1263                                                 ini_entries_len += sizeof("\n\0\"") - 2;
1264                                         } else {
1265                                                 ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0"));
1266                                                 memcpy(ini_entries + ini_entries_len, php_optarg, len);
1267                                                 memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0"));
1268                                                 ini_entries_len += len + sizeof("\n\0") - 2;
1269                                         }
1270                                 } else {
1271                                         ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0"));
1272                                         memcpy(ini_entries + ini_entries_len, php_optarg, len);
1273                                         memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0"));
1274                                         ini_entries_len += len + sizeof("=1\n\0") - 2;
1275                                 }
1276                                 break;
1277                         }
1278 #ifndef PHP_CLI_WIN32_NO_CONSOLE
1279                         case 'S':
1280                                 sapi_module = &cli_server_sapi_module;
1281                                 cli_server_sapi_module.additional_functions = server_additional_functions;
1282                                 break;
1283 #endif
1284                         case 'h': /* help & quit */
1285                         case '?':
1286                                 php_cli_usage(argv[0]);
1287                                 goto out;
1288                         case 'i': case 'v': case 'm':
1289                                 sapi_module = &cli_sapi_module;
1290                                 goto exit_loop;
1291                         case 'e': /* enable extended info output */
1292                                 use_extended_info = 1;
1293                                 break;
1294                 }
1295         }
1296 exit_loop:
1297 
1298         sapi_module->ini_defaults = sapi_cli_ini_defaults;
1299         sapi_module->php_ini_path_override = ini_path_override;
1300         sapi_module->phpinfo_as_text = 1;
1301         sapi_module->php_ini_ignore_cwd = 1;
1302         sapi_startup(sapi_module);
1303         sapi_started = 1;
1304 
1305         sapi_module->php_ini_ignore = ini_ignore;
1306 
1307         sapi_module->executable_location = argv[0];
1308 
1309         if (sapi_module == &cli_sapi_module) {
1310                 if (ini_entries) {
1311                         ini_entries = realloc(ini_entries, ini_entries_len + sizeof(HARDCODED_INI));
1312                         memmove(ini_entries + sizeof(HARDCODED_INI) - 2, ini_entries, ini_entries_len + 1);
1313                         memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI) - 2);
1314                 } else {
1315                         ini_entries = malloc(sizeof(HARDCODED_INI));
1316                         memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
1317                 }
1318                 ini_entries_len += sizeof(HARDCODED_INI) - 2;
1319         }
1320 
1321         sapi_module->ini_entries = ini_entries;
1322 
1323         /* startup after we get the above ini override se we get things right */
1324         if (sapi_module->startup(sapi_module) == FAILURE) {
1325                 /* there is no way to see if we must call zend_ini_deactivate()
1326                  * since we cannot check if EG(ini_directives) has been initialised
1327                  * because the executor's constructor does not set initialize it.
1328                  * Apart from that there seems no need for zend_ini_deactivate() yet.
1329                  * So we goto out_err.*/
1330                 exit_status = 1;
1331                 goto out;
1332         }
1333         module_started = 1;
1334 
1335         /* -e option */
1336         if (use_extended_info) {
1337                 CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
1338         }
1339 
1340         zend_first_try {
1341 #ifndef PHP_CLI_WIN32_NO_CONSOLE
1342                 if (sapi_module == &cli_sapi_module) {
1343 #endif
1344                         exit_status = do_cli(argc, argv);
1345 #ifndef PHP_CLI_WIN32_NO_CONSOLE
1346                 } else {
1347                         exit_status = do_cli_server(argc, argv);
1348                 }
1349 #endif
1350         } zend_end_try();
1351 out:
1352         if (ini_path_override) {
1353                 free(ini_path_override);
1354         }
1355         if (ini_entries) {
1356                 free(ini_entries);
1357         }
1358         if (module_started) {
1359                 php_module_shutdown();
1360         }
1361         if (sapi_started) {
1362                 sapi_shutdown();
1363         }
1364 #ifdef ZTS
1365         tsrm_shutdown();
1366 #endif
1367 
1368         /*
1369          * Do not move this de-initialization. It needs to happen right before
1370          * exiting.
1371          */
1372         cleanup_ps_args(argv);
1373         exit(exit_status);
1374 }
1375 /* }}} */
1376 
1377 /*
1378  * Local variables:
1379  * tab-width: 4
1380  * c-basic-offset: 4
1381  * End:
1382  * vim600: sw=4 ts=4 fdm=marker
1383  * vim<600: sw=4 ts=4
1384  */

/* [<][>][^][v][top][bottom][index][help] */