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