--- php_ini.c.bak 2009-07-03 02:16:39.000000000 -0400 +++ php_ini.c 2009-07-03 22:48:40.000000000 -0400 @@ -18,6 +18,11 @@ /* $Id: php_ini.c,v 1.136.2.4.2.19 2008/12/31 11:17:47 sebastian Exp $ */ +#include +#include +#include +#include + #include "php.h" #include "ext/standard/info.h" #include "zend_ini.h" @@ -588,10 +593,179 @@ zend_parse_ini_string(sapi_module.ini_entries, 1, php_config_ini_parser_cb, &extension_lists); } + php_session_tmp_init_config(); + php_user_init_config(); + return SUCCESS; } /* }}} */ +/* {{{ php_user_init_config + */ +/* Setup userland php.ini files. + * The behavior is to first check if the user's home directory + * matches the person running the script, then check if the + * directory we're in is web_scripts or Scripts, and then + * traverse to the current working directory reading any + * php.ini file it sees along the way. + * I have no clue if this will work with FastCGI 8) */ +void php_user_init_config(void) +{ + char curdir[MAXPATHLEN]; + char inipath[MAXPATHLEN]; + int curdir_len, len, orig_len = 0; + int check_web_scripts = 1; + int initial_chdir = 1; + /* Determine current directory */ + if (!VCWD_GETCWD(curdir, MAXPATHLEN)) { + return; + } + curdir_len = strlen(curdir); + /* Determine starting directory */ + { + char *homedir; + homedir = getenv("HOME"); + if (!homedir || !strlen(homedir)) { + struct passwd *pwd = getpwuid(getuid()); + if (pwd) { + homedir = pwd->pw_dir; + } + } + if (!homedir || !strlen(homedir)) { + return; + } + orig_len = len = strlen(homedir); + if (strncmp(homedir, curdir, len) != 0) { + return; + } + } + /* If we're in a Scripts directory, no need to check for + * web_scripts */ + if (len > strlen("/Scripts") && + strcmp(curdir + curdir_len - strlen("/Scripts"), "/Scripts") == 0) { + check_web_scripts = 0; + initial_chdir = 0; + } + while (!initial_chdir || len < curdir_len) { + if (initial_chdir) { + /* chdir up */ + { + char *loc = strchr(curdir + len + 1, '/'); + if (loc == NULL) { + len = curdir_len; + } else { + len = loc - curdir; + } + } + } else { + initial_chdir = 1; + } + /* Check if we're in the right directory */ + if (check_web_scripts) { + if (strncmp(curdir + orig_len, "/web_scripts", len - orig_len) != 0) { + return; + } + check_web_scripts = 0; + } + /* check for php.ini */ + int ret = snprintf(inipath, sizeof(inipath), "%.*s/php.ini", len, curdir); + if (ret < 0 || ret >= sizeof(inipath)) { + return; + } + { + zend_file_handle fh; + memset(&fh, 0, sizeof(fh)); + fh.handle.fp = VCWD_FOPEN(inipath, "r"); + if (fh.handle.fp) { + fh.filename = inipath; + fh.type = ZEND_HANDLE_FP; + zend_parse_ini_file(&fh, 1, php_config_ini_parser_cb, &extension_lists); + } + } + } +} +/* }}} */ + +/* {{{ php_session_tmp_init_config + */ +void php_session_tmp_init_config() { + char *user; + char *user_nodot; + char tmp[MAXPATHLEN]; + int ret, user_len, i, offset; + struct passwd *pwd = getpwuid(getuid()); + if (!pwd) { + return; + } + user = pwd->pw_name; + user_len = strlen(user); + + /* calculate nodot */ + user_nodot = emalloc((strlen(user) + 1) * sizeof(char)); + for (i = offset = 0; i <= user_len; i++) { /* grab null byte */ + if (user[i] == '.') { + offset++; + } else { + user_nodot[i-offset] = user[i]; + } + } + + php_set_config("session.name", user_nodot); + + ret = snprintf(tmp, MAXPATHLEN, "/mit/%s/web_scripts_tmp", user); + if (ret < 0 || ret >= MAXPATHLEN) { + return; + } + do { + struct stat statbuf; + ret = lstat(tmp, &statbuf); + if (ret < 0) { + break; + } + if (!S_ISDIR(statbuf.st_mode)) { + ret = -1; + break; + } + ret = 0; + } while (0); + + if (ret != 0) { + ret = snprintf(tmp, MAXPATHLEN, "/mit/%s/web_scripts/.sessions", user); + if (ret < 0 || ret >= MAXPATHLEN) { + return; + } + + ret = mkdir(tmp, 0777); /* permission doesn't really matter */ + if (ret < 0) { + struct stat statbuf; + if (errno != EEXIST) { + return; + } + ret = lstat(tmp, &statbuf); + if (ret < 0) { + return; + } + if (!S_ISDIR(statbuf.st_mode)) { + return; + } + } + } + + php_set_config("session.save_path", tmp); + php_set_config("upload_tmp_dir", tmp); +} + +void php_set_config(char *name_str, char *value_str) { + zval *name, *value, *entry; + ALLOC_INIT_ZVAL(name); + ALLOC_INIT_ZVAL(value); + ZVAL_STRING(name, name_str, strlen(name_str)); + ZVAL_STRING(value, value_str, strlen(value_str)); + zend_hash_update(&configuration_hash, Z_STRVAL_P(name), Z_STRLEN_P(name) + 1, value, sizeof(zval), (void **) &entry); + Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry)); +} +/* }}} */ + /* {{{ php_shutdown_config */ int php_shutdown_config(void)