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