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