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