Coverage Report

Created: 2025-06-13 06:43

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