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