1.0d7 prerelease, see the NEWS file

diff --git a/NEWS b/NEWS
index eab5e91..d9a1eca 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Changes in 1.0d7
+--------------------------------------------------------------------------------
+- Fixed <Tcl>...</Tcl>, these should be placed outside of <Directory>/<Location> directives.  Everything in <Tcl>...</Tcl> is added to a global variable and then made local to the namespace of the file, this is due to several problems with handling configuration, mainly that exection would either result in a "this directive doesn't belong here" or a problem with the configuration not being built yet as in an EXEC_ON_READ.
+- Fixed a bug in ap_create_environment.
+
 Changes in 1.0d6
 --------------------------------------------------------------------------------
 
@@ -15,7 +20,7 @@
 --------------------------------------------------------------------------------
 
 1. Add configuration documentation to README, add documentation regarding `r' and `r_set' commands.
-2. Possible addition of option to build shared object (.so) library.  (It appears Apache 2.0 has a configuration directive for this --enable-shared, but it appears to be not implemented yet...).
+DONE 2. Possible addition of option to build shared object (.so) library.  (It appears Apache 2.0 has a configuration directive for this --enable-shared, but it appears to be not implemented yet...).
 3. A couple of hooks are broken (Apache bug?) the DECLINE causes the server to exit on signal 11 (SEGV).
 4. Add non-standard hooks?
 5. Add filters?
@@ -40,10 +45,10 @@
 - 1.0d5 -| constants commands in ::apache namespace, mmap checking, test
          | script
          |
-* 1.0d6 *| ap_send_http_header deprecated, updated to be peachy with
+- 1.0d6 -| ap_send_http_header deprecated, updated to be peachy with
          | Apache 2.0.14
          |
-- 1.0d7 -|
+% 1.0d7 %| we're still here, just a pre-release
          |
 - 1.0d8 -|
          |
diff --git a/tcl_cmds.c b/tcl_cmds.c
index 3b24632..89bb08e 100644
--- a/tcl_cmds.c
+++ b/tcl_cmds.c
@@ -2222,7 +2222,7 @@
 	char **env, *nm_env;
 	int i;
 	
-	asprintf(&nm_env, "%s::env", _r->filename);
+	asprintf(&nm_env, "::%s::env", _r->filename);
 	
 	ap_add_cgi_vars(_r);
 	ap_add_common_vars(_r);
diff --git a/tcl_core.c b/tcl_core.c
index fc78e12..adb6a27 100644
--- a/tcl_core.c
+++ b/tcl_core.c
@@ -79,7 +79,6 @@
 static const char* tcl_set(cmd_parms *parms, void *mconfig, const char *one, const char *two, const char *three);
 static const char* tcl_setlist(cmd_parms *parms, void *mconfig, const char *one, const char *two);
 static const char* tcl_raw_args(cmd_parms *parms, void *mconfig, char *arg);
-static const char* tcl_no_args(cmd_parms *parms, void *mconfig);
 
 typedef const char* (*fz_t)(void);
 
@@ -89,7 +88,7 @@
 	AP_INIT_FLAG(		"Tcl",							(fz_t) sfl,				(void*) 1,	OR_AUTHCFG,		"turn mod_tcl on or off." ),
 	AP_INIT_TAKE23(		"Tcl_Var",						(fz_t) tcl_set,			NULL,		OR_AUTHCFG,		"set global variables in TCL." ),
 	AP_INIT_TAKE2(		"Tcl_ListVar",					(fz_t) tcl_setlist,		NULL,		OR_AUTHCFG,		"set global list variables." ),
-	
+
 	/* this may be phased out, it should now be, Tcl_ContentHandler */
 	AP_INIT_TAKE1(		"Tcl_ContentHandlers",			(fz_t) add_hand,		(void*) 0,	OR_AUTHCFG,		"add content handler." ),
 	
@@ -103,8 +102,7 @@
 	AP_INIT_TAKE1(		"Tcl_Hook_Type_Checker",		(fz_t) add_hand,		(void*) 7,	OR_AUTHCFG,		"add type_checker handlers." ),
 	AP_INIT_TAKE1(		"Tcl_Hook_Fixups",				(fz_t) add_hand,		(void*) 8,	OR_AUTHCFG,		"add fixups handlers." ),
 	AP_INIT_TAKE1(		"Tcl_Hook_Log_Transaction",		(fz_t) add_hand,		(void*) 9,	OR_AUTHCFG,		"add log_transaction handlers." ),
-	AP_INIT_RAW_ARGS(	"<Tcl>",						(fz_t) tcl_raw_args,	NULL,		OR_AUTHCFG,		"add raw tcl to the interpreter." ),
-	AP_INIT_NO_ARGS(	"</Tcl>",						(fz_t) tcl_no_args,		NULL,		OR_AUTHCFG,		"end of tcl section." ),
+	AP_INIT_RAW_ARGS(	"<Tcl>",						(fz_t) tcl_raw_args,	NULL,		RSRC_CONF|EXEC_ON_READ,		"add raw tcl to the interpreter." ),
 	{ NULL }
 };
 
@@ -113,16 +111,16 @@
 	ap_hook_pre_config(tcl_init, NULL, NULL, APR_HOOK_REALLY_FIRST);
 	ap_hook_post_config(tcl_init_handler, NULL, NULL, APR_HOOK_MIDDLE);
 	
-//	ap_hook_post_read_request(tcl_post_read_request, NULL, NULL, APR_HOOK_MIDDLE);
-//	ap_hook_translate_name(tcl_translate_name, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_header_parser(tcl_header_parser, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_access_checker(tcl_access_checker, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_check_user_id(tcl_check_user_id, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_auth_checker(tcl_auth_checker, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_type_checker(tcl_type_checker, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_fixups(tcl_fixups, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_handler(tcl_handler, NULL, NULL, APR_HOOK_MIDDLE);
-	ap_hook_log_transaction(tcl_log_transaction, NULL, NULL, APR_HOOK_MIDDLE);
+//	ap_hook_post_read_request(tcl_post_read_request, NULL, NULL, APR_HOOK_FIRST);
+//	ap_hook_translate_name(tcl_translate_name, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_header_parser(tcl_header_parser, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_access_checker(tcl_access_checker, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_check_user_id(tcl_check_user_id, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_auth_checker(tcl_auth_checker, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_type_checker(tcl_type_checker, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_fixups(tcl_fixups, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_handler(tcl_handler, NULL, NULL, APR_HOOK_FIRST);
+	ap_hook_log_transaction(tcl_log_transaction, NULL, NULL, APR_HOOK_FIRST);
 }
 
 AP_DECLARE_DATA module tcl_module = {
@@ -144,9 +142,21 @@
 	int					fl;
 	char				*handlers[NUM_HANDLERS];
 	apr_array_header_t	*var_list;
-	apr_array_header_t	*raw_list;
 } tcl_config_rec;
 
+typedef struct {
+	char			*file;
+	struct stat		st;
+} file_cache;
+
+Tcl_Interp			*interp = NULL;
+apr_array_header_t	*fcache = NULL;
+char				*raw_tcl = NULL;
+apr_pool_t			*_pconf = NULL;
+request_rec			*_r = NULL;
+char				*current_namespace = NULL;
+int					read_post_ok;
+
 static void* tcl_create_dir_config(apr_pool_t *p, char *d)
 {
 	int i;
@@ -154,7 +164,6 @@
 	
 	tclr->fl		= 0;
 	tclr->var_list	= apr_array_make(p, 0, sizeof(var_cache));
-	tclr->raw_list	= apr_array_make(p, 0, sizeof(char*));
 	
 	memset(tclr->handlers, 0, NUM_HANDLERS * sizeof(char*));
 	
@@ -223,50 +232,24 @@
 	return NULL;
 }
 
-static const char *tcl_raw_args(cmd_parms *parms, void *mconfig, char *arg)
+static const char* tcl_raw_args(cmd_parms *cmd, void *mconfig, char *arg)
 {
-	tcl_config_rec *tclr = (tcl_config_rec*) mconfig;
+	char **xx, *z = apr_pstrdup(cmd->pool, "");
 	char l[MAX_STRING_LEN];
-	char **line, *script, **xx;
-	int i, j = 0, k = 0;
-	apr_array_header_t *temp = apr_array_make(parms->pool, 0, sizeof(char*));
-	char **temp_elts = (char**) temp->elts;
-
-	while (!(ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))) {
+    
+    while (!(ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))) {
 		if (!strncasecmp(l, "</Tcl>", 6)) {
-			goto cleanup;
+			break;
 		}
-
-		line = (char**) apr_array_push(temp);
-		j += asprintf(line, l);
-		k++;
-	}
-	
-  cleanup:
-  
-	script = (char*) malloc(j + k + 1);
-	j = 0;
-	
-	for (i = 0; i < temp->nelts; i++) {
-		memcpy(&(script[j]), temp_elts[i], j += strlen(temp_elts[i]));
-		script[j] = '\n';
-		j++;
 		
-		free(temp_elts[i]);
-	}
+    	/* ick */
+    	z = apr_pstrcat(cmd->pool, z, l, "\n", NULL);
+    }
 	
-	script[j] = '\0';
+	/* ick */
+	raw_tcl = realloc(raw_tcl, strlen(z) + 1);
+	strcat(raw_tcl, z);
 	
-	xx = (char**) apr_array_push(tclr->raw_list);
-	*xx = apr_pstrdup(parms->pool, script);
-	
-	free(script);
-
-	return NULL;
-}
-
-static const char *tcl_no_args(cmd_parms *parms, void *dummy)
-{
 	return NULL;
 }
 
@@ -326,18 +309,6 @@
 	}
 }
 
-typedef struct {
-	char			*file;
-	struct stat		st;
-} file_cache;
-
-Tcl_Interp			*interp = NULL;
-apr_array_header_t	*fcache = NULL;
-apr_pool_t			*_pconf = NULL;
-request_rec			*_r = NULL;
-char				*current_namespace = NULL;
-int					read_post_ok;
-
 static void tcl_init(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp)
 {
 	char *buf;
@@ -438,7 +409,7 @@
 	/* util_script.h */
 	Tcl_CreateObjCommand(interp, "apache::ap_create_environment", cmd_ap_create_environment, NULL, NULL);
 	
-	// provided nasty
+	/* output script */
 	buf = "\
 	proc apache::output { script } {\n\
 		set script [split $script \\n]\n\
@@ -452,6 +423,16 @@
 	}";
 						
 	run_script(interp, buf);
+	
+	/* built-in null handler for cancelling out previously defined handlers in parent directories */
+	buf = "\
+	proc apache::null_handler { } {\n\
+		variable DECLINED\n\
+		\n\
+		return $DECLINED\n\
+	}";
+	
+	run_script(interp, buf);
 
 	set_vari(interp, "apache::DECLINED", NULL, DECLINED);
 	set_vari(interp, "apache::DONE", NULL, DONE);
@@ -568,7 +549,7 @@
 
 static void tcl_init_handler(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
 {
-	ap_add_version_component(pconf, "mod_tcl/1.0d6");
+	ap_add_version_component(pconf, "mod_tcl/1.0dPRE7-2001032000");
 }
 
 static int run_handler(request_rec *r, int hh)
@@ -578,7 +559,6 @@
 	size_t flen = strlen(r->filename);
 	file_cache *fptr = NULL, *fa = (file_cache*) fcache->elts;
 	var_cache *vl = (var_cache*) tclr->var_list->elts;
-	char **rl = (char**) tclr->raw_list->elts;
 	struct stat st;
 	
 	if (!(tclr->fl & 1) || !interp) {
@@ -666,26 +646,7 @@
 			}
 		}
 		
-		for (i = 0, pos = 0; i < tclr->raw_list->nelts; i++) {
-			int rl_len = strlen(rl[i]);
-			
-			bptr = (char*) malloc(rl_len + flen + 21);
-			
-			memcpy(bptr, "namespace eval ", 15);		pos += 15;
-			memcpy(bptr + pos, r->filename, flen);		pos += flen;
-			memcpy(bptr + pos, " {\n", 3);				pos += 3;
-			memcpy(bptr + pos, rl[i], rl_len);			pos += rl_len;
-			memcpy(bptr + pos, "\n}\0", 3);
-			
-			obj = Tcl_NewStringObj(bptr, -1);
-			
-			free(bptr);
-			
-			if (Tcl_EvalObjEx(interp, obj, 0) == TCL_ERROR) {
-				ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Tcl_EvalObjEx(...): %s\n%s", Tcl_GetStringResult(interp), Tcl_GetVar(interp, "errorInfo", 0));
-				return HTTP_INTERNAL_SERVER_ERROR;
-			}
-		}
+		run_script(interp, "namespace eval %s { %s }", r->filename, raw_tcl);
 	}
 	else if (st.st_mtime > fptr->st.st_mtime) {
 		int fd;
@@ -703,7 +664,7 @@
 		mptr = mmap((caddr_t) 0, r->finfo.size, PROT_READ, MAP_SHARED, fd, 0);
 #else
 		mptr = malloc(r->finfo.size);
-		read(fd, mptr, f->finfo.size);
+		read(fd, mptr, r->finfo.size);
 #endif /* HAVE_MMAP */
 
 		bptr = malloc(r->finfo.size + flen + 21);