This source file includes following definitions.
- php_cli_get_shell_callbacks
- print_module_info
- module_name_cmp
- print_modules
- print_extension_info
- extension_name_cmp
- print_extensions
- sapi_cli_select
- sapi_cli_single_write
- sapi_cli_ub_write
- sapi_cli_flush
- sapi_cli_register_variables
- sapi_cli_log_message
- sapi_cli_deactivate
- sapi_cli_read_cookies
- sapi_cli_header_handler
- sapi_cli_send_headers
- sapi_cli_send_header
- php_cli_startup
- sapi_cli_ini_defaults
- php_cli_usage
- cli_register_file_handles
- cli_seek_file_begin
- do_cli
- WinMain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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"},
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"},
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"},
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}
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
332
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
351
352
353 php_import_environment_variables(track_vars_array);
354
355
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
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
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
411
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
431
432
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
446
447 static sapi_module_struct cli_sapi_module = {
448 "cli",
449 "Command Line Interface",
450
451 php_cli_startup,
452 php_module_shutdown_wrapper,
453
454 NULL,
455 sapi_cli_deactivate,
456
457 sapi_cli_ub_write,
458 sapi_cli_flush,
459 NULL,
460 NULL,
461
462 php_error,
463
464 sapi_cli_header_handler,
465 sapi_cli_send_headers,
466 sapi_cli_send_header,
467
468 NULL,
469 sapi_cli_read_cookies,
470
471 sapi_cli_register_variables,
472 sapi_cli_log_message,
473 NULL,
474 NULL,
475
476 STANDARD_SAPI_MODULE_PROPERTIES
477 };
478
479
480
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
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
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
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
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);
632 }
633
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;
670
671 while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
672 switch (c) {
673
674 case 'i':
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':
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':
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
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':
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':
743
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':
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':
772 if (behavior != PHP_MODE_STANDARD) {
773 break;
774 }
775 behavior=PHP_MODE_LINT;
776 break;
777
778 case 'q':
779
780 break;
781
782 case 'r':
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':
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':
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
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
925
926
927
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
937
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;
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
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
1184
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);
1210
1211
1212
1213
1214
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;
1231 setmode(_fileno(stdin), O_BINARY);
1232 setmode(_fileno(stdout), O_BINARY);
1233 setmode(_fileno(stderr), O_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
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':
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':
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
1324 if (sapi_module->startup(sapi_module) == FAILURE) {
1325
1326
1327
1328
1329
1330 exit_status = 1;
1331 goto out;
1332 }
1333 module_started = 1;
1334
1335
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
1370
1371
1372 cleanup_ps_args(argv);
1373 exit(exit_status);
1374 }
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384