Annotation of embedaddon/php/main/php_ini.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 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: php_ini.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            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 insensitivty. Does nothign 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:        zend_load_extension(*((char **) arg));
        !           361: }
        !           362: /* }}} */
        !           363: 
        !           364: /* {{{ php_init_config
        !           365:  */
        !           366: int php_init_config(TSRMLS_D)
        !           367: {
        !           368:        char *php_ini_file_name = NULL;
        !           369:        char *php_ini_search_path = NULL;
        !           370:        int php_ini_scanned_path_len;
        !           371:        int safe_mode_state;
        !           372:        char *open_basedir;
        !           373:        int free_ini_search_path = 0;
        !           374:        zend_file_handle fh;
        !           375: 
        !           376:        if (zend_hash_init(&configuration_hash, 0, NULL, (dtor_func_t) config_zval_dtor, 1) == FAILURE) {
        !           377:                return FAILURE;
        !           378:        }
        !           379: 
        !           380:        if (sapi_module.ini_defaults) {
        !           381:                sapi_module.ini_defaults(&configuration_hash);
        !           382:        }
        !           383: 
        !           384:        zend_llist_init(&extension_lists.engine, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
        !           385:        zend_llist_init(&extension_lists.functions, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
        !           386: 
        !           387:        safe_mode_state = PG(safe_mode);
        !           388:        open_basedir = PG(open_basedir);
        !           389: 
        !           390:        if (sapi_module.php_ini_path_override) {
        !           391:                php_ini_file_name = sapi_module.php_ini_path_override;
        !           392:                php_ini_search_path = sapi_module.php_ini_path_override;
        !           393:                free_ini_search_path = 0;
        !           394:        } else if (!sapi_module.php_ini_ignore) {
        !           395:                int search_path_size;
        !           396:                char *default_location;
        !           397:                char *env_location;
        !           398:                char *binary_location;
        !           399:                static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 };
        !           400: #ifdef PHP_WIN32
        !           401:                char *reg_location;
        !           402:                char phprc_path[MAXPATHLEN];
        !           403: #endif
        !           404: 
        !           405:                env_location = getenv("PHPRC");
        !           406: 
        !           407: #ifdef PHP_WIN32
        !           408:                if (!env_location) {
        !           409:                        char dummybuf;
        !           410:                        int size;
        !           411: 
        !           412:                        SetLastError(0);
        !           413: 
        !           414:                        /*If the given bugger is not large enough to hold the data, the return value is 
        !           415:                        the buffer size,  in characters, required to hold the string and its terminating 
        !           416:                        null character. We use this return value to alloc the final buffer. */
        !           417:                        size = GetEnvironmentVariableA("PHPRC", &dummybuf, 0);
        !           418:                        if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
        !           419:                                /* The environment variable doesn't exist. */
        !           420:                                env_location = "";
        !           421:                        } else {
        !           422:                                if (size == 0) {
        !           423:                                        env_location = "";
        !           424:                                } else {
        !           425:                                        size = GetEnvironmentVariableA("PHPRC", phprc_path, size);
        !           426:                                        env_location = phprc_path;
        !           427:                                }
        !           428:                        }
        !           429:                }
        !           430: #else
        !           431:                if (!env_location) {
        !           432:                        env_location = "";
        !           433:                }
        !           434: #endif
        !           435:                /*
        !           436:                 * Prepare search path
        !           437:                 */
        !           438: 
        !           439:                search_path_size = MAXPATHLEN * 4 + strlen(env_location) + 3 + 1;
        !           440:                php_ini_search_path = (char *) emalloc(search_path_size);
        !           441:                free_ini_search_path = 1;
        !           442:                php_ini_search_path[0] = 0;
        !           443: 
        !           444:                /* Add environment location */
        !           445:                if (env_location[0]) {
        !           446:                        if (*php_ini_search_path) {
        !           447:                                strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           448:                        }
        !           449:                        strlcat(php_ini_search_path, env_location, search_path_size);
        !           450:                        php_ini_file_name = env_location;
        !           451:                }
        !           452: 
        !           453: #ifdef PHP_WIN32
        !           454:                /* Add registry location */
        !           455:                reg_location = GetIniPathFromRegistry();
        !           456:                if (reg_location != NULL) {
        !           457:                        if (*php_ini_search_path) {
        !           458:                                strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           459:                        }
        !           460:                        strlcat(php_ini_search_path, reg_location, search_path_size);
        !           461:                        efree(reg_location);
        !           462:                }
        !           463: #endif
        !           464: 
        !           465:                /* Add cwd (not with CLI) */
        !           466:                if (strcmp(sapi_module.name, "cli") != 0) {
        !           467:                        if (*php_ini_search_path) {
        !           468:                                strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           469:                        }
        !           470:                        strlcat(php_ini_search_path, ".", search_path_size);
        !           471:                }
        !           472: 
        !           473:                /* Add binary directory */
        !           474: #ifdef PHP_WIN32
        !           475:                binary_location = (char *) emalloc(MAXPATHLEN);
        !           476:                if (GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) {
        !           477:                        efree(binary_location);
        !           478:                        binary_location = NULL;
        !           479:                }
        !           480: #else
        !           481:                if (sapi_module.executable_location) {
        !           482:                        binary_location = (char *)emalloc(MAXPATHLEN);
        !           483:                        if (!strchr(sapi_module.executable_location, '/')) {
        !           484:                                char *envpath, *path;
        !           485:                                int found = 0;
        !           486: 
        !           487:                                if ((envpath = getenv("PATH")) != NULL) {
        !           488:                                        char *search_dir, search_path[MAXPATHLEN];
        !           489:                                        char *last = NULL;
        !           490: 
        !           491:                                        path = estrdup(envpath);
        !           492:                                        search_dir = php_strtok_r(path, ":", &last);
        !           493: 
        !           494:                                        while (search_dir) {
        !           495:                                                snprintf(search_path, MAXPATHLEN, "%s/%s", search_dir, sapi_module.executable_location);
        !           496:                                                if (VCWD_REALPATH(search_path, binary_location) && !VCWD_ACCESS(binary_location, X_OK)) {
        !           497:                                                        found = 1;
        !           498:                                                        break;
        !           499:                                                }
        !           500:                                                search_dir = php_strtok_r(NULL, ":", &last);
        !           501:                                        }
        !           502:                                        efree(path);
        !           503:                                }
        !           504:                                if (!found) {
        !           505:                                        efree(binary_location);
        !           506:                                        binary_location = NULL;
        !           507:                                }
        !           508:                        } else if (!VCWD_REALPATH(sapi_module.executable_location, binary_location) || VCWD_ACCESS(binary_location, X_OK)) {
        !           509:                                efree(binary_location);
        !           510:                                binary_location = NULL;
        !           511:                        }
        !           512:                } else {
        !           513:                        binary_location = NULL;
        !           514:                }
        !           515: #endif
        !           516:                if (binary_location) {
        !           517:                        char *separator_location = strrchr(binary_location, DEFAULT_SLASH);
        !           518: 
        !           519:                        if (separator_location && separator_location != binary_location) {
        !           520:                                *(separator_location) = 0;
        !           521:                        }
        !           522:                        if (*php_ini_search_path) {
        !           523:                                strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           524:                        }
        !           525:                        strlcat(php_ini_search_path, binary_location, search_path_size);
        !           526:                        efree(binary_location);
        !           527:                }
        !           528: 
        !           529:                /* Add default location */
        !           530: #ifdef PHP_WIN32
        !           531:                default_location = (char *) emalloc(MAXPATHLEN + 1);
        !           532: 
        !           533:                if (0 < GetWindowsDirectory(default_location, MAXPATHLEN)) {
        !           534:                        if (*php_ini_search_path) {
        !           535:                                strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           536:                        }
        !           537:                        strlcat(php_ini_search_path, default_location, search_path_size);
        !           538:                }
        !           539: 
        !           540:                /* For people running under terminal services, GetWindowsDirectory will
        !           541:                 * return their personal Windows directory, so lets add the system
        !           542:                 * windows directory too */
        !           543:                if (0 < GetSystemWindowsDirectory(default_location, MAXPATHLEN)) {
        !           544:                        if (*php_ini_search_path) {
        !           545:                                strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           546:                        }
        !           547:                        strlcat(php_ini_search_path, default_location, search_path_size);
        !           548:                }
        !           549:                efree(default_location);
        !           550: 
        !           551: #else
        !           552:                default_location = PHP_CONFIG_FILE_PATH;
        !           553:                if (*php_ini_search_path) {
        !           554:                        strlcat(php_ini_search_path, paths_separator, search_path_size);
        !           555:                }
        !           556:                strlcat(php_ini_search_path, default_location, search_path_size);
        !           557: #endif
        !           558:        }
        !           559: 
        !           560:        PG(safe_mode) = 0;
        !           561:        PG(open_basedir) = NULL;
        !           562: 
        !           563:        /*
        !           564:         * Find and open actual ini file
        !           565:         */
        !           566: 
        !           567:        memset(&fh, 0, sizeof(fh));
        !           568: 
        !           569:        /* If SAPI does not want to ignore all ini files OR an overriding file/path is given.
        !           570:         * This allows disabling scanning for ini files in the PHP_CONFIG_FILE_SCAN_DIR but still
        !           571:         * load an optional ini file. */
        !           572:        if (!sapi_module.php_ini_ignore || sapi_module.php_ini_path_override) {
        !           573: 
        !           574:                /* Check if php_ini_file_name is a file and can be opened */
        !           575:                if (php_ini_file_name && php_ini_file_name[0]) {
        !           576:                        struct stat statbuf;
        !           577: 
        !           578:                        if (!VCWD_STAT(php_ini_file_name, &statbuf)) {
        !           579:                                if (!((statbuf.st_mode & S_IFMT) == S_IFDIR)) {
        !           580:                                        fh.handle.fp = VCWD_FOPEN(php_ini_file_name, "r");
        !           581:                                        if (fh.handle.fp) {
        !           582:                                                fh.filename = php_ini_opened_path = expand_filepath(php_ini_file_name, NULL TSRMLS_CC);
        !           583:                                        }
        !           584:                                }
        !           585:                        }
        !           586:                }
        !           587: 
        !           588:                /* Otherwise search for php-%sapi-module-name%.ini file in search path */
        !           589:                if (!fh.handle.fp) {
        !           590:                        const char *fmt = "php-%s.ini";
        !           591:                        char *ini_fname;
        !           592:                        spprintf(&ini_fname, 0, fmt, sapi_module.name);
        !           593:                        fh.handle.fp = php_fopen_with_path(ini_fname, "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC);
        !           594:                        efree(ini_fname);
        !           595:                        if (fh.handle.fp) {
        !           596:                                fh.filename = php_ini_opened_path;
        !           597:                        }
        !           598:                }
        !           599: 
        !           600:                /* If still no ini file found, search for php.ini file in search path */
        !           601:                if (!fh.handle.fp) {
        !           602:                        fh.handle.fp = php_fopen_with_path("php.ini", "r", php_ini_search_path, &php_ini_opened_path TSRMLS_CC);
        !           603:                        if (fh.handle.fp) {
        !           604:                                fh.filename = php_ini_opened_path;
        !           605:                        }
        !           606:                }
        !           607:        }
        !           608: 
        !           609:        if (free_ini_search_path) {
        !           610:                efree(php_ini_search_path);
        !           611:        }
        !           612: 
        !           613:        PG(safe_mode) = safe_mode_state;
        !           614:        PG(open_basedir) = open_basedir;
        !           615: 
        !           616:        if (fh.handle.fp) {
        !           617:                fh.type = ZEND_HANDLE_FP;
        !           618:                RESET_ACTIVE_INI_HASH();
        !           619: 
        !           620:                zend_parse_ini_file(&fh, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash TSRMLS_CC);
        !           621: 
        !           622:                {
        !           623:                        zval tmp;
        !           624: 
        !           625:                        Z_STRLEN(tmp) = strlen(fh.filename);
        !           626:                        Z_STRVAL(tmp) = zend_strndup(fh.filename, Z_STRLEN(tmp));
        !           627:                        Z_TYPE(tmp) = IS_STRING;
        !           628:                        Z_SET_REFCOUNT(tmp, 0);
        !           629: 
        !           630:                        zend_hash_update(&configuration_hash, "cfg_file_path", sizeof("cfg_file_path"), (void *) &tmp, sizeof(zval), NULL);
        !           631:                        if (php_ini_opened_path) {
        !           632:                                efree(php_ini_opened_path);
        !           633:                        }
        !           634:                        php_ini_opened_path = zend_strndup(Z_STRVAL(tmp), Z_STRLEN(tmp));
        !           635:                }
        !           636:        }
        !           637: 
        !           638:        /* Check for PHP_INI_SCAN_DIR environment variable to override/set config file scan directory */
        !           639:        php_ini_scanned_path = getenv("PHP_INI_SCAN_DIR");
        !           640:        if (!php_ini_scanned_path) {
        !           641:                /* Or fall back using possible --with-config-file-scan-dir setting (defaults to empty string!) */
        !           642:                php_ini_scanned_path = PHP_CONFIG_FILE_SCAN_DIR;
        !           643:        }
        !           644:        php_ini_scanned_path_len = strlen(php_ini_scanned_path);
        !           645: 
        !           646:        /* Scan and parse any .ini files found in scan path if path not empty. */
        !           647:        if (!sapi_module.php_ini_ignore && php_ini_scanned_path_len) {
        !           648:                struct dirent **namelist;
        !           649:                int ndir, i;
        !           650:                struct stat sb;
        !           651:                char ini_file[MAXPATHLEN];
        !           652:                char *p;
        !           653:                zend_file_handle fh2;
        !           654:                zend_llist scanned_ini_list;
        !           655:                zend_llist_element *element;
        !           656:                int l, total_l = 0;
        !           657: 
        !           658:                if ((ndir = php_scandir(php_ini_scanned_path, &namelist, 0, php_alphasort)) > 0) {
        !           659:                        zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1);
        !           660:                        memset(&fh2, 0, sizeof(fh2));
        !           661: 
        !           662:                        for (i = 0; i < ndir; i++) {
        !           663: 
        !           664:                                /* check for any file with .ini extension */
        !           665:                                if (!(p = strrchr(namelist[i]->d_name, '.')) || (p && strcmp(p, ".ini"))) {
        !           666:                                        free(namelist[i]);
        !           667:                                        continue;
        !           668:                                }
        !           669:                                /* Reset active ini section */
        !           670:                                RESET_ACTIVE_INI_HASH();
        !           671: 
        !           672:                                if (IS_SLASH(php_ini_scanned_path[php_ini_scanned_path_len - 1])) {
        !           673:                                        snprintf(ini_file, MAXPATHLEN, "%s%s", php_ini_scanned_path, namelist[i]->d_name);
        !           674:                                } else {
        !           675:                                        snprintf(ini_file, MAXPATHLEN, "%s%c%s", php_ini_scanned_path, DEFAULT_SLASH, namelist[i]->d_name);
        !           676:                                }
        !           677:                                if (VCWD_STAT(ini_file, &sb) == 0) {
        !           678:                                        if (S_ISREG(sb.st_mode)) {
        !           679:                                                if ((fh2.handle.fp = VCWD_FOPEN(ini_file, "r"))) {
        !           680:                                                        fh2.filename = ini_file;
        !           681:                                                        fh2.type = ZEND_HANDLE_FP;
        !           682: 
        !           683:                                                        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) {
        !           684:                                                                /* Here, add it to the list of ini files read */
        !           685:                                                                l = strlen(ini_file);
        !           686:                                                                total_l += l + 2;
        !           687:                                                                p = estrndup(ini_file, l);
        !           688:                                                                zend_llist_add_element(&scanned_ini_list, &p);
        !           689:                                                        }
        !           690:                                                }
        !           691:                                        }
        !           692:                                }
        !           693:                                free(namelist[i]);
        !           694:                        }
        !           695:                        free(namelist);
        !           696: 
        !           697:                        if (total_l) {
        !           698:                                int php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0;
        !           699:                                php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1);
        !           700:                                if (!php_ini_scanned_files_len) {
        !           701:                                        *php_ini_scanned_files = '\0';
        !           702:                                }
        !           703:                                total_l += php_ini_scanned_files_len;
        !           704:                                for (element = scanned_ini_list.head; element; element = element->next) {
        !           705:                                        if (php_ini_scanned_files_len) {
        !           706:                                                strlcat(php_ini_scanned_files, ",\n", total_l);
        !           707:                                        }
        !           708:                                        strlcat(php_ini_scanned_files, *(char **)element->data, total_l);
        !           709:                                        strlcat(php_ini_scanned_files, element->next ? ",\n" : "\n", total_l);
        !           710:                                }
        !           711:                        }
        !           712:                        zend_llist_destroy(&scanned_ini_list);
        !           713:                }
        !           714:        } else {
        !           715:                /* Make sure an empty php_ini_scanned_path ends up as NULL */
        !           716:                php_ini_scanned_path = NULL;
        !           717:        }
        !           718: 
        !           719:        if (sapi_module.ini_entries) {
        !           720:                /* Reset active ini section */
        !           721:                RESET_ACTIVE_INI_HASH();
        !           722:                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);
        !           723:        }
        !           724: 
        !           725:        return SUCCESS;
        !           726: }
        !           727: /* }}} */
        !           728: 
        !           729: /* {{{ php_shutdown_config
        !           730:  */
        !           731: int php_shutdown_config(void)
        !           732: {
        !           733:        zend_hash_destroy(&configuration_hash);
        !           734:        if (php_ini_opened_path) {
        !           735:                free(php_ini_opened_path);
        !           736:                php_ini_opened_path = NULL;
        !           737:        }
        !           738:        if (php_ini_scanned_files) {
        !           739:                free(php_ini_scanned_files);
        !           740:                php_ini_scanned_files = NULL;
        !           741:        }
        !           742:        return SUCCESS;
        !           743: }
        !           744: /* }}} */
        !           745: 
        !           746: /* {{{ php_ini_register_extensions
        !           747:  */
        !           748: void php_ini_register_extensions(TSRMLS_D)
        !           749: {
        !           750:        zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC);
        !           751:        zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb TSRMLS_CC);
        !           752: 
        !           753:        zend_llist_destroy(&extension_lists.engine);
        !           754:        zend_llist_destroy(&extension_lists.functions);
        !           755: }
        !           756: /* }}} */
        !           757: 
        !           758: /* {{{ php_parse_user_ini_file
        !           759:  */
        !           760: PHPAPI int php_parse_user_ini_file(const char *dirname, char *ini_filename, HashTable *target_hash TSRMLS_DC)
        !           761: {
        !           762:        struct stat sb;
        !           763:        char ini_file[MAXPATHLEN];
        !           764:        zend_file_handle fh;
        !           765: 
        !           766:        snprintf(ini_file, MAXPATHLEN, "%s%c%s", dirname, DEFAULT_SLASH, ini_filename);
        !           767: 
        !           768:        if (VCWD_STAT(ini_file, &sb) == 0) {
        !           769:                if (S_ISREG(sb.st_mode)) {
        !           770:                        memset(&fh, 0, sizeof(fh));
        !           771:                        if ((fh.handle.fp = VCWD_FOPEN(ini_file, "r"))) {
        !           772:                                fh.filename = ini_file;
        !           773:                                fh.type = ZEND_HANDLE_FP;
        !           774: 
        !           775:                                /* Reset active ini section */
        !           776:                                RESET_ACTIVE_INI_HASH();
        !           777: 
        !           778:                                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) {
        !           779:                                        /* FIXME: Add parsed file to the list of user files read? */
        !           780:                                        return SUCCESS;
        !           781:                                }
        !           782:                                return FAILURE;
        !           783:                        }
        !           784:                }
        !           785:        }
        !           786:        return FAILURE;
        !           787: }
        !           788: /* }}} */
        !           789: 
        !           790: /* {{{ php_ini_activate_config
        !           791:  */
        !           792: PHPAPI void php_ini_activate_config(HashTable *source_hash, int modify_type, int stage TSRMLS_DC)
        !           793: {
        !           794:        char *str;
        !           795:        zval *data;
        !           796:        uint str_len;
        !           797:        ulong num_index;
        !           798: 
        !           799:        /* Walk through config hash and alter matching ini entries using the values found in the hash */
        !           800:        for (zend_hash_internal_pointer_reset(source_hash);
        !           801:                zend_hash_get_current_key_ex(source_hash, &str, &str_len, &num_index, 0, NULL) == HASH_KEY_IS_STRING;
        !           802:                zend_hash_move_forward(source_hash)
        !           803:        ) {
        !           804:                zend_hash_get_current_data(source_hash, (void **) &data);
        !           805:                zend_alter_ini_entry_ex(str, str_len, Z_STRVAL_P(data), Z_STRLEN_P(data), modify_type, stage, 0 TSRMLS_CC);
        !           806:        }
        !           807: }
        !           808: /* }}} */
        !           809: 
        !           810: /* {{{ php_ini_has_per_dir_config
        !           811:  */
        !           812: PHPAPI int php_ini_has_per_dir_config(void)
        !           813: {
        !           814:        return has_per_dir_config;
        !           815: }
        !           816: /* }}} */
        !           817: 
        !           818: /* {{{ php_ini_activate_per_dir_config
        !           819:  */
        !           820: PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC)
        !           821: {
        !           822:        zval *tmp2;
        !           823:        char *ptr;
        !           824: 
        !           825: #if PHP_WIN32
        !           826:        char path_bak[MAXPATHLEN];
        !           827: #endif
        !           828: 
        !           829:        if (path_len > MAXPATHLEN) {
        !           830:                return;
        !           831:        }
        !           832: 
        !           833: #if PHP_WIN32
        !           834:        memcpy(path_bak, path, path_len);
        !           835:        path_bak[path_len] = 0;
        !           836:        TRANSLATE_SLASHES_LOWER(path_bak);
        !           837:        path = path_bak;
        !           838: #endif
        !           839: 
        !           840:        /* Walk through each directory in path and apply any found per-dir-system-configuration from configuration_hash */
        !           841:        if (has_per_dir_config && path && path_len) {
        !           842:                ptr = path + 1;
        !           843:                while ((ptr = strchr(ptr, '/')) != NULL) {
        !           844:                        *ptr = 0;
        !           845:                        /* Search for source array matching the path from configuration_hash */
        !           846:                        if (zend_hash_find(&configuration_hash, path, strlen(path) + 1, (void **) &tmp2) == SUCCESS) {
        !           847:                                php_ini_activate_config(Z_ARRVAL_P(tmp2), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE TSRMLS_CC);
        !           848:                        }
        !           849:                        *ptr = '/';
        !           850:                        ptr++;
        !           851:                }
        !           852:        }
        !           853: }
        !           854: /* }}} */
        !           855: 
        !           856: /* {{{ php_ini_has_per_host_config
        !           857:  */
        !           858: PHPAPI int php_ini_has_per_host_config(void)
        !           859: {
        !           860:        return has_per_host_config;
        !           861: }
        !           862: /* }}} */
        !           863: 
        !           864: /* {{{ php_ini_activate_per_host_config
        !           865:  */
        !           866: PHPAPI void php_ini_activate_per_host_config(const char *host, uint host_len TSRMLS_DC)
        !           867: {
        !           868:        zval *tmp;
        !           869: 
        !           870:        if (has_per_host_config && host && host_len) {
        !           871:                /* Search for source array matching the host from configuration_hash */
        !           872:                if (zend_hash_find(&configuration_hash, host, host_len, (void **) &tmp) == SUCCESS) {
        !           873:                        php_ini_activate_config(Z_ARRVAL_P(tmp), PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE TSRMLS_CC);
        !           874:                }
        !           875:        }
        !           876: }
        !           877: /* }}} */
        !           878: 
        !           879: /* {{{ cfg_get_entry
        !           880:  */
        !           881: PHPAPI zval *cfg_get_entry(const char *name, uint name_length)
        !           882: {
        !           883:        zval *tmp;
        !           884: 
        !           885:        if (zend_hash_find(&configuration_hash, name, name_length, (void **) &tmp) == SUCCESS) {
        !           886:                return tmp;
        !           887:        } else {
        !           888:                return NULL;
        !           889:        }
        !           890: }
        !           891: /* }}} */
        !           892: 
        !           893: /* {{{ cfg_get_long
        !           894:  */
        !           895: PHPAPI int cfg_get_long(const char *varname, long *result)
        !           896: {
        !           897:        zval *tmp, var;
        !           898: 
        !           899:        if (zend_hash_find(&configuration_hash, varname, strlen(varname) + 1, (void **) &tmp) == FAILURE) {
        !           900:                *result = 0;
        !           901:                return FAILURE;
        !           902:        }
        !           903:        var = *tmp;
        !           904:        zval_copy_ctor(&var);
        !           905:        convert_to_long(&var);
        !           906:        *result = Z_LVAL(var);
        !           907:        return SUCCESS;
        !           908: }
        !           909: /* }}} */
        !           910: 
        !           911: /* {{{ cfg_get_double
        !           912:  */
        !           913: PHPAPI int cfg_get_double(const char *varname, double *result)
        !           914: {
        !           915:        zval *tmp, var;
        !           916: 
        !           917:        if (zend_hash_find(&configuration_hash, varname, strlen(varname) + 1, (void **) &tmp) == FAILURE) {
        !           918:                *result = (double) 0;
        !           919:                return FAILURE;
        !           920:        }
        !           921:        var = *tmp;
        !           922:        zval_copy_ctor(&var);
        !           923:        convert_to_double(&var);
        !           924:        *result = Z_DVAL(var);
        !           925:        return SUCCESS;
        !           926: }
        !           927: /* }}} */
        !           928: 
        !           929: /* {{{ cfg_get_string
        !           930:  */
        !           931: PHPAPI int cfg_get_string(const char *varname, char **result)
        !           932: {
        !           933:        zval *tmp;
        !           934: 
        !           935:        if (zend_hash_find(&configuration_hash, varname, strlen(varname)+1, (void **) &tmp) == FAILURE) {
        !           936:                *result = NULL;
        !           937:                return FAILURE;
        !           938:        }
        !           939:        *result = Z_STRVAL_P(tmp);
        !           940:        return SUCCESS;
        !           941: }
        !           942: /* }}} */
        !           943: 
        !           944: PHPAPI HashTable* php_ini_get_configuration_hash(void) /* {{{ */
        !           945: {
        !           946:        return &configuration_hash;
        !           947: } /* }}} */
        !           948: 
        !           949: /*
        !           950:  * Local variables:
        !           951:  * tab-width: 4
        !           952:  * c-basic-offset: 4
        !           953:  * indent-tabs-mode: t
        !           954:  * End:
        !           955:  * vim600: sw=4 ts=4 fdm=marker
        !           956:  * vim<600: sw=4 ts=4
        !           957:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>