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