xref: /PHP-7.3/ext/standard/info.c (revision 9afce019)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 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 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 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 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 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 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 
_display_module_info_func(zval * el)167 static int _display_module_info_func(zval *el) /* {{{ */
168 {
169 	zend_module_entry *module = (zend_module_entry*)Z_PTR_P(el);
170 	if (module->info_func || module->version) {
171 		php_info_print_module(module);
172 	}
173 	return ZEND_HASH_APPLY_KEEP;
174 }
175 /* }}} */
176 
_display_module_info_def(zval * el)177 static int _display_module_info_def(zval *el) /* {{{ */
178 {
179 	zend_module_entry *module = (zend_module_entry*)Z_PTR_P(el);
180 	if (!module->info_func && !module->version) {
181 		php_info_print_module(module);
182 	}
183 	return ZEND_HASH_APPLY_KEEP;
184 }
185 /* }}} */
186 
187 /* {{{ php_print_gpcse_array
188  */
php_print_gpcse_array(char * name,uint32_t name_length)189 static void php_print_gpcse_array(char *name, uint32_t name_length)
190 {
191 	zval *data, *tmp;
192 	zend_string *string_key;
193 	zend_ulong num_key;
194 	zend_string *key;
195 
196 	key = zend_string_init(name, name_length, 0);
197 	zend_is_auto_global(key);
198 
199 	if ((data = zend_hash_find(&EG(symbol_table), key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
200 		ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_key, string_key, tmp) {
201 			if (!sapi_module.phpinfo_as_text) {
202 				php_info_print("<tr>");
203 				php_info_print("<td class=\"e\">");
204 			}
205 
206 			php_info_print("$");
207 			php_info_print(name);
208 			php_info_print("['");
209 
210 			if (string_key != NULL) {
211 				if (!sapi_module.phpinfo_as_text) {
212 					php_info_print_html_esc(ZSTR_VAL(string_key), ZSTR_LEN(string_key));
213 				} else {
214 					php_info_print(ZSTR_VAL(string_key));
215 				}
216 			} else {
217 				php_info_printf(ZEND_ULONG_FMT, num_key);
218 			}
219 			php_info_print("']");
220 			if (!sapi_module.phpinfo_as_text) {
221 				php_info_print("</td><td class=\"v\">");
222 			} else {
223 				php_info_print(" => ");
224 			}
225 			if (Z_TYPE_P(tmp) == IS_ARRAY) {
226 				if (!sapi_module.phpinfo_as_text) {
227 					zend_string *str = zend_print_zval_r_to_str(tmp, 0);
228 					php_info_print("<pre>");
229 					php_info_print_html_esc(ZSTR_VAL(str), ZSTR_LEN(str));
230 					php_info_print("</pre>");
231 					zend_string_release_ex(str, 0);
232 				} else {
233 					zend_print_zval_r(tmp, 0);
234 				}
235 			} else {
236 				zend_string *tmp2;
237 				zend_string *str = zval_get_tmp_string(tmp, &tmp2);
238 
239 				if (!sapi_module.phpinfo_as_text) {
240 					if (ZSTR_LEN(str) == 0) {
241 						php_info_print("<i>no value</i>");
242 					} else {
243 						php_info_print_html_esc(ZSTR_VAL(str), ZSTR_LEN(str));
244 					}
245 				} else {
246 					php_info_print(ZSTR_VAL(str));
247 				}
248 
249 				zend_tmp_string_release(tmp2);
250 			}
251 			if (!sapi_module.phpinfo_as_text) {
252 				php_info_print("</td></tr>\n");
253 			} else {
254 				php_info_print("\n");
255 			}
256 		} ZEND_HASH_FOREACH_END();
257 	}
258 	zend_string_efree(key);
259 }
260 /* }}} */
261 
262 /* {{{ php_info_print_style
263  */
php_info_print_style(void)264 void php_info_print_style(void)
265 {
266 	php_info_printf("<style type=\"text/css\">\n");
267 	php_info_print_css();
268 	php_info_printf("</style>\n");
269 }
270 /* }}} */
271 
272 /* {{{ php_info_html_esc
273  */
php_info_html_esc(char * string)274 PHPAPI zend_string *php_info_html_esc(char *string)
275 {
276 	return php_escape_html_entities((unsigned char *) string, strlen(string), 0, ENT_QUOTES, NULL);
277 }
278 /* }}} */
279 
280 #ifdef PHP_WIN32
281 /* {{{  */
282 
php_get_windows_name()283 char* php_get_windows_name()
284 {
285 	OSVERSIONINFOEX osvi = EG(windows_version_info);
286 	SYSTEM_INFO si;
287 	DWORD dwType;
288 	char *major = NULL, *sub = NULL, *retval;
289 
290 	ZeroMemory(&si, sizeof(SYSTEM_INFO));
291 
292 	GetNativeSystemInfo(&si);
293 
294 	if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion >= 10) {
295 		if (osvi.dwMajorVersion == 10) {
296 			if( osvi.dwMinorVersion == 0 ) {
297 				if( osvi.wProductType == VER_NT_WORKSTATION ) {
298 					major = "Windows 10";
299 				} else {
300 					major = "Windows Server 2016";
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 		case PROCESSOR_ARCHITECTURE_UNKNOWN :
652 		default:
653 			snprintf(buf, bufsize, "Unknown");
654 			break;
655 	}
656 }
657 /* }}}  */
658 #endif
659 
660 /* {{{ php_get_uname
661  */
php_get_uname(char mode)662 PHPAPI zend_string *php_get_uname(char mode)
663 {
664 	char *php_uname;
665 	char tmp_uname[256];
666 #ifdef PHP_WIN32
667 	DWORD dwBuild=0;
668 	DWORD dwVersion = GetVersion();
669 	DWORD dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwVersion)));
670 	DWORD dwWindowsMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwVersion)));
671 	DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
672 	char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
673 
674 	GetComputerName(ComputerName, &dwSize);
675 
676 	if (mode == 's') {
677 		php_uname = "Windows NT";
678 	} else if (mode == 'r') {
679 		snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d", dwWindowsMajorVersion, dwWindowsMinorVersion);
680 		php_uname = tmp_uname;
681 	} else if (mode == 'n') {
682 		php_uname = ComputerName;
683 	} else if (mode == 'v') {
684 		char *winver = php_get_windows_name();
685 		dwBuild = (DWORD)(HIWORD(dwVersion));
686 		if(winver == NULL) {
687 			snprintf(tmp_uname, sizeof(tmp_uname), "build %d", dwBuild);
688 		} else {
689 			snprintf(tmp_uname, sizeof(tmp_uname), "build %d (%s)", dwBuild, winver);
690 		}
691 		php_uname = tmp_uname;
692 		if(winver) {
693 			efree(winver);
694 		}
695 	} else if (mode == 'm') {
696 		php_get_windows_cpu(tmp_uname, sizeof(tmp_uname));
697 		php_uname = tmp_uname;
698 	} else { /* assume mode == 'a' */
699 		char *winver = php_get_windows_name();
700 		char wincpu[20];
701 
702 		ZEND_ASSERT(winver != NULL);
703 
704 		php_get_windows_cpu(wincpu, sizeof(wincpu));
705 		dwBuild = (DWORD)(HIWORD(dwVersion));
706 
707 		/* Windows "version" 6.2 could be Windows 8/Windows Server 2012, but also Windows 8.1/Windows Server 2012 R2 */
708 		if (dwWindowsMajorVersion == 6 && dwWindowsMinorVersion == 2) {
709 			if (strncmp(winver, "Windows 8.1", 11) == 0 || strncmp(winver, "Windows Server 2012 R2", 22) == 0) {
710 				dwWindowsMinorVersion = 3;
711 			}
712 		}
713 
714 		snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d build %d (%s) %s",
715 				 "Windows NT", ComputerName,
716 				 dwWindowsMajorVersion, dwWindowsMinorVersion, dwBuild, winver?winver:"unknown", wincpu);
717 		if(winver) {
718 			efree(winver);
719 		}
720 		php_uname = tmp_uname;
721 	}
722 #else
723 #ifdef HAVE_SYS_UTSNAME_H
724 	struct utsname buf;
725 	if (uname((struct utsname *)&buf) == -1) {
726 		php_uname = PHP_UNAME;
727 	} else {
728 		if (mode == 's') {
729 			php_uname = buf.sysname;
730 		} else if (mode == 'r') {
731 			php_uname = buf.release;
732 		} else if (mode == 'n') {
733 			php_uname = buf.nodename;
734 		} else if (mode == 'v') {
735 			php_uname = buf.version;
736 		} else if (mode == 'm') {
737 			php_uname = buf.machine;
738 		} else { /* assume mode == 'a' */
739 			snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %s %s %s",
740 					 buf.sysname, buf.nodename, buf.release, buf.version,
741 					 buf.machine);
742 			php_uname = tmp_uname;
743 		}
744 	}
745 #else
746 	php_uname = PHP_UNAME;
747 #endif
748 #endif
749 	return zend_string_init(php_uname, strlen(php_uname), 0);
750 }
751 /* }}} */
752 
753 /* {{{ php_print_info_htmlhead
754  */
php_print_info_htmlhead(void)755 PHPAPI void php_print_info_htmlhead(void)
756 {
757 	php_info_print("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"DTD/xhtml1-transitional.dtd\">\n");
758 	php_info_print("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
759 	php_info_print("<head>\n");
760 	php_info_print_style();
761 	php_info_printf("<title>PHP %s - phpinfo()</title>", PHP_VERSION);
762 	php_info_print("<meta name=\"ROBOTS\" content=\"NOINDEX,NOFOLLOW,NOARCHIVE\" />");
763 	php_info_print("</head>\n");
764 	php_info_print("<body><div class=\"center\">\n");
765 }
766 /* }}} */
767 
768 /* {{{ module_name_cmp */
module_name_cmp(const void * a,const void * b)769 static int module_name_cmp(const void *a, const void *b)
770 {
771 	Bucket *f = (Bucket *) a;
772 	Bucket *s = (Bucket *) b;
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
780  */
php_print_info(int flag)781 PHPAPI void php_print_info(int flag)
782 {
783 	char **env, *tmp1, *tmp2;
784 	zend_string *php_uname;
785 
786 	if (!sapi_module.phpinfo_as_text) {
787 		php_print_info_htmlhead();
788 	} else {
789 		php_info_print("phpinfo()\n");
790 	}
791 
792 	if (flag & PHP_INFO_GENERAL) {
793 		char *zend_version = get_zend_version();
794 		char temp_api[10];
795 
796 		php_uname = php_get_uname('a');
797 
798 		if (!sapi_module.phpinfo_as_text) {
799 			php_info_print_box_start(1);
800 		}
801 
802 		if (!sapi_module.phpinfo_as_text) {
803 	        time_t the_time;
804 	        struct tm *ta, tmbuf;
805 
806 	        the_time = time(NULL);
807 	        ta = php_localtime_r(&the_time, &tmbuf);
808 
809             php_info_print("<a href=\"http://www.php.net/\"><img border=\"0\" src=\"");
810 	        if (ta && (ta->tm_mon==3) && (ta->tm_mday==1)) {
811 		        php_info_print(PHP_EGG_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
812 	        } else {
813 		        php_info_print(PHP_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
814 			}
815 		}
816 
817 		if (!sapi_module.phpinfo_as_text) {
818 			php_info_printf("<h1 class=\"p\">PHP Version %s</h1>\n", PHP_VERSION);
819 		} else {
820 			php_info_print_table_row(2, "PHP Version", PHP_VERSION);
821 		}
822 		php_info_print_box_end();
823 		php_info_print_table_start();
824 		php_info_print_table_row(2, "System", ZSTR_VAL(php_uname));
825 		php_info_print_table_row(2, "Build Date", __DATE__ " " __TIME__);
826 #ifdef COMPILER
827 		php_info_print_table_row(2, "Compiler", COMPILER);
828 #endif
829 #ifdef ARCHITECTURE
830 		php_info_print_table_row(2, "Architecture", ARCHITECTURE);
831 #endif
832 #ifdef CONFIGURE_COMMAND
833 		php_info_print_table_row(2, "Configure Command", CONFIGURE_COMMAND );
834 #endif
835 
836 		if (sapi_module.pretty_name) {
837 			php_info_print_table_row(2, "Server API", sapi_module.pretty_name );
838 		}
839 
840 #ifdef VIRTUAL_DIR
841 		php_info_print_table_row(2, "Virtual Directory Support", "enabled" );
842 #else
843 		php_info_print_table_row(2, "Virtual Directory Support", "disabled" );
844 #endif
845 
846 		php_info_print_table_row(2, "Configuration File (php.ini) Path", PHP_CONFIG_FILE_PATH);
847 		php_info_print_table_row(2, "Loaded Configuration File", php_ini_opened_path ? php_ini_opened_path : "(none)");
848 		php_info_print_table_row(2, "Scan this dir for additional .ini files", php_ini_scanned_path ? php_ini_scanned_path : "(none)");
849 		php_info_print_table_row(2, "Additional .ini files parsed", php_ini_scanned_files ? php_ini_scanned_files : "(none)");
850 
851 		snprintf(temp_api, sizeof(temp_api), "%d", PHP_API_VERSION);
852 		php_info_print_table_row(2, "PHP API", temp_api);
853 
854 		snprintf(temp_api, sizeof(temp_api), "%d", ZEND_MODULE_API_NO);
855 		php_info_print_table_row(2, "PHP Extension", temp_api);
856 
857 		snprintf(temp_api, sizeof(temp_api), "%d", ZEND_EXTENSION_API_NO);
858 		php_info_print_table_row(2, "Zend Extension", temp_api);
859 
860 		php_info_print_table_row(2, "Zend Extension Build", ZEND_EXTENSION_BUILD_ID);
861 		php_info_print_table_row(2, "PHP Extension Build", ZEND_MODULE_BUILD_ID);
862 
863 #if ZEND_DEBUG
864 		php_info_print_table_row(2, "Debug Build", "yes" );
865 #else
866 		php_info_print_table_row(2, "Debug Build", "no" );
867 #endif
868 
869 #ifdef ZTS
870 		php_info_print_table_row(2, "Thread Safety", "enabled" );
871 		php_info_print_table_row(2, "Thread API", tsrm_api_name() );
872 #else
873 		php_info_print_table_row(2, "Thread Safety", "disabled" );
874 #endif
875 
876 #ifdef ZEND_SIGNALS
877 		php_info_print_table_row(2, "Zend Signal Handling", "enabled" );
878 #else
879 		php_info_print_table_row(2, "Zend Signal Handling", "disabled" );
880 #endif
881 
882 		php_info_print_table_row(2, "Zend Memory Manager", is_zend_mm() ? "enabled" : "disabled" );
883 
884 		{
885 			const zend_multibyte_functions *functions = zend_multibyte_get_functions();
886 			char *descr;
887 			if (functions) {
888 				spprintf(&descr, 0, "provided by %s", functions->provider_name);
889 			} else {
890 				descr = estrdup("disabled");
891 			}
892             php_info_print_table_row(2, "Zend Multibyte Support", descr);
893 			efree(descr);
894 		}
895 
896 #if HAVE_IPV6
897 		php_info_print_table_row(2, "IPv6 Support", "enabled" );
898 #else
899 		php_info_print_table_row(2, "IPv6 Support", "disabled" );
900 #endif
901 
902 #if HAVE_DTRACE
903 		php_info_print_table_row(2, "DTrace Support", (zend_dtrace_enabled ? "enabled" : "available, disabled"));
904 #else
905 		php_info_print_table_row(2, "DTrace Support", "disabled" );
906 #endif
907 
908 		php_info_print_stream_hash("PHP Streams",  php_stream_get_url_stream_wrappers_hash());
909 		php_info_print_stream_hash("Stream Socket Transports", php_stream_xport_get_hash());
910 		php_info_print_stream_hash("Stream Filters", php_get_stream_filters_hash());
911 
912 		php_info_print_table_end();
913 
914 		/* Zend Engine */
915 		php_info_print_box_start(0);
916 		if (!sapi_module.phpinfo_as_text) {
917 			php_info_print("<a href=\"http://www.zend.com/\"><img border=\"0\" src=\"");
918 			php_info_print(ZEND_LOGO_DATA_URI "\" alt=\"Zend logo\" /></a>\n");
919 		}
920 		php_info_print("This program makes use of the Zend Scripting Language Engine:");
921 		php_info_print(!sapi_module.phpinfo_as_text?"<br />":"\n");
922 		if (sapi_module.phpinfo_as_text) {
923 			php_info_print(zend_version);
924 		} else {
925 			zend_html_puts(zend_version, strlen(zend_version));
926 		}
927 		php_info_print_box_end();
928 		zend_string_free(php_uname);
929 	}
930 
931 	zend_ini_sort_entries();
932 
933 	if (flag & PHP_INFO_CONFIGURATION) {
934 		php_info_print_hr();
935 		if (!sapi_module.phpinfo_as_text) {
936 			php_info_print("<h1>Configuration</h1>\n");
937 		} else {
938 			SECTION("Configuration");
939 		}
940 		if (!(flag & PHP_INFO_MODULES)) {
941 			SECTION("PHP Core");
942 			display_ini_entries(NULL);
943 		}
944 	}
945 
946 	if (flag & PHP_INFO_MODULES) {
947 		HashTable sorted_registry;
948 
949 		zend_hash_init(&sorted_registry, zend_hash_num_elements(&module_registry), NULL, NULL, 1);
950 		zend_hash_copy(&sorted_registry, &module_registry, NULL);
951 		zend_hash_sort(&sorted_registry, module_name_cmp, 0);
952 
953 		zend_hash_apply(&sorted_registry, _display_module_info_func);
954 
955 		SECTION("Additional Modules");
956 		php_info_print_table_start();
957 		php_info_print_table_header(1, "Module Name");
958 		zend_hash_apply(&sorted_registry, _display_module_info_def);
959 		php_info_print_table_end();
960 
961 		zend_hash_destroy(&sorted_registry);
962 	}
963 
964 	if (flag & PHP_INFO_ENVIRONMENT) {
965 		SECTION("Environment");
966 		php_info_print_table_start();
967 		php_info_print_table_header(2, "Variable", "Value");
968 		for (env=environ; env!=NULL && *env !=NULL; env++) {
969 			tmp1 = estrdup(*env);
970 			if (!(tmp2=strchr(tmp1,'='))) { /* malformed entry? */
971 				efree(tmp1);
972 				continue;
973 			}
974 			*tmp2 = 0;
975 			tmp2++;
976 			php_info_print_table_row(2, tmp1, tmp2);
977 			efree(tmp1);
978 		}
979 		php_info_print_table_end();
980 	}
981 
982 	if (flag & PHP_INFO_VARIABLES) {
983 		zval *data;
984 
985 		SECTION("PHP Variables");
986 
987 		php_info_print_table_start();
988 		php_info_print_table_header(2, "Variable", "Value");
989 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
990 			php_info_print_table_row(2, "PHP_SELF", Z_STRVAL_P(data));
991 		}
992 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
993 			php_info_print_table_row(2, "PHP_AUTH_TYPE", Z_STRVAL_P(data));
994 		}
995 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
996 			php_info_print_table_row(2, "PHP_AUTH_USER", Z_STRVAL_P(data));
997 		}
998 		if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
999 			php_info_print_table_row(2, "PHP_AUTH_PW", Z_STRVAL_P(data));
1000 		}
1001 		php_print_gpcse_array(ZEND_STRL("_REQUEST"));
1002 		php_print_gpcse_array(ZEND_STRL("_GET"));
1003 		php_print_gpcse_array(ZEND_STRL("_POST"));
1004 		php_print_gpcse_array(ZEND_STRL("_FILES"));
1005 		php_print_gpcse_array(ZEND_STRL("_COOKIE"));
1006 		php_print_gpcse_array(ZEND_STRL("_SERVER"));
1007 		php_print_gpcse_array(ZEND_STRL("_ENV"));
1008 		php_info_print_table_end();
1009 	}
1010 
1011 
1012 	if ((flag & PHP_INFO_CREDITS) && !sapi_module.phpinfo_as_text) {
1013 		php_info_print_hr();
1014 		php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE);
1015 	}
1016 
1017 	if (flag & PHP_INFO_LICENSE) {
1018 		if (!sapi_module.phpinfo_as_text) {
1019 			SECTION("PHP License");
1020 			php_info_print_box_start(0);
1021 			php_info_print("<p>\n");
1022 			php_info_print("This program is free software; you can redistribute it and/or modify ");
1023 			php_info_print("it under the terms of the PHP License as published by the PHP Group ");
1024 			php_info_print("and included in the distribution in the file:  LICENSE\n");
1025 			php_info_print("</p>\n");
1026 			php_info_print("<p>");
1027 			php_info_print("This program is distributed in the hope that it will be useful, ");
1028 			php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of ");
1029 			php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
1030 			php_info_print("</p>\n");
1031 			php_info_print("<p>");
1032 			php_info_print("If you did not receive a copy of the PHP license, or have any questions about ");
1033 			php_info_print("PHP licensing, please contact license@php.net.\n");
1034 			php_info_print("</p>\n");
1035 			php_info_print_box_end();
1036 		} else {
1037 			php_info_print("\nPHP License\n");
1038 			php_info_print("This program is free software; you can redistribute it and/or modify\n");
1039 			php_info_print("it under the terms of the PHP License as published by the PHP Group\n");
1040 			php_info_print("and included in the distribution in the file:  LICENSE\n");
1041 			php_info_print("\n");
1042 			php_info_print("This program is distributed in the hope that it will be useful,\n");
1043 			php_info_print("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
1044 			php_info_print("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
1045 			php_info_print("\n");
1046 			php_info_print("If you did not receive a copy of the PHP license, or have any\n");
1047 			php_info_print("questions about PHP licensing, please contact license@php.net.\n");
1048 		}
1049 	}
1050 
1051 	if (!sapi_module.phpinfo_as_text) {
1052 		php_info_print("</div></body></html>");
1053 	}
1054 }
1055 /* }}} */
1056 
php_info_print_table_start(void)1057 PHPAPI void php_info_print_table_start(void) /* {{{ */
1058 {
1059 	if (!sapi_module.phpinfo_as_text) {
1060 		php_info_print("<table>\n");
1061 	} else {
1062 		php_info_print("\n");
1063 	}
1064 }
1065 /* }}} */
1066 
php_info_print_table_end(void)1067 PHPAPI void php_info_print_table_end(void) /* {{{ */
1068 {
1069 	if (!sapi_module.phpinfo_as_text) {
1070 		php_info_print("</table>\n");
1071 	}
1072 
1073 }
1074 /* }}} */
1075 
php_info_print_box_start(int flag)1076 PHPAPI void php_info_print_box_start(int flag) /* {{{ */
1077 {
1078 	php_info_print_table_start();
1079 	if (flag) {
1080 		if (!sapi_module.phpinfo_as_text) {
1081 			php_info_print("<tr class=\"h\"><td>\n");
1082 		}
1083 	} else {
1084 		if (!sapi_module.phpinfo_as_text) {
1085 			php_info_print("<tr class=\"v\"><td>\n");
1086 		} else {
1087 			php_info_print("\n");
1088 		}
1089 	}
1090 }
1091 /* }}} */
1092 
php_info_print_box_end(void)1093 PHPAPI void php_info_print_box_end(void) /* {{{ */
1094 {
1095 	if (!sapi_module.phpinfo_as_text) {
1096 		php_info_print("</td></tr>\n");
1097 	}
1098 	php_info_print_table_end();
1099 }
1100 /* }}} */
1101 
php_info_print_hr(void)1102 PHPAPI void php_info_print_hr(void) /* {{{ */
1103 {
1104 	if (!sapi_module.phpinfo_as_text) {
1105 		php_info_print("<hr />\n");
1106 	} else {
1107 		php_info_print("\n\n _______________________________________________________________________\n\n");
1108 	}
1109 }
1110 /* }}} */
1111 
php_info_print_table_colspan_header(int num_cols,char * header)1112 PHPAPI void php_info_print_table_colspan_header(int num_cols, char *header) /* {{{ */
1113 {
1114 	int spaces;
1115 
1116 	if (!sapi_module.phpinfo_as_text) {
1117 		php_info_printf("<tr class=\"h\"><th colspan=\"%d\">%s</th></tr>\n", num_cols, header );
1118 	} else {
1119 		spaces = (int)(74 - strlen(header));
1120 		php_info_printf("%*s%s%*s\n", (int)(spaces/2), " ", header, (int)(spaces/2), " ");
1121 	}
1122 }
1123 /* }}} */
1124 
1125 /* {{{ php_info_print_table_header
1126  */
php_info_print_table_header(int num_cols,...)1127 PHPAPI void php_info_print_table_header(int num_cols, ...)
1128 {
1129 	int i;
1130 	va_list row_elements;
1131 	char *row_element;
1132 
1133 	va_start(row_elements, num_cols);
1134 	if (!sapi_module.phpinfo_as_text) {
1135 		php_info_print("<tr class=\"h\">");
1136 	}
1137 	for (i=0; i<num_cols; i++) {
1138 		row_element = va_arg(row_elements, char *);
1139 		if (!row_element || !*row_element) {
1140 			row_element = " ";
1141 		}
1142 		if (!sapi_module.phpinfo_as_text) {
1143 			php_info_print("<th>");
1144 			php_info_print(row_element);
1145 			php_info_print("</th>");
1146 		} else {
1147 			php_info_print(row_element);
1148 			if (i < num_cols-1) {
1149 				php_info_print(" => ");
1150 			} else {
1151 				php_info_print("\n");
1152 			}
1153 		}
1154 	}
1155 	if (!sapi_module.phpinfo_as_text) {
1156 		php_info_print("</tr>\n");
1157 	}
1158 
1159 	va_end(row_elements);
1160 }
1161 /* }}} */
1162 
1163 /* {{{ php_info_print_table_row_internal
1164  */
php_info_print_table_row_internal(int num_cols,const char * value_class,va_list row_elements)1165 static void php_info_print_table_row_internal(int num_cols,
1166 		const char *value_class, va_list row_elements)
1167 {
1168 	int i;
1169 	char *row_element;
1170 
1171 	if (!sapi_module.phpinfo_as_text) {
1172 		php_info_print("<tr>");
1173 	}
1174 	for (i=0; i<num_cols; i++) {
1175 		if (!sapi_module.phpinfo_as_text) {
1176 			php_info_printf("<td class=\"%s\">",
1177 			   (i==0 ? "e" : value_class )
1178 			);
1179 		}
1180 		row_element = va_arg(row_elements, char *);
1181 		if (!row_element || !*row_element) {
1182 			if (!sapi_module.phpinfo_as_text) {
1183 				php_info_print( "<i>no value</i>" );
1184 			} else {
1185 				php_info_print( " " );
1186 			}
1187 		} else {
1188 			if (!sapi_module.phpinfo_as_text) {
1189 				php_info_print_html_esc(row_element, strlen(row_element));
1190 			} else {
1191 				php_info_print(row_element);
1192 				if (i < num_cols-1) {
1193 					php_info_print(" => ");
1194 				}
1195 			}
1196 		}
1197 		if (!sapi_module.phpinfo_as_text) {
1198 			php_info_print(" </td>");
1199 		} else if (i == (num_cols - 1)) {
1200 			php_info_print("\n");
1201 		}
1202 	}
1203 	if (!sapi_module.phpinfo_as_text) {
1204 		php_info_print("</tr>\n");
1205 	}
1206 }
1207 /* }}} */
1208 
1209 /* {{{ php_info_print_table_row
1210  */
php_info_print_table_row(int num_cols,...)1211 PHPAPI void php_info_print_table_row(int num_cols, ...)
1212 {
1213 	va_list row_elements;
1214 
1215 	va_start(row_elements, num_cols);
1216 	php_info_print_table_row_internal(num_cols, "v", row_elements);
1217 	va_end(row_elements);
1218 }
1219 /* }}} */
1220 
1221 /* {{{ php_info_print_table_row_ex
1222  */
php_info_print_table_row_ex(int num_cols,const char * value_class,...)1223 PHPAPI void php_info_print_table_row_ex(int num_cols, const char *value_class,
1224 		...)
1225 {
1226 	va_list row_elements;
1227 
1228 	va_start(row_elements, value_class);
1229 	php_info_print_table_row_internal(num_cols, value_class, row_elements);
1230 	va_end(row_elements);
1231 }
1232 /* }}} */
1233 
1234 /* {{{ register_phpinfo_constants
1235  */
register_phpinfo_constants(INIT_FUNC_ARGS)1236 void register_phpinfo_constants(INIT_FUNC_ARGS)
1237 {
1238 	REGISTER_LONG_CONSTANT("INFO_GENERAL", PHP_INFO_GENERAL, CONST_PERSISTENT|CONST_CS);
1239 	REGISTER_LONG_CONSTANT("INFO_CREDITS", PHP_INFO_CREDITS, CONST_PERSISTENT|CONST_CS);
1240 	REGISTER_LONG_CONSTANT("INFO_CONFIGURATION", PHP_INFO_CONFIGURATION, CONST_PERSISTENT|CONST_CS);
1241 	REGISTER_LONG_CONSTANT("INFO_MODULES", PHP_INFO_MODULES, CONST_PERSISTENT|CONST_CS);
1242 	REGISTER_LONG_CONSTANT("INFO_ENVIRONMENT", PHP_INFO_ENVIRONMENT, CONST_PERSISTENT|CONST_CS);
1243 	REGISTER_LONG_CONSTANT("INFO_VARIABLES", PHP_INFO_VARIABLES, CONST_PERSISTENT|CONST_CS);
1244 	REGISTER_LONG_CONSTANT("INFO_LICENSE", PHP_INFO_LICENSE, CONST_PERSISTENT|CONST_CS);
1245 	REGISTER_LONG_CONSTANT("INFO_ALL", PHP_INFO_ALL, CONST_PERSISTENT|CONST_CS);
1246 	REGISTER_LONG_CONSTANT("CREDITS_GROUP",	PHP_CREDITS_GROUP, CONST_PERSISTENT|CONST_CS);
1247 	REGISTER_LONG_CONSTANT("CREDITS_GENERAL",	PHP_CREDITS_GENERAL, CONST_PERSISTENT|CONST_CS);
1248 	REGISTER_LONG_CONSTANT("CREDITS_SAPI",	PHP_CREDITS_SAPI, CONST_PERSISTENT|CONST_CS);
1249 	REGISTER_LONG_CONSTANT("CREDITS_MODULES",	PHP_CREDITS_MODULES, CONST_PERSISTENT|CONST_CS);
1250 	REGISTER_LONG_CONSTANT("CREDITS_DOCS",	PHP_CREDITS_DOCS, CONST_PERSISTENT|CONST_CS);
1251 	REGISTER_LONG_CONSTANT("CREDITS_FULLPAGE",	PHP_CREDITS_FULLPAGE, CONST_PERSISTENT|CONST_CS);
1252 	REGISTER_LONG_CONSTANT("CREDITS_QA",	PHP_CREDITS_QA, CONST_PERSISTENT|CONST_CS);
1253 	REGISTER_LONG_CONSTANT("CREDITS_ALL",	PHP_CREDITS_ALL, CONST_PERSISTENT|CONST_CS);
1254 }
1255 /* }}} */
1256 
1257 /* {{{ proto void phpinfo([int what])
1258    Output a page of useful information about PHP and the current request */
PHP_FUNCTION(phpinfo)1259 PHP_FUNCTION(phpinfo)
1260 {
1261 	zend_long flag = PHP_INFO_ALL;
1262 
1263 	ZEND_PARSE_PARAMETERS_START(0, 1)
1264 		Z_PARAM_OPTIONAL
1265 		Z_PARAM_LONG(flag)
1266 	ZEND_PARSE_PARAMETERS_END();
1267 
1268 	/* Andale!  Andale!  Yee-Hah! */
1269 	php_output_start_default();
1270 	php_print_info((int)flag);
1271 	php_output_end();
1272 
1273 	RETURN_TRUE;
1274 }
1275 
1276 /* }}} */
1277 
1278 /* {{{ proto string phpversion([string extension])
1279    Return the current PHP version */
PHP_FUNCTION(phpversion)1280 PHP_FUNCTION(phpversion)
1281 {
1282 	char *ext_name = NULL;
1283 	size_t ext_name_len = 0;
1284 
1285 	ZEND_PARSE_PARAMETERS_START(0, 1)
1286 		Z_PARAM_OPTIONAL
1287 		Z_PARAM_STRING(ext_name, ext_name_len)
1288 	ZEND_PARSE_PARAMETERS_END();
1289 
1290 	if (!ext_name) {
1291 		RETURN_STRING(PHP_VERSION);
1292 	} else {
1293 		const char *version;
1294 		version = zend_get_module_version(ext_name);
1295 		if (version == NULL) {
1296 			RETURN_FALSE;
1297 		}
1298 		RETURN_STRING(version);
1299 	}
1300 }
1301 /* }}} */
1302 
1303 /* {{{ proto void phpcredits([int flag])
1304    Prints the list of people who've contributed to the PHP project */
PHP_FUNCTION(phpcredits)1305 PHP_FUNCTION(phpcredits)
1306 {
1307 	zend_long flag = PHP_CREDITS_ALL;
1308 
1309 	ZEND_PARSE_PARAMETERS_START(0, 1)
1310 		Z_PARAM_OPTIONAL
1311 		Z_PARAM_LONG(flag)
1312 	ZEND_PARSE_PARAMETERS_END();
1313 
1314 	php_print_credits((int)flag);
1315 	RETURN_TRUE;
1316 }
1317 /* }}} */
1318 
1319 /* {{{ proto string php_sapi_name(void)
1320    Return the current SAPI module name */
PHP_FUNCTION(php_sapi_name)1321 PHP_FUNCTION(php_sapi_name)
1322 {
1323 	if (zend_parse_parameters_none() == FAILURE) {
1324 		return;
1325 	}
1326 
1327 	if (sapi_module.name) {
1328 		RETURN_STRING(sapi_module.name);
1329 	} else {
1330 		RETURN_FALSE;
1331 	}
1332 }
1333 
1334 /* }}} */
1335 
1336 /* {{{ proto string php_uname(void)
1337    Return information about the system PHP was built on */
PHP_FUNCTION(php_uname)1338 PHP_FUNCTION(php_uname)
1339 {
1340 	char *mode = "a";
1341 	size_t modelen = sizeof("a")-1;
1342 
1343 	ZEND_PARSE_PARAMETERS_START(0, 1)
1344 		Z_PARAM_OPTIONAL
1345 		Z_PARAM_STRING(mode, modelen)
1346 	ZEND_PARSE_PARAMETERS_END();
1347 
1348 	RETURN_STR(php_get_uname(*mode));
1349 }
1350 
1351 /* }}} */
1352 
1353 /* {{{ proto string php_ini_scanned_files(void)
1354    Return comma-separated string of .ini files parsed from the additional ini dir */
PHP_FUNCTION(php_ini_scanned_files)1355 PHP_FUNCTION(php_ini_scanned_files)
1356 {
1357 	if (zend_parse_parameters_none() == FAILURE) {
1358 		return;
1359 	}
1360 
1361 	if (php_ini_scanned_files) {
1362 		RETURN_STRING(php_ini_scanned_files);
1363 	} else {
1364 		RETURN_FALSE;
1365 	}
1366 }
1367 /* }}} */
1368 
1369 /* {{{ proto string php_ini_loaded_file(void)
1370    Return the actual loaded ini filename */
PHP_FUNCTION(php_ini_loaded_file)1371 PHP_FUNCTION(php_ini_loaded_file)
1372 {
1373 	if (zend_parse_parameters_none() == FAILURE) {
1374 		return;
1375 	}
1376 
1377 	if (php_ini_opened_path) {
1378 		RETURN_STRING(php_ini_opened_path);
1379 	} else {
1380 		RETURN_FALSE;
1381 	}
1382 }
1383 /* }}} */
1384 
1385 /*
1386  * Local variables:
1387  * tab-width: 4
1388  * c-basic-offset: 4
1389  * End:
1390  * vim600: sw=4 ts=4 fdm=marker
1391  * vim<600: sw=4 ts=4
1392  */
1393