in tcl_core.c [550:746]
static int run_handler(request_rec *r, int hh)
{
int xx = HTTP_NOT_FOUND, i;
tcl_config_rec *tclr = (tcl_config_rec*) ap_get_module_config(r->per_dir_config, &tcl_module);
size_t flen;
file_cache *fptr = NULL, *fa = (file_cache*) fcache->elts;
var_cache *vl = (var_cache*) tclr->var_list->elts;
struct stat st;
char *tmp_filename;
if (!interp) {
return DECLINED;
}
/* handler wasn't set so ignore it */
if (!tclr->handlers[hh]) {
return DECLINED;
}
if (hh != 8) {
if (hh < 2) {
tmp_filename = tclr->file_location[hh];
}
else {
tmp_filename = r->filename;
}
/* this will be rewritten by some translation... */
r->filename = tclr->file_location[hh];
}
else if (r->finfo.filetype != APR_REG) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "request URI does not match a file, a translation phase may have failed, r->filename = %s", r->filename);
return DECLINED;
}
flen = strlen(r->filename);
stat(r->filename, &st);
for (i = 0; i < fcache->nelts; i++) {
if (!strcmp(fa[i].file, r->filename)) {
fptr = &(fa[i]);
break;
}
}
if (!fptr) {
int fd;
void *mptr;
char *bptr;
off_t pos = 0;
Tcl_Obj *obj;
if ((fd = open(r->filename, O_RDONLY, 0)) == -1) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "open(%s, ...): %s", r->filename, strerror(errno));
return HTTP_NOT_FOUND;
}
#ifdef HAVE_MMAP
mptr = mmap((caddr_t) 0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
#else
mptr = malloc(st.st_size);
read(fd, mptr, st.st_size);
#endif /* HAVE_MMAP */
bptr = (char*) malloc(st.st_size + 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, mptr, st.st_size); pos += st.st_size;
memcpy(bptr + pos, "\n}\0", 3);
#ifdef HAVE_MMAP
munmap((char*) mptr, st.st_size);
#else
free(mptr);
#endif /* HAVE_MMAP */
close(fd);
fptr = (file_cache*) apr_array_push(fcache);
fptr->file = apr_pstrdup(fcache->pool, r->filename);
memcpy(&(fptr->st), &st, sizeof(struct stat));
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;
}
for (i = 0; i < tclr->var_list->nelts; i++) {
if (vl[i].fl == 1) {
char *namespc = (char*) malloc(strlen(r->filename) + strlen(vl[i].var1) + 3);
sprintf(namespc, "%s::%s", r->filename, vl[i].var1);
set_var(interp, namespc, vl[i].var2, "%s", vl[i].var3);
free(namespc);
}
else if (vl[i].fl == 2) {
char *namespc = (char*) malloc(strlen(r->filename) + strlen(vl[i].var1) + 3);
sprintf(namespc, "%s::%s", r->filename, vl[i].var1);
run_script(interp, "lappend %s %s", namespc, vl[i].var2);
free(namespc);
}
}
if (raw_tcl) {
run_script(interp, "namespace eval %s { %s }", r->filename, raw_tcl);
}
}
else if (st.st_mtime > fptr->st.st_mtime) {
int fd;
void *mptr;
char *bptr;
off_t pos = 0;
Tcl_Obj *obj;
if ((fd = open(r->filename, O_RDONLY, 0)) == -1) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "open(%s, ...): %s", r->filename, strerror(errno));
return HTTP_INTERNAL_SERVER_ERROR;
}
#ifdef HAVE_MMAP
mptr = mmap((caddr_t) 0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
#else
mptr = malloc(st.st_size);
read(fd, mptr, st.st_size);
#endif /* HAVE_MMAP */
bptr = malloc(st.st_size + 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, mptr, st.st_size); pos += st.st_size;
memcpy(bptr + pos, "\n}\0", 3);
#ifdef HAVE_MMAP
munmap((char*) mptr, st.st_size);
#else
free(mptr);
#endif /* HAVE_MMAP */
close(fd);
fptr = (file_cache*) apr_array_push(fcache);
fptr->file = apr_pstrdup(fcache->pool, r->filename);
memcpy(&(fptr->st), &st, sizeof(struct stat));
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;
}
}
_r = r;
current_namespace = r->filename;
read_post_ok = 1;
{
char *eptr = (char*) malloc(strlen(tclr->handlers[hh]) + flen + 3);
Tcl_Obj *obj;
sprintf(eptr, "%s::%s", fptr->file, tclr->handlers[hh]);
obj = Tcl_NewStringObj(eptr, -1);
free(eptr);
if (Tcl_EvalObjEx(interp, obj, 0) == TCL_ERROR) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r->server, "Tcl_EvalObjEx(%s): %s", eptr, Tcl_GetStringResult(interp));
r->content_type = "text/html";
ap_rprintf(r, "<H3>TCL Error</H3><BR><PRE>%s</PRE>", Tcl_GetString(Tcl_GetVar2Ex(interp, "errorInfo", NULL, 0)));
return OK;
}
Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &xx);
}
r->filename = tmp_filename;
return xx;
}