sorry, the attachment didn't make it. here's the patch inlined. ====== BEGIN PATCH ====== Index: configure.in =================================================================== RCS file: /repository/php4/configure.in,v retrieving revision 1.372 diff -u -b -B -r1.372 configure.in --- configure.in 6 Sep 2002 17:18:16 -0000 1.372 +++ configure.in 24 Sep 2002 17:12:42 -0000 @@ -1044,6 +1044,10 @@
PHP_ADD_SOURCES(TSRM, TSRM.c tsrm_strtok_r.c tsrm_virtual_cwd.c) +dnl need the ini scanner before the main for include capabilities. +PHP_ADD_SOURCES(/Zend, zend_language_parser.c zend_language_scanner.c \ + zend_ini_parser.c zend_ini_scanner.c) + PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c php_sprintf.c \ safe_mode.c fopen_wrappers.c alloca.c \ php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \ @@ -1052,9 +1056,6 @@ output.c memory_streams.c user_streams.c) PHP_ADD_SOURCES(/main, internal_functions.c,, sapi) PHP_ADD_SOURCES(/main, internal_functions_cli.c,, cli) - -PHP_ADD_SOURCES(/Zend, zend_language_parser.c zend_language_scanner.c \ - zend_ini_parser.c zend_ini_scanner.c) PHP_ADD_SOURCES(Zend, \ zend_alloc.c zend_compile.c zend_constants.c zend_dynamic_array.c \ Index: Zend/zend_ini_scanner.h =================================================================== RCS file: /repository/Zend/zend_ini_scanner.h,v retrieving revision 1.10 diff -u -b -B -r1.10 zend_ini_scanner.h --- Zend/zend_ini_scanner.h 9 Sep 2001 23:49:26 -0000 1.10 +++ Zend/zend_ini_scanner.h 24 Sep 2002 17:12:42 -0000 @@ -7,6 +7,10 @@ int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC); void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC); int ini_lex(zval *ini_lval TSRMLS_DC); + +int zend_ini_initialize_lexer_state(FILE *fp, char *filename TSRMLS_DC); +void zend_ini_save_lexer_state(TSRMLS_D); + END_EXTERN_C() #endif /* _ZEND_INI_SCANNER_H */ Index: Zend/zend_ini_scanner.l =================================================================== RCS file: /repository/Zend/zend_ini_scanner.l,v retrieving revision 1.25 diff -u -b -B -r1.25 zend_ini_scanner.l --- Zend/zend_ini_scanner.l 4 Jun 2002 22:03:25 -0000 1.25 +++ Zend/zend_ini_scanner.l 24 Sep 2002 17:12:42 -0000 @@ -27,6 +27,11 @@ #define yy_more_flag SCNG(_yy_more_flag) #define yy_more_len SCNG(_yy_more_len) +/* + * define DEBUG_CFG_LEXER to have the lexer print out information as it finds it + */ +#undef DEBUG_CFG_LEXER + #include <errno.h> #include "zend.h" #include "zend_globals.h" @@ -47,6 +52,27 @@ #endif +/* the include information */ +#define MAX_INCLUDE_DEPTH 10 + +/* how many levels into an include we are currently */ +int include_stack_ptr = 0; + +/* + * the file_stack array will keep info about where + * we are when we switch files being parsed + */ +struct { + YY_BUFFER_STATE buffer; + int lineno; + char *filename; +} include_stack[MAX_INCLUDE_DEPTH]; + + +/* forward declarations of useful functions */ +int zend_ini_handle_eof(TSRMLS_D); + + static char *ini_filename; void init_ini_scanner() @@ -66,46 +92,12 @@ return ini_filename; } - -int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC) -{ - FILE *fp; - - switch (fh->type) { - case ZEND_HANDLE_FP: - fp = fh->handle.fp; - break; - case ZEND_HANDLE_FILENAME: - fp = zend_fopen(fh->filename, NULL); - fh->type = ZEND_HANDLE_FP; - break; - default: - return FAILURE; - } - - init_ini_scanner(); - yyin = fp; - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC); - ini_filename = fh->filename; - return SUCCESS; -} - - -void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC) -{ - switch (fh->type) { - case ZEND_HANDLE_FP: - fclose(fh->handle.fp); - break; - } -} - %} NEWLINE ("\r"|"\n"|"\r\n") -%option noyywrap %option yylineno +%option noyywrap %% @@ -191,6 +182,9 @@ ini_lval->value.str.val = zend_strndup(yytext, yyleng); ini_lval->value.str.len = yyleng; ini_lval->type = IS_STRING; +#ifdef DEBUG_CFG_LEXER + fprintf(stderr,"Lexer found string %s\n",ini_lval->value.str.val); +#endif return TC_STRING; } else { /* whitespace */ @@ -223,6 +217,127 @@ } <<EOF>> { - yy_delete_buffer(YY_CURRENT_BUFFER TSRMLS_CC); + return zend_ini_handle_eof(TSRMLS_C); +} + +%% + + +/* this is the user defined section of the lexer */ + +/* + * zend_ini_save_current_state will just store the current + * lexer information into the include_stack structure + */ +void zend_ini_save_lexer_state(TSRMLS_D) +{ +#ifdef DEBUG_INI_INCLUDE + fprintf(stderr,"zend_ini_save_lexer_state: saving state from file %s lineno %i\n", + zend_ini_scanner_get_filename(TSRMLS_C),zend_ini_scanner_get_lineno(TSRMLS_C ) + ); +#endif + include_stack[include_stack_ptr].buffer = YY_CURRENT_BUFFER; + include_stack[include_stack_ptr].lineno = zend_ini_scanner_get_lineno(TSRMLS_C); + include_stack[include_stack_ptr].filename = zend_ini_scanner_get_filename(TSRMLS_C); + include_stack_ptr++; +} + + +/* + * zend_ini_initialize_lexer_state will set up the lexer to read from the given + * file handle and filename + */ +int zend_ini_initialize_lexer_state(FILE *fp, char *filename TSRMLS_DC) +{ + init_ini_scanner(); + ini_filename = filename; + /* yyin = fp; */ + yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE TSRMLS_CC) TSRMLS_CC); + BEGIN(INITIAL); + return SUCCESS; +} + +/* + * zend_ini_handle_eof is called when the lexer reaches the end of a file + * if zend_ini_handle_eof returns 0, then the lexer will assume that it needs to continue + * analyze. If it returns 1, then the lexer will assume that there is nothing + * left to analyze. + * + */ +int zend_ini_handle_eof(TSRMLS_D) +{ + + if ( --include_stack_ptr < 0) + { +#ifdef DEBUG_CFG_LEXER + fprintf(stderr,"Flex lexer is at the EOF for all include files\n"); +#endif yyterminate(); + return 1; + } + else + { + /* this means that we've reached the end of an include file... */ +#ifdef DEBUG_CFG_LEXER + fprintf(stderr,"Flex lexer is at the EOF, but more includes to +read\n"); +#endif + /* delete the current buffer */ + yy_delete_buffer(YY_CURRENT_BUFFER TSRMLS_CC); + + /* now switch to the previous buffer */ + yy_switch_to_buffer(include_stack[include_stack_ptr].buffer TSRMLS_CC); + +#ifdef DEBUG_INI_INCLUDE + fprintf(stderr,"zend_ini_handle_eof: Switching back to filename %s +lineno %i\n",include_stack[include_stack_ptr].filename,include_stack[include_stack_ ptr].lineno); +#endif + + /* now reset the current line number and filename */ + ini_lineno = include_stack[include_stack_ptr].lineno; + ini_filename = include_stack[include_stack_ptr].filename; + return 0; + } + +} + +int zend_ini_open_file_for_scanning(zend_file_handle *fh TSRMLS_DC) +{ + FILE *fp = NULL; + + switch (fh->type) + { + case ZEND_HANDLE_FP: + fp = fh->handle.fp; + break; + case ZEND_HANDLE_FILENAME: + fp = zend_fopen(fh->filename, NULL); + fh->type = ZEND_HANDLE_FP; + break; + default: + return FAILURE; + } + + /* initialize the lexer */ + return zend_ini_initialize_lexer_state(fp, fh->filename TSRMLS_CC); + +} + +/* + * zend_ini_close_file will take a zend file handle, and just close the open file pointer + */ +void zend_ini_close_file(zend_file_handle *fh TSRMLS_DC) +{ + switch (fh->type) { + case ZEND_HANDLE_FP: + if (fh->handle.fp != NULL) { +#ifdef DEBUG_CFG_LEXER + fprintf(stderr,"zend_ini_scanner: freeing filehandle to %s\n",fh->filename); +#endif + fclose(fh->handle.fp); +#ifdef DEBUG_CFG_LEXER + } else { + fprintf(stderr,"zend_ini_scanner: no filehandle to +free\n"); +#endif + } + break; + } } Index: main/php_ini.c =================================================================== RCS file: /repository/php4/main/php_ini.c,v retrieving revision 1.102 diff -u -b -B -r1.102 php_ini.c --- main/php_ini.c 23 Sep 2002 12:10:07 -0000 1.102 +++ main/php_ini.c 24 Sep 2002 17:12:45 -0000 @@ -27,6 +27,11 @@ #endif #include "ext/standard/info.h" #include "zend_ini.h" + +/* to parse includes */ +#include "zend_ini_scanner.h" +#include "zend_ini_parser.h" + #include "php_ini.h" #include "ext/standard/dl.h" #include "zend_extensions.h" @@ -34,12 +39,27 @@ #include "SAPI.h" #include "php_main.h" +/* + * DEBUG_INI_INCLUDE will print out all the actions that are taken as a result + * of discovering includes in the ini file + */ +/* #define DEBUG_INI_INCLUDE showme */ + + typedef struct _php_extension_lists { zend_llist engine; zend_llist functions; } php_extension_lists; +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif + +#ifndef S_ISREG +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#endif + /* True globals */ static HashTable configuration_hash; PHPAPI char *php_ini_opened_path=NULL; @@ -155,6 +175,9 @@ # endif #endif +/* forward declarations */ +static void php_handle_include_ini(zval *path); + /* {{{ pvalue_config_destructor */ static void pvalue_config_destructor(zval *pvalue) @@ -165,6 +188,108 @@ } /* }}} */ + +/* {{{ php_prepare_ini_search_path +*/ +int php_prepare_ini_search_path(char **php_ini_search_path) +{ + char *env_location; + int free_ini_search_path; + char *binary_location; + + /* + * this just prepares the search path for searching for php.ini or an + * include file. + */ + env_location = getenv("PHPRC"); + if (!env_location) { + env_location=""; + } + if (sapi_module.php_ini_path_override) { + (*php_ini_search_path) = sapi_module.php_ini_path_override; + free_ini_search_path = 0; + } else { + char *default_location; + static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 }; + + (*php_ini_search_path) = (char *) emalloc(MAXPATHLEN*3+strlen(env_location)+3+1); + free_ini_search_path = 1; + (*php_ini_search_path)[0] = 0; + + /* + * Prepare search path + */ + + /* Add cwd */ +#ifdef INI_CHECK_CWD + if (strcmp(sapi_module.name, "cli")!=0) { + if (**php_ini_search_path) { + strcat((*php_ini_search_path), paths_separator); + } + strcat((*php_ini_search_path), "."); + } +#endif + + /* Add binary directory */ +#ifdef PHP_WIN32 + binary_location = (char *) emalloc(MAXPATHLEN); + if (GetModuleFileName(0, binary_location, MAXPATHLEN)==0) { + efree(binary_location); + binary_location = NULL; + } +#else + if (sapi_module.executable_location) { + binary_location = estrdup(sapi_module.executable_location); + } else { + binary_location = NULL; + } +#endif + if (binary_location) { + char *separator_location = strrchr(binary_location, +DEFAULT_SLASH); + + if (separator_location) { + *(separator_location+1) = 0; + } + if (**php_ini_search_path) { + strcat((*php_ini_search_path), paths_separator); + } + strcat((*php_ini_search_path), binary_location); + efree(binary_location); + } + + /* Add environment location */ + if (env_location[0]) { + if (**php_ini_search_path) { + strcat((*php_ini_search_path), paths_separator); + } + strcat((*php_ini_search_path), env_location); + } + + /* Add default location */ +#ifdef PHP_WIN32 + default_location = (char *) emalloc(MAXPATHLEN+1); + + if (0 < GetWindowsDirectory(default_location, MAXPATHLEN)) { + if (**php_ini_search_path) { + strcat((*php_ini_search_path), paths_separator); + } + strcat((*php_ini_search_path), default_location); + } + efree(default_location); +#else + default_location = PHP_CONFIG_FILE_PATH; + if (**php_ini_search_path) { + strcat((*php_ini_search_path), paths_separator); + } + strcat((*php_ini_search_path), default_location); +#endif + } + + return free_ini_search_path; +} +/* }}} */ + + /* {{{ php_config_ini_parser_cb */ static void php_config_ini_parser_cb(zval *arg1, zval *arg2, int callback_type, void *arg) @@ -187,6 +312,11 @@ char *extension_name = estrndup(Z_STRVAL_P(arg2), Z_STRLEN_P(arg2)); zend_llist_add_element(&extension_lists.engine, &extension_name); + + } else if (!strcasecmp(Z_STRVAL_P(arg1), "include")) { +/* handle Include directive */ + + php_handle_include_ini(arg2); + } else { zend_hash_update(&configuration_hash, Z_STRVAL_P(arg1), Z_STRLEN_P(arg1)+1, arg2, sizeof(zval), (void **) &entry); Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)); @@ -199,6 +329,230 @@ } /* }}} */ + +/* {{{ php_handle_include_ini_dir +*/ +static void php_handle_include_ini_dir(char *dirpath) +{ + /* + * here, we know that dirpath contains the full path to a directory + * and each file in that directory needs to be read for inclusion into + * the configuration + */ + DIR *dirp = NULL; + struct dirent *dir_entry; + struct stat sb; + char trypath[MAXPATHLEN]; + TSRMLS_FETCH(); + + fprintf(stderr,"Processing PHP ini directory %s\n",dirpath); + + dirp = VCWD_OPENDIR(dirpath); + if(dirp) + { + while ( (dir_entry = readdir(dirp)) != NULL) + { + /* skip directory names */ + if ((strcmp(dir_entry->d_name,".") == 0) || (strcmp(dir_entry->d_name,"..") == 0)) + continue; + + /* look specifically for a file now */ + + snprintf(trypath, MAXPATHLEN, "%s%c%s", dirpath, DEFAULT_SLASH, dir_entry->d_name); + if (VCWD_STAT(trypath, &sb) == 0) + { + if (S_ISREG(sb.st_mode)) + { + zval tmp; + + Z_STRLEN(tmp) = strlen(trypath); + Z_STRVAL(tmp) = zend_strndup(trypath, +Z_STRLEN(tmp)); + Z_TYPE(tmp) = IS_STRING; + + php_handle_include_ini(&tmp); + } + } + + } + closedir(dirp); + } +#ifdef DEBUG_INI_INCLUDE + fprintf(stderr," done handling include directory %s\n",dirpath); +#endif +} +/* }}} */ + +/* {{{ php_open_include_ini +*/ +static void php_open_include_ini_file(char *path, zend_file_handle **include_fh TSRMLS_DC) +{ + (*include_fh)->handle.fp = VCWD_FOPEN(path, "r"); + (*include_fh)->filename = expand_filepath(path, NULL TSRMLS_CC); + fprintf(stderr,"Processing PHP ini file: %s\n",(*include_fh)->filename); +} +/* }}} */ + +/* {{{ php_discover_include_ini +*/ +static int php_discover_include_ini(zval *path, char *search_path, zend_file_handle **include_fh TSRMLS_DC) +{ + /* + * this function needs to find a file or directory from path. + * if path is absolute and a directory, then we're done + * otherwise, look thru the search path to find a directory + */ + + if (IS_ABSOLUTE_PATH(Z_STRVAL_P(path),Z_STRLEN_P(path))) + { + /* the path is absolute, so see if the directory exists */ + struct stat sb; + if (VCWD_STAT(Z_STRVAL_P(path), &sb) == 0) + { + if (S_ISREG(sb.st_mode)) + { + /* the path is just a file so open it and return*/ + php_open_include_ini_file(Z_STRVAL_P(path), include_fh +TSRMLS_CC); + return 1; + } + else + { + if (S_ISDIR(sb.st_mode)) + { + /* we have a directory! */ + php_handle_include_ini_dir(Z_STRVAL_P(path)); + return 1; + } +#ifdef DEBUG_INI_INCLUDE + else + fprintf(stderr," requested include ini '%s' +is not a directory or a file (absolute path)\n",Z_STRVAL_P(path)); +#endif + } + } +#ifdef DEBUG_INI_INCLUDE + else + fprintf(stderr," requested include ini '%s' doesn't exist\n",Z_STRVAL_P(path)); +#endif + } + else + { + /* the path is not absolute, so it must be a directory that + * we need to find the search path + * this code is the same from fopen_wrapper's php_fopen_with_path + */ + char *end; + char trypath[MAXPATHLEN]; + struct stat sb; + + while (search_path && *search_path) { + end = strchr(search_path, DEFAULT_DIR_SEPARATOR); + if (end != NULL) { + *end = '\0'; + end++; + } + snprintf(trypath, MAXPATHLEN, "%s%c%s", search_path, DEFAULT_SLASH,Z_STRVAL_P(path)); +#ifdef DEBUG_INI_INCLUDE + fprintf(stderr," searching for directory or file at path: %s\n",trypath); +#endif + if (VCWD_STAT(trypath, &sb) == 0) + { + if (S_ISDIR(sb.st_mode)) + { + /* found a directory to read */ + php_handle_include_ini_dir(trypath); + return 1; + } + else + { + if (S_ISREG(sb.st_mode)) + { + /* found a file to read */ + php_open_include_ini_file(trypath, +include_fh TSRMLS_CC); + return 1; + } +#ifdef DEBUG_INI_INCLUDE + else + fprintf(stderr," '%s' is not a +directory or a file (relative path)\n",trypath); +#endif + } + } + search_path = end; + } /* end provided path */ + } + return 0; +} +/* }}} */ + + +/* {{{ php_handle_include_ini +*/ +static void php_handle_include_ini(zval *path) +{ + int free_ini_search_path = 0; + char *php_ini_search_path = NULL; + char *php_included_ini_opened_path = (char *) emalloc(MAXPATHLEN*3); + zend_file_handle *include_fh = (zend_file_handle *)emalloc(sizeof(zend_file_handle)); + int retval = 0; + + TSRMLS_FETCH(); + + + /* path is what is given on the include line in the ini file. + * so first, just try to open the file itself. + */ + + include_fh->handle.fp = NULL; + + /* prepare the search path */ + free_ini_search_path = php_prepare_ini_search_path(&php_ini_search_path); + + /* now try to find the file or directory */ + retval = php_discover_include_ini(path, php_ini_search_path, &include_fh TSRMLS_CC); + + if (free_ini_search_path) { + efree(php_ini_search_path); + } + + + + if (include_fh->handle.fp) { +#ifdef DEBUG_INI_INCLUDE + fprintf(stderr," parsing include file %s\n",include_fh->filename); +#endif + + /* first, save the lexer state so that we can return after parsing */ + zend_ini_save_lexer_state(TSRMLS_C); + + /* now re-initialize the lexer state */ + zend_ini_initialize_lexer_state(include_fh->handle.fp, include_fh->filename TSRMLS_CC); + + /* now run the parser */ + retval = ini_parse(TSRMLS_C); + + /* now close the file we've opened */ + zend_ini_close_file(include_fh TSRMLS_CC); + +#ifdef DEBUG_INI_INCLUDE + if (retval == 0) { + fprintf(stderr," successfully parsed included ini file %s\n",include_fh->filename); + } else { + fprintf(stderr," failed parsing included ini file %s\n",include_fh->filename); + } +#endif + } + + + /* now free the resources we allocated to handle this include */ + if (php_included_ini_opened_path != NULL) { + efree(php_included_ini_opened_path); + } + + + if(include_fh != NULL) { + efree(include_fh); + } +} +/* }}} */ + /* {{{ php_load_function_extension_cb */ static void php_load_function_extension_cb(void *arg TSRMLS_DC) @@ -222,8 +576,7 @@ */ int php_init_config() { - char *env_location, *php_ini_search_path; - char *binary_location; + char *php_ini_search_path; int safe_mode_state; char *open_basedir; int free_ini_search_path=0; @@ -240,89 +593,8 @@ safe_mode_state = PG(safe_mode); open_basedir = PG(open_basedir); - env_location = getenv("PHPRC"); - if (!env_location) { - env_location=""; - } - if (sapi_module.php_ini_path_override) { - php_ini_search_path = sapi_module.php_ini_path_override; - free_ini_search_path = 0; - } else { - char *default_location; - static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 }; - - php_ini_search_path = (char *) emalloc(MAXPATHLEN*3+strlen(env_location)+3+1); - free_ini_search_path = 1; - php_ini_search_path[0] = 0; - - /* - * Prepare search path - */ - - /* Add cwd */ -#ifdef INI_CHECK_CWD - if (strcmp(sapi_module.name, "cli")!=0) { - if (*php_ini_search_path) { - strcat(php_ini_search_path, paths_separator); - } - strcat(php_ini_search_path, "."); - } -#endif - - /* Add binary directory */ -#ifdef PHP_WIN32 - binary_location = (char *) emalloc(MAXPATHLEN); - if (GetModuleFileName(0, binary_location, MAXPATHLEN)==0) { - efree(binary_location); - binary_location = NULL; - } -#else - if (sapi_module.executable_location) { - binary_location = estrdup(sapi_module.executable_location); - } else { - binary_location = NULL; - } -#endif - if (binary_location) { - char *separator_location = strrchr(binary_location, DEFAULT_SLASH); - - if (separator_location) { - *(separator_location+1) = 0; - } - if (*php_ini_search_path) { - strcat(php_ini_search_path, paths_separator); - } - strcat(php_ini_search_path, binary_location); - efree(binary_location); - } - - /* Add environment location */ - if (env_location[0]) { - if (*php_ini_search_path) { - strcat(php_ini_search_path, paths_separator); - } - strcat(php_ini_search_path, env_location); - } - - /* Add default location */ -#ifdef PHP_WIN32 - default_location = (char *) emalloc(MAXPATHLEN+1); - - if (0 < GetWindowsDirectory(default_location, MAXPATHLEN)) { - if (*php_ini_search_path) { - strcat(php_ini_search_path, paths_separator); - } - strcat(php_ini_search_path, default_location); - } - efree(default_location); -#else - default_location = PHP_CONFIG_FILE_PATH; - if (*php_ini_search_path) { - strcat(php_ini_search_path, paths_separator); - } - strcat(php_ini_search_path, default_location); -#endif - } + /* build the search path */ + free_ini_search_path = php_prepare_ini_search_path(&php_ini_search_path); PG(safe_mode) = 0; PG(open_basedir) = NULL; @@ -333,7 +605,7 @@ struct stat statbuf; if (!VCWD_STAT(sapi_module.php_ini_path_override, &statbuf)) { - if (!((statbuf.st_mode & S_IFMT) == S_IFDIR)) { + if (S_ISDIR(statbuf.st_mode) == 0) { fh.handle.fp = VCWD_FOPEN(sapi_module.php_ini_path_override, "r"); fh.filename = sapi_module.php_ini_path_override; } ====== END PATCH ====== -----Original Message----- From: David Viner [mailto:[EMAIL PROTECTED]] Sent: Tuesday, September 24, 2002 1:40 PM To: Php-Dev@lists. php. net Subject: [PHP-DEV] [PATCH] include statement in php.ini file Hi, I've been working with Brian France on a patch that will allow users to include other ini files from the php.ini (see http://marc.theaimsgroup.com/?t=103179766700001&r=1&w=2 for earlier discussions). This patch allows the following functionality from the php.ini file: include = file include = directory include = /full/path/to/file include = /full/path/to/directory When a full path is not specified, it will look in the same directory which were examined to find the php.ini file itself. When a directory is specified, it will process each file in the directory. The files included are process exactly as the php.ini file is. (The included ini files are handled as ini files, not .php files.) This is nearly identical to the Include capability of Apache's configuration files. For those interested in using an Include feature from within the php.ini, please let me know if this is sufficient. Thanks Dave Viner -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php