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