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