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
  19. cfg_get_long
  20. cfg_get_double
  21. cfg_get_string
  22. php_ini_get_configuration_hash

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

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