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);