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