php-internal-docs 8.4.8
Unofficial docs for php/php-src
Loading...
Searching...
No Matches
php_ini.c
Go to the documentation of this file.
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 | Author: Zeev Suraski <zeev@php.net> |
14 +----------------------------------------------------------------------+
15 */
16
17#include "php.h"
18#include "ext/standard/info.h"
19#include "zend_ini.h"
20#include "zend_ini_scanner.h"
21#include "php_ini.h"
22#include "ext/standard/dl.h"
23#include "zend_extensions.h"
24#include "zend_highlight.h"
25#include "SAPI.h"
26#include "php_main.h"
27#include "php_scandir.h"
28#ifdef PHP_WIN32
29#include "win32/php_registry.h"
30#include "win32/winutil.h"
31#endif
32
33#if defined(HAVE_SCANDIR) && defined(HAVE_ALPHASORT) && defined(HAVE_DIRENT_H)
34#include <dirent.h>
35#endif
36
37#ifdef PHP_WIN32
38#define TRANSLATE_SLASHES_LOWER(path) \
39 { \
40 char *tmp = path; \
41 while (*tmp) { \
42 if (*tmp == '\\') *tmp = '/'; \
43 else *tmp = tolower(*tmp); \
44 tmp++; \
45 } \
46 }
47#else
48#define TRANSLATE_SLASHES_LOWER(path)
49#endif
50
51
56
57/* True globals */
58static int is_special_section = 0;
59static HashTable *active_ini_hash;
60static HashTable configuration_hash;
61static int has_per_dir_config = 0;
62static int has_per_host_config = 0;
64static php_extension_lists extension_lists;
67
68/* {{{ php_ini_displayer_cb */
69static ZEND_COLD void php_ini_displayer_cb(zend_ini_entry *ini_entry, int type)
70{
71 if (ini_entry->displayer) {
72 ini_entry->displayer(ini_entry, type);
73 } else {
74 char *display_string;
75 size_t display_string_length;
76 int esc_html=0;
77
78 if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) {
79 if (ini_entry->orig_value && ZSTR_VAL(ini_entry->orig_value)[0]) {
80 display_string = ZSTR_VAL(ini_entry->orig_value);
81 display_string_length = ZSTR_LEN(ini_entry->orig_value);
82 esc_html = !sapi_module.phpinfo_as_text;
83 } else {
84 if (!sapi_module.phpinfo_as_text) {
85 display_string = "<i>no value</i>";
86 display_string_length = sizeof("<i>no value</i>") - 1;
87 } else {
88 display_string = "no value";
89 display_string_length = sizeof("no value") - 1;
90 }
91 }
92 } else if (ini_entry->value && ZSTR_VAL(ini_entry->value)[0]) {
93 display_string = ZSTR_VAL(ini_entry->value);
94 display_string_length = ZSTR_LEN(ini_entry->value);
95 esc_html = !sapi_module.phpinfo_as_text;
96 } else {
97 if (!sapi_module.phpinfo_as_text) {
98 display_string = "<i>no value</i>";
99 display_string_length = sizeof("<i>no value</i>") - 1;
100 } else {
101 display_string = "no value";
102 display_string_length = sizeof("no value") - 1;
103 }
104 }
105
106 if (esc_html) {
107 php_html_puts(display_string, display_string_length);
108 } else {
109 PHPWRITE(display_string, display_string_length);
110 }
111 }
112}
113/* }}} */
114
115/* {{{ display_ini_entries */
117{
118 int module_number;
119 zend_ini_entry *ini_entry;
120 bool first = 1;
121
122 if (module) {
123 module_number = module->module_number;
124 } else {
125 module_number = 0;
126 }
127
128 ZEND_HASH_MAP_FOREACH_PTR(EG(ini_directives), ini_entry) {
129 if (ini_entry->module_number != module_number) {
130 continue;
131 }
132 if (first) {
134 php_info_print_table_header(3, "Directive", "Local Value", "Master Value");
135 first = 0;
136 }
137 if (!sapi_module.phpinfo_as_text) {
138 PUTS("<tr>");
139 PUTS("<td class=\"e\">");
140 PHPWRITE(ZSTR_VAL(ini_entry->name), ZSTR_LEN(ini_entry->name));
141 PUTS("</td><td class=\"v\">");
142 php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE);
143 PUTS("</td><td class=\"v\">");
144 php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG);
145 PUTS("</td></tr>\n");
146 } else {
147 PHPWRITE(ZSTR_VAL(ini_entry->name), ZSTR_LEN(ini_entry->name));
148 PUTS(" => ");
149 php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ACTIVE);
150 PUTS(" => ");
151 php_ini_displayer_cb(ini_entry, ZEND_INI_DISPLAY_ORIG);
152 PUTS("\n");
153 }
155 if (!first) {
157 }
158}
159/* }}} */
160
161/* php.ini support */
162#define PHP_EXTENSION_TOKEN "extension"
163#define ZEND_EXTENSION_TOKEN "zend_extension"
164
165/* {{{ config_zval_dtor */
167{
168 if (Z_TYPE_P(zvalue) == IS_ARRAY) {
170 free(Z_ARR_P(zvalue));
171 } else if (Z_TYPE_P(zvalue) == IS_STRING) {
173 }
174}
175/* Reset / free active_ini_section global */
176#define RESET_ACTIVE_INI_HASH() do { \
177 active_ini_hash = NULL; \
178 is_special_section = 0; \
179} while (0)
180/* }}} */
181
182/* {{{ php_ini_parser_cb */
183static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_type, HashTable *target_hash)
184{
185 zval *entry;
186 HashTable *active_hash;
187 char *extension_name;
188
189 if (active_ini_hash) {
190 active_hash = active_ini_hash;
191 } else {
192 active_hash = target_hash;
193 }
194
195 switch (callback_type) {
197 if (!arg2) {
198 /* bare string - nothing to do */
199 break;
200 }
201
202 /* PHP and Zend extensions are not added into configuration hash! */
203 if (!is_special_section && zend_string_equals_literal_ci(Z_STR_P(arg1), PHP_EXTENSION_TOKEN)) { /* load PHP extension */
204 extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
205 zend_llist_add_element(&extension_lists.functions, &extension_name);
206 } else if (!is_special_section && zend_string_equals_literal_ci(Z_STR_P(arg1), ZEND_EXTENSION_TOKEN)) { /* load Zend extension */
207 extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2));
208 zend_llist_add_element(&extension_lists.engine, &extension_name);
209
210 /* All other entries are added into either configuration_hash or active ini section array */
211 } else {
212 /* Store in active hash */
213 entry = zend_hash_update(active_hash, Z_STR_P(arg1), arg2);
214 Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1);
215 }
216 }
217 break;
218
220 zval option_arr;
221 zval *find_arr;
222
223 if (!arg2) {
224 /* bare string - nothing to do */
225 break;
226 }
227
228/* fprintf(stdout, "ZEND_INI_PARSER_POP_ENTRY: %s[%s] = %s\n",Z_STRVAL_P(arg1), Z_STRVAL_P(arg3), Z_STRVAL_P(arg2)); */
229
230 /* If option not found in hash or is not an array -> create array, otherwise add to existing array */
231 if ((find_arr = zend_hash_find(active_hash, Z_STR_P(arg1))) == NULL || Z_TYPE_P(find_arr) != IS_ARRAY) {
232 ZVAL_NEW_PERSISTENT_ARR(&option_arr);
233 zend_hash_init(Z_ARRVAL(option_arr), 8, NULL, config_zval_dtor, 1);
234 find_arr = zend_hash_update(active_hash, Z_STR_P(arg1), &option_arr);
235 }
236
237 /* arg3 is possible option offset name */
238 if (arg3 && Z_STRLEN_P(arg3) > 0) {
239 entry = zend_symtable_update(Z_ARRVAL_P(find_arr), Z_STR_P(arg3), arg2);
240 } else {
241 entry = zend_hash_next_index_insert(Z_ARRVAL_P(find_arr), arg2);
242 }
243 Z_STR_P(entry) = zend_string_dup(Z_STR_P(entry), 1);
244 }
245 break;
246
247 case ZEND_INI_PARSER_SECTION: { /* Create an array of entries of each section */
248
249/* fprintf(stdout, "ZEND_INI_PARSER_SECTION: %s\n",Z_STRVAL_P(arg1)); */
250
251 char *key = NULL;
252 size_t key_len;
253
254 /* PATH sections */
255 if (!zend_binary_strncasecmp(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), "PATH", sizeof("PATH") - 1, sizeof("PATH") - 1)) {
257 key = key + sizeof("PATH") - 1;
258 key_len = Z_STRLEN_P(arg1) - sizeof("PATH") + 1;
259 is_special_section = 1;
260 has_per_dir_config = 1;
261
262 /* make the path lowercase on Windows, for case insensitivity. Does nothing for other platforms */
264
265 /* HOST sections */
266 } else if (!zend_binary_strncasecmp(Z_STRVAL_P(arg1), Z_STRLEN_P(arg1), "HOST", sizeof("HOST") - 1, sizeof("HOST") - 1)) {
268 key = key + sizeof("HOST") - 1;
269 key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1;
270 is_special_section = 1;
271 has_per_host_config = 1;
272 zend_str_tolower(key, key_len); /* host names are case-insensitive. */
273
274 } else {
275 is_special_section = 0;
276 }
277
278 if (key && key_len > 0) {
279 /* Strip any trailing slashes */
280 while (key_len > 0 && (key[key_len - 1] == '/' || key[key_len - 1] == '\\')) {
281 key_len--;
282 key[key_len] = 0;
283 }
284
285 /* Strip any leading whitespace and '=' */
286 while (*key && (
287 *key == '=' ||
288 *key == ' ' ||
289 *key == '\t'
290 )) {
291 key++;
292 key_len--;
293 }
294
295 /* Search for existing entry and if it does not exist create one */
296 if ((entry = zend_hash_str_find(target_hash, key, key_len)) == NULL) {
297 zval section_arr;
298
299 ZVAL_NEW_PERSISTENT_ARR(&section_arr);
301 entry = zend_hash_str_update(target_hash, key, key_len, &section_arr);
302 }
303 if (Z_TYPE_P(entry) == IS_ARRAY) {
304 active_ini_hash = Z_ARRVAL_P(entry);
305 }
306 }
307 }
308 break;
309 }
310}
311/* }}} */
312
313/* {{{ php_load_php_extension_cb */
314static void php_load_php_extension_cb(void *arg)
315{
316#ifdef HAVE_LIBDL
317 php_load_extension(*((char **) arg), MODULE_PERSISTENT, 0);
318#endif
319}
320/* }}} */
321
322/* {{{ php_load_zend_extension_cb */
323#ifdef HAVE_LIBDL
324static void php_load_zend_extension_cb(void *arg)
325{
326 char *filename = *((char **) arg);
327 const size_t length = strlen(filename);
328
329#ifndef PHP_WIN32
330 (void) length;
331#endif
332
333 if (IS_ABSOLUTE_PATH(filename, length)) {
334 zend_load_extension(filename);
335 } else {
337 char *libpath;
338 char *extension_dir = INI_STR("extension_dir");
339 int slash_suffix = 0;
340 char *err1, *err2;
341
342 if (extension_dir && extension_dir[0]) {
343 slash_suffix = IS_SLASH(extension_dir[strlen(extension_dir)-1]);
344 }
345
346 /* Try as filename first */
347 if (slash_suffix) {
348 spprintf(&libpath, 0, "%s%s", extension_dir, filename); /* SAFE */
349 } else {
350 spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename); /* SAFE */
351 }
352
353 handle = (DL_HANDLE)php_load_shlib(libpath, &err1);
354 if (!handle) {
355 /* If file does not exist, consider as extension name and build file name */
356 char *orig_libpath = libpath;
357
358 if (slash_suffix) {
359 spprintf(&libpath, 0, "%s" PHP_SHLIB_EXT_PREFIX "%s." PHP_SHLIB_SUFFIX, extension_dir, filename); /* SAFE */
360 } else {
361 spprintf(&libpath, 0, "%s%c" PHP_SHLIB_EXT_PREFIX "%s." PHP_SHLIB_SUFFIX, extension_dir, DEFAULT_SLASH, filename); /* SAFE */
362 }
363
364 handle = (DL_HANDLE)php_load_shlib(libpath, &err2);
365 if (!handle) {
366 php_error(E_CORE_WARNING, "Failed loading Zend extension '%s' (tried: %s (%s), %s (%s))",
367 filename, orig_libpath, err1, libpath, err2);
368 efree(orig_libpath);
369 efree(err1);
370 efree(libpath);
371 efree(err2);
372 return;
373 }
374
375 efree(orig_libpath);
376 efree(err1);
377 }
378
379#ifdef PHP_WIN32
380 if (!php_win32_image_compatible(handle, &err1)) {
382 efree(err1);
383 efree(libpath);
384 DL_UNLOAD(handle);
385 return;
386 }
387#endif
388
390 efree(libpath);
391 }
392}
393#else
394static void php_load_zend_extension_cb(void *arg) { }
395#endif
396/* }}} */
397
398static void append_ini_path(char *php_ini_search_path, size_t search_path_size, const char *path)
399{
400 static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 };
401
402 if (*php_ini_search_path) {
403 strlcat(php_ini_search_path, paths_separator, search_path_size);
404 }
405
406 strlcat(php_ini_search_path, path, search_path_size);
407}
408
409/* {{{ php_init_config */
411{
412 char *php_ini_file_name = NULL;
413 char *php_ini_search_path = NULL;
414 int php_ini_scanned_path_len;
415 char *open_basedir;
416 int free_ini_search_path = 0;
417 zend_string *opened_path = NULL;
418
419 zend_hash_init(&configuration_hash, 8, NULL, config_zval_dtor, 1);
420
421 if (sapi_module.ini_defaults) {
422 sapi_module.ini_defaults(&configuration_hash);
423 }
424
425 zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
426 zend_llist_init(&extension_lists.functions, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
427
428 open_basedir = PG(open_basedir);
429
430 if (sapi_module.php_ini_path_override) {
431 php_ini_file_name = sapi_module.php_ini_path_override;
432 php_ini_search_path = sapi_module.php_ini_path_override;
433 free_ini_search_path = 0;
434 } else if (!sapi_module.php_ini_ignore) {
435 size_t search_path_size;
436 char *default_location;
437 char *env_location;
438#ifdef PHP_WIN32
439 char *reg_location;
440 char phprc_path[MAXPATHLEN];
441#endif
442
443 env_location = getenv("PHPRC");
444
445#ifdef PHP_WIN32
446 if (!env_location) {
447 char dummybuf;
448 int size;
449
450 SetLastError(0);
451
452 /*If the given buffer is not large enough to hold the data, the return value is
453 the buffer size, in characters, required to hold the string and its terminating
454 null character. We use this return value to alloc the final buffer. */
455 size = GetEnvironmentVariableA("PHPRC", &dummybuf, 0);
456 if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
457 /* The environment variable doesn't exist. */
458 env_location = "";
459 } else {
460 if (size == 0) {
461 env_location = "";
462 } else {
463 size = GetEnvironmentVariableA("PHPRC", phprc_path, size);
464 if (size == 0) {
465 env_location = "";
466 } else {
467 env_location = phprc_path;
468 }
469 }
470 }
471 }
472#else
473 if (!env_location) {
474 env_location = "";
475 }
476#endif
477 /*
478 * Prepare search path
479 */
480
481 search_path_size = MAXPATHLEN * 4 + strlen(env_location) + 3 + 1;
482 php_ini_search_path = (char *) emalloc(search_path_size);
483 free_ini_search_path = 1;
484 php_ini_search_path[0] = 0;
485
486 /* Add environment location */
487 if (env_location[0]) {
488 append_ini_path(php_ini_search_path, search_path_size, env_location);
489 php_ini_file_name = env_location;
490 }
491
492#ifdef PHP_WIN32
493 /* Add registry location */
494 reg_location = GetIniPathFromRegistry();
495 if (reg_location != NULL) {
496 append_ini_path(php_ini_search_path, search_path_size, reg_location);
497 efree(reg_location);
498 }
499#endif
500
501 /* Add cwd (not with CLI) */
502 if (!sapi_module.php_ini_ignore_cwd) {
503 append_ini_path(php_ini_search_path, search_path_size, ".");
504 }
505
506 if (PG(php_binary)) {
507 char *separator_location, *binary_location;
508
509 binary_location = estrdup(PG(php_binary));
510 separator_location = strrchr(binary_location, DEFAULT_SLASH);
511
512 if (separator_location && separator_location != binary_location) {
513 *(separator_location) = 0;
514 }
515 append_ini_path(php_ini_search_path, search_path_size, binary_location);
516
517 efree(binary_location);
518 }
519
520 /* Add default location */
521#ifdef PHP_WIN32
522 default_location = (char *) emalloc(MAXPATHLEN + 1);
523
524 if (0 < GetWindowsDirectory(default_location, MAXPATHLEN)) {
525 append_ini_path(php_ini_search_path, search_path_size, default_location);
526 }
527
528 /* For people running under terminal services, GetWindowsDirectory will
529 * return their personal Windows directory, so lets add the system
530 * windows directory too */
531 if (0 < GetSystemWindowsDirectory(default_location, MAXPATHLEN)) {
532 append_ini_path(php_ini_search_path, search_path_size, default_location);
533 }
534 efree(default_location);
535
536#else
537 default_location = PHP_CONFIG_FILE_PATH;
538 append_ini_path(php_ini_search_path, search_path_size, default_location);
539#endif
540 }
541
542 PG(open_basedir) = NULL;
543
544 /*
545 * Find and open actual ini file
546 */
547
548 FILE *fp = NULL;
549 char *filename = NULL;
550 bool free_filename = false;
551
552 /* If SAPI does not want to ignore all ini files OR an overriding file/path is given.
553 * This allows disabling scanning for ini files in the PHP_CONFIG_FILE_SCAN_DIR but still
554 * load an optional ini file. */
555 if (!sapi_module.php_ini_ignore || sapi_module.php_ini_path_override) {
556
557 /* Check if php_ini_file_name is a file and can be opened */
558 if (php_ini_file_name && php_ini_file_name[0]) {
559 zend_stat_t statbuf = {0};
560
561 if (!VCWD_STAT(php_ini_file_name, &statbuf)) {
562 if (!((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
563 fp = VCWD_FOPEN(php_ini_file_name, "r");
564 if (fp) {
565 filename = expand_filepath(php_ini_file_name, NULL);
566 free_filename = true;
567 }
568 }
569 }
570 }
571
572 /* Otherwise search for php-%sapi-module-name%.ini file in search path */
573 if (!fp) {
574 const char *fmt = "php-%s.ini";
575 char *ini_fname;
576 spprintf(&ini_fname, 0, fmt, sapi_module.name);
577 fp = php_fopen_with_path(ini_fname, "r", php_ini_search_path, &opened_path);
578 efree(ini_fname);
579 if (fp) {
580 filename = ZSTR_VAL(opened_path);
581 }
582 }
583
584 /* If still no ini file found, search for php.ini file in search path */
585 if (!fp) {
586 fp = php_fopen_with_path("php.ini", "r", php_ini_search_path, &opened_path);
587 if (fp) {
588 filename = ZSTR_VAL(opened_path);
589 }
590 }
591 }
592
593 if (free_ini_search_path) {
594 efree(php_ini_search_path);
595 }
596
597 PG(open_basedir) = open_basedir;
598
599 if (fp) {
601 zend_stream_init_fp(&fh, fp, filename);
603
604 zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash);
605
606 {
607 zval tmp;
608
609 ZVAL_NEW_STR(&tmp, zend_string_init(filename, strlen(filename), 1));
610 zend_hash_str_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path")-1, &tmp);
611 if (opened_path) {
612 zend_string_release_ex(opened_path, 0);
613 }
615 }
617
618 if (free_filename) {
619 efree(filename);
620 }
621 }
622
623 /* Check for PHP_INI_SCAN_DIR environment variable to override/set config file scan directory */
624 php_ini_scanned_path = getenv("PHP_INI_SCAN_DIR");
626 /* Or fall back using possible --with-config-file-scan-dir setting (defaults to empty string!) */
628 }
629 php_ini_scanned_path_len = (int)strlen(php_ini_scanned_path);
630
631 /* Scan and parse any .ini files found in scan path if path not empty. */
632 if (!sapi_module.php_ini_ignore && php_ini_scanned_path_len) {
633 struct dirent **namelist;
634 int ndir, i;
635 zend_stat_t sb = {0};
636 char ini_file[MAXPATHLEN];
637 char *p;
638 zend_llist scanned_ini_list;
639 zend_llist_element *element;
640 int l, total_l = 0;
641 char *bufpath, *debpath, *endpath;
642 int lenpath;
643
644 zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
645
646 bufpath = estrdup(php_ini_scanned_path);
647 for (debpath = bufpath ; debpath ; debpath=endpath) {
648 endpath = strchr(debpath, DEFAULT_DIR_SEPARATOR);
649 if (endpath) {
650 *(endpath++) = 0;
651 }
652 if (!debpath[0]) {
653 /* empty string means default builtin value
654 to allow "/foo/php.d:" or ":/foo/php.d" */
655 debpath = PHP_CONFIG_FILE_SCAN_DIR;
656 }
657 lenpath = (int)strlen(debpath);
658
659 if (lenpath > 0 && (ndir = php_scandir(debpath, &namelist, 0, php_alphasort)) > 0) {
660
661 for (i = 0; i < ndir; i++) {
662
663 /* check for any file with .ini extension */
664 if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) {
665 free(namelist[i]);
666 continue;
667 }
668 /* Reset active ini section */
670
671 if (IS_SLASH(debpath[lenpath - 1])) {
672 snprintf(ini_file, MAXPATHLEN, "%s%s", debpath, namelist[i]->d_name);
673 } else {
674 snprintf(ini_file, MAXPATHLEN, "%s%c%s", debpath, DEFAULT_SLASH, namelist[i]->d_name);
675 }
676 if (VCWD_STAT(ini_file, &sb) == 0) {
677 if (S_ISREG(sb.st_mode)) {
679 FILE *file = VCWD_FOPEN(ini_file, "r");
680 if (file) {
681 zend_stream_init_fp(&fh, file, ini_file);
682 if (zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash) == SUCCESS) {
683 /* Here, add it to the list of ini files read */
684 l = (int)strlen(ini_file);
685 total_l += l + 2;
686 p = estrndup(ini_file, l);
687 zend_llist_add_element(&scanned_ini_list, &p);
688 }
690 }
691 }
692 }
693 free(namelist[i]);
694 }
695 free(namelist);
696 }
697 }
698 efree(bufpath);
699
700 if (total_l) {
701 int php_ini_scanned_files_len = (php_ini_scanned_files) ? (int)strlen(php_ini_scanned_files) + 1 : 0;
702 php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1);
703 if (!php_ini_scanned_files_len) {
704 *php_ini_scanned_files = '\0';
705 }
706 total_l += php_ini_scanned_files_len;
707 for (element = scanned_ini_list.head; element; element = element->next) {
708 if (php_ini_scanned_files_len) {
709 strlcat(php_ini_scanned_files, ",\n", total_l);
710 }
711 strlcat(php_ini_scanned_files, *(char **)element->data, total_l);
712 strlcat(php_ini_scanned_files, element->next ? ",\n" : "\n", total_l);
713 }
714 }
715 zend_llist_destroy(&scanned_ini_list);
716 } else {
717 /* Make sure an empty php_ini_scanned_path ends up as NULL */
719 }
720
721 if (sapi_module.ini_entries) {
722 /* Reset active ini section */
724 zend_parse_ini_string(sapi_module.ini_entries, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash);
725 }
726
727 return SUCCESS;
728}
729/* }}} */
730
731/* {{{ php_shutdown_config */
733{
734 zend_hash_destroy(&configuration_hash);
738 }
742 }
743 return SUCCESS;
744}
745/* }}} */
746
747/* {{{ php_ini_register_extensions */
749{
750 zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb);
751 zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb);
752
753 zend_llist_destroy(&extension_lists.engine);
754 zend_llist_destroy(&extension_lists.functions);
755}
756/* }}} */
757
758/* {{{ php_parse_user_ini_file */
759PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename, HashTable *target_hash)
760{
761 zend_stat_t sb = {0};
762 char ini_file[MAXPATHLEN];
763
764 snprintf(ini_file, MAXPATHLEN, "%s%c%s", dirname, DEFAULT_SLASH, ini_filename);
765
766 if (VCWD_STAT(ini_file, &sb) == 0) {
767 if (S_ISREG(sb.st_mode)) {
769 int ret = FAILURE;
770
771 zend_stream_init_fp(&fh, VCWD_FOPEN(ini_file, "r"), ini_file);
772 if (fh.handle.fp) {
773 /* Reset active ini section */
775
776#if ZEND_RC_DEBUG
777 /* User inis are parsed during SAPI activate (part of the request),
778 * but persistently allocated to allow caching. This is fine as long as
779 * strings are duplicated in php_ini_activate_config(). */
780 bool orig_rc_debug = zend_rc_debug;
781 zend_rc_debug = false;
782#endif
783 ret = zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, target_hash);
784#if ZEND_RC_DEBUG
785 zend_rc_debug = orig_rc_debug;
786#endif
787 if (ret == SUCCESS) {
788 /* FIXME: Add parsed file to the list of user files read? */
789 }
790 }
792 return ret;
793 }
794 }
795 return FAILURE;
796}
797/* }}} */
798
799/* {{{ php_ini_activate_config */
800PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage)
801{
802 zend_string *str;
803 zval *data;
804
805 /* Walk through config hash and alter matching ini entries using the values found in the hash */
806 ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(source_hash, str, data) {
807 zend_string *data_str = zend_string_dup(Z_STR_P(data), 0);
808 zend_alter_ini_entry_ex(str, data_str, modify_type, stage, 0);
809 zend_string_release(data_str);
811}
812/* }}} */
813
814/* {{{ php_ini_has_per_dir_config */
816{
817 return has_per_dir_config;
818}
819/* }}} */
820
821/* {{{ php_ini_activate_per_dir_config */
822PHPAPI void php_ini_activate_per_dir_config(char *path, size_t path_len)
823{
824 zval *tmp2;
825 char *ptr;
826
827#ifdef PHP_WIN32
828 char path_bak[MAXPATHLEN];
829#endif
830
831#ifdef PHP_WIN32
832 /* MAX_PATH is \0-terminated, path_len == MAXPATHLEN would overrun path_bak */
833 if (path_len >= MAXPATHLEN) {
834#else
835 if (path_len > MAXPATHLEN) {
836#endif
837 return;
838 }
839
840#ifdef PHP_WIN32
841 memcpy(path_bak, path, path_len);
842 path_bak[path_len] = 0;
843 TRANSLATE_SLASHES_LOWER(path_bak);
844 path = path_bak;
845#endif
846
847 /* Walk through each directory in path and apply any found per-dir-system-configuration from configuration_hash */
848 if (has_per_dir_config && path && path_len) {
849 ptr = path + 1;
850 while ((ptr = strchr(ptr, '/')) != NULL) {
851 *ptr = 0;
852 /* Search for source array matching the path from configuration_hash */
853 if ((tmp2 = zend_hash_str_find(&configuration_hash, path, strlen(path))) != NULL) {
855 }
856 *ptr = '/';
857 ptr++;
858 }
859 }
860}
861/* }}} */
862
863/* {{{ php_ini_has_per_host_config */
865{
866 return has_per_host_config;
867}
868/* }}} */
869
870/* {{{ php_ini_activate_per_host_config */
871PHPAPI void php_ini_activate_per_host_config(const char *host, size_t host_len)
872{
873 zval *tmp;
874
875 if (has_per_host_config && host && host_len) {
876 /* Search for source array matching the host from configuration_hash */
877 if ((tmp = zend_hash_str_find(&configuration_hash, host, host_len)) != NULL) {
879 }
880 }
881}
882/* }}} */
883
884/* {{{ cfg_get_entry */
886{
887 return zend_hash_find(&configuration_hash, name);
888}
889/* }}} */
890
891/* {{{ cfg_get_entry */
892PHPAPI zval *cfg_get_entry(const char *name, size_t name_length)
893{
894 return zend_hash_str_find(&configuration_hash, name, name_length);
895}
896/* }}} */
897
898/* {{{ cfg_get_long */
899PHPAPI int cfg_get_long(const char *varname, zend_long *result)
900{
901 zval *tmp;
902
903 if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) {
904 *result = 0;
905 return FAILURE;
906 }
907 *result = zval_get_long(tmp);
908 return SUCCESS;
909}
910/* }}} */
911
912/* {{{ cfg_get_double */
913PHPAPI int cfg_get_double(const char *varname, double *result)
914{
915 zval *tmp;
916
917 if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) {
918 *result = (double) 0;
919 return FAILURE;
920 }
921 *result = zval_get_double(tmp);
922 return SUCCESS;
923}
924/* }}} */
925
926/* {{{ cfg_get_string */
927PHPAPI int cfg_get_string(const char *varname, char **result)
928{
929 zval *tmp;
930
931 if ((tmp = zend_hash_str_find(&configuration_hash, varname, strlen(varname))) == NULL) {
932 *result = NULL;
933 return FAILURE;
934 }
935 *result = Z_STRVAL_P(tmp);
936 return SUCCESS;
937}
938/* }}} */
939
941{
942 return &configuration_hash;
943} /* }}} */
SAPI_API sapi_module_struct sapi_module
Definition SAPI.c:65
getenv(?string $name=null, bool $local_only=false)
file(string $filename, int $flags=0, $context=null)
strrchr(string $haystack, string $needle, bool $before_needle=false)
dirname(string $path, int $levels=1)
strchr(string $haystack, string $needle, bool $before_needle=false)
PHPAPI int php_load_extension(const char *filename, int type, int start_now)
Definition dl.c:271
PHPAPI void * php_load_shlib(const char *path, char **errp)
Definition dl.c:264
zend_ffi_type * type
Definition ffi.c:3812
DL_HANDLE handle
Definition ffi.c:3028
new_type size
Definition ffi.c:4365
void * ptr
Definition ffi.c:3814
memcpy(ptr1, ptr2, size)
zval * arg
Definition ffi.c:3975
PHPAPI char * expand_filepath(const char *filepath, char *real_path)
PHPAPI FILE * php_fopen_with_path(const char *filename, const char *mode, const char *path, zend_string **opened_path)
#define NULL
Definition gdcache.h:45
#define SUCCESS
Definition hash_sha3.c:261
PHPAPI ZEND_COLD void php_info_print_table_header(int num_cols,...)
Definition info.c:1133
PHPAPI void php_html_puts(const char *str, size_t size)
Definition main.c:1235
const PHP_SHLIB_SUFFIX
const PHP_CONFIG_FILE_SCAN_DIR
const PHP_CONFIG_FILE_PATH
php_info_print_table_start()
Definition info.c:1064
php_info_print_table_end()
Definition info.c:1074
#define strlcat
Definition php.h:169
#define PHPAPI
Definition php.h:71
#define php_error
Definition php.h:310
#define PG(v)
Definition php_globals.h:31
PHPAPI int cfg_get_string(const char *varname, char **result)
Definition php_ini.c:927
int php_shutdown_config(void)
Definition php_ini.c:732
PHPAPI void config_zval_dtor(zval *zvalue)
Definition php_ini.c:166
PHPAPI int php_parse_user_ini_file(const char *dirname, const char *ini_filename, HashTable *target_hash)
Definition php_ini.c:759
PHPAPI HashTable * php_ini_get_configuration_hash(void)
Definition php_ini.c:940
PHPAPI zval * cfg_get_entry_ex(zend_string *name)
Definition php_ini.c:885
#define TRANSLATE_SLASHES_LOWER(path)
Definition php_ini.c:48
#define RESET_ACTIVE_INI_HASH()
Definition php_ini.c:176
PHPAPI int php_ini_has_per_host_config(void)
Definition php_ini.c:864
PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage)
Definition php_ini.c:800
int php_init_config(void)
Definition php_ini.c:410
PHPAPI int php_ini_has_per_dir_config(void)
Definition php_ini.c:815
PHPAPI void php_ini_activate_per_host_config(const char *host, size_t host_len)
Definition php_ini.c:871
PHPAPI char * php_ini_scanned_files
Definition php_ini.c:66
PHPAPI char * php_ini_scanned_path
Definition php_ini.c:65
PHPAPI int cfg_get_long(const char *varname, zend_long *result)
Definition php_ini.c:899
PHPAPI int cfg_get_double(const char *varname, double *result)
Definition php_ini.c:913
PHPAPI char * php_ini_opened_path
Definition php_ini.c:63
PHPAPI void php_ini_activate_per_dir_config(char *path, size_t path_len)
Definition php_ini.c:822
#define PHP_EXTENSION_TOKEN
Definition php_ini.c:162
PHPAPI ZEND_COLD void display_ini_entries(zend_module_entry *module)
Definition php_ini.c:116
PHPAPI zval * cfg_get_entry(const char *name, size_t name_length)
Definition php_ini.c:892
struct _php_extension_lists php_extension_lists
void php_ini_register_extensions(void)
Definition php_ini.c:748
#define ZEND_EXTENSION_TOKEN
Definition php_ini.c:163
#define PHP_INI_STAGE_ACTIVATE
Definition php_ini.h:73
#define PHP_INI_SYSTEM
Definition php_ini.h:43
#define PHPWRITE(str, str_len)
#define PUTS(str)
unsigned char key[REFLECTION_KEY_LEN]
char * GetIniPathFromRegistry()
Definition registry.c:282
PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int(*selector)(const struct dirent *entry), int(*compare)(const struct dirent **a, const struct dirent **b))
Definition php_scandir.c:52
PHPAPI int php_alphasort(const struct dirent **a, const struct dirent **b)
Definition php_scandir.c:45
char * extension_dir
Definition php_sqlite3.h:26
zend_constant * data
p
Definition session.c:1105
#define spprintf
Definition spprintf.h:29
zend_llist engine
Definition php_ini.c:53
zend_llist functions
Definition php_ini.c:54
union _zend_file_handle::@045057025306333206016200356074063117305134322373 handle
zend_string * value
Definition zend_ini.h:53
zend_string * orig_value
Definition zend_ini.h:54
void(* displayer)(zend_ini_entry *ini_entry, int type)
Definition zend_ini.h:55
int module_number
Definition zend_ini.h:57
zend_string * name
Definition zend_ini.h:48
uint8_t modified
Definition zend_ini.h:61
struct _zend_llist_element * next
Definition zend_llist.h:26
zend_llist_element * head
Definition zend_llist.h:38
char d_name[1]
Definition readdir.h:29
PHP_WINUTIL_API BOOL php_win32_image_compatible(HMODULE handle, char **err)
Definition winutil.c:479
void free_estring(char **str_p)
Definition zend.c:2002
ZEND_API char *ZEND_FASTCALL zend_strndup(const char *s, size_t length)
#define estrndup(s, length)
Definition zend_alloc.h:165
#define efree(ptr)
Definition zend_alloc.h:155
#define estrdup(s)
Definition zend_alloc.h:164
#define emalloc(size)
Definition zend_alloc.h:151
struct _zval_struct zval
strlen(string $string)
strcmp(string $string1, string $string2)
zend_string_release_ex(func->internal_function.function_name, 0)
ZEND_API void zend_destroy_file_handle(zend_file_handle *file_handle)
#define snprintf
#define E_CORE_WARNING
Definition zend_errors.h:28
ZEND_API void(ZEND_FASTCALL *zend_touch_vm_stack_data)(void *vm_stack_data)
zend_result zend_load_extension(const char *path)
zend_result zend_load_extension_handle(DL_HANDLE handle, const char *path)
struct _zend_ini_entry zend_ini_entry
#define EG(v)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
Definition zend_hash.c:1727
ZEND_API zval *ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *str, size_t len)
Definition zend_hash.c:2689
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert(HashTable *ht, zval *pData)
Definition zend_hash.c:1224
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
Definition zend_hash.c:1031
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
Definition zend_hash.c:997
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
Definition zend_hash.c:2668
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
Definition zend_hash.h:108
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
Definition zend_hash.h:1326
#define ZEND_HASH_FOREACH_END()
Definition zend_hash.h:1086
#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, _key, _val)
Definition zend_hash.h:1374
ZEND_API zend_result zend_alter_ini_entry_ex(zend_string *name, zend_string *new_value, int modify_type, int stage, bool force_change)
Definition zend_ini.c:356
ZEND_API zend_result zend_parse_ini_file(zend_file_handle *fh, bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg)
#define ZEND_INI_PARSER_ENTRY
Definition zend_ini.h:244
void(* zend_ini_parser_cb_t)(zval *arg1, zval *arg2, zval *arg3, int callback_type, void *arg)
Definition zend_ini.h:237
#define ZEND_INI_DISPLAY_ORIG
Definition zend_ini.h:224
#define ZEND_INI_PARSER_POP_ENTRY
Definition zend_ini.h:246
ZEND_API zend_result zend_parse_ini_string(const char *str, bool unbuffered_errors, int scanner_mode, zend_ini_parser_cb_t ini_parser_cb, void *arg)
#define ZEND_INI_PARSER_SECTION
Definition zend_ini.h:245
#define INI_STR(name)
Definition zend_ini.h:195
#define ZEND_INI_DISPLAY_ACTIVE
Definition zend_ini.h:225
struct _zend_file_handle zend_file_handle
#define ZEND_INI_SCANNER_NORMAL
ZEND_API void zend_llist_destroy(zend_llist *l)
Definition zend_llist.c:102
ZEND_API void zend_llist_add_element(zend_llist *l, const void *element)
Definition zend_llist.c:34
ZEND_API void zend_llist_init(zend_llist *l, size_t size, llist_dtor_func_t dtor, unsigned char persistent)
Definition zend_llist.c:24
ZEND_API void zend_llist_apply(zend_llist *l, llist_apply_func_t func)
Definition zend_llist.c:179
struct _zend_llist_element zend_llist_element
void(* llist_dtor_func_t)(void *)
Definition zend_llist.h:31
struct _zend_llist zend_llist
int32_t zend_long
Definition zend_long.h:42
struct _zend_string zend_string
struct _zend_module_entry zend_module_entry
#define MODULE_PERSISTENT
ZEND_API void ZEND_FASTCALL zend_str_tolower(char *str, size_t length)
ZEND_API int ZEND_FASTCALL zend_binary_strncasecmp(const char *s1, size_t len1, const char *s2, size_t len2, size_t length)
#define DL_HANDLE
#define ZEND_COLD
#define ZEND_PATHS_SEPARATOR
ZEND_API void zend_stream_init_fp(zend_file_handle *handle, FILE *fp, const char *filename)
Definition zend_stream.c:63
struct stat zend_stat_t
Definition zend_stream.h:94
#define ZSTR_VAL(zstr)
Definition zend_string.h:68
#define ZSTR_LEN(zstr)
Definition zend_string.h:69
#define zend_string_equals_literal_ci(str, c)
#define Z_TYPE_P(zval_p)
Definition zend_types.h:660
#define Z_STRVAL_P(zval_p)
Definition zend_types.h:975
#define Z_ARRVAL_P(zval_p)
Definition zend_types.h:987
#define IS_STRING
Definition zend_types.h:606
struct _zend_array HashTable
Definition zend_types.h:386
#define IS_ARRAY
Definition zend_types.h:607
#define Z_STR_P(zval_p)
Definition zend_types.h:972
void(* dtor_func_t)(zval *pDest)
Definition zend_types.h:107
#define Z_STRLEN_P(zval_p)
Definition zend_types.h:978
#define Z_STRVAL(zval)
Definition zend_types.h:974
@ FAILURE
Definition zend_types.h:61
#define Z_STRLEN(zval)
Definition zend_types.h:977
#define ZVAL_NEW_STR(z, s)
#define ZVAL_NEW_PERSISTENT_ARR(z)
#define Z_ARRVAL(zval)
Definition zend_types.h:986
#define Z_ARR_P(zval_p)
Definition zend_types.h:984
#define IS_SLASH(c)
#define DEFAULT_SLASH
#define VCWD_FOPEN(path, mode)
#define IS_ABSOLUTE_PATH(path, len)
#define S_ISREG(mode)
#define DEFAULT_DIR_SEPARATOR
#define MAXPATHLEN
#define VCWD_STAT(path, buff)
zval * arg1
zval * arg2
zend_string * name
zval * arg3
bool result
zval * ret