1/*
2   +----------------------------------------------------------------------+
3   | PHP Version 7                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 1997-2015 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   | Authors: Andi Gutmans <andi@zend.com>                                |
16   |          Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
17   |          Zeev Suraski <zeev@zend.com>                                |
18   +----------------------------------------------------------------------+
19*/
20
21/* $Id$ */
22
23/* {{{ includes
24 */
25
26#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
27
28#include "php.h"
29#include <stdio.h>
30#include <fcntl.h>
31#ifdef PHP_WIN32
32#include "win32/time.h"
33#include "win32/signal.h"
34#include "win32/php_win32_globals.h"
35#include "win32/winutil.h"
36#include <process.h>
37#elif defined(NETWARE)
38#include <sys/timeval.h>
39#ifdef USE_WINSOCK
40#include <novsock2.h>
41#endif
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_types.h"
57#include "zend_extensions.h"
58#include "php_ini.h"
59#include "php_globals.h"
60#include "php_main.h"
61#include "fopen_wrappers.h"
62#include "ext/standard/php_standard.h"
63#include "ext/standard/php_string.h"
64#include "ext/date/php_date.h"
65#include "php_variables.h"
66#include "ext/standard/credits.h"
67#ifdef PHP_WIN32
68#include <io.h>
69#include "win32/php_registry.h"
70#include "ext/standard/flock_compat.h"
71#endif
72#include "php_syslog.h"
73#include "Zend/zend_exceptions.h"
74
75#if PHP_SIGCHILD
76#include <sys/types.h>
77#include <sys/wait.h>
78#endif
79
80#include "zend_compile.h"
81#include "zend_execute.h"
82#include "zend_highlight.h"
83#include "zend_indent.h"
84#include "zend_extensions.h"
85#include "zend_ini.h"
86#include "zend_dtrace.h"
87
88#include "php_content_types.h"
89#include "php_ticks.h"
90#include "php_streams.h"
91#include "php_open_temporary_file.h"
92
93#include "SAPI.h"
94#include "rfc1867.h"
95
96#if HAVE_MMAP || defined(PHP_WIN32)
97# if HAVE_UNISTD_H
98#  include <unistd.h>
99#  if defined(_SC_PAGESIZE)
100#    define REAL_PAGE_SIZE sysconf(_SC_PAGESIZE);
101#  elif defined(_SC_PAGE_SIZE)
102#    define REAL_PAGE_SIZE sysconf(_SC_PAGE_SIZE);
103#  endif
104# endif
105# if HAVE_SYS_MMAN_H
106#  include <sys/mman.h>
107# endif
108# ifndef REAL_PAGE_SIZE
109#  ifdef PAGE_SIZE
110#   define REAL_PAGE_SIZE PAGE_SIZE
111#  else
112#   define REAL_PAGE_SIZE 4096
113#  endif
114# endif
115#endif
116/* }}} */
117
118#ifndef S_ISREG
119#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
120#endif
121
122PHPAPI int (*php_register_internal_extensions_func)(void) = php_register_internal_extensions;
123
124#ifndef ZTS
125php_core_globals core_globals;
126#else
127PHPAPI int core_globals_id;
128#endif
129
130#ifdef PHP_WIN32
131#include "win32_internal_function_disabled.h"
132
133static int php_win32_disable_functions(void)
134{
135    int i;
136
137    if (EG(windows_version_info).dwMajorVersion < 5) {
138        for (i = 0; i < function_name_cnt_5; i++) {
139            if (zend_hash_str_del(CG(function_table), function_name_5[i], strlen(function_name_5[i]))==FAILURE) {
140                php_printf("Unable to disable function '%s'\n", function_name_5[i]);
141                return FAILURE;
142            }
143        }
144    }
145
146    if (EG(windows_version_info).dwMajorVersion < 6) {
147        for (i = 0; i < function_name_cnt_6; i++) {
148            if (zend_hash_str_del(CG(function_table), function_name_6[i], strlen(function_name_6[i]))==FAILURE) {
149                php_printf("Unable to disable function '%s'\n", function_name_6[i]);
150                return FAILURE;
151            }
152        }
153    }
154    return SUCCESS;
155}
156#endif
157
158#define SAFE_FILENAME(f) ((f)?(f):"-")
159
160/* {{{ PHP_INI_MH
161 */
162static PHP_INI_MH(OnSetPrecision)
163{
164    zend_long i;
165
166    ZEND_ATOL(i, new_value->val);
167    if (i >= 0) {
168        EG(precision) = i;
169        return SUCCESS;
170    } else {
171        return FAILURE;
172    }
173}
174/* }}} */
175
176/* {{{ PHP_INI_MH
177 */
178static PHP_INI_MH(OnChangeMemoryLimit)
179{
180    if (new_value) {
181        PG(memory_limit) = zend_atol(new_value->val, (int)new_value->len);
182    } else {
183        PG(memory_limit) = 1<<30;       /* effectively, no limit */
184    }
185    return zend_set_memory_limit(PG(memory_limit));
186}
187/* }}} */
188
189
190/* {{{ php_disable_functions
191 */
192static void php_disable_functions(void)
193{
194    char *s = NULL, *e;
195
196    if (!*(INI_STR("disable_functions"))) {
197        return;
198    }
199
200    e = PG(disable_functions) = strdup(INI_STR("disable_functions"));
201    if (e == NULL) {
202        return;
203    }
204    while (*e) {
205        switch (*e) {
206            case ' ':
207            case ',':
208                if (s) {
209                    *e = '\0';
210                    zend_disable_function(s, e-s);
211                    s = NULL;
212                }
213                break;
214            default:
215                if (!s) {
216                    s = e;
217                }
218                break;
219        }
220        e++;
221    }
222    if (s) {
223        zend_disable_function(s, e-s);
224    }
225}
226/* }}} */
227
228/* {{{ php_disable_classes
229 */
230static void php_disable_classes(void)
231{
232    char *s = NULL, *e;
233
234    if (!*(INI_STR("disable_classes"))) {
235        return;
236    }
237
238    e = PG(disable_classes) = strdup(INI_STR("disable_classes"));
239
240    while (*e) {
241        switch (*e) {
242            case ' ':
243            case ',':
244                if (s) {
245                    *e = '\0';
246                    zend_disable_class(s, e-s);
247                    s = NULL;
248                }
249                break;
250            default:
251                if (!s) {
252                    s = e;
253                }
254                break;
255        }
256        e++;
257    }
258    if (s) {
259        zend_disable_class(s, e-s);
260    }
261}
262/* }}} */
263
264/* {{{ php_binary_init
265 */
266static void php_binary_init(void)
267{
268    char *binary_location;
269#ifdef PHP_WIN32
270    binary_location = (char *)malloc(MAXPATHLEN);
271    if (GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) {
272        free(binary_location);
273        PG(php_binary) = NULL;
274    }
275#else
276    if (sapi_module.executable_location) {
277        binary_location = (char *)malloc(MAXPATHLEN);
278        if (!strchr(sapi_module.executable_location, '/')) {
279            char *envpath, *path;
280            int found = 0;
281
282            if ((envpath = getenv("PATH")) != NULL) {
283                char *search_dir, search_path[MAXPATHLEN];
284                char *last = NULL;
285                zend_stat_t s;
286
287                path = estrdup(envpath);
288                search_dir = php_strtok_r(path, ":", &last);
289
290                while (search_dir) {
291                    snprintf(search_path, MAXPATHLEN, "%s/%s", search_dir, sapi_module.executable_location);
292                    if (VCWD_REALPATH(search_path, binary_location) && !VCWD_ACCESS(binary_location, X_OK) && VCWD_STAT(binary_location, &s) == 0 && S_ISREG(s.st_mode)) {
293                        found = 1;
294                        break;
295                    }
296                    search_dir = php_strtok_r(NULL, ":", &last);
297                }
298                efree(path);
299            }
300            if (!found) {
301                free(binary_location);
302                binary_location = NULL;
303            }
304        } else if (!VCWD_REALPATH(sapi_module.executable_location, binary_location) || VCWD_ACCESS(binary_location, X_OK)) {
305            free(binary_location);
306            binary_location = NULL;
307        }
308    } else {
309        binary_location = NULL;
310    }
311#endif
312    PG(php_binary) = binary_location;
313}
314/* }}} */
315
316/* {{{ PHP_INI_MH
317 */
318static PHP_INI_MH(OnUpdateTimeout)
319{
320    if (stage==PHP_INI_STAGE_STARTUP) {
321        /* Don't set a timeout on startup, only per-request */
322        ZEND_ATOL(EG(timeout_seconds), new_value->val);
323        return SUCCESS;
324    }
325    zend_unset_timeout();
326    ZEND_ATOL(EG(timeout_seconds), new_value->val);
327    zend_set_timeout(EG(timeout_seconds), 0);
328    return SUCCESS;
329}
330/* }}} */
331
332/* {{{ php_get_display_errors_mode() helper function
333 */
334static int php_get_display_errors_mode(char *value, int value_length)
335{
336    int mode;
337
338    if (!value) {
339        return PHP_DISPLAY_ERRORS_STDOUT;
340    }
341
342    if (value_length == 2 && !strcasecmp("on", value)) {
343        mode = PHP_DISPLAY_ERRORS_STDOUT;
344    } else if (value_length == 3 && !strcasecmp("yes", value)) {
345        mode = PHP_DISPLAY_ERRORS_STDOUT;
346    } else if (value_length == 4 && !strcasecmp("true", value)) {
347        mode = PHP_DISPLAY_ERRORS_STDOUT;
348    } else if (value_length == 6 && !strcasecmp(value, "stderr")) {
349        mode = PHP_DISPLAY_ERRORS_STDERR;
350    } else if (value_length == 6 && !strcasecmp(value, "stdout")) {
351        mode = PHP_DISPLAY_ERRORS_STDOUT;
352    } else {
353        ZEND_ATOL(mode, value);
354        if (mode && mode != PHP_DISPLAY_ERRORS_STDOUT && mode != PHP_DISPLAY_ERRORS_STDERR) {
355            mode = PHP_DISPLAY_ERRORS_STDOUT;
356        }
357    }
358
359    return mode;
360}
361/* }}} */
362
363/* {{{ PHP_INI_MH
364 */
365static PHP_INI_MH(OnUpdateDisplayErrors)
366{
367    PG(display_errors) = (zend_bool) php_get_display_errors_mode(new_value->val, (int)new_value->len);
368
369    return SUCCESS;
370}
371/* }}} */
372
373/* {{{ PHP_INI_DISP
374 */
375static PHP_INI_DISP(display_errors_mode)
376{
377    int mode, tmp_value_length, cgi_or_cli;
378    char *tmp_value;
379
380    if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
381        tmp_value = (ini_entry->orig_value ? ini_entry->orig_value->val : NULL );
382        tmp_value_length = (int)(ini_entry->orig_value? ini_entry->orig_value->len : 0);
383    } else if (ini_entry->value) {
384        tmp_value = ini_entry->value->val;
385        tmp_value_length = (int)ini_entry->value->len;
386    } else {
387        tmp_value = NULL;
388        tmp_value_length = 0;
389    }
390
391    mode = php_get_display_errors_mode(tmp_value, tmp_value_length);
392
393    /* Display 'On' for other SAPIs instead of STDOUT or STDERR */
394    cgi_or_cli = (!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi"));
395
396    switch (mode) {
397        case PHP_DISPLAY_ERRORS_STDERR:
398            if (cgi_or_cli ) {
399                PUTS("STDERR");
400            } else {
401                PUTS("On");
402            }
403            break;
404
405        case PHP_DISPLAY_ERRORS_STDOUT:
406            if (cgi_or_cli ) {
407                PUTS("STDOUT");
408            } else {
409                PUTS("On");
410            }
411            break;
412
413        default:
414            PUTS("Off");
415            break;
416    }
417}
418/* }}} */
419
420/* {{{ PHP_INI_MH
421 */
422static PHP_INI_MH(OnUpdateInternalEncoding)
423{
424    if (new_value) {
425        OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
426    }
427    return SUCCESS;
428}
429/* }}} */
430
431/* {{{ PHP_INI_MH
432 */
433static PHP_INI_MH(OnUpdateInputEncoding)
434{
435    if (new_value) {
436        OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
437    }
438    return SUCCESS;
439}
440/* }}} */
441
442/* {{{ PHP_INI_MH
443 */
444static PHP_INI_MH(OnUpdateOutputEncoding)
445{
446    if (new_value) {
447        OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
448    }
449    return SUCCESS;
450}
451/* }}} */
452
453/* {{{ PHP_INI_MH
454 */
455static PHP_INI_MH(OnUpdateErrorLog)
456{
457    /* Only do the safemode/open_basedir check at runtime */
458    if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value && strcmp(new_value->val, "syslog")) {
459        if (PG(open_basedir) && php_check_open_basedir(new_value->val)) {
460            return FAILURE;
461        }
462    }
463    OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
464    return SUCCESS;
465}
466/* }}} */
467
468/* {{{ PHP_INI_MH
469 */
470static PHP_INI_MH(OnUpdateMailLog)
471{
472    /* Only do the safemode/open_basedir check at runtime */
473    if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value) {
474        if (PG(open_basedir) && php_check_open_basedir(new_value->val)) {
475            return FAILURE;
476        }
477    }
478    OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage);
479    return SUCCESS;
480}
481/* }}} */
482
483/* {{{ PHP_INI_MH
484 */
485static PHP_INI_MH(OnChangeMailForceExtra)
486{
487    /* Don't allow changing it in htaccess */
488    if (stage == PHP_INI_STAGE_HTACCESS) {
489            return FAILURE;
490    }
491    return SUCCESS;
492}
493/* }}} */
494
495/* defined in browscap.c */
496PHP_INI_MH(OnChangeBrowscap);
497
498
499/* Need to be read from the environment (?):
500 * PHP_AUTO_PREPEND_FILE
501 * PHP_AUTO_APPEND_FILE
502 * PHP_DOCUMENT_ROOT
503 * PHP_USER_DIR
504 * PHP_INCLUDE_PATH
505 */
506
507 /* Windows and Netware use the internal mail */
508#if defined(PHP_WIN32) || defined(NETWARE)
509# define DEFAULT_SENDMAIL_PATH NULL
510#elif defined(PHP_PROG_SENDMAIL)
511# define DEFAULT_SENDMAIL_PATH PHP_PROG_SENDMAIL " -t -i "
512#else
513# define DEFAULT_SENDMAIL_PATH "/usr/sbin/sendmail -t -i"
514#endif
515
516/* {{{ PHP_INI
517 */
518PHP_INI_BEGIN()
519    PHP_INI_ENTRY_EX("highlight.comment",       HL_COMMENT_COLOR,   PHP_INI_ALL,    NULL,           php_ini_color_displayer_cb)
520    PHP_INI_ENTRY_EX("highlight.default",       HL_DEFAULT_COLOR,   PHP_INI_ALL,    NULL,           php_ini_color_displayer_cb)
521    PHP_INI_ENTRY_EX("highlight.html",          HL_HTML_COLOR,      PHP_INI_ALL,    NULL,           php_ini_color_displayer_cb)
522    PHP_INI_ENTRY_EX("highlight.keyword",       HL_KEYWORD_COLOR,   PHP_INI_ALL,    NULL,           php_ini_color_displayer_cb)
523    PHP_INI_ENTRY_EX("highlight.string",        HL_STRING_COLOR,    PHP_INI_ALL,    NULL,           php_ini_color_displayer_cb)
524
525    STD_PHP_INI_ENTRY_EX("display_errors",      "1",        PHP_INI_ALL,        OnUpdateDisplayErrors,  display_errors,         php_core_globals,   core_globals, display_errors_mode)
526    STD_PHP_INI_BOOLEAN("display_startup_errors",   "0",    PHP_INI_ALL,        OnUpdateBool,           display_startup_errors, php_core_globals,   core_globals)
527    STD_PHP_INI_BOOLEAN("enable_dl",            "1",        PHP_INI_SYSTEM,     OnUpdateBool,           enable_dl,              php_core_globals,   core_globals)
528    STD_PHP_INI_BOOLEAN("expose_php",           "1",        PHP_INI_SYSTEM,     OnUpdateBool,           expose_php,             php_core_globals,   core_globals)
529    STD_PHP_INI_ENTRY("docref_root",            "",         PHP_INI_ALL,        OnUpdateString,         docref_root,            php_core_globals,   core_globals)
530    STD_PHP_INI_ENTRY("docref_ext",             "",         PHP_INI_ALL,        OnUpdateString,         docref_ext,             php_core_globals,   core_globals)
531    STD_PHP_INI_BOOLEAN("html_errors",          "1",        PHP_INI_ALL,        OnUpdateBool,           html_errors,            php_core_globals,   core_globals)
532    STD_PHP_INI_BOOLEAN("xmlrpc_errors",        "0",        PHP_INI_SYSTEM,     OnUpdateBool,           xmlrpc_errors,          php_core_globals,   core_globals)
533    STD_PHP_INI_ENTRY("xmlrpc_error_number",    "0",        PHP_INI_ALL,        OnUpdateLong,           xmlrpc_error_number,    php_core_globals,   core_globals)
534    STD_PHP_INI_ENTRY("max_input_time",         "-1",   PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLong,           max_input_time, php_core_globals,   core_globals)
535    STD_PHP_INI_BOOLEAN("ignore_user_abort",    "0",        PHP_INI_ALL,        OnUpdateBool,           ignore_user_abort,      php_core_globals,   core_globals)
536    STD_PHP_INI_BOOLEAN("implicit_flush",       "0",        PHP_INI_ALL,        OnUpdateBool,           implicit_flush,         php_core_globals,   core_globals)
537    STD_PHP_INI_BOOLEAN("log_errors",           "0",        PHP_INI_ALL,        OnUpdateBool,           log_errors,             php_core_globals,   core_globals)
538    STD_PHP_INI_ENTRY("log_errors_max_len",  "1024",        PHP_INI_ALL,        OnUpdateLong,           log_errors_max_len,     php_core_globals,   core_globals)
539    STD_PHP_INI_BOOLEAN("ignore_repeated_errors",   "0",    PHP_INI_ALL,        OnUpdateBool,           ignore_repeated_errors, php_core_globals,   core_globals)
540    STD_PHP_INI_BOOLEAN("ignore_repeated_source",   "0",    PHP_INI_ALL,        OnUpdateBool,           ignore_repeated_source, php_core_globals,   core_globals)
541    STD_PHP_INI_BOOLEAN("report_memleaks",      "1",        PHP_INI_ALL,        OnUpdateBool,           report_memleaks,        php_core_globals,   core_globals)
542    STD_PHP_INI_BOOLEAN("report_zend_debug",    "1",        PHP_INI_ALL,        OnUpdateBool,           report_zend_debug,      php_core_globals,   core_globals)
543    STD_PHP_INI_ENTRY("output_buffering",       "0",        PHP_INI_PERDIR|PHP_INI_SYSTEM,  OnUpdateLong,   output_buffering,       php_core_globals,   core_globals)
544    STD_PHP_INI_ENTRY("output_handler",         NULL,       PHP_INI_PERDIR|PHP_INI_SYSTEM,  OnUpdateString, output_handler,     php_core_globals,   core_globals)
545    STD_PHP_INI_BOOLEAN("register_argc_argv",   "1",        PHP_INI_PERDIR|PHP_INI_SYSTEM,  OnUpdateBool,   register_argc_argv,     php_core_globals,   core_globals)
546    STD_PHP_INI_BOOLEAN("auto_globals_jit",     "1",        PHP_INI_PERDIR|PHP_INI_SYSTEM,  OnUpdateBool,   auto_globals_jit,   php_core_globals,   core_globals)
547    STD_PHP_INI_BOOLEAN("short_open_tag",   DEFAULT_SHORT_OPEN_TAG, PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateBool,           short_tags,             zend_compiler_globals,  compiler_globals)
548    STD_PHP_INI_BOOLEAN("sql.safe_mode",        "0",        PHP_INI_SYSTEM,     OnUpdateBool,           sql_safe_mode,          php_core_globals,   core_globals)
549    STD_PHP_INI_BOOLEAN("track_errors",         "0",        PHP_INI_ALL,        OnUpdateBool,           track_errors,           php_core_globals,   core_globals)
550
551    STD_PHP_INI_ENTRY("unserialize_callback_func",  NULL,   PHP_INI_ALL,        OnUpdateString,         unserialize_callback_func,  php_core_globals,   core_globals)
552    STD_PHP_INI_ENTRY("serialize_precision",    "17",   PHP_INI_ALL,        OnUpdateLongGEZero,         serialize_precision,    php_core_globals,   core_globals)
553    STD_PHP_INI_ENTRY("arg_separator.output",   "&",        PHP_INI_ALL,        OnUpdateStringUnempty,  arg_separator.output,   php_core_globals,   core_globals)
554    STD_PHP_INI_ENTRY("arg_separator.input",    "&",        PHP_INI_SYSTEM|PHP_INI_PERDIR,  OnUpdateStringUnempty,  arg_separator.input,    php_core_globals,   core_globals)
555
556    STD_PHP_INI_ENTRY("auto_append_file",       NULL,       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateString,         auto_append_file,       php_core_globals,   core_globals)
557    STD_PHP_INI_ENTRY("auto_prepend_file",      NULL,       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateString,         auto_prepend_file,      php_core_globals,   core_globals)
558    STD_PHP_INI_ENTRY("doc_root",               NULL,       PHP_INI_SYSTEM,     OnUpdateStringUnempty,  doc_root,               php_core_globals,   core_globals)
559    STD_PHP_INI_ENTRY("default_charset",        PHP_DEFAULT_CHARSET,    PHP_INI_ALL,    OnUpdateString,         default_charset,        sapi_globals_struct, sapi_globals)
560    STD_PHP_INI_ENTRY("default_mimetype",       SAPI_DEFAULT_MIMETYPE,  PHP_INI_ALL,    OnUpdateString,         default_mimetype,       sapi_globals_struct, sapi_globals)
561    STD_PHP_INI_ENTRY("internal_encoding",      NULL,           PHP_INI_ALL,    OnUpdateInternalEncoding,   internal_encoding,  php_core_globals, core_globals)
562    STD_PHP_INI_ENTRY("input_encoding",         NULL,           PHP_INI_ALL,    OnUpdateInputEncoding,              input_encoding,     php_core_globals, core_globals)
563    STD_PHP_INI_ENTRY("output_encoding",        NULL,           PHP_INI_ALL,    OnUpdateOutputEncoding,             output_encoding,    php_core_globals, core_globals)
564    STD_PHP_INI_ENTRY("error_log",              NULL,       PHP_INI_ALL,        OnUpdateErrorLog,           error_log,              php_core_globals,   core_globals)
565    STD_PHP_INI_ENTRY("extension_dir",          PHP_EXTENSION_DIR,      PHP_INI_SYSTEM,     OnUpdateStringUnempty,  extension_dir,          php_core_globals,   core_globals)
566    STD_PHP_INI_ENTRY("sys_temp_dir",           NULL,       PHP_INI_SYSTEM,     OnUpdateStringUnempty,  sys_temp_dir,           php_core_globals,   core_globals)
567    STD_PHP_INI_ENTRY("include_path",           PHP_INCLUDE_PATH,       PHP_INI_ALL,        OnUpdateStringUnempty,  include_path,           php_core_globals,   core_globals)
568    PHP_INI_ENTRY("max_execution_time",         "30",       PHP_INI_ALL,            OnUpdateTimeout)
569    STD_PHP_INI_ENTRY("open_basedir",           NULL,       PHP_INI_ALL,        OnUpdateBaseDir,            open_basedir,           php_core_globals,   core_globals)
570
571    STD_PHP_INI_BOOLEAN("file_uploads",         "1",        PHP_INI_SYSTEM,     OnUpdateBool,           file_uploads,           php_core_globals,   core_globals)
572    STD_PHP_INI_ENTRY("upload_max_filesize",    "2M",       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLong,           upload_max_filesize,    php_core_globals,   core_globals)
573    STD_PHP_INI_ENTRY("post_max_size",          "8M",       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLong,           post_max_size,          sapi_globals_struct,sapi_globals)
574    STD_PHP_INI_ENTRY("upload_tmp_dir",         NULL,       PHP_INI_SYSTEM,     OnUpdateStringUnempty,  upload_tmp_dir,         php_core_globals,   core_globals)
575    STD_PHP_INI_ENTRY("max_input_nesting_level", "64",      PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLongGEZero, max_input_nesting_level,            php_core_globals,   core_globals)
576    STD_PHP_INI_ENTRY("max_input_vars",         "1000",     PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLongGEZero, max_input_vars,                     php_core_globals,   core_globals)
577
578    STD_PHP_INI_ENTRY("user_dir",               NULL,       PHP_INI_SYSTEM,     OnUpdateString,         user_dir,               php_core_globals,   core_globals)
579    STD_PHP_INI_ENTRY("variables_order",        "EGPCS",    PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateStringUnempty,  variables_order,        php_core_globals,   core_globals)
580    STD_PHP_INI_ENTRY("request_order",          NULL,       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateString, request_order,      php_core_globals,   core_globals)
581
582    STD_PHP_INI_ENTRY("error_append_string",    NULL,       PHP_INI_ALL,        OnUpdateString,         error_append_string,    php_core_globals,   core_globals)
583    STD_PHP_INI_ENTRY("error_prepend_string",   NULL,       PHP_INI_ALL,        OnUpdateString,         error_prepend_string,   php_core_globals,   core_globals)
584
585    PHP_INI_ENTRY("SMTP",                       "localhost",PHP_INI_ALL,        NULL)
586    PHP_INI_ENTRY("smtp_port",                  "25",       PHP_INI_ALL,        NULL)
587    STD_PHP_INI_BOOLEAN("mail.add_x_header",            "0",        PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateBool,           mail_x_header,          php_core_globals,   core_globals)
588    STD_PHP_INI_ENTRY("mail.log",                   NULL,       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateMailLog,            mail_log,           php_core_globals,   core_globals)
589    PHP_INI_ENTRY("browscap",                   NULL,       PHP_INI_SYSTEM,     OnChangeBrowscap)
590    PHP_INI_ENTRY("memory_limit",               "128M",     PHP_INI_ALL,        OnChangeMemoryLimit)
591    PHP_INI_ENTRY("precision",                  "14",       PHP_INI_ALL,        OnSetPrecision)
592    PHP_INI_ENTRY("sendmail_from",              NULL,       PHP_INI_ALL,        NULL)
593    PHP_INI_ENTRY("sendmail_path",  DEFAULT_SENDMAIL_PATH,  PHP_INI_SYSTEM,     NULL)
594    PHP_INI_ENTRY("mail.force_extra_parameters",NULL,       PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnChangeMailForceExtra)
595    PHP_INI_ENTRY("disable_functions",          "",         PHP_INI_SYSTEM,     NULL)
596    PHP_INI_ENTRY("disable_classes",            "",         PHP_INI_SYSTEM,     NULL)
597    PHP_INI_ENTRY("max_file_uploads",           "20",           PHP_INI_SYSTEM|PHP_INI_PERDIR,      NULL)
598
599    STD_PHP_INI_BOOLEAN("allow_url_fopen",      "1",        PHP_INI_SYSTEM,     OnUpdateBool,       allow_url_fopen,        php_core_globals,       core_globals)
600    STD_PHP_INI_BOOLEAN("allow_url_include",    "0",        PHP_INI_SYSTEM,     OnUpdateBool,       allow_url_include,      php_core_globals,       core_globals)
601    STD_PHP_INI_BOOLEAN("enable_post_data_reading", "1",    PHP_INI_SYSTEM|PHP_INI_PERDIR,  OnUpdateBool,   enable_post_data_reading,   php_core_globals,   core_globals)
602
603    STD_PHP_INI_ENTRY("realpath_cache_size",    "16K",      PHP_INI_SYSTEM,     OnUpdateLong,   realpath_cache_size_limit,  virtual_cwd_globals,    cwd_globals)
604    STD_PHP_INI_ENTRY("realpath_cache_ttl",     "120",      PHP_INI_SYSTEM,     OnUpdateLong,   realpath_cache_ttl,         virtual_cwd_globals,    cwd_globals)
605
606    STD_PHP_INI_ENTRY("user_ini.filename",      ".user.ini",    PHP_INI_SYSTEM,     OnUpdateString,     user_ini_filename,  php_core_globals,       core_globals)
607    STD_PHP_INI_ENTRY("user_ini.cache_ttl",     "300",          PHP_INI_SYSTEM,     OnUpdateLong,       user_ini_cache_ttl, php_core_globals,       core_globals)
608    STD_PHP_INI_BOOLEAN("exit_on_timeout",      "0",        PHP_INI_ALL,        OnUpdateBool,           exit_on_timeout,            php_core_globals,   core_globals)
609#ifdef PHP_WIN32
610    STD_PHP_INI_BOOLEAN("windows.show_crt_warning",     "0",        PHP_INI_ALL,        OnUpdateBool,           windows_show_crt_warning,           php_core_globals,   core_globals)
611#endif
612PHP_INI_END()
613/* }}} */
614
615/* True globals (no need for thread safety */
616/* But don't make them a single int bitfield */
617static int module_initialized = 0;
618static int module_startup = 1;
619static int module_shutdown = 0;
620
621/* {{{ php_during_module_startup */
622static int php_during_module_startup(void)
623{
624    return module_startup;
625}
626/* }}} */
627
628/* {{{ php_during_module_shutdown */
629static int php_during_module_shutdown(void)
630{
631    return module_shutdown;
632}
633/* }}} */
634
635/* {{{ php_get_module_initialized
636 */
637PHPAPI int php_get_module_initialized(void)
638{
639    return module_initialized;
640}
641/* }}} */
642
643/* {{{ php_log_err
644 */
645PHPAPI void php_log_err(char *log_message)
646{
647    int fd = -1;
648    time_t error_time;
649
650    if (PG(in_error_log)) {
651        /* prevent recursive invocation */
652        return;
653    }
654    PG(in_error_log) = 1;
655
656    /* Try to use the specified logging location. */
657    if (PG(error_log) != NULL) {
658#ifdef HAVE_SYSLOG_H
659        if (!strcmp(PG(error_log), "syslog")) {
660            php_syslog(LOG_NOTICE, "%s", log_message);
661            PG(in_error_log) = 0;
662            return;
663        }
664#endif
665        fd = VCWD_OPEN_MODE(PG(error_log), O_CREAT | O_APPEND | O_WRONLY, 0644);
666        if (fd != -1) {
667            char *tmp;
668            size_t len;
669            zend_string *error_time_str;
670
671            time(&error_time);
672#ifdef ZTS
673            if (!php_during_module_startup()) {
674                error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1);
675            } else {
676                error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 0);
677            }
678#else
679            error_time_str = php_format_date("d-M-Y H:i:s e", 13, error_time, 1);
680#endif
681            len = spprintf(&tmp, 0, "[%s] %s%s", error_time_str->val, log_message, PHP_EOL);
682#ifdef PHP_WIN32
683            php_flock(fd, 2);
684            /* XXX should eventually write in a loop if len > UINT_MAX */
685            php_ignore_value(write(fd, tmp, (unsigned)len));
686#else
687            php_ignore_value(write(fd, tmp, len));
688#endif
689            efree(tmp);
690            zend_string_free(error_time_str);
691            close(fd);
692            PG(in_error_log) = 0;
693            return;
694        }
695    }
696
697    /* Otherwise fall back to the default logging location, if we have one */
698
699    if (sapi_module.log_message) {
700        sapi_module.log_message(log_message);
701    }
702    PG(in_error_log) = 0;
703}
704/* }}} */
705
706/* {{{ php_write
707   wrapper for modules to use PHPWRITE */
708PHPAPI size_t php_write(void *buf, size_t size)
709{
710    return PHPWRITE(buf, size);
711}
712/* }}} */
713
714/* {{{ php_printf
715 */
716PHPAPI size_t php_printf(const char *format, ...)
717{
718    va_list args;
719    size_t ret;
720    char *buffer;
721    size_t size;
722
723    va_start(args, format);
724    size = vspprintf(&buffer, 0, format, args);
725    ret = PHPWRITE(buffer, size);
726    efree(buffer);
727    va_end(args);
728
729    return ret;
730}
731/* }}} */
732
733/* {{{ php_verror */
734/* php_verror is called from php_error_docref<n> functions.
735 * Its purpose is to unify error messages and automatically generate clickable
736 * html error messages if correcponding ini setting (html_errors) is activated.
737 * See: CODING_STANDARDS for details.
738 */
739PHPAPI void php_verror(const char *docref, const char *params, int type, const char *format, va_list args)
740{
741    zend_string *replace_buffer = NULL, *replace_origin = NULL;
742    char *buffer = NULL, *docref_buf = NULL, *target = NULL;
743    char *docref_target = "", *docref_root = "";
744    char *p;
745    int buffer_len = 0;
746    const char *space = "";
747    const char *class_name = "";
748    const char *function;
749    int origin_len;
750    char *origin;
751    char *message;
752    int is_function = 0;
753
754    /* get error text into buffer and escape for html if necessary */
755    buffer_len = (int)vspprintf(&buffer, 0, format, args);
756
757    if (PG(html_errors)) {
758        replace_buffer = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, NULL);
759        efree(buffer);
760        buffer = replace_buffer->val;
761        buffer_len = (int)replace_buffer->len;
762    }
763
764    /* which function caused the problem if any at all */
765    if (php_during_module_startup()) {
766        function = "PHP Startup";
767    } else if (php_during_module_shutdown()) {
768        function = "PHP Shutdown";
769    } else if (EG(current_execute_data) &&
770                EG(current_execute_data)->func &&
771                ZEND_USER_CODE(EG(current_execute_data)->func->common.type) &&
772                EG(current_execute_data)->opline &&
773                EG(current_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL
774    ) {
775        switch (EG(current_execute_data)->opline->extended_value) {
776            case ZEND_EVAL:
777                function = "eval";
778                is_function = 1;
779                break;
780            case ZEND_INCLUDE:
781                function = "include";
782                is_function = 1;
783                break;
784            case ZEND_INCLUDE_ONCE:
785                function = "include_once";
786                is_function = 1;
787                break;
788            case ZEND_REQUIRE:
789                function = "require";
790                is_function = 1;
791                break;
792            case ZEND_REQUIRE_ONCE:
793                function = "require_once";
794                is_function = 1;
795                break;
796            default:
797                function = "Unknown";
798        }
799    } else {
800        function = get_active_function_name();
801        if (!function || !strlen(function)) {
802            function = "Unknown";
803        } else {
804            is_function = 1;
805            class_name = get_active_class_name(&space);
806        }
807    }
808
809    /* if we still have memory then format the origin */
810    if (is_function) {
811        origin_len = (int)spprintf(&origin, 0, "%s%s%s(%s)", class_name, space, function, params);
812    } else {
813        origin_len = (int)spprintf(&origin, 0, "%s", function);
814    }
815
816    if (PG(html_errors)) {
817        replace_origin = php_escape_html_entities((unsigned char*)origin, origin_len, 0, ENT_COMPAT, NULL);
818        efree(origin);
819        origin = replace_origin->val;
820    }
821
822    /* origin and buffer available, so lets come up with the error message */
823    if (docref && docref[0] == '#') {
824        docref_target = strchr(docref, '#');
825        docref = NULL;
826    }
827
828    /* no docref given but function is known (the default) */
829    if (!docref && is_function) {
830        int doclen;
831        while (*function == '_') {
832            function++;
833        }
834        if (space[0] == '\0') {
835            doclen = (int)spprintf(&docref_buf, 0, "function.%s", function);
836        } else {
837            doclen = (int)spprintf(&docref_buf, 0, "%s.%s", class_name, function);
838        }
839        while((p = strchr(docref_buf, '_')) != NULL) {
840            *p = '-';
841        }
842        docref = php_strtolower(docref_buf, doclen);
843    }
844
845    /* we have a docref for a function AND
846     * - we show errors in html mode AND
847     * - the user wants to see the links
848     */
849    if (docref && is_function && PG(html_errors) && strlen(PG(docref_root))) {
850        if (strncmp(docref, "http://", 7)) {
851            /* We don't have 'http://' so we use docref_root */
852
853            char *ref;  /* temp copy for duplicated docref */
854
855            docref_root = PG(docref_root);
856
857            ref = estrdup(docref);
858            if (docref_buf) {
859                efree(docref_buf);
860            }
861            docref_buf = ref;
862            /* strip of the target if any */
863            p = strrchr(ref, '#');
864            if (p) {
865                target = estrdup(p);
866                if (target) {
867                    docref_target = target;
868                    *p = '\0';
869                }
870            }
871            /* add the extension if it is set in ini */
872            if (PG(docref_ext) && strlen(PG(docref_ext))) {
873                spprintf(&docref_buf, 0, "%s%s", ref, PG(docref_ext));
874                efree(ref);
875            }
876            docref = docref_buf;
877        }
878        /* display html formatted or only show the additional links */
879        if (PG(html_errors)) {
880            spprintf(&message, 0, "%s [<a href='%s%s%s'>%s</a>]: %s", origin, docref_root, docref, docref_target, docref, buffer);
881        } else {
882            spprintf(&message, 0, "%s [%s%s%s]: %s", origin, docref_root, docref, docref_target, buffer);
883        }
884        if (target) {
885            efree(target);
886        }
887    } else {
888        spprintf(&message, 0, "%s: %s", origin, buffer);
889    }
890    if (replace_origin) {
891        zend_string_free(replace_origin);
892    } else {
893        efree(origin);
894    }
895    if (docref_buf) {
896        efree(docref_buf);
897    }
898
899    if (PG(track_errors) && module_initialized && EG(valid_symbol_table) &&
900            (Z_TYPE(EG(user_error_handler)) == IS_UNDEF || !(EG(user_error_handler_error_reporting) & type))) {
901        zval tmp;
902        ZVAL_STRINGL(&tmp, buffer, buffer_len);
903        if (EG(current_execute_data)) {
904            if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0) == FAILURE) {
905                zval_ptr_dtor(&tmp);
906            }
907        } else {
908            zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp);
909        }
910    }
911    if (replace_buffer) {
912        zend_string_free(replace_buffer);
913    } else {
914        efree(buffer);
915    }
916
917    php_error(type, "%s", message);
918    efree(message);
919}
920/* }}} */
921
922/* {{{ php_error_docref0 */
923/* See: CODING_STANDARDS for details. */
924PHPAPI void php_error_docref0(const char *docref, int type, const char *format, ...)
925{
926    va_list args;
927
928    va_start(args, format);
929    php_verror(docref, "", type, format, args);
930    va_end(args);
931}
932/* }}} */
933
934/* {{{ php_error_docref1 */
935/* See: CODING_STANDARDS for details. */
936PHPAPI void php_error_docref1(const char *docref, const char *param1, int type, const char *format, ...)
937{
938    va_list args;
939
940    va_start(args, format);
941    php_verror(docref, param1, type, format, args);
942    va_end(args);
943}
944/* }}} */
945
946/* {{{ php_error_docref2 */
947/* See: CODING_STANDARDS for details. */
948PHPAPI void php_error_docref2(const char *docref, const char *param1, const char *param2, int type, const char *format, ...)
949{
950    char *params;
951    va_list args;
952
953    spprintf(&params, 0, "%s,%s", param1, param2);
954    va_start(args, format);
955    php_verror(docref, params ? params : "...", type, format, args);
956    va_end(args);
957    if (params) {
958        efree(params);
959    }
960}
961/* }}} */
962
963#ifdef PHP_WIN32
964#define PHP_WIN32_ERROR_MSG_BUFFER_SIZE 512
965PHPAPI void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) {
966    if (error == 0) {
967        php_error_docref2(NULL, param1, param2, E_WARNING, "%s", strerror(errno));
968    } else {
969        char buf[PHP_WIN32_ERROR_MSG_BUFFER_SIZE + 1];
970        int buf_len;
971
972        FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buf, PHP_WIN32_ERROR_MSG_BUFFER_SIZE, NULL);
973        buf_len = (int)strlen(buf);
974        if (buf_len >= 2) {
975            buf[buf_len - 1] = '\0';
976            buf[buf_len - 2] = '\0';
977        }
978        php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", (char *)buf, error);
979    }
980}
981#undef PHP_WIN32_ERROR_MSG_BUFFER_SIZE
982#endif
983
984/* {{{ php_html_puts */
985PHPAPI void php_html_puts(const char *str, size_t size)
986{
987    zend_html_puts(str, size);
988}
989/* }}} */
990
991/* {{{ php_error_cb
992 extended error handling function */
993static void php_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args)
994{
995    char *buffer;
996    int buffer_len, display;
997
998    buffer_len = (int)vspprintf(&buffer, PG(log_errors_max_len), format, args);
999
1000    /* check for repeated errors to be ignored */
1001    if (PG(ignore_repeated_errors) && PG(last_error_message)) {
1002        /* no check for PG(last_error_file) is needed since it cannot
1003         * be NULL if PG(last_error_message) is not NULL */
1004        if (strcmp(PG(last_error_message), buffer)
1005            || (!PG(ignore_repeated_source)
1006                && ((PG(last_error_lineno) != (int)error_lineno)
1007                    || strcmp(PG(last_error_file), error_filename)))) {
1008            display = 1;
1009        } else {
1010            display = 0;
1011        }
1012    } else {
1013        display = 1;
1014    }
1015
1016    /* store the error if it has changed */
1017    if (display) {
1018#ifdef ZEND_SIGNALS
1019        HANDLE_BLOCK_INTERRUPTIONS();
1020#endif
1021        if (PG(last_error_message)) {
1022            free(PG(last_error_message));
1023            PG(last_error_message) = NULL;
1024        }
1025        if (PG(last_error_file)) {
1026            free(PG(last_error_file));
1027            PG(last_error_file) = NULL;
1028        }
1029#ifdef ZEND_SIGNALS
1030        HANDLE_UNBLOCK_INTERRUPTIONS();
1031#endif
1032        if (!error_filename) {
1033            error_filename = "Unknown";
1034        }
1035        PG(last_error_type) = type;
1036        PG(last_error_message) = strdup(buffer);
1037        PG(last_error_file) = strdup(error_filename);
1038        PG(last_error_lineno) = error_lineno;
1039    }
1040
1041    /* according to error handling mode, suppress error, throw exception or show it */
1042    if (EG(error_handling) != EH_NORMAL) {
1043        switch (type) {
1044            case E_ERROR:
1045            case E_CORE_ERROR:
1046            case E_COMPILE_ERROR:
1047            case E_USER_ERROR:
1048            case E_PARSE:
1049                /* fatal errors are real errors and cannot be made exceptions */
1050                break;
1051            case E_STRICT:
1052            case E_DEPRECATED:
1053            case E_USER_DEPRECATED:
1054                /* for the sake of BC to old damaged code */
1055                break;
1056            case E_NOTICE:
1057            case E_USER_NOTICE:
1058                /* notices are no errors and are not treated as such like E_WARNINGS */
1059                break;
1060            default:
1061                /* throw an exception if we are in EH_THROW mode
1062                 * but DO NOT overwrite a pending exception
1063                 */
1064                if (EG(error_handling) == EH_THROW && !EG(exception)) {
1065                    zend_throw_error_exception(EG(exception_class), buffer, 0, type);
1066                }
1067                efree(buffer);
1068                return;
1069        }
1070    }
1071
1072    /* display/log the error if necessary */
1073    if (display && (EG(error_reporting) & type || (type & E_CORE))
1074        && (PG(log_errors) || PG(display_errors) || (!module_initialized))) {
1075        char *error_type_str;
1076
1077        switch (type) {
1078            case E_ERROR:
1079            case E_CORE_ERROR:
1080            case E_COMPILE_ERROR:
1081            case E_USER_ERROR:
1082                error_type_str = "Fatal error";
1083                break;
1084            case E_RECOVERABLE_ERROR:
1085                error_type_str = "Catchable fatal error";
1086                break;
1087            case E_WARNING:
1088            case E_CORE_WARNING:
1089            case E_COMPILE_WARNING:
1090            case E_USER_WARNING:
1091                error_type_str = "Warning";
1092                break;
1093            case E_PARSE:
1094                error_type_str = "Parse error";
1095                break;
1096            case E_NOTICE:
1097            case E_USER_NOTICE:
1098                error_type_str = "Notice";
1099                break;
1100            case E_STRICT:
1101                error_type_str = "Strict Standards";
1102                break;
1103            case E_DEPRECATED:
1104            case E_USER_DEPRECATED:
1105                error_type_str = "Deprecated";
1106                break;
1107            default:
1108                error_type_str = "Unknown error";
1109                break;
1110        }
1111
1112        if (!module_initialized || PG(log_errors)) {
1113            char *log_buffer;
1114#ifdef PHP_WIN32
1115            if (type == E_CORE_ERROR || type == E_CORE_WARNING) {
1116                syslog(LOG_ALERT, "PHP %s: %s (%s)", error_type_str, buffer, GetCommandLine());
1117            }
1118#endif
1119            spprintf(&log_buffer, 0, "PHP %s:  %s in %s on line %d", error_type_str, buffer, error_filename, error_lineno);
1120            php_log_err(log_buffer);
1121            efree(log_buffer);
1122        }
1123
1124        if (PG(display_errors) && ((module_initialized && !PG(during_request_startup)) || (PG(display_startup_errors)))) {
1125            if (PG(xmlrpc_errors)) {
1126                php_printf("<?xml version=\"1.0\"?><methodResponse><fault><value><struct><member><name>faultCode</name><value><int>%pd</int></value></member><member><name>faultString</name><value><string>%s:%s in %s on line %d</string></value></member></struct></value></fault></methodResponse>", PG(xmlrpc_error_number), error_type_str, buffer, error_filename, error_lineno);
1127            } else {
1128                char *prepend_string = INI_STR("error_prepend_string");
1129                char *append_string = INI_STR("error_append_string");
1130
1131                if (PG(html_errors)) {
1132                    if (type == E_ERROR || type == E_PARSE) {
1133                        zend_string *buf = php_escape_html_entities((unsigned char*)buffer, buffer_len, 0, ENT_COMPAT, NULL);
1134                        php_printf("%s<br />\n<b>%s</b>:  %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buf->val, error_filename, error_lineno, STR_PRINT(append_string));
1135                        zend_string_free(buf);
1136                    } else {
1137                        php_printf("%s<br />\n<b>%s</b>:  %s in <b>%s</b> on line <b>%d</b><br />\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string));
1138                    }
1139                } else {
1140                    /* Write CLI/CGI errors to stderr if display_errors = "stderr" */
1141                    if ((!strcmp(sapi_module.name, "cli") || !strcmp(sapi_module.name, "cgi")) &&
1142                        PG(display_errors) == PHP_DISPLAY_ERRORS_STDERR
1143                    ) {
1144#ifdef PHP_WIN32
1145                        fprintf(stderr, "%s: %s in %s on line %u\n", error_type_str, buffer, error_filename, error_lineno);
1146                        fflush(stderr);
1147#else
1148                        fprintf(stderr, "%s: %s in %s on line %u\n", error_type_str, buffer, error_filename, error_lineno);
1149#endif
1150                    } else {
1151                        php_printf("%s\n%s: %s in %s on line %d\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string));
1152                    }
1153                }
1154            }
1155        }
1156#if ZEND_DEBUG
1157        if (PG(report_zend_debug)) {
1158            zend_bool trigger_break;
1159
1160            switch (type) {
1161                case E_ERROR:
1162                case E_CORE_ERROR:
1163                case E_COMPILE_ERROR:
1164                case E_USER_ERROR:
1165                    trigger_break=1;
1166                    break;
1167                default:
1168                    trigger_break=0;
1169                    break;
1170            }
1171            zend_output_debug_string(trigger_break, "%s(%d) : %s - %s", error_filename, error_lineno, error_type_str, buffer);
1172        }
1173#endif
1174    }
1175
1176    /* Bail out if we can't recover */
1177    switch (type) {
1178        case E_CORE_ERROR:
1179            if(!module_initialized) {
1180                /* bad error in module startup - no way we can live with this */
1181                exit(-2);
1182            }
1183        /* no break - intentionally */
1184        case E_ERROR:
1185        case E_RECOVERABLE_ERROR:
1186        case E_PARSE:
1187        case E_COMPILE_ERROR:
1188        case E_USER_ERROR:
1189        { /* new block to allow variable definition */
1190            /* eval() errors do not affect exit_status or response code */
1191            zend_bool during_eval = 0;
1192
1193            if (type == E_PARSE) {
1194                zend_execute_data *execute_data = EG(current_execute_data);
1195
1196                while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) {
1197                    execute_data = execute_data->prev_execute_data;
1198                }
1199
1200                during_eval = (execute_data &&
1201                    execute_data->opline->opcode == ZEND_INCLUDE_OR_EVAL &&
1202                    execute_data->opline->extended_value == ZEND_EVAL);
1203            }
1204            if (!during_eval) {
1205                EG(exit_status) = 255;
1206            }
1207            if (module_initialized) {
1208                if (!PG(display_errors) &&
1209                    !SG(headers_sent) &&
1210                    SG(sapi_headers).http_response_code == 200 &&
1211                    !during_eval
1212                ) {
1213                    sapi_header_line ctr = {0};
1214
1215                    ctr.line = "HTTP/1.0 500 Internal Server Error";
1216                    ctr.line_len = sizeof("HTTP/1.0 500 Internal Server Error") - 1;
1217                    sapi_header_op(SAPI_HEADER_REPLACE, &ctr);
1218                }
1219                /* the parser would return 1 (failure), we can bail out nicely */
1220                if (type == E_PARSE) {
1221                    CG(parse_error) = 0;
1222                } else {
1223                    /* restore memory limit */
1224                    zend_set_memory_limit(PG(memory_limit));
1225                    efree(buffer);
1226                    zend_objects_store_mark_destructed(&EG(objects_store));
1227                    zend_bailout();
1228                    return;
1229                }
1230            }
1231            break;
1232        }
1233    }
1234
1235    /* Log if necessary */
1236    if (!display) {
1237        efree(buffer);
1238        return;
1239    }
1240
1241    if (PG(track_errors) && module_initialized && EG(valid_symbol_table)) {
1242        zval tmp;
1243
1244        ZVAL_STRINGL(&tmp, buffer, buffer_len);
1245        if (EG(current_execute_data)) {
1246            if (zend_set_local_var_str("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0) == FAILURE) {
1247                zval_ptr_dtor(&tmp);
1248            }
1249        } else {
1250            zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp);
1251        }
1252    }
1253
1254    efree(buffer);
1255}
1256/* }}} */
1257
1258/* {{{ php_get_current_user
1259 */
1260PHPAPI char *php_get_current_user(void)
1261{
1262    zend_stat_t *pstat;
1263
1264    if (SG(request_info).current_user) {
1265        return SG(request_info).current_user;
1266    }
1267
1268    /* FIXME: I need to have this somehow handled if
1269    USE_SAPI is defined, because cgi will also be
1270    interfaced in USE_SAPI */
1271
1272    pstat = sapi_get_stat();
1273
1274    if (!pstat) {
1275        return "";
1276    } else {
1277#ifdef PHP_WIN32
1278        char name[256];
1279        DWORD len = sizeof(name)-1;
1280
1281        if (!GetUserName(name, &len)) {
1282            return "";
1283        }
1284        name[len] = '\0';
1285        SG(request_info).current_user_length = len;
1286        SG(request_info).current_user = estrndup(name, len);
1287        return SG(request_info).current_user;
1288#else
1289        struct passwd *pwd;
1290#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
1291        struct passwd _pw;
1292        struct passwd *retpwptr = NULL;
1293        int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
1294        char *pwbuf;
1295
1296        if (pwbuflen < 1) {
1297            return "";
1298        }
1299        pwbuf = emalloc(pwbuflen);
1300        if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) {
1301            efree(pwbuf);
1302            return "";
1303        }
1304        if (retpwptr == NULL) {
1305            efree(pwbuf);
1306            return "";
1307        }
1308        pwd = &_pw;
1309#else
1310        if ((pwd=getpwuid(pstat->st_uid))==NULL) {
1311            return "";
1312        }
1313#endif
1314        SG(request_info).current_user_length = strlen(pwd->pw_name);
1315        SG(request_info).current_user = estrndup(pwd->pw_name, SG(request_info).current_user_length);
1316#if defined(ZTS) && defined(HAVE_GETPWUID_R) && defined(_SC_GETPW_R_SIZE_MAX)
1317        efree(pwbuf);
1318#endif
1319        return SG(request_info).current_user;
1320#endif
1321    }
1322}
1323/* }}} */
1324
1325/* {{{ proto bool set_time_limit(int seconds)
1326   Sets the maximum time a script can run */
1327PHP_FUNCTION(set_time_limit)
1328{
1329    zend_long new_timeout;
1330    char *new_timeout_str;
1331    int new_timeout_strlen;
1332    zend_string *key;
1333
1334    if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &new_timeout) == FAILURE) {
1335        return;
1336    }
1337
1338    new_timeout_strlen = (int)zend_spprintf(&new_timeout_str, 0, ZEND_LONG_FMT, new_timeout);
1339
1340    key = zend_string_init("max_execution_time", sizeof("max_execution_time")-1, 0);
1341    if (zend_alter_ini_entry_chars_ex(key, new_timeout_str, new_timeout_strlen, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0) == SUCCESS) {
1342        RETVAL_TRUE;
1343    } else {
1344        RETVAL_FALSE;
1345    }
1346    zend_string_release(key);
1347    efree(new_timeout_str);
1348}
1349/* }}} */
1350
1351/* {{{ php_fopen_wrapper_for_zend
1352 */
1353static FILE *php_fopen_wrapper_for_zend(const char *filename, zend_string **opened_path)
1354{
1355    return php_stream_open_wrapper_as_file((char *)filename, "rb", USE_PATH|IGNORE_URL_WIN|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE, opened_path);
1356}
1357/* }}} */
1358
1359static void php_zend_stream_closer(void *handle) /* {{{ */
1360{
1361    php_stream_close((php_stream*)handle);
1362}
1363/* }}} */
1364
1365static void php_zend_stream_mmap_closer(void *handle) /* {{{ */
1366{
1367    php_stream_mmap_unmap((php_stream*)handle);
1368    php_zend_stream_closer(handle);
1369}
1370/* }}} */
1371
1372static size_t php_zend_stream_fsizer(void *handle) /* {{{ */
1373{
1374    php_stream_statbuf  ssb;
1375    if (php_stream_stat((php_stream*)handle, &ssb) == 0) {
1376        return ssb.sb.st_size;
1377    }
1378    return 0;
1379}
1380/* }}} */
1381
1382static int php_stream_open_for_zend(const char *filename, zend_file_handle *handle) /* {{{ */
1383{
1384    return php_stream_open_for_zend_ex(filename, handle, USE_PATH|REPORT_ERRORS|STREAM_OPEN_FOR_INCLUDE);
1385}
1386/* }}} */
1387
1388PHPAPI int php_stream_open_for_zend_ex(const char *filename, zend_file_handle *handle, int mode) /* {{{ */
1389{
1390    char *p;
1391    size_t len, mapped_len;
1392    php_stream *stream = php_stream_open_wrapper((char *)filename, "rb", mode, &handle->opened_path);
1393
1394    if (stream) {
1395#if HAVE_MMAP || defined(PHP_WIN32)
1396        size_t page_size = REAL_PAGE_SIZE;
1397#endif
1398
1399        handle->filename = (char*)filename;
1400        handle->free_filename = 0;
1401        handle->handle.stream.handle  = stream;
1402        handle->handle.stream.reader  = (zend_stream_reader_t)_php_stream_read;
1403        handle->handle.stream.fsizer  = php_zend_stream_fsizer;
1404        handle->handle.stream.isatty  = 0;
1405        /* can we mmap immediately? */
1406        memset(&handle->handle.stream.mmap, 0, sizeof(handle->handle.stream.mmap));
1407        len = php_zend_stream_fsizer(stream);
1408        if (len != 0
1409#if HAVE_MMAP || defined(PHP_WIN32)
1410        && ((len - 1) % page_size) <= page_size - ZEND_MMAP_AHEAD
1411#endif
1412        && php_stream_mmap_possible(stream)
1413        && (p = php_stream_mmap_range(stream, 0, len, PHP_STREAM_MAP_MODE_SHARED_READONLY, &mapped_len)) != NULL) {
1414            handle->handle.stream.closer   = php_zend_stream_mmap_closer;
1415            handle->handle.stream.mmap.buf = p;
1416            handle->handle.stream.mmap.len = mapped_len;
1417            handle->type = ZEND_HANDLE_MAPPED;
1418        } else {
1419            handle->handle.stream.closer = php_zend_stream_closer;
1420            handle->type = ZEND_HANDLE_STREAM;
1421        }
1422        /* suppress warning if this stream is not explicitly closed */
1423        php_stream_auto_cleanup(stream);
1424
1425        return SUCCESS;
1426    }
1427    return FAILURE;
1428}
1429/* }}} */
1430
1431static zend_string *php_resolve_path_for_zend(const char *filename, int filename_len) /* {{{ */
1432{
1433    return php_resolve_path(filename, filename_len, PG(include_path));
1434}
1435/* }}} */
1436
1437/* {{{ php_get_configuration_directive_for_zend
1438 */
1439static zval *php_get_configuration_directive_for_zend(zend_string *name)
1440{
1441    return cfg_get_entry_ex(name);
1442}
1443/* }}} */
1444
1445/* {{{ php_message_handler_for_zend
1446 */
1447static void php_message_handler_for_zend(zend_long message, const void *data)
1448{
1449    switch (message) {
1450        case ZMSG_FAILED_INCLUDE_FOPEN:
1451            php_error_docref("function.include", E_WARNING, "Failed opening '%s' for inclusion (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));
1452            break;
1453        case ZMSG_FAILED_REQUIRE_FOPEN:
1454            php_error_docref("function.require", E_COMPILE_ERROR, "Failed opening required '%s' (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));
1455            break;
1456        case ZMSG_FAILED_HIGHLIGHT_FOPEN:
1457            php_error_docref(NULL, E_WARNING, "Failed opening '%s' for highlighting", php_strip_url_passwd((char *) data));
1458            break;
1459        case ZMSG_MEMORY_LEAK_DETECTED:
1460        case ZMSG_MEMORY_LEAK_REPEATED:
1461#if ZEND_DEBUG
1462            if (EG(error_reporting) & E_WARNING) {
1463                char memory_leak_buf[1024];
1464
1465                if (message==ZMSG_MEMORY_LEAK_DETECTED) {
1466                    zend_leak_info *t = (zend_leak_info *) data;
1467
1468                    snprintf(memory_leak_buf, 512, "%s(%d) :  Freeing 0x%.8lX (%zu bytes), script=%s\n", t->filename, t->lineno, (zend_uintptr_t)t->addr, t->size, SAFE_FILENAME(SG(request_info).path_translated));
1469                    if (t->orig_filename) {
1470                        char relay_buf[512];
1471
1472                        snprintf(relay_buf, 512, "%s(%d) : Actual location (location was relayed)\n", t->orig_filename, t->orig_lineno);
1473                        strlcat(memory_leak_buf, relay_buf, sizeof(memory_leak_buf));
1474                    }
1475                } else {
1476                    unsigned long leak_count = (zend_uintptr_t) data;
1477
1478                    snprintf(memory_leak_buf, 512, "Last leak repeated %ld time%s\n", leak_count, (leak_count>1?"s":""));
1479                }
1480#   if defined(PHP_WIN32)
1481                OutputDebugString(memory_leak_buf);
1482#   else
1483                fprintf(stderr, "%s", memory_leak_buf);
1484#   endif
1485            }
1486#endif
1487            break;
1488        case ZMSG_MEMORY_LEAKS_GRAND_TOTAL:
1489#if ZEND_DEBUG
1490            if (EG(error_reporting) & E_WARNING) {
1491                char memory_leak_buf[512];
1492
1493                snprintf(memory_leak_buf, 512, "=== Total %d memory leaks detected ===\n", *((uint32_t *) data));
1494#   if defined(PHP_WIN32)
1495                OutputDebugString(memory_leak_buf);
1496#   else
1497                fprintf(stderr, "%s", memory_leak_buf);
1498#   endif
1499            }
1500#endif
1501            break;
1502        case ZMSG_LOG_SCRIPT_NAME: {
1503                struct tm *ta, tmbuf;
1504                time_t curtime;
1505                char *datetime_str, asctimebuf[52];
1506                char memory_leak_buf[4096];
1507
1508                time(&curtime);
1509                ta = php_localtime_r(&curtime, &tmbuf);
1510                datetime_str = php_asctime_r(ta, asctimebuf);
1511                if (datetime_str) {
1512                    datetime_str[strlen(datetime_str)-1]=0; /* get rid of the trailing newline */
1513                    snprintf(memory_leak_buf, sizeof(memory_leak_buf), "[%s]  Script:  '%s'\n", datetime_str, SAFE_FILENAME(SG(request_info).path_translated));
1514                } else {
1515                    snprintf(memory_leak_buf, sizeof(memory_leak_buf), "[null]  Script:  '%s'\n", SAFE_FILENAME(SG(request_info).path_translated));
1516                }
1517#   if defined(PHP_WIN32)
1518                OutputDebugString(memory_leak_buf);
1519#   else
1520                fprintf(stderr, "%s", memory_leak_buf);
1521#   endif
1522            }
1523            break;
1524    }
1525}
1526/* }}} */
1527
1528
1529void php_on_timeout(int seconds)
1530{
1531    PG(connection_status) |= PHP_CONNECTION_TIMEOUT;
1532    zend_set_timeout(EG(timeout_seconds), 1);
1533    if(PG(exit_on_timeout)) sapi_terminate_process();
1534}
1535
1536#if PHP_SIGCHILD
1537/* {{{ sigchld_handler
1538 */
1539static void sigchld_handler(int apar)
1540{
1541    int errno_save = errno;
1542
1543    while (waitpid(-1, NULL, WNOHANG) > 0);
1544    signal(SIGCHLD, sigchld_handler);
1545
1546    errno = errno_save;
1547}
1548/* }}} */
1549#endif
1550
1551/* {{{ php_start_sapi()
1552 */
1553static int php_start_sapi(void)
1554{
1555    int retval = SUCCESS;
1556
1557    if(!SG(sapi_started)) {
1558        zend_try {
1559            PG(during_request_startup) = 1;
1560
1561            /* initialize global variables */
1562            PG(modules_activated) = 0;
1563            PG(header_is_being_sent) = 0;
1564            PG(connection_status) = PHP_CONNECTION_NORMAL;
1565
1566            zend_activate();
1567            zend_set_timeout(EG(timeout_seconds), 1);
1568            zend_activate_modules();
1569            PG(modules_activated)=1;
1570        } zend_catch {
1571            retval = FAILURE;
1572        } zend_end_try();
1573
1574        SG(sapi_started) = 1;
1575    }
1576    return retval;
1577}
1578
1579/* }}} */
1580
1581/* {{{ php_request_startup
1582 */
1583#ifndef APACHE_HOOKS
1584int php_request_startup(void)
1585{
1586    int retval = SUCCESS;
1587
1588#ifdef HAVE_DTRACE
1589    DTRACE_REQUEST_STARTUP(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
1590#endif /* HAVE_DTRACE */
1591
1592#ifdef PHP_WIN32
1593    PG(com_initialized) = 0;
1594#endif
1595
1596#if PHP_SIGCHILD
1597    signal(SIGCHLD, sigchld_handler);
1598#endif
1599
1600    zend_try {
1601        PG(in_error_log) = 0;
1602        PG(during_request_startup) = 1;
1603
1604        php_output_activate();
1605
1606        /* initialize global variables */
1607        PG(modules_activated) = 0;
1608        PG(header_is_being_sent) = 0;
1609        PG(connection_status) = PHP_CONNECTION_NORMAL;
1610        PG(in_user_include) = 0;
1611
1612        zend_activate();
1613        sapi_activate();
1614
1615#ifdef ZEND_SIGNALS
1616        zend_signal_activate();
1617#endif
1618
1619        if (PG(max_input_time) == -1) {
1620            zend_set_timeout(EG(timeout_seconds), 1);
1621        } else {
1622            zend_set_timeout(PG(max_input_time), 1);
1623        }
1624
1625        /* Disable realpath cache if an open_basedir is set */
1626        if (PG(open_basedir) && *PG(open_basedir)) {
1627            CWDG(realpath_cache_size_limit) = 0;
1628        }
1629
1630        if (PG(expose_php)) {
1631            sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
1632        }
1633
1634        if (PG(output_handler) && PG(output_handler)[0]) {
1635            zval oh;
1636
1637            ZVAL_STRING(&oh, PG(output_handler));
1638            php_output_start_user(&oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1639            zval_ptr_dtor(&oh);
1640        } else if (PG(output_buffering)) {
1641            php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS);
1642        } else if (PG(implicit_flush)) {
1643            php_output_set_implicit_flush(1);
1644        }
1645
1646        /* We turn this off in php_execute_script() */
1647        /* PG(during_request_startup) = 0; */
1648
1649        php_hash_environment();
1650        zend_activate_modules();
1651        PG(modules_activated)=1;
1652    } zend_catch {
1653        retval = FAILURE;
1654    } zend_end_try();
1655
1656    SG(sapi_started) = 1;
1657
1658    return retval;
1659}
1660# else
1661int php_request_startup(void)
1662{
1663    int retval = SUCCESS;
1664
1665#if PHP_SIGCHILD
1666    signal(SIGCHLD, sigchld_handler);
1667#endif
1668
1669    if (php_start_sapi() == FAILURE) {
1670        return FAILURE;
1671    }
1672
1673    php_output_activate();
1674    sapi_activate();
1675    php_hash_environment();
1676
1677    zend_try {
1678        PG(during_request_startup) = 1;
1679        if (PG(expose_php)) {
1680            sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
1681        }
1682    } zend_catch {
1683        retval = FAILURE;
1684    } zend_end_try();
1685
1686    return retval;
1687}
1688# endif
1689/* }}} */
1690
1691/* {{{ php_request_startup_for_hook
1692 */
1693int php_request_startup_for_hook(void)
1694{
1695    int retval = SUCCESS;
1696
1697#if PHP_SIGCHLD
1698    signal(SIGCHLD, sigchld_handler);
1699#endif
1700
1701    if (php_start_sapi() == FAILURE) {
1702        return FAILURE;
1703    }
1704
1705    php_output_activate();
1706    sapi_activate_headers_only();
1707    php_hash_environment();
1708
1709    return retval;
1710}
1711/* }}} */
1712
1713/* {{{ php_request_shutdown_for_exec
1714 */
1715void php_request_shutdown_for_exec(void *dummy)
1716{
1717
1718    /* used to close fd's in the 3..255 range here, but it's problematic
1719     */
1720    shutdown_memory_manager(1, 1);
1721    zend_interned_strings_restore();
1722}
1723/* }}} */
1724
1725/* {{{ php_request_shutdown_for_hook
1726 */
1727void php_request_shutdown_for_hook(void *dummy)
1728{
1729
1730    if (PG(modules_activated)) zend_try {
1731        php_call_shutdown_functions();
1732    } zend_end_try();
1733
1734    if (PG(modules_activated)) {
1735        zend_deactivate_modules();
1736        php_free_shutdown_functions();
1737    }
1738
1739    zend_try {
1740        zend_unset_timeout();
1741    } zend_end_try();
1742
1743    zend_try {
1744        int i;
1745
1746        for (i = 0; i < NUM_TRACK_VARS; i++) {
1747            zval_ptr_dtor(&PG(http_globals)[i]);
1748        }
1749    } zend_end_try();
1750
1751    zend_deactivate();
1752
1753    zend_try {
1754        sapi_deactivate();
1755    } zend_end_try();
1756
1757    zend_try {
1758        php_shutdown_stream_hashes();
1759    } zend_end_try();
1760
1761    zend_try {
1762        shutdown_memory_manager(CG(unclean_shutdown), 0);
1763    } zend_end_try();
1764
1765    zend_interned_strings_restore();
1766
1767#ifdef ZEND_SIGNALS
1768    zend_try {
1769        zend_signal_deactivate();
1770    } zend_end_try();
1771#endif
1772}
1773
1774/* }}} */
1775
1776/* {{{ php_request_shutdown
1777 */
1778void php_request_shutdown(void *dummy)
1779{
1780    zend_bool report_memleaks;
1781
1782    report_memleaks = PG(report_memleaks);
1783
1784    /* EG(current_execute_data) points into nirvana and therefore cannot be safely accessed
1785     * inside zend_executor callback functions.
1786     */
1787    EG(current_execute_data) = NULL;
1788
1789    php_deactivate_ticks();
1790
1791    /* 1. Call all possible shutdown functions registered with register_shutdown_function() */
1792    if (PG(modules_activated)) zend_try {
1793        php_call_shutdown_functions();
1794    } zend_end_try();
1795
1796    /* 2. Call all possible __destruct() functions */
1797    zend_try {
1798        zend_call_destructors();
1799    } zend_end_try();
1800
1801    /* 3. Flush all output buffers */
1802    zend_try {
1803        zend_bool send_buffer = SG(request_info).headers_only ? 0 : 1;
1804
1805        if (CG(unclean_shutdown) && PG(last_error_type) == E_ERROR &&
1806            (size_t)PG(memory_limit) < zend_memory_usage(1)
1807        ) {
1808            send_buffer = 0;
1809        }
1810
1811        if (!send_buffer) {
1812            php_output_discard_all();
1813        } else {
1814            php_output_end_all();
1815        }
1816    } zend_end_try();
1817
1818    /* 4. Reset max_execution_time (no longer executing php code after response sent) */
1819    zend_try {
1820        zend_unset_timeout();
1821    } zend_end_try();
1822
1823    /* 5. Call all extensions RSHUTDOWN functions */
1824    if (PG(modules_activated)) {
1825        zend_deactivate_modules();
1826        php_free_shutdown_functions();
1827    }
1828
1829    /* 6. Shutdown output layer (send the set HTTP headers, cleanup output handlers, etc.) */
1830    zend_try {
1831        php_output_deactivate();
1832    } zend_end_try();
1833
1834    /* 7. Destroy super-globals */
1835    zend_try {
1836        int i;
1837
1838        for (i=0; i<NUM_TRACK_VARS; i++) {
1839            zval_ptr_dtor(&PG(http_globals)[i]);
1840        }
1841    } zend_end_try();
1842
1843    /* 8. free last error information */
1844    if (PG(last_error_message)) {
1845        free(PG(last_error_message));
1846        PG(last_error_message) = NULL;
1847    }
1848    if (PG(last_error_file)) {
1849        free(PG(last_error_file));
1850        PG(last_error_file) = NULL;
1851    }
1852
1853    /* 9. Shutdown scanner/executor/compiler and restore ini entries */
1854    zend_deactivate();
1855
1856    /* 10. Call all extensions post-RSHUTDOWN functions */
1857    zend_try {
1858        zend_post_deactivate_modules();
1859    } zend_end_try();
1860
1861    /* 11. SAPI related shutdown (free stuff) */
1862    zend_try {
1863        sapi_deactivate();
1864    } zend_end_try();
1865
1866    /* 12. free virtual CWD memory */
1867    virtual_cwd_deactivate();
1868
1869    /* 13. Destroy stream hashes */
1870    zend_try {
1871        php_shutdown_stream_hashes();
1872    } zend_end_try();
1873
1874    /* 14. Free Willy (here be crashes) */
1875    zend_interned_strings_restore();
1876    zend_try {
1877        shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0);
1878    } zend_end_try();
1879
1880    /* 15. Reset max_execution_time */
1881    zend_try {
1882        zend_unset_timeout();
1883    } zend_end_try();
1884
1885#ifdef PHP_WIN32
1886    if (PG(com_initialized)) {
1887        CoUninitialize();
1888        PG(com_initialized) = 0;
1889    }
1890#endif
1891
1892#ifdef HAVE_DTRACE
1893    DTRACE_REQUEST_SHUTDOWN(SAFE_FILENAME(SG(request_info).path_translated), SAFE_FILENAME(SG(request_info).request_uri), (char *)SAFE_FILENAME(SG(request_info).request_method));
1894#endif /* HAVE_DTRACE */
1895}
1896/* }}} */
1897
1898/* {{{ php_com_initialize
1899 */
1900PHPAPI void php_com_initialize(void)
1901{
1902#ifdef PHP_WIN32
1903    if (!PG(com_initialized)) {
1904        if (CoInitialize(NULL) == S_OK) {
1905            PG(com_initialized) = 1;
1906        }
1907    }
1908#endif
1909}
1910/* }}} */
1911
1912/* {{{ php_output_wrapper
1913 */
1914static size_t php_output_wrapper(const char *str, size_t str_length)
1915{
1916    return php_output_write(str, str_length);
1917}
1918/* }}} */
1919
1920#ifdef ZTS
1921/* {{{ core_globals_ctor
1922 */
1923static void core_globals_ctor(php_core_globals *core_globals)
1924{
1925    memset(core_globals, 0, sizeof(*core_globals));
1926}
1927/* }}} */
1928#endif
1929
1930/* {{{ core_globals_dtor
1931 */
1932static void core_globals_dtor(php_core_globals *core_globals)
1933{
1934    if (core_globals->last_error_message) {
1935        free(core_globals->last_error_message);
1936    }
1937    if (core_globals->last_error_file) {
1938        free(core_globals->last_error_file);
1939    }
1940    if (core_globals->disable_functions) {
1941        free(core_globals->disable_functions);
1942    }
1943    if (core_globals->disable_classes) {
1944        free(core_globals->disable_classes);
1945    }
1946    if (core_globals->php_binary) {
1947        free(core_globals->php_binary);
1948    }
1949
1950    php_shutdown_ticks();
1951}
1952/* }}} */
1953
1954PHP_MINFO_FUNCTION(php_core) { /* {{{ */
1955    php_info_print_table_start();
1956    php_info_print_table_row(2, "PHP Version", PHP_VERSION);
1957    php_info_print_table_end();
1958    DISPLAY_INI_ENTRIES();
1959}
1960/* }}} */
1961
1962/* {{{ php_register_extensions
1963 */
1964int php_register_extensions(zend_module_entry **ptr, int count)
1965{
1966    zend_module_entry **end = ptr + count;
1967
1968    while (ptr < end) {
1969        if (*ptr) {
1970            if (zend_register_internal_module(*ptr)==NULL) {
1971                return FAILURE;
1972            }
1973        }
1974        ptr++;
1975    }
1976    return SUCCESS;
1977}
1978
1979/* A very long time ago php_module_startup() was refactored in a way
1980 * which broke calling it with more than one additional module.
1981 * This alternative to php_register_extensions() works around that
1982 * by walking the shallower structure.
1983 *
1984 * See algo: https://bugs.php.net/bug.php?id=63159
1985 */
1986static int php_register_extensions_bc(zend_module_entry *ptr, int count)
1987{
1988    while (count--) {
1989        if (zend_register_internal_module(ptr++) == NULL) {
1990            return FAILURE;
1991        }
1992    }
1993    return SUCCESS;
1994}
1995/* }}} */
1996
1997#if defined(PHP_WIN32) && _MSC_VER >= 1400
1998static _invalid_parameter_handler old_invalid_parameter_handler;
1999
2000void dummy_invalid_parameter_handler(
2001        const wchar_t *expression,
2002        const wchar_t *function,
2003        const wchar_t *file,
2004        unsigned int   line,
2005        uintptr_t      pEwserved)
2006{
2007    static int called = 0;
2008    char buf[1024];
2009    int len;
2010
2011    if (!called) {
2012            if(PG(windows_show_crt_warning)) {
2013            called = 1;
2014            if (function) {
2015                if (file) {
2016                    len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws' (%ws:%u)", function, file, line);
2017                } else {
2018                    len = _snprintf(buf, sizeof(buf)-1, "Invalid parameter detected in CRT function '%ws'", function);
2019                }
2020            } else {
2021                len = _snprintf(buf, sizeof(buf)-1, "Invalid CRT parameter detected (function not known)");
2022            }
2023            zend_error(E_WARNING, "%s", buf);
2024            called = 0;
2025        }
2026    }
2027}
2028#endif
2029
2030/* {{{ php_module_startup
2031 */
2032int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_modules, uint num_additional_modules)
2033{
2034    zend_utility_functions zuf;
2035    zend_utility_values zuv;
2036    int retval = SUCCESS, module_number=0;  /* for REGISTER_INI_ENTRIES() */
2037    char *php_os;
2038    zend_module_entry *module;
2039
2040#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK))
2041    WORD wVersionRequested = MAKEWORD(2, 0);
2042    WSADATA wsaData;
2043#endif
2044#ifdef PHP_WIN32
2045    php_os = "WINNT";
2046#if _MSC_VER >= 1400
2047    old_invalid_parameter_handler =
2048        _set_invalid_parameter_handler(dummy_invalid_parameter_handler);
2049    if (old_invalid_parameter_handler != NULL) {
2050        _set_invalid_parameter_handler(old_invalid_parameter_handler);
2051    }
2052
2053    /* Disable the message box for assertions.*/
2054    _CrtSetReportMode(_CRT_ASSERT, 0);
2055#endif
2056#else
2057    php_os = PHP_OS;
2058#endif
2059
2060#ifdef ZTS
2061    (void)ts_resource(0);
2062#endif
2063
2064#ifdef PHP_WIN32
2065    php_win32_init_rng_lock();
2066#endif
2067
2068    module_shutdown = 0;
2069    module_startup = 1;
2070    sapi_initialize_empty_request();
2071    sapi_activate();
2072
2073    if (module_initialized) {
2074        return SUCCESS;
2075    }
2076
2077    sapi_module = *sf;
2078
2079    php_output_startup();
2080
2081#ifdef ZTS
2082    ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor);
2083    php_startup_ticks();
2084#ifdef PHP_WIN32
2085    ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor);
2086#endif
2087#else
2088    php_startup_ticks();
2089#endif
2090    gc_globals_ctor();
2091
2092    zuf.error_function = php_error_cb;
2093    zuf.printf_function = php_printf;
2094    zuf.write_function = php_output_wrapper;
2095    zuf.fopen_function = php_fopen_wrapper_for_zend;
2096    zuf.message_handler = php_message_handler_for_zend;
2097    zuf.block_interruptions = sapi_module.block_interruptions;
2098    zuf.unblock_interruptions = sapi_module.unblock_interruptions;
2099    zuf.get_configuration_directive = php_get_configuration_directive_for_zend;
2100    zuf.ticks_function = php_run_ticks;
2101    zuf.on_timeout = php_on_timeout;
2102    zuf.stream_open_function = php_stream_open_for_zend;
2103    zuf.vspprintf_function = vspprintf;
2104    zuf.vstrpprintf_function = vstrpprintf;
2105    zuf.getenv_function = sapi_getenv;
2106    zuf.resolve_path_function = php_resolve_path_for_zend;
2107    zend_startup(&zuf, NULL);
2108
2109#ifdef PHP_WIN32
2110    {
2111        OSVERSIONINFOEX *osvi = &EG(windows_version_info);
2112
2113        ZeroMemory(osvi, sizeof(OSVERSIONINFOEX));
2114        osvi->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
2115        if( !GetVersionEx((OSVERSIONINFO *) osvi)) {
2116            php_printf("\nGetVersionEx unusable. %d\n", GetLastError());
2117            return FAILURE;
2118        }
2119    }
2120#endif
2121
2122#if HAVE_SETLOCALE
2123    setlocale(LC_CTYPE, "");
2124    zend_update_current_locale();
2125#endif
2126
2127#if HAVE_TZSET
2128    tzset();
2129#endif
2130
2131#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK))
2132    /* start up winsock services */
2133    if (WSAStartup(wVersionRequested, &wsaData) != 0) {
2134        php_printf("\nwinsock.dll unusable. %d\n", WSAGetLastError());
2135        return FAILURE;
2136    }
2137#endif
2138
2139    le_index_ptr = zend_register_list_destructors_ex(NULL, NULL, "index pointer", 0);
2140
2141    /* Register constants */
2142    REGISTER_MAIN_STRINGL_CONSTANT("PHP_VERSION", PHP_VERSION, sizeof(PHP_VERSION)-1, CONST_PERSISTENT | CONST_CS);
2143    REGISTER_MAIN_LONG_CONSTANT("PHP_MAJOR_VERSION", PHP_MAJOR_VERSION, CONST_PERSISTENT | CONST_CS);
2144    REGISTER_MAIN_LONG_CONSTANT("PHP_MINOR_VERSION", PHP_MINOR_VERSION, CONST_PERSISTENT | CONST_CS);
2145    REGISTER_MAIN_LONG_CONSTANT("PHP_RELEASE_VERSION", PHP_RELEASE_VERSION, CONST_PERSISTENT | CONST_CS);
2146    REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTRA_VERSION", PHP_EXTRA_VERSION, sizeof(PHP_EXTRA_VERSION) - 1, CONST_PERSISTENT | CONST_CS);
2147    REGISTER_MAIN_LONG_CONSTANT("PHP_VERSION_ID", PHP_VERSION_ID, CONST_PERSISTENT | CONST_CS);
2148#ifdef ZTS
2149    REGISTER_MAIN_LONG_CONSTANT("PHP_ZTS", 1, CONST_PERSISTENT | CONST_CS);
2150#else
2151    REGISTER_MAIN_LONG_CONSTANT("PHP_ZTS", 0, CONST_PERSISTENT | CONST_CS);
2152#endif
2153    REGISTER_MAIN_LONG_CONSTANT("PHP_DEBUG", PHP_DEBUG, CONST_PERSISTENT | CONST_CS);
2154    REGISTER_MAIN_STRINGL_CONSTANT("PHP_OS", php_os, strlen(php_os), CONST_PERSISTENT | CONST_CS);
2155    REGISTER_MAIN_STRINGL_CONSTANT("PHP_SAPI", sapi_module.name, strlen(sapi_module.name), CONST_PERSISTENT | CONST_CS);
2156    REGISTER_MAIN_STRINGL_CONSTANT("DEFAULT_INCLUDE_PATH", PHP_INCLUDE_PATH, sizeof(PHP_INCLUDE_PATH)-1, CONST_PERSISTENT | CONST_CS);
2157    REGISTER_MAIN_STRINGL_CONSTANT("PEAR_INSTALL_DIR", PEAR_INSTALLDIR, sizeof(PEAR_INSTALLDIR)-1, CONST_PERSISTENT | CONST_CS);
2158    REGISTER_MAIN_STRINGL_CONSTANT("PEAR_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS);
2159    REGISTER_MAIN_STRINGL_CONSTANT("PHP_EXTENSION_DIR", PHP_EXTENSION_DIR, sizeof(PHP_EXTENSION_DIR)-1, CONST_PERSISTENT | CONST_CS);
2160    REGISTER_MAIN_STRINGL_CONSTANT("PHP_PREFIX", PHP_PREFIX, sizeof(PHP_PREFIX)-1, CONST_PERSISTENT | CONST_CS);
2161    REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINDIR", PHP_BINDIR, sizeof(PHP_BINDIR)-1, CONST_PERSISTENT | CONST_CS);
2162#ifndef PHP_WIN32
2163    REGISTER_MAIN_STRINGL_CONSTANT("PHP_MANDIR", PHP_MANDIR, sizeof(PHP_MANDIR)-1, CONST_PERSISTENT | CONST_CS);
2164#endif
2165    REGISTER_MAIN_STRINGL_CONSTANT("PHP_LIBDIR", PHP_LIBDIR, sizeof(PHP_LIBDIR)-1, CONST_PERSISTENT | CONST_CS);
2166    REGISTER_MAIN_STRINGL_CONSTANT("PHP_DATADIR", PHP_DATADIR, sizeof(PHP_DATADIR)-1, CONST_PERSISTENT | CONST_CS);
2167    REGISTER_MAIN_STRINGL_CONSTANT("PHP_SYSCONFDIR", PHP_SYSCONFDIR, sizeof(PHP_SYSCONFDIR)-1, CONST_PERSISTENT | CONST_CS);
2168    REGISTER_MAIN_STRINGL_CONSTANT("PHP_LOCALSTATEDIR", PHP_LOCALSTATEDIR, sizeof(PHP_LOCALSTATEDIR)-1, CONST_PERSISTENT | CONST_CS);
2169    REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_PATH", PHP_CONFIG_FILE_PATH, strlen(PHP_CONFIG_FILE_PATH), CONST_PERSISTENT | CONST_CS);
2170    REGISTER_MAIN_STRINGL_CONSTANT("PHP_CONFIG_FILE_SCAN_DIR", PHP_CONFIG_FILE_SCAN_DIR, sizeof(PHP_CONFIG_FILE_SCAN_DIR)-1, CONST_PERSISTENT | CONST_CS);
2171    REGISTER_MAIN_STRINGL_CONSTANT("PHP_SHLIB_SUFFIX", PHP_SHLIB_SUFFIX, sizeof(PHP_SHLIB_SUFFIX)-1, CONST_PERSISTENT | CONST_CS);
2172    REGISTER_MAIN_STRINGL_CONSTANT("PHP_EOL", PHP_EOL, sizeof(PHP_EOL)-1, CONST_PERSISTENT | CONST_CS);
2173    REGISTER_MAIN_LONG_CONSTANT("PHP_MAXPATHLEN", MAXPATHLEN, CONST_PERSISTENT | CONST_CS);
2174    REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MAX", ZEND_LONG_MAX, CONST_PERSISTENT | CONST_CS);
2175    REGISTER_MAIN_LONG_CONSTANT("PHP_INT_MIN", ZEND_LONG_MIN, CONST_PERSISTENT | CONST_CS);
2176    REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS);
2177
2178#ifdef PHP_WIN32
2179    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MAJOR",      EG(windows_version_info).dwMajorVersion, CONST_PERSISTENT | CONST_CS);
2180    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_MINOR",      EG(windows_version_info).dwMinorVersion, CONST_PERSISTENT | CONST_CS);
2181    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_BUILD",      EG(windows_version_info).dwBuildNumber, CONST_PERSISTENT | CONST_CS);
2182    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_PLATFORM",   EG(windows_version_info).dwPlatformId, CONST_PERSISTENT | CONST_CS);
2183    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SP_MAJOR",   EG(windows_version_info).wServicePackMajor, CONST_PERSISTENT | CONST_CS);
2184    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SP_MINOR",   EG(windows_version_info).wServicePackMinor, CONST_PERSISTENT | CONST_CS);
2185    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_SUITEMASK",  EG(windows_version_info).wSuiteMask, CONST_PERSISTENT | CONST_CS);
2186    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_VERSION_PRODUCTTYPE", EG(windows_version_info).wProductType, CONST_PERSISTENT | CONST_CS);
2187    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_DOMAIN_CONTROLLER", VER_NT_DOMAIN_CONTROLLER, CONST_PERSISTENT | CONST_CS);
2188    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_SERVER", VER_NT_SERVER, CONST_PERSISTENT | CONST_CS);
2189    REGISTER_MAIN_LONG_CONSTANT("PHP_WINDOWS_NT_WORKSTATION", VER_NT_WORKSTATION, CONST_PERSISTENT | CONST_CS);
2190#endif
2191
2192    php_binary_init();
2193    if (PG(php_binary)) {
2194        REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", PG(php_binary), strlen(PG(php_binary)), CONST_PERSISTENT | CONST_CS);
2195    } else {
2196        REGISTER_MAIN_STRINGL_CONSTANT("PHP_BINARY", "", 0, CONST_PERSISTENT | CONST_CS);
2197    }
2198
2199    php_output_register_constants();
2200    php_rfc1867_register_constants();
2201
2202    /* this will read in php.ini, set up the configuration parameters,
2203       load zend extensions and register php function extensions
2204       to be loaded later */
2205    if (php_init_config() == FAILURE) {
2206        return FAILURE;
2207    }
2208
2209    /* Register PHP core ini entries */
2210    REGISTER_INI_ENTRIES();
2211
2212    /* Register Zend ini entries */
2213    zend_register_standard_ini_entries();
2214
2215    /* Disable realpath cache if an open_basedir is set */
2216    if (PG(open_basedir) && *PG(open_basedir)) {
2217        CWDG(realpath_cache_size_limit) = 0;
2218    }
2219
2220    /* initialize stream wrappers registry
2221     * (this uses configuration parameters from php.ini)
2222     */
2223    if (php_init_stream_wrappers(module_number) == FAILURE) {
2224        php_printf("PHP:  Unable to initialize stream url wrappers.\n");
2225        return FAILURE;
2226    }
2227
2228    zuv.html_errors = 1;
2229    zuv.import_use_extension = ".php";
2230    zuv.import_use_extension_length = (uint)strlen(zuv.import_use_extension);
2231    php_startup_auto_globals();
2232    zend_set_utility_values(&zuv);
2233    php_startup_sapi_content_types();
2234
2235    /* startup extensions statically compiled in */
2236    if (php_register_internal_extensions_func() == FAILURE) {
2237        php_printf("Unable to start builtin modules\n");
2238        return FAILURE;
2239    }
2240
2241    /* start additional PHP extensions */
2242    php_register_extensions_bc(additional_modules, num_additional_modules);
2243
2244    /* load and startup extensions compiled as shared objects (aka DLLs)
2245       as requested by php.ini entries
2246       these are loaded after initialization of internal extensions
2247       as extensions *might* rely on things from ext/standard
2248       which is always an internal extension and to be initialized
2249       ahead of all other internals
2250     */
2251    php_ini_register_extensions();
2252    zend_startup_modules();
2253
2254    /* start Zend extensions */
2255    zend_startup_extensions();
2256
2257    zend_collect_module_handlers();
2258
2259    /* register additional functions */
2260    if (sapi_module.additional_functions) {
2261        if ((module = zend_hash_str_find_ptr(&module_registry, "standard", sizeof("standard")-1)) != NULL) {
2262            EG(current_module) = module;
2263            zend_register_functions(NULL, sapi_module.additional_functions, NULL, MODULE_PERSISTENT);
2264            EG(current_module) = NULL;
2265        }
2266    }
2267
2268    /* disable certain classes and functions as requested by php.ini */
2269    php_disable_functions();
2270    php_disable_classes();
2271
2272    /* make core report what it should */
2273    if ((module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core")-1)) != NULL) {
2274        module->version = PHP_VERSION;
2275        module->info_func = PHP_MINFO(php_core);
2276    }
2277
2278
2279#ifdef PHP_WIN32
2280    /* Disable incompatible functions for the running platform */
2281    if (php_win32_disable_functions() == FAILURE) {
2282        php_printf("Unable to disable unsupported functions\n");
2283        return FAILURE;
2284    }
2285#endif
2286
2287    zend_post_startup();
2288
2289    module_initialized = 1;
2290
2291    /* Check for deprecated directives */
2292    /* NOTE: If you add anything here, remember to add it to Makefile.global! */
2293    {
2294        struct {
2295            const long error_level;
2296            const char *phrase;
2297            const char *directives[17]; /* Remember to change this if the number of directives change */
2298        } directives[2] = {
2299            {
2300                E_DEPRECATED,
2301                "Directive '%s' is deprecated in PHP 5.3 and greater",
2302                {
2303                    NULL
2304                }
2305            },
2306            {
2307                E_CORE_ERROR,
2308                "Directive '%s' is no longer available in PHP",
2309                {
2310                    "allow_call_time_pass_reference",
2311                    "asp_tags",
2312                    "define_syslog_variables",
2313                    "highlight.bg",
2314                    "magic_quotes_gpc",
2315                    "magic_quotes_runtime",
2316                    "magic_quotes_sybase",
2317                    "register_globals",
2318                    "register_long_arrays",
2319                    "safe_mode",
2320                    "safe_mode_gid",
2321                    "safe_mode_include_dir",
2322                    "safe_mode_exec_dir",
2323                    "safe_mode_allowed_env_vars",
2324                    "safe_mode_protected_env_vars",
2325                    "zend.ze1_compatibility_mode",
2326                    NULL
2327                }
2328            }
2329        };
2330
2331        unsigned int i;
2332
2333        zend_try {
2334            /* 2 = Count of deprecation structs */
2335            for (i = 0; i < 2; i++) {
2336                const char **p = directives[i].directives;
2337
2338                while(*p) {
2339                    zend_long value;
2340
2341                    if (cfg_get_long((char*)*p, &value) == SUCCESS && value) {
2342                        zend_error(directives[i].error_level, directives[i].phrase, *p);
2343                    }
2344
2345                    ++p;
2346                }
2347            }
2348        } zend_catch {
2349            retval = FAILURE;
2350        } zend_end_try();
2351    }
2352
2353    sapi_deactivate();
2354    module_startup = 0;
2355
2356    shutdown_memory_manager(1, 0);
2357    zend_interned_strings_snapshot();
2358    virtual_cwd_activate();
2359
2360    /* we're done */
2361    return retval;
2362}
2363/* }}} */
2364
2365void php_module_shutdown_for_exec(void)
2366{
2367    /* used to close fd's in the range 3.255 here, but it's problematic */
2368}
2369
2370/* {{{ php_module_shutdown_wrapper
2371 */
2372int php_module_shutdown_wrapper(sapi_module_struct *sapi_globals)
2373{
2374    php_module_shutdown();
2375    return SUCCESS;
2376}
2377/* }}} */
2378
2379/* {{{ php_module_shutdown
2380 */
2381void php_module_shutdown(void)
2382{
2383    int module_number=0;    /* for UNREGISTER_INI_ENTRIES() */
2384
2385    module_shutdown = 1;
2386
2387    if (!module_initialized) {
2388        return;
2389    }
2390
2391#ifdef ZTS
2392    ts_free_worker_threads();
2393#endif
2394
2395#if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK))
2396    /*close winsock */
2397    WSACleanup();
2398#endif
2399
2400#ifdef PHP_WIN32
2401    php_win32_free_rng_lock();
2402#endif
2403
2404    sapi_flush();
2405
2406    zend_shutdown();
2407
2408    /* Destroys filter & transport registries too */
2409    php_shutdown_stream_wrappers(module_number);
2410
2411    UNREGISTER_INI_ENTRIES();
2412
2413    /* close down the ini config */
2414    php_shutdown_config();
2415
2416#ifndef ZTS
2417    zend_ini_shutdown();
2418    shutdown_memory_manager(CG(unclean_shutdown), 1);
2419#else
2420    zend_ini_global_shutdown();
2421#endif
2422
2423    php_output_shutdown();
2424    php_shutdown_temporary_directory();
2425
2426    module_initialized = 0;
2427
2428#ifndef ZTS
2429    core_globals_dtor(&core_globals);
2430    gc_globals_dtor();
2431#else
2432    ts_free_id(core_globals_id);
2433#endif
2434
2435#if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400)
2436    if (old_invalid_parameter_handler == NULL) {
2437        _set_invalid_parameter_handler(old_invalid_parameter_handler);
2438    }
2439#endif
2440}
2441/* }}} */
2442
2443/* {{{ php_execute_script
2444 */
2445PHPAPI int php_execute_script(zend_file_handle *primary_file)
2446{
2447    zend_file_handle *prepend_file_p, *append_file_p;
2448    zend_file_handle prepend_file = {{0}, NULL, NULL, 0, 0}, append_file = {{0}, NULL, NULL, 0, 0};
2449#if HAVE_BROKEN_GETCWD
2450    volatile int old_cwd_fd = -1;
2451#else
2452    char *old_cwd;
2453    ALLOCA_FLAG(use_heap)
2454#endif
2455    int retval = 0;
2456
2457    EG(exit_status) = 0;
2458#ifndef HAVE_BROKEN_GETCWD
2459# define OLD_CWD_SIZE 4096
2460    old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
2461    old_cwd[0] = '\0';
2462#endif
2463
2464    zend_try {
2465        char realfile[MAXPATHLEN];
2466
2467#ifdef PHP_WIN32
2468        if(primary_file->filename) {
2469            UpdateIniFromRegistry((char*)primary_file->filename);
2470        }
2471#endif
2472
2473        PG(during_request_startup) = 0;
2474
2475        if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
2476#if HAVE_BROKEN_GETCWD
2477            /* this looks nasty to me */
2478            old_cwd_fd = open(".", 0);
2479#else
2480            php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
2481#endif
2482            VCWD_CHDIR_FILE(primary_file->filename);
2483        }
2484
2485        /* Only lookup the real file path and add it to the included_files list if already opened
2486         *   otherwise it will get opened and added to the included_files list in zend_execute_scripts
2487         */
2488        if (primary_file->filename &&
2489            (primary_file->filename[0] != '-' || primary_file->filename[1] != 0) &&
2490            primary_file->opened_path == NULL &&
2491            primary_file->type != ZEND_HANDLE_FILENAME
2492        ) {
2493            if (expand_filepath(primary_file->filename, realfile)) {
2494                primary_file->opened_path = zend_string_init(realfile, strlen(realfile), 0);
2495                zend_hash_add_empty_element(&EG(included_files), primary_file->opened_path);
2496            }
2497        }
2498
2499        if (PG(auto_prepend_file) && PG(auto_prepend_file)[0]) {
2500            prepend_file.filename = PG(auto_prepend_file);
2501            prepend_file.opened_path = NULL;
2502            prepend_file.free_filename = 0;
2503            prepend_file.type = ZEND_HANDLE_FILENAME;
2504            prepend_file_p = &prepend_file;
2505        } else {
2506            prepend_file_p = NULL;
2507        }
2508
2509        if (PG(auto_append_file) && PG(auto_append_file)[0]) {
2510            append_file.filename = PG(auto_append_file);
2511            append_file.opened_path = NULL;
2512            append_file.free_filename = 0;
2513            append_file.type = ZEND_HANDLE_FILENAME;
2514            append_file_p = &append_file;
2515        } else {
2516            append_file_p = NULL;
2517        }
2518        if (PG(max_input_time) != -1) {
2519#ifdef PHP_WIN32
2520            zend_unset_timeout();
2521#endif
2522            zend_set_timeout(INI_INT("max_execution_time"), 0);
2523        }
2524
2525        /*
2526           If cli primary file has shabang line and there is a prepend file,
2527           the `start_lineno` will be used by prepend file but not primary file,
2528           save it and restore after prepend file been executed.
2529         */
2530        if (CG(start_lineno) && prepend_file_p) {
2531            int orig_start_lineno = CG(start_lineno);
2532
2533            CG(start_lineno) = 0;
2534            if (zend_execute_scripts(ZEND_REQUIRE, NULL, 1, prepend_file_p) == SUCCESS) {
2535                CG(start_lineno) = orig_start_lineno;
2536                retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 2, primary_file, append_file_p) == SUCCESS);
2537            }
2538        } else {
2539            retval = (zend_execute_scripts(ZEND_REQUIRE, NULL, 3, prepend_file_p, primary_file, append_file_p) == SUCCESS);
2540        }
2541    } zend_end_try();
2542
2543#if HAVE_BROKEN_GETCWD
2544    if (old_cwd_fd != -1) {
2545        fchdir(old_cwd_fd);
2546        close(old_cwd_fd);
2547    }
2548#else
2549    if (old_cwd[0] != '\0') {
2550        php_ignore_value(VCWD_CHDIR(old_cwd));
2551    }
2552    free_alloca(old_cwd, use_heap);
2553#endif
2554    return retval;
2555}
2556/* }}} */
2557
2558/* {{{ php_execute_simple_script
2559 */
2560PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval *ret)
2561{
2562    char *old_cwd;
2563    ALLOCA_FLAG(use_heap)
2564
2565    EG(exit_status) = 0;
2566#define OLD_CWD_SIZE 4096
2567    old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
2568    old_cwd[0] = '\0';
2569
2570    zend_try {
2571#ifdef PHP_WIN32
2572        if(primary_file->filename) {
2573            UpdateIniFromRegistry((char*)primary_file->filename);
2574        }
2575#endif
2576
2577        PG(during_request_startup) = 0;
2578
2579        if (primary_file->filename && !(SG(options) & SAPI_OPTION_NO_CHDIR)) {
2580            php_ignore_value(VCWD_GETCWD(old_cwd, OLD_CWD_SIZE-1));
2581            VCWD_CHDIR_FILE(primary_file->filename);
2582        }
2583        zend_execute_scripts(ZEND_REQUIRE, ret, 1, primary_file);
2584    } zend_end_try();
2585
2586    if (old_cwd[0] != '\0') {
2587        php_ignore_value(VCWD_CHDIR(old_cwd));
2588    }
2589
2590    free_alloca(old_cwd, use_heap);
2591    return EG(exit_status);
2592}
2593/* }}} */
2594
2595/* {{{ php_handle_aborted_connection
2596 */
2597PHPAPI void php_handle_aborted_connection(void)
2598{
2599
2600    PG(connection_status) = PHP_CONNECTION_ABORTED;
2601    php_output_set_status(PHP_OUTPUT_DISABLED);
2602
2603    if (!PG(ignore_user_abort)) {
2604        zend_bailout();
2605    }
2606}
2607/* }}} */
2608
2609/* {{{ php_handle_auth_data
2610 */
2611PHPAPI int php_handle_auth_data(const char *auth)
2612{
2613    int ret = -1;
2614
2615    if (auth && auth[0] != '\0' && strncmp(auth, "Basic ", 6) == 0) {
2616        char *pass;
2617        zend_string *user;
2618
2619        user = php_base64_decode((const unsigned char*)auth + 6, strlen(auth) - 6);
2620        if (user) {
2621            pass = strchr(user->val, ':');
2622            if (pass) {
2623                *pass++ = '\0';
2624                SG(request_info).auth_user = estrndup(user->val, user->len);
2625                SG(request_info).auth_password = estrdup(pass);
2626                ret = 0;
2627            }
2628            zend_string_free(user);
2629        }
2630    }
2631
2632    if (ret == -1) {
2633        SG(request_info).auth_user = SG(request_info).auth_password = NULL;
2634    } else {
2635        SG(request_info).auth_digest = NULL;
2636    }
2637
2638    if (ret == -1 && auth && auth[0] != '\0' && strncmp(auth, "Digest ", 7) == 0) {
2639        SG(request_info).auth_digest = estrdup(auth + 7);
2640        ret = 0;
2641    }
2642
2643    if (ret == -1) {
2644        SG(request_info).auth_digest = NULL;
2645    }
2646
2647    return ret;
2648}
2649/* }}} */
2650
2651/* {{{ php_lint_script
2652 */
2653PHPAPI int php_lint_script(zend_file_handle *file)
2654{
2655    zend_op_array *op_array;
2656    int retval = FAILURE;
2657
2658    zend_try {
2659        op_array = zend_compile_file(file, ZEND_INCLUDE);
2660        zend_destroy_file_handle(file);
2661
2662        if (op_array) {
2663            destroy_op_array(op_array);
2664            efree(op_array);
2665            retval = SUCCESS;
2666        }
2667    } zend_end_try();
2668
2669    return retval;
2670}
2671/* }}} */
2672
2673#ifdef PHP_WIN32
2674/* {{{ dummy_indent
2675   just so that this symbol gets exported... */
2676PHPAPI void dummy_indent(void)
2677{
2678    zend_indent();
2679}
2680/* }}} */
2681#endif
2682
2683/*
2684 * Local variables:
2685 * tab-width: 4
2686 * c-basic-offset: 4
2687 * End:
2688 * vim600: sw=4 ts=4 fdm=marker
2689 * vim<600: sw=4 ts=4
2690 */
2691