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