1 /*
2    +----------------------------------------------------------------------+
3    | Copyright (c) The PHP Group                                          |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.php.net/license/3_01.txt                                  |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
14    |          Zeev Suraski <zeev@php.net>                                 |
15    |          Colin Viebrock <colin@viebrock.ca>                          |
16    +----------------------------------------------------------------------+
17 */
18 
19 #include "php.h"
20 #include "php_ini.h"
21 #include "php_globals.h"
22 #include "ext/standard/head.h"
23 #include "ext/standard/html.h"
24 #include "info.h"
25 #include "credits.h"
26 #include "css.h"
27 #include "SAPI.h"
28 #include <time.h>
29 #include "php_main.h"
30 #include "zend_globals.h"		/* needs ELS */
31 #include "zend_extensions.h"
32 #include "zend_highlight.h"
33 #ifdef HAVE_SYS_UTSNAME_H
34 #include <sys/utsname.h>
35 #endif
36 #include "url.h"
37 #include "php_string.h"
38 
39 #ifdef PHP_WIN32
40 # include "winver.h"
41 #endif
42 
43 #define SECTION(name)	if (!sapi_module.phpinfo_as_text) { \
44 							php_info_print("<h2>" name "</h2>\n"); \
45 						} else { \
46 							php_info_print_table_start(); \
47 							php_info_print_table_header(1, name); \
48 							php_info_print_table_end(); \
49 						} \
50 
51 PHPAPI extern char *php_ini_opened_path;
52 PHPAPI extern char *php_ini_scanned_path;
53 PHPAPI extern char *php_ini_scanned_files;
54 
php_info_print_html_esc(const char * str,size_t len)55 static ZEND_COLD int php_info_print_html_esc(const char *str, size_t len) /* {{{ */
56 {
57 	size_t written;
58 	zend_string *new_str;
59 
60 	new_str = php_escape_html_entities((const unsigned char *) str, len, 0, ENT_QUOTES, "utf-8");
61 	written = php_output_write(ZSTR_VAL(new_str), ZSTR_LEN(new_str));
62 	zend_string_free(new_str);
63 	return written;
64 }
65 /* }}} */
66 
php_info_printf(const char * fmt,...)67 static ZEND_COLD int php_info_printf(const char *fmt, ...) /* {{{ */
68 {
69 	char *buf;
70 	size_t len, written;
71 	va_list argv;
72 
73 	va_start(argv, fmt);
74 	len = vspprintf(&buf, 0, fmt, argv);
75 	va_end(argv);
76 
77 	written = php_output_write(buf, len);
78 	efree(buf);
79 	return written;
80 }
81 /* }}} */
82 
php_info_print(const char * str)83 static zend_always_inline int php_info_print(const char *str) /* {{{ */
84 {
85 	return php_output_write(str, strlen(str));
86 }
87 /* }}} */
88 
php_info_print_stream_hash(const char * name,HashTable * ht)89 static ZEND_COLD void php_info_print_stream_hash(const char *name, HashTable *ht) /* {{{ */
90 {
91 	zend_string *key;
92 
93 	if (ht) {
94 		if (zend_hash_num_elements(ht)) {
95 			int first = 1;
96 
97 			if (!sapi_module.phpinfo_as_text) {
98 				php_info_printf("<tr><td class=\"e\">Registered %s</td><td class=\"v\">", name);
99 			} else {
100 				php_info_printf("\nRegistered %s => ", name);
101 			}
102 
103 			ZEND_HASH_FOREACH_STR_KEY(ht, key) {
104 				if (key) {
105 					if (first) {
106 						first = 0;
107 					} else {
108 						php_info_print(", ");
109 					}
110 					if (!sapi_module.phpinfo_as_text) {
111 						php_info_print_html_esc(ZSTR_VAL(key), ZSTR_LEN(key));
112 					} else {
113 						php_info_print(ZSTR_VAL(key));
114 					}
115 				}
116 			} ZEND_HASH_FOREACH_END();
117 
118 			if (!sapi_module.phpinfo_as_text) {
119 				php_info_print("</td></tr>\n");
120 			}
121 		} else {
122 			char reg_name[128];
123 			snprintf(reg_name, sizeof(reg_name), "Registered %s", name);
124 			php_info_print_table_row(2, reg_name, "none registered");
125 		}
126 	} else {
127 		php_info_print_table_row(2, name, "disabled");
128 	}
129 }
130 /* }}} */
131 
php_info_print_module(zend_module_entry * zend_module)132 PHPAPI ZEND_COLD void php_info_print_module(zend_module_entry *zend_module) /* {{{ */
133 {
134 	if (zend_module->info_func || zend_module->version) {
135 		if (!sapi_module.phpinfo_as_text) {
136 			zend_string *url_name = php_url_encode(zend_module->name, strlen(zend_module->name));
137 
138 			php_strtolower(ZSTR_VAL(url_name), ZSTR_LEN(url_name));
139 			php_info_printf("<h2><a name=\"module_%s\">%s</a></h2>\n", ZSTR_VAL(url_name), zend_module->name);
140 
141 			efree(url_name);
142 		} else {
143 			php_info_print_table_start();
144 			php_info_print_table_header(1, zend_module->name);
145 			php_info_print_table_end();
146 		}
147 		if (zend_module->info_func) {
148 			zend_module->info_func(zend_module);
149 		} else {
150 			php_info_print_table_start();
151 			php_info_print_table_row(2, "Version", zend_module->version);
152 			php_info_print_table_end();
153 			DISPLAY_INI_ENTRIES();
154 		}
155 	} else {
156 		if (!sapi_module.phpinfo_as_text) {
157 			php_info_printf("<tr><td class=\"v\">%s</td></tr>\n", zend_module->name);
158 		} else {
159 			php_info_printf("%s\n", zend_module->name);
160 		}
161 	}
162 }
163 /* }}} */
164 
165 /* {{{ php_print_gpcse_array */
php_print_gpcse_array(char * name,uint32_t name_length)166 static ZEND_COLD void php_print_gpcse_array(char *name, uint32_t name_length)
167 {
168 	zval *data, *tmp;
169 	zend_string *string_key;
170 	zend_ulong num_key;
171 	zend_string *key;
172 
173 	key = zend_string_init(name, name_length, 0);
174 	zend_is_auto_global(key);
175 
176 	if ((data = zend_hash_find_deref(&EG(symbol_table), key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
177 		ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_key, string_key, tmp) {
178 			if (!sapi_module.phpinfo_as_text) {
179 				php_info_print("<tr>");
180 				php_info_print("<td class=\"e\">");
181 			}
182 
183 			php_info_print("$");
184 			php_info_print(name);
185 			php_info_print("['");
186 
187 			if (string_key != NULL) {
188 				if (!sapi_module.phpinfo_as_text) {
189 					php_info_print_html_esc(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
190 				} else {
191 					php_info_print(ZSTR_VAL(string_key));
192 				}
193 			} else {
194 				php_info_printf(ZEND_ULONG_FMT, num_key);
195 			}
196 			php_info_print("']");
197 			if (!sapi_module.phpinfo_as_text) {
198 				php_info_print("</td><td class=\"v\">");
199 			} else {
200 				php_info_print(" => ");
201 			}
202 			ZVAL_DEREF(tmp);
203 			if (Z_TYPE_P(tmp) == IS_ARRAY) {
204 				if (!sapi_module.phpinfo_as_text) {
205 					zend_string *str = zend_print_zval_r_to_str(tmp, 0);
206 					php_info_print("<pre>");
207 					php_info_print_html_esc(ZSTR_VAL(str), ZSTR_LEN(str));
208 					php_info_print("</pre>");
209 					zend_string_release_ex(str, 0);
210 				} else {
211 					zend_print_zval_r(tmp, 0);
212 				}
213 			} else {
214 				zend_string *tmp2;
215 				zend_string *str = zval_get_tmp_string(tmp, &tmp2);
216 
217 				if (!sapi_module.phpinfo_as_text) {
218 					if (ZSTR_LEN(str) == 0) {
219 						php_info_print("<i>no value</i>");
220 					} else {
221 						php_info_print_html_esc(ZSTR_VAL(str), ZSTR_LEN(str));
222 					}
223 				} else {
224 					php_info_print(ZSTR_VAL(str));
225 				}
226 
227 				zend_tmp_string_release(tmp2);
228 			}
229 			if (!sapi_module.phpinfo_as_text) {
230 				php_info_print("</td></tr>\n");
231 			} else {
232 				php_info_print("\n");
233 			}
234 		} ZEND_HASH_FOREACH_END();
235 	}
236 	zend_string_efree(key);
237 }
238 /* }}} */
239 
240 /* {{{ php_info_print_style */
php_info_print_style(void)241 PHPAPI ZEND_COLD void ZEND_COLD php_info_print_style(void)
242 {
243 	php_info_printf("<style type=\"text/css\">\n");
244 	php_info_print_css();
245 	php_info_printf("</style>\n");
246 }
247 /* }}} */
248 
249 /* {{{ php_info_html_esc */
php_info_html_esc(const char * string)250 PHPAPI ZEND_COLD zend_string *php_info_html_esc(const char *string)
251 {
252 	return php_escape_html_entities((const unsigned char *) string, strlen(string), 0, ENT_QUOTES, NULL);
253 }
254 /* }}} */
255 
256 #ifdef PHP_WIN32
257 /* {{{  */
258 
php_get_windows_name()259 char* php_get_windows_name()
260 {
261 	OSVERSIONINFOEX osvi = EG(windows_version_info);
262 	SYSTEM_INFO si;
263 	DWORD dwType;
264 	char *major = NULL, *sub = NULL, *retval;
265 
266 	ZeroMemory(&si, sizeof(SYSTEM_INFO));
267 
268 	GetNativeSystemInfo(&si);
269 
270 	if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) {
271 		if (osvi.dwMajorVersion == 10) {
272 			if( osvi.dwMinorVersion == 0 ) {
273 				if( osvi.wProductType == VER_NT_WORKSTATION ) {
274 					major = "Windows 10";
275 				} else {
276 					major = "Windows Server 2016";
277 				}
278 			}
279 		}
280 	} else if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 6) {
281 		if (osvi.dwMajorVersion == 6) {
282 			if( osvi.dwMinorVersion == 0 ) {
283 				if( osvi.wProductType == VER_NT_WORKSTATION ) {
284 					major = "Windows Vista";
285 				} else {
286 					major = "Windows Server 2008";
287 				}
288 			} else if ( osvi.dwMinorVersion == 1 ) {
289 				if( osvi.wProductType == VER_NT_WORKSTATION )  {
290 					major = "Windows 7";
291 				} else {
292 					major = "Windows Server 2008 R2";
293 				}
294 			} else if ( osvi.dwMinorVersion == 2 ) {
295 				/* could be Windows 8/Windows Server 2012, could be Windows 8.1/Windows Server 2012 R2 */
296 				/* XXX and one more X - the above comment is true if no manifest is used for two cases:
297 					- if the PHP build doesn't use the correct manifest
298 					- if PHP DLL loaded under some binary that doesn't use the correct manifest
299 
300 					So keep the handling here as is for now, even if we know 6.2 is win8 and nothing else, and think about an improvement. */
301 				OSVERSIONINFOEX osvi81;
302 				DWORDLONG dwlConditionMask = 0;
303 				int op = VER_GREATER_EQUAL;
304 
305 				ZeroMemory(&osvi81, sizeof(OSVERSIONINFOEX));
306 				osvi81.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
307 				osvi81.dwMajorVersion = 6;
308 				osvi81.dwMinorVersion = 3;
309 				osvi81.wServicePackMajor = 0;
310 
311 				VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, op);
312 				VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, op);
313 				VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, op);
314 
315 				if (VerifyVersionInfo(&osvi81,
316 					VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
317 					dwlConditionMask)) {
318 					osvi.dwMinorVersion = 3; /* Windows 8.1/Windows Server 2012 R2 */
319 					if( osvi.wProductType == VER_NT_WORKSTATION )  {
320 						major = "Windows 8.1";
321 					} else {
322 						major = "Windows Server 2012 R2";
323 					}
324 				} else {
325 					if( osvi.wProductType == VER_NT_WORKSTATION )  {
326 						major = "Windows 8";
327 					} else {
328 						major = "Windows Server 2012";
329 					}
330 				}
331 			} else if (osvi.dwMinorVersion == 3) {
332 				if( osvi.wProductType == VER_NT_WORKSTATION )  {
333 					major = "Windows 8.1";
334 				} else {
335 					major = "Windows Server 2012 R2";
336 				}
337 			} else {
338 				major = "Unknown Windows version";
339 			}
340 
341 			/* No return value check, as it can only fail if the input parameters are broken (which we manually supply) */
342 			GetProductInfo(6, 0, 0, 0, &dwType);
343 
344 			switch (dwType) {
345 				case PRODUCT_ULTIMATE:
346 					sub = "Ultimate Edition";
347 					break;
348 				case PRODUCT_HOME_BASIC:
349 					sub = "Home Basic Edition";
350 					break;
351 				case PRODUCT_HOME_PREMIUM:
352 					sub = "Home Premium Edition";
353 					break;
354 				case PRODUCT_ENTERPRISE:
355 					sub = "Enterprise Edition";
356 					break;
357 				case PRODUCT_HOME_BASIC_N:
358 					sub = "Home Basic N Edition";
359 					break;
360 				case PRODUCT_BUSINESS:
361 					if ((osvi.dwMajorVersion > 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 0)) {
362 						sub = "Professional Edition";
363 					} else {
364 						sub = "Business Edition";
365 					}
366 					break;
367 				case PRODUCT_STANDARD_SERVER:
368 					sub = "Standard Edition";
369 					break;
370 				case PRODUCT_DATACENTER_SERVER:
371 					sub = "Datacenter Edition";
372 					break;
373 				case PRODUCT_SMALLBUSINESS_SERVER:
374 					sub = "Small Business Server";
375 					break;
376 				case PRODUCT_ENTERPRISE_SERVER:
377 					sub = "Enterprise Edition";
378 					break;
379 				case PRODUCT_STARTER:
380 					if ((osvi.dwMajorVersion > 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 0)) {
381 						sub = "Starter N Edition";
382 					} else {
383 					    sub = "Starter Edition";
384 					}
385 					break;
386 				case PRODUCT_DATACENTER_SERVER_CORE:
387 					sub = "Datacenter Edition (core installation)";
388 					break;
389 				case PRODUCT_STANDARD_SERVER_CORE:
390 					sub = "Standard Edition (core installation)";
391 					break;
392 				case PRODUCT_ENTERPRISE_SERVER_CORE:
393 					sub = "Enterprise Edition (core installation)";
394 					break;
395 				case PRODUCT_ENTERPRISE_SERVER_IA64:
396 					sub = "Enterprise Edition for Itanium-based Systems";
397 					break;
398 				case PRODUCT_BUSINESS_N:
399 					if ((osvi.dwMajorVersion > 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion > 0)) {
400 						sub = "Professional N Edition";
401 					} else {
402 						sub = "Business N Edition";
403 					}
404 					break;
405 				case PRODUCT_WEB_SERVER:
406 					sub = "Web Server Edition";
407 					break;
408 				case PRODUCT_CLUSTER_SERVER:
409 					sub = "HPC Edition";
410 					break;
411 				case PRODUCT_HOME_SERVER:
412 					sub = "Storage Server Essentials Edition";
413 					break;
414 				case PRODUCT_STORAGE_EXPRESS_SERVER:
415 					sub = "Storage Server Express Edition";
416 					break;
417 				case PRODUCT_STORAGE_STANDARD_SERVER:
418 					sub = "Storage Server Standard Edition";
419 					break;
420 				case PRODUCT_STORAGE_WORKGROUP_SERVER:
421 					sub = "Storage Server Workgroup Edition";
422 					break;
423 				case PRODUCT_STORAGE_ENTERPRISE_SERVER:
424 					sub = "Storage Server Enterprise Edition";
425 					break;
426 				case PRODUCT_SERVER_FOR_SMALLBUSINESS:
427 					sub = "Essential Server Solutions Edition";
428 					break;
429 				case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
430 					sub = "Small Business Server Premium Edition";
431 					break;
432 				case PRODUCT_HOME_PREMIUM_N:
433 					sub = "Home Premium N Edition";
434 					break;
435 				case PRODUCT_ENTERPRISE_N:
436 					sub = "Enterprise N Edition";
437 					break;
438 				case PRODUCT_ULTIMATE_N:
439 					sub = "Ultimate N Edition";
440 					break;
441 				case PRODUCT_WEB_SERVER_CORE:
442 					sub = "Web Server Edition (core installation)";
443 					break;
444 				case PRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
445 					sub = "Essential Business Server Management Server Edition";
446 					break;
447 				case PRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
448 					sub = "Essential Business Server Management Security Edition";
449 					break;
450 				case PRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
451 					sub = "Essential Business Server Management Messaging Edition";
452 					break;
453 				case PRODUCT_SERVER_FOUNDATION:
454 					sub = "Foundation Edition";
455 					break;
456 				case PRODUCT_HOME_PREMIUM_SERVER:
457 					sub = "Home Server 2011 Edition";
458 					break;
459 				case PRODUCT_SERVER_FOR_SMALLBUSINESS_V:
460 					sub = "Essential Server Solutions Edition (without Hyper-V)";
461 					break;
462 				case PRODUCT_STANDARD_SERVER_V:
463 					sub = "Standard Edition (without Hyper-V)";
464 					break;
465 				case PRODUCT_DATACENTER_SERVER_V:
466 					sub = "Datacenter Edition (without Hyper-V)";
467 					break;
468 				case PRODUCT_ENTERPRISE_SERVER_V:
469 					sub = "Enterprise Edition (without Hyper-V)";
470 					break;
471 				case PRODUCT_DATACENTER_SERVER_CORE_V:
472 					sub = "Datacenter Edition (core installation, without Hyper-V)";
473 					break;
474 				case PRODUCT_STANDARD_SERVER_CORE_V:
475 					sub = "Standard Edition (core installation, without Hyper-V)";
476 					break;
477 				case PRODUCT_ENTERPRISE_SERVER_CORE_V:
478 					sub = "Enterprise Edition (core installation, without Hyper-V)";
479 					break;
480 				case PRODUCT_HYPERV:
481 					sub = "Hyper-V Server";
482 					break;
483 				case PRODUCT_STORAGE_EXPRESS_SERVER_CORE:
484 					sub = "Storage Server Express Edition (core installation)";
485 					break;
486 				case PRODUCT_STORAGE_STANDARD_SERVER_CORE:
487 					sub = "Storage Server Standard Edition (core installation)";
488 					break;
489 				case PRODUCT_STORAGE_WORKGROUP_SERVER_CORE:
490 					sub = "Storage Server Workgroup Edition (core installation)";
491 					break;
492 				case PRODUCT_STORAGE_ENTERPRISE_SERVER_CORE:
493 					sub = "Storage Server Enterprise Edition (core installation)";
494 					break;
495 				case PRODUCT_STARTER_N:
496 					sub = "Starter N Edition";
497 					break;
498 				case PRODUCT_PROFESSIONAL:
499 					sub = "Professional Edition";
500 					break;
501 				case PRODUCT_PROFESSIONAL_N:
502 					sub = "Professional N Edition";
503 					break;
504 				case PRODUCT_SB_SOLUTION_SERVER:
505 					sub = "Small Business Server 2011 Essentials Edition";
506 					break;
507 				case PRODUCT_SERVER_FOR_SB_SOLUTIONS:
508 					sub = "Server For SB Solutions Edition";
509 					break;
510 				case PRODUCT_STANDARD_SERVER_SOLUTIONS:
511 					sub = "Solutions Premium Edition";
512 					break;
513 				case PRODUCT_STANDARD_SERVER_SOLUTIONS_CORE:
514 					sub = "Solutions Premium Edition (core installation)";
515 					break;
516 				case PRODUCT_SB_SOLUTION_SERVER_EM:
517 					sub = "Server For SB Solutions EM Edition";
518 					break;
519 				case PRODUCT_SERVER_FOR_SB_SOLUTIONS_EM:
520 					sub = "Server For SB Solutions EM Edition";
521 					break;
522 				case PRODUCT_SOLUTION_EMBEDDEDSERVER:
523 					sub = "MultiPoint Server Edition";
524 					break;
525 				case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMT:
526 					sub = "Essential Server Solution Management Edition";
527 					break;
528 				case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDL:
529 					sub = "Essential Server Solution Additional Edition";
530 					break;
531 				case PRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC:
532 					sub = "Essential Server Solution Management SVC Edition";
533 					break;
534 				case PRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC:
535 					sub = "Essential Server Solution Additional SVC Edition";
536 					break;
537 				case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE:
538 					sub = "Small Business Server Premium Edition (core installation)";
539 					break;
540 				case PRODUCT_CLUSTER_SERVER_V:
541 					sub = "Hyper Core V Edition";
542 					break;
543 				case PRODUCT_STARTER_E:
544 					sub = "Hyper Core V Edition";
545 					break;
546 				case PRODUCT_ENTERPRISE_EVALUATION:
547 					sub = "Enterprise Edition (evaluation installation)";
548 					break;
549 				case PRODUCT_MULTIPOINT_STANDARD_SERVER:
550 					sub = "MultiPoint Server Standard Edition (full installation)";
551 					break;
552 				case PRODUCT_MULTIPOINT_PREMIUM_SERVER:
553 					sub = "MultiPoint Server Premium Edition (full installation)";
554 					break;
555 				case PRODUCT_STANDARD_EVALUATION_SERVER:
556 					sub = "Standard Edition (evaluation installation)";
557 					break;
558 				case PRODUCT_DATACENTER_EVALUATION_SERVER:
559 					sub = "Datacenter Edition (evaluation installation)";
560 					break;
561 				case PRODUCT_ENTERPRISE_N_EVALUATION:
562 					sub = "Enterprise N Edition (evaluation installation)";
563 					break;
564 				case PRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER:
565 					sub = "Storage Server Workgroup Edition (evaluation installation)";
566 					break;
567 				case PRODUCT_STORAGE_STANDARD_EVALUATION_SERVER:
568 					sub = "Storage Server Standard Edition (evaluation installation)";
569 					break;
570 				case PRODUCT_CORE_N:
571 					sub = "Windows 8 N Edition";
572 					break;
573 				case PRODUCT_CORE_COUNTRYSPECIFIC:
574 					sub = "Windows 8 China Edition";
575 					break;
576 				case PRODUCT_CORE_SINGLELANGUAGE:
577 					sub = "Windows 8 Single Language Edition";
578 					break;
579 				case PRODUCT_CORE:
580 					sub = "Windows 8 Edition";
581 					break;
582 				case PRODUCT_PROFESSIONAL_WMC:
583 					sub = "Professional with Media Center Edition";
584 					break;
585 			}
586 		}
587 	} else {
588 		return NULL;
589 	}
590 
591 	spprintf(&retval, 0, "%s%s%s%s%s", major, sub?" ":"", sub?sub:"", osvi.szCSDVersion[0] != '\0'?" ":"", osvi.szCSDVersion);
592 	return retval;
593 }
594 /* }}}  */
595 
596 /* {{{  */
php_get_windows_cpu(char * buf,int bufsize)597 void php_get_windows_cpu(char *buf, int bufsize)
598 {
599 	SYSTEM_INFO SysInfo;
600 	GetSystemInfo(&SysInfo);
601 	switch (SysInfo.wProcessorArchitecture) {
602 		case PROCESSOR_ARCHITECTURE_INTEL :
603 			snprintf(buf, bufsize, "i%d", SysInfo.dwProcessorType);
604 			break;
605 		case PROCESSOR_ARCHITECTURE_MIPS :
606 			snprintf(buf, bufsize, "MIPS R%d000", SysInfo.wProcessorLevel);
607 			break;
608 		case PROCESSOR_ARCHITECTURE_ALPHA :
609 			snprintf(buf, bufsize, "Alpha %d", SysInfo.wProcessorLevel);
610 			break;
611 		case PROCESSOR_ARCHITECTURE_PPC :
612 			snprintf(buf, bufsize, "PPC 6%02d", SysInfo.wProcessorLevel);
613 			break;
614 		case PROCESSOR_ARCHITECTURE_IA64 :
615 			snprintf(buf, bufsize,  "IA64");
616 			break;
617 #if defined(PROCESSOR_ARCHITECTURE_IA32_ON_WIN64)
618 		case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 :
619 			snprintf(buf, bufsize, "IA32");
620 			break;
621 #endif
622 #if defined(PROCESSOR_ARCHITECTURE_AMD64)
623 		case PROCESSOR_ARCHITECTURE_AMD64 :
624 			snprintf(buf, bufsize, "AMD64");
625 			break;
626 #endif
627 		case PROCESSOR_ARCHITECTURE_UNKNOWN :
628 		default:
629 			snprintf(buf, bufsize, "Unknown");
630 			break;
631 	}
632 }
633 /* }}}  */
634 #endif
635 
636 /* {{{ php_get_uname */
php_get_uname(char mode)637 PHPAPI zend_string *php_get_uname(char mode)
638 {
639 	char *php_uname;
640 	char tmp_uname[256];
641 #ifdef PHP_WIN32
642 	DWORD dwBuild=0;
643 	DWORD dwVersion = GetVersion();
644 	DWORD dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
645 	DWORD dwWindowsMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
646 	DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
647 	char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
648 
649 	GetComputerName(ComputerName, &dwSize);
650 
651 	if (mode == 's') {
652 		php_uname = "Windows NT";
653 	} else if (mode == 'r') {
654 		snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d", dwWindowsMajorVersion, dwWindowsMinorVersion);
655 		php_uname = tmp_uname;
656 	} else if (mode == 'n') {
657 		php_uname = ComputerName;
658 	} else if (mode == 'v') {
659 		char *winver = php_get_windows_name();
660 		dwBuild = (DWORD)(HIWORD(dwVersion));
661 		if(winver == NULL) {
662 			snprintf(tmp_uname, sizeof(tmp_uname), "build %d", dwBuild);
663 		} else {
664 			snprintf(tmp_uname, sizeof(tmp_uname), "build %d (%s)", dwBuild, winver);
665 		}
666 		php_uname = tmp_uname;
667 		if(winver) {
668 			efree(winver);
669 		}
670 	} else if (mode == 'm') {
671 		php_get_windows_cpu(tmp_uname, sizeof(tmp_uname));
672 		php_uname = tmp_uname;
673 	} else { /* assume mode == 'a' */
674 		char *winver = php_get_windows_name();
675 		char wincpu[20];
676 
677 		ZEND_ASSERT(winver != NULL);
678 
679 		php_get_windows_cpu(wincpu, sizeof(wincpu));
680 		dwBuild = (DWORD)(HIWORD(dwVersion));
681 
682 		/* Windows "version" 6.2 could be Windows 8/Windows Server 2012, but also Windows 8.1/Windows Server 2012 R2 */
683 		if (dwWindowsMajorVersion == 6 && dwWindowsMinorVersion == 2) {
684 			if (strncmp(winver, "Windows 8.1", 11) == 0 || strncmp(winver, "Windows Server 2012 R2", 22) == 0) {
685 				dwWindowsMinorVersion = 3;
686 			}
687 		}
688 
689 		snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d (%s) %s",
690 				 "Windows NT", ComputerName,
691 				 dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild, winver?winver:"unknown", wincpu);
692 		if(winver) {
693 			efree(winver);
694 		}
695 		php_uname = tmp_uname;
696 	}
697 #else
698 #ifdef HAVE_SYS_UTSNAME_H
699 	struct utsname buf;
700 	if (uname((struct utsname *)&buf) == -1) {
701 		php_uname = PHP_UNAME;
702 	} else {
703 		if (mode == 's') {
704 			php_uname = buf.sysname;
705 		} else if (mode == 'r') {
706 			php_uname = buf.release;
707 		} else if (mode == 'n') {
708 			php_uname = buf.nodename;
709 		} else if (mode == 'v') {
710 			php_uname = buf.version;
711 		} else if (mode == 'm') {
712 			php_uname = buf.machine;
713 		} else { /* assume mode == 'a' */
714 			snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %s %s %s",
715 					 buf.sysname, buf.nodename, buf.release, buf.version,
716 					 buf.machine);
717 			php_uname = tmp_uname;
718 		}
719 	}
720 #else
721 	php_uname = PHP_UNAME;
722 #endif
723 #endif
724 	return zend_string_init(php_uname, strlen(php_uname), 0);
725 }
726 /* }}} */
727 
728 /* {{{ php_print_info_htmlhead */
php_print_info_htmlhead(void)729 PHPAPI ZEND_COLD void php_print_info_htmlhead(void)
730 {
731 	php_info_print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n");
732 	php_info_print("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
733 	php_info_print("<head>\n");
734 	php_info_print_style();
735 	php_info_printf("<title>PHP %s - phpinfo()</title>", PHP_VERSION);
736 	php_info_print("<meta name=\"ROBOTS\" content=\"NOINDEX,NOFOLLOW,NOARCHIVE\" />");
737 	php_info_print("</head>\n");
738 	php_info_print("<body><div class=\"center\">\n");
739 }
740 /* }}} */
741 
742 /* {{{ module_name_cmp */
module_name_cmp(Bucket * f,Bucket * s)743 static int module_name_cmp(Bucket *f, Bucket *s)
744 {
745 	return strcasecmp(((zend_module_entry *)Z_PTR(f->val))->name,
746 				  ((zend_module_entry *)Z_PTR(s->val))->name);
747 }
748 /* }}} */
749 
750 /* {{{ php_print_info */
php_print_info(int flag)751 PHPAPI ZEND_COLD void php_print_info(int flag)
752 {
753 	char **env, *tmp1, *tmp2;
754 	zend_string *php_uname;
755 
756 	if (!sapi_module.phpinfo_as_text) {
757 		php_print_info_htmlhead();
758 	} else {
759 		php_info_print("phpinfo()\n");
760 	}
761 
762 	if (flag & PHP_INFO_GENERAL) {
763 		const char *zend_version = get_zend_version();
764 		char temp_api[10];
765 
766 		php_uname = php_get_uname('a');
767 
768 		if (!sapi_module.phpinfo_as_text) {
769 			php_info_print_box_start(1);
770 		}
771 
772 		if (!sapi_module.phpinfo_as_text) {
773 	        time_t the_time;
774 	        struct tm *ta, tmbuf;
775 
776 	        the_time = time(NULL);
777 	        ta = php_localtime_r(&the_time, &tmbuf);
778 
779             php_info_print("<a href=\"http://www.php.net/\"><img border=\"0\" src=\"");
780 	        if (ta && (ta->tm_mon==3) && (ta->tm_mday==1)) {
781 		        php_info_print(PHP_EGG_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
782 	        } else {
783 		        php_info_print(PHP_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
784 			}
785 		}
786 
787 		if (!sapi_module.phpinfo_as_text) {
788 			php_info_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
789 		} else {
790 			php_info_print_table_row(2, "PHP Version", PHP_VERSION);
791 		}
792 		php_info_print_box_end();
793 		php_info_print_table_start();
794 		php_info_print_table_row(2, "System", ZSTR_VAL(php_uname));
795 		php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__);
796 #ifdef PHP_BUILD_SYSTEM
797 		php_info_print_table_row(2, "Build System", PHP_BUILD_SYSTEM);
798 #endif
799 #ifdef PHP_BUILD_PROVIDER
800 		php_info_print_table_row(2, "Build Provider", PHP_BUILD_PROVIDER);
801 #endif
802 #ifdef COMPILER
803 		php_info_print_table_row(2, "Compiler", COMPILER);
804 #endif
805 #ifdef ARCHITECTURE
806 		php_info_print_table_row(2, "Architecture", ARCHITECTURE);
807 #endif
808 #ifdef CONFIGURE_COMMAND
809 		php_info_print_table_row(2, "Configure Command", CONFIGURE_COMMAND );
810 #endif
811 
812 		if (sapi_module.pretty_name) {
813 			php_info_print_table_row(2, "Server API", sapi_module.pretty_name );
814 		}
815 
816 #ifdef VIRTUAL_DIR
817 		php_info_print_table_row(2, "Virtual Directory Support", "enabled" );
818 #else
819 		php_info_print_table_row(2, "Virtual Directory Support", "disabled" );
820 #endif
821 
822 		php_info_print_table_row(2, "Configuration File (php.ini) Path", PHP_CONFIG_FILE_PATH);
823 		php_info_print_table_row(2, "Loaded Configuration File", php_ini_opened_path ? php_ini_opened_path : "(none)");
824 		php_info_print_table_row(2, "Scan this dir for additional .ini files", php_ini_scanned_path ? php_ini_scanned_path : "(none)");
825 		php_info_print_table_row(2, "Additional .ini files parsed", php_ini_scanned_files ? php_ini_scanned_files : "(none)");
826 
827 		snprintf(temp_api, sizeof(temp_api), "%d", PHP_API_VERSION);
828 		php_info_print_table_row(2, "PHP API", temp_api);
829 
830 		snprintf(temp_api, sizeof(temp_api), "%d", ZEND_MODULE_API_NO);
831 		php_info_print_table_row(2, "PHP Extension", temp_api);
832 
833 		snprintf(temp_api, sizeof(temp_api), "%d", ZEND_EXTENSION_API_NO);
834 		php_info_print_table_row(2, "Zend Extension", temp_api);
835 
836 		php_info_print_table_row(2, "Zend Extension Build", ZEND_EXTENSION_BUILD_ID);
837 		php_info_print_table_row(2, "PHP Extension Build", ZEND_MODULE_BUILD_ID);
838 
839 #if ZEND_DEBUG
840 		php_info_print_table_row(2, "Debug Build", "yes" );
841 #else
842 		php_info_print_table_row(2, "Debug Build", "no" );
843 #endif
844 
845 #ifdef ZTS
846 		php_info_print_table_row(2, "Thread Safety", "enabled" );
847 		php_info_print_table_row(2, "Thread API", tsrm_api_name() );
848 #else
849 		php_info_print_table_row(2, "Thread Safety", "disabled" );
850 #endif
851 
852 #ifdef ZEND_SIGNALS
853 		php_info_print_table_row(2, "Zend Signal Handling", "enabled" );
854 #else
855 		php_info_print_table_row(2, "Zend Signal Handling", "disabled" );
856 #endif
857 
858 		php_info_print_table_row(2, "Zend Memory Manager", is_zend_mm() ? "enabled" : "disabled" );
859 
860 		{
861 			const zend_multibyte_functions *functions = zend_multibyte_get_functions();
862 			char *descr;
863 			if (functions) {
864 				spprintf(&descr, 0, "provided by %s", functions->provider_name);
865 			} else {
866 				descr = estrdup("disabled");
867 			}
868             php_info_print_table_row(2, "Zend Multibyte Support", descr);
869 			efree(descr);
870 		}
871 
872 #if HAVE_IPV6
873 		php_info_print_table_row(2, "IPv6 Support", "enabled" );
874 #else
875 		php_info_print_table_row(2, "IPv6 Support", "disabled" );
876 #endif
877 
878 #if HAVE_DTRACE
879 		php_info_print_table_row(2, "DTrace Support", (zend_dtrace_enabled ? "enabled" : "available, disabled"));
880 #else
881 		php_info_print_table_row(2, "DTrace Support", "disabled" );
882 #endif
883 
884 		php_info_print_stream_hash("PHP Streams",  php_stream_get_url_stream_wrappers_hash());
885 		php_info_print_stream_hash("Stream Socket Transports", php_stream_xport_get_hash());
886 		php_info_print_stream_hash("Stream Filters", php_get_stream_filters_hash());
887 
888 		php_info_print_table_end();
889 
890 		/* Zend Engine */
891 		php_info_print_box_start(0);
892 		if (!sapi_module.phpinfo_as_text) {
893 			php_info_print("<a href=\"http://www.zend.com/\"><img border=\"0\" src=\"");
894 			php_info_print(ZEND_LOGO_DATA_URI "\" alt=\"Zend logo\" /></a>\n");
895 		}
896 		php_info_print("This program makes use of the Zend Scripting Language Engine:");
897 		php_info_print(!sapi_module.phpinfo_as_text?"<br />":"\n");
898 		if (sapi_module.phpinfo_as_text) {
899 			php_info_print(zend_version);
900 		} else {
901 			zend_html_puts(zend_version, strlen(zend_version));
902 		}
903 		php_info_print_box_end();
904 		zend_string_free(php_uname);
905 	}
906 
907 	zend_ini_sort_entries();
908 
909 	if (flag & PHP_INFO_CONFIGURATION) {
910 		php_info_print_hr();
911 		if (!sapi_module.phpinfo_as_text) {
912 			php_info_print("<h1>Configuration</h1>\n");
913 		} else {
914 			SECTION("Configuration");
915 		}
916 		if (!(flag & PHP_INFO_MODULES)) {
917 			SECTION("PHP Core");
918 			display_ini_entries(NULL);
919 		}
920 	}
921 
922 	if (flag & PHP_INFO_MODULES) {
923 		HashTable sorted_registry;
924 		zend_module_entry *module;
925 
926 		zend_hash_init(&sorted_registry, zend_hash_num_elements(&module_registry), NULL, NULL, 1);
927 		zend_hash_copy(&sorted_registry, &module_registry, NULL);
928 		zend_hash_sort(&sorted_registry, module_name_cmp, 0);
929 
930 		ZEND_HASH_FOREACH_PTR(&sorted_registry, module) {
931 			if (module->info_func || module->version) {
932 				php_info_print_module(module);
933 			}
934 		} ZEND_HASH_FOREACH_END();
935 
936 		SECTION("Additional Modules");
937 		php_info_print_table_start();
938 		php_info_print_table_header(1, "Module Name");
939 		ZEND_HASH_FOREACH_PTR(&sorted_registry, module) {
940 			if (!module->info_func && !module->version) {
941 				php_info_print_module(module);
942 			}
943 		} ZEND_HASH_FOREACH_END();
944 		php_info_print_table_end();
945 
946 		zend_hash_destroy(&sorted_registry);
947 	}
948 
949 	if (flag & PHP_INFO_ENVIRONMENT) {
950 		SECTION("Environment");
951 		php_info_print_table_start();
952 		php_info_print_table_header(2, "Variable", "Value");
953 		tsrm_env_lock();
954 		for (env=environ; env!=NULL && *env !=NULL; env++) {
955 			tmp1 = estrdup(*env);
956 			if (!(tmp2=strchr(tmp1,'='))) { /* malformed entry? */
957 				efree(tmp1);
958 				continue;
959 			}
960 			*tmp2 = 0;
961 			tmp2++;
962 			php_info_print_table_row(2, tmp1, tmp2);
963 			efree(tmp1);
964 		}
965         tsrm_env_unlock();
966 		php_info_print_table_end();
967 	}
968 
969 	if (flag & PHP_INFO_VARIABLES) {
970 		zval *data;
971 
972 		SECTION("PHP Variables");
973 
974 		php_info_print_table_start();
975 		php_info_print_table_header(2, "Variable", "Value");
976 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
977 			php_info_print_table_row(2, "PHP_SELF", Z_STRVAL_P(data));
978 		}
979 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
980 			php_info_print_table_row(2, "PHP_AUTH_TYPE", Z_STRVAL_P(data));
981 		}
982 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
983 			php_info_print_table_row(2, "PHP_AUTH_USER", Z_STRVAL_P(data));
984 		}
985 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
986 			php_info_print_table_row(2, "PHP_AUTH_PW", Z_STRVAL_P(data));
987 		}
988 		php_print_gpcse_array(ZEND_STRL("_REQUEST"));
989 		php_print_gpcse_array(ZEND_STRL("_GET"));
990 		php_print_gpcse_array(ZEND_STRL("_POST"));
991 		php_print_gpcse_array(ZEND_STRL("_FILES"));
992 		php_print_gpcse_array(ZEND_STRL("_COOKIE"));
993 		php_print_gpcse_array(ZEND_STRL("_SERVER"));
994 		php_print_gpcse_array(ZEND_STRL("_ENV"));
995 		php_info_print_table_end();
996 	}
997 
998 
999 	if (flag & PHP_INFO_CREDITS) {
1000 		php_info_print_hr();
1001 		php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE);
1002 	}
1003 
1004 	if (flag & PHP_INFO_LICENSE) {
1005 		if (!sapi_module.phpinfo_as_text) {
1006 			SECTION("PHP License");
1007 			php_info_print_box_start(0);
1008 			php_info_print("<p>\n");
1009 			php_info_print("This program is free software; you can redistribute it and/or modify ");
1010 			php_info_print("it under the terms of the PHP License as published by the PHP Group ");
1011 			php_info_print("and included in the distribution in the file:  LICENSE\n");
1012 			php_info_print("</p>\n");
1013 			php_info_print("<p>");
1014 			php_info_print("This program is distributed in the hope that it will be useful, ");
1015 			php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of ");
1016 			php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
1017 			php_info_print("</p>\n");
1018 			php_info_print("<p>");
1019 			php_info_print("If you did not receive a copy of the PHP license, or have any questions about ");
1020 			php_info_print("PHP licensing, please contact license@php.net.\n");
1021 			php_info_print("</p>\n");
1022 			php_info_print_box_end();
1023 		} else {
1024 			php_info_print("\nPHP License\n");
1025 			php_info_print("This program is free software; you can redistribute it and/or modify\n");
1026 			php_info_print("it under the terms of the PHP License as published by the PHP Group\n");
1027 			php_info_print("and included in the distribution in the file:  LICENSE\n");
1028 			php_info_print("\n");
1029 			php_info_print("This program is distributed in the hope that it will be useful,\n");
1030 			php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
1031 			php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
1032 			php_info_print("\n");
1033 			php_info_print("If you did not receive a copy of the PHP license, or have any\n");
1034 			php_info_print("questions about PHP licensing, please contact license@php.net.\n");
1035 		}
1036 	}
1037 
1038 	if (!sapi_module.phpinfo_as_text) {
1039 		php_info_print("</div></body></html>");
1040 	}
1041 }
1042 /* }}} */
1043 
php_info_print_table_start(void)1044 PHPAPI ZEND_COLD void php_info_print_table_start(void) /* {{{ */
1045 {
1046 	if (!sapi_module.phpinfo_as_text) {
1047 		php_info_print("<table>\n");
1048 	} else {
1049 		php_info_print("\n");
1050 	}
1051 }
1052 /* }}} */
1053 
php_info_print_table_end(void)1054 PHPAPI ZEND_COLD void php_info_print_table_end(void) /* {{{ */
1055 {
1056 	if (!sapi_module.phpinfo_as_text) {
1057 		php_info_print("</table>\n");
1058 	}
1059 
1060 }
1061 /* }}} */
1062 
php_info_print_box_start(int flag)1063 PHPAPI ZEND_COLD void php_info_print_box_start(int flag) /* {{{ */
1064 {
1065 	php_info_print_table_start();
1066 	if (flag) {
1067 		if (!sapi_module.phpinfo_as_text) {
1068 			php_info_print("<tr class=\"h\"><td>\n");
1069 		}
1070 	} else {
1071 		if (!sapi_module.phpinfo_as_text) {
1072 			php_info_print("<tr class=\"v\"><td>\n");
1073 		} else {
1074 			php_info_print("\n");
1075 		}
1076 	}
1077 }
1078 /* }}} */
1079 
php_info_print_box_end(void)1080 PHPAPI ZEND_COLD void php_info_print_box_end(void) /* {{{ */
1081 {
1082 	if (!sapi_module.phpinfo_as_text) {
1083 		php_info_print("</td></tr>\n");
1084 	}
1085 	php_info_print_table_end();
1086 }
1087 /* }}} */
1088 
php_info_print_hr(void)1089 PHPAPI ZEND_COLD void php_info_print_hr(void) /* {{{ */
1090 {
1091 	if (!sapi_module.phpinfo_as_text) {
1092 		php_info_print("<hr />\n");
1093 	} else {
1094 		php_info_print("\n\n _______________________________________________________________________\n\n");
1095 	}
1096 }
1097 /* }}} */
1098 
php_info_print_table_colspan_header(int num_cols,const char * header)1099 PHPAPI ZEND_COLD void php_info_print_table_colspan_header(int num_cols, const char *header) /* {{{ */
1100 {
1101 	int spaces;
1102 
1103 	if (!sapi_module.phpinfo_as_text) {
1104 		php_info_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header );
1105 	} else {
1106 		spaces = (int)(74 - strlen(header));
1107 		php_info_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " ");
1108 	}
1109 }
1110 /* }}} */
1111 
1112 /* {{{ php_info_print_table_header */
php_info_print_table_header(int num_cols,...)1113 PHPAPI ZEND_COLD void php_info_print_table_header(int num_cols, ...)
1114 {
1115 	int i;
1116 	va_list row_elements;
1117 	char *row_element;
1118 
1119 	va_start(row_elements, num_cols);
1120 	if (!sapi_module.phpinfo_as_text) {
1121 		php_info_print("<tr class=\"h\">");
1122 	}
1123 	for (i=0; i<num_cols; i++) {
1124 		row_element = va_arg(row_elements, char *);
1125 		if (!row_element || !*row_element) {
1126 			row_element = " ";
1127 		}
1128 		if (!sapi_module.phpinfo_as_text) {
1129 			php_info_print("<th>");
1130 			php_info_print(row_element);
1131 			php_info_print("</th>");
1132 		} else {
1133 			php_info_print(row_element);
1134 			if (i < num_cols-1) {
1135 				php_info_print(" => ");
1136 			} else {
1137 				php_info_print("\n");
1138 			}
1139 		}
1140 	}
1141 	if (!sapi_module.phpinfo_as_text) {
1142 		php_info_print("</tr>\n");
1143 	}
1144 
1145 	va_end(row_elements);
1146 }
1147 /* }}} */
1148 
1149 /* {{{ php_info_print_table_row_internal */
php_info_print_table_row_internal(int num_cols,const char * value_class,va_list row_elements)1150 static ZEND_COLD void php_info_print_table_row_internal(int num_cols,
1151 		const char *value_class, va_list row_elements)
1152 {
1153 	int i;
1154 	char *row_element;
1155 
1156 	if (!sapi_module.phpinfo_as_text) {
1157 		php_info_print("<tr>");
1158 	}
1159 	for (i=0; i<num_cols; i++) {
1160 		if (!sapi_module.phpinfo_as_text) {
1161 			php_info_printf("<td class=\"%s\">",
1162 			   (i==0 ? "e" : value_class )
1163 			);
1164 		}
1165 		row_element = va_arg(row_elements, char *);
1166 		if (!row_element || !*row_element) {
1167 			if (!sapi_module.phpinfo_as_text) {
1168 				php_info_print( "<i>no value</i>" );
1169 			} else {
1170 				php_info_print( " " );
1171 			}
1172 		} else {
1173 			if (!sapi_module.phpinfo_as_text) {
1174 				php_info_print_html_esc(row_element, strlen(row_element));
1175 			} else {
1176 				php_info_print(row_element);
1177 				if (i < num_cols-1) {
1178 					php_info_print(" => ");
1179 				}
1180 			}
1181 		}
1182 		if (!sapi_module.phpinfo_as_text) {
1183 			php_info_print(" </td>");
1184 		} else if (i == (num_cols - 1)) {
1185 			php_info_print("\n");
1186 		}
1187 	}
1188 	if (!sapi_module.phpinfo_as_text) {
1189 		php_info_print("</tr>\n");
1190 	}
1191 }
1192 /* }}} */
1193 
1194 /* {{{ php_info_print_table_row */
php_info_print_table_row(int num_cols,...)1195 PHPAPI ZEND_COLD void php_info_print_table_row(int num_cols, ...)
1196 {
1197 	va_list row_elements;
1198 
1199 	va_start(row_elements, num_cols);
1200 	php_info_print_table_row_internal(num_cols, "v", row_elements);
1201 	va_end(row_elements);
1202 }
1203 /* }}} */
1204 
1205 /* {{{ php_info_print_table_row_ex */
php_info_print_table_row_ex(int num_cols,const char * value_class,...)1206 PHPAPI ZEND_COLD void php_info_print_table_row_ex(int num_cols, const char *value_class,
1207 		...)
1208 {
1209 	va_list row_elements;
1210 
1211 	va_start(row_elements, value_class);
1212 	php_info_print_table_row_internal(num_cols, value_class, row_elements);
1213 	va_end(row_elements);
1214 }
1215 /* }}} */
1216 
1217 /* {{{ register_phpinfo_constants */
register_phpinfo_constants(INIT_FUNC_ARGS)1218 void register_phpinfo_constants(INIT_FUNC_ARGS)
1219 {
1220 	REGISTER_LONG_CONSTANT("INFO_GENERAL", PHP_INFO_GENERAL, CONST_PERSISTENT|CONST_CS);
1221 	REGISTER_LONG_CONSTANT("INFO_CREDITS", PHP_INFO_CREDITS, CONST_PERSISTENT|CONST_CS);
1222 	REGISTER_LONG_CONSTANT("INFO_CONFIGURATION", PHP_INFO_CONFIGURATION, CONST_PERSISTENT|CONST_CS);
1223 	REGISTER_LONG_CONSTANT("INFO_MODULES", PHP_INFO_MODULES, CONST_PERSISTENT|CONST_CS);
1224 	REGISTER_LONG_CONSTANT("INFO_ENVIRONMENT", PHP_INFO_ENVIRONMENT, CONST_PERSISTENT|CONST_CS);
1225 	REGISTER_LONG_CONSTANT("INFO_VARIABLES", PHP_INFO_VARIABLES, CONST_PERSISTENT|CONST_CS);
1226 	REGISTER_LONG_CONSTANT("INFO_LICENSE", PHP_INFO_LICENSE, CONST_PERSISTENT|CONST_CS);
1227 	REGISTER_LONG_CONSTANT("INFO_ALL", PHP_INFO_ALL, CONST_PERSISTENT|CONST_CS);
1228 	REGISTER_LONG_CONSTANT("CREDITS_GROUP",	PHP_CREDITS_GROUP, CONST_PERSISTENT|CONST_CS);
1229 	REGISTER_LONG_CONSTANT("CREDITS_GENERAL",	PHP_CREDITS_GENERAL, CONST_PERSISTENT|CONST_CS);
1230 	REGISTER_LONG_CONSTANT("CREDITS_SAPI",	PHP_CREDITS_SAPI, CONST_PERSISTENT|CONST_CS);
1231 	REGISTER_LONG_CONSTANT("CREDITS_MODULES",	PHP_CREDITS_MODULES, CONST_PERSISTENT|CONST_CS);
1232 	REGISTER_LONG_CONSTANT("CREDITS_DOCS",	PHP_CREDITS_DOCS, CONST_PERSISTENT|CONST_CS);
1233 	REGISTER_LONG_CONSTANT("CREDITS_FULLPAGE",	PHP_CREDITS_FULLPAGE, CONST_PERSISTENT|CONST_CS);
1234 	REGISTER_LONG_CONSTANT("CREDITS_QA",	PHP_CREDITS_QA, CONST_PERSISTENT|CONST_CS);
1235 	REGISTER_LONG_CONSTANT("CREDITS_ALL",	PHP_CREDITS_ALL, CONST_PERSISTENT|CONST_CS);
1236 }
1237 /* }}} */
1238 
1239 /* {{{ Output a page of useful information about PHP and the current request */
PHP_FUNCTION(phpinfo)1240 PHP_FUNCTION(phpinfo)
1241 {
1242 	zend_long flag = PHP_INFO_ALL;
1243 
1244 	ZEND_PARSE_PARAMETERS_START(0, 1)
1245 		Z_PARAM_OPTIONAL
1246 		Z_PARAM_LONG(flag)
1247 	ZEND_PARSE_PARAMETERS_END();
1248 
1249 	/* Andale!  Andale!  Yee-Hah! */
1250 	php_output_start_default();
1251 	php_print_info((int)flag);
1252 	php_output_end();
1253 
1254 	RETURN_TRUE;
1255 }
1256 
1257 /* }}} */
1258 
1259 /* {{{ Return the current PHP version */
PHP_FUNCTION(phpversion)1260 PHP_FUNCTION(phpversion)
1261 {
1262 	char *ext_name = NULL;
1263 	size_t ext_name_len = 0;
1264 
1265 	ZEND_PARSE_PARAMETERS_START(0, 1)
1266 		Z_PARAM_OPTIONAL
1267 		Z_PARAM_STRING_OR_NULL(ext_name, ext_name_len)
1268 	ZEND_PARSE_PARAMETERS_END();
1269 
1270 	if (!ext_name) {
1271 		RETURN_STRING(PHP_VERSION);
1272 	} else {
1273 		const char *version;
1274 		version = zend_get_module_version(ext_name);
1275 		if (version == NULL) {
1276 			RETURN_FALSE;
1277 		}
1278 		RETURN_STRING(version);
1279 	}
1280 }
1281 /* }}} */
1282 
1283 /* {{{ Prints the list of people who've contributed to the PHP project */
PHP_FUNCTION(phpcredits)1284 PHP_FUNCTION(phpcredits)
1285 {
1286 	zend_long flag = PHP_CREDITS_ALL;
1287 
1288 	ZEND_PARSE_PARAMETERS_START(0, 1)
1289 		Z_PARAM_OPTIONAL
1290 		Z_PARAM_LONG(flag)
1291 	ZEND_PARSE_PARAMETERS_END();
1292 
1293 	php_print_credits((int)flag);
1294 	RETURN_TRUE;
1295 }
1296 /* }}} */
1297 
1298 /* {{{ Return the current SAPI module name */
PHP_FUNCTION(php_sapi_name)1299 PHP_FUNCTION(php_sapi_name)
1300 {
1301 	ZEND_PARSE_PARAMETERS_NONE();
1302 
1303 	if (sapi_module.name) {
1304 		RETURN_STRING(sapi_module.name);
1305 	} else {
1306 		RETURN_FALSE;
1307 	}
1308 }
1309 
1310 /* }}} */
1311 
1312 /* {{{ Return information about the system PHP was built on */
PHP_FUNCTION(php_uname)1313 PHP_FUNCTION(php_uname)
1314 {
1315 	char *mode = "a";
1316 	size_t modelen = sizeof("a")-1;
1317 
1318 	ZEND_PARSE_PARAMETERS_START(0, 1)
1319 		Z_PARAM_OPTIONAL
1320 		Z_PARAM_STRING(mode, modelen)
1321 	ZEND_PARSE_PARAMETERS_END();
1322 
1323 	RETURN_STR(php_get_uname(*mode));
1324 }
1325 
1326 /* }}} */
1327 
1328 /* {{{ Return comma-separated string of .ini files parsed from the additional ini dir */
PHP_FUNCTION(php_ini_scanned_files)1329 PHP_FUNCTION(php_ini_scanned_files)
1330 {
1331 	ZEND_PARSE_PARAMETERS_NONE();
1332 
1333 	if (php_ini_scanned_files) {
1334 		RETURN_STRING(php_ini_scanned_files);
1335 	} else {
1336 		RETURN_FALSE;
1337 	}
1338 }
1339 /* }}} */
1340 
1341 /* {{{ Return the actual loaded ini filename */
PHP_FUNCTION(php_ini_loaded_file)1342 PHP_FUNCTION(php_ini_loaded_file)
1343 {
1344 	ZEND_PARSE_PARAMETERS_NONE();
1345 
1346 	if (php_ini_opened_path) {
1347 		RETURN_STRING(php_ini_opened_path);
1348 	} else {
1349 		RETURN_FALSE;
1350 	}
1351 }
1352 /* }}} */
1353