root/main/php_ini.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_ini_displayer_cb
  2. php_ini_displayer
  3. php_ini_available
  4. display_ini_entries
  5. config_zval_dtor
  6. php_ini_parser_cb
  7. php_load_php_extension_cb
  8. php_load_zend_extension_cb
  9. php_init_config
  10. php_shutdown_config
  11. php_ini_register_extensions
  12. php_parse_user_ini_file
  13. php_ini_activate_config
  14. php_ini_has_per_dir_config
  15. php_ini_activate_per_dir_config
  16. php_ini_has_per_host_config
  17. php_ini_activate_per_host_config
  18. cfg_get_entry_ex
  19. cfg_get_entry
  20. cfg_get_long
  21. cfg_get_double
  22. cfg_get_string
  23. php_ini_get_configuration_hash

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

/* [<][>][^][v][top][bottom][index][help] */