You are viewing a plain text version of this content. The canonical link for it is here.
Posted to mod_dtcl-cvs@tcl.apache.org by da...@apache.org on 2001/06/21 19:47:20 UTC
cvs commit: tcl-moddtcl/docs documentation.txt
davidw 01/06/21 10:47:20
Modified: . apache_cookie.c apache_multipart_buffer.c
apache_request.c apache_request.h mod_dtcl.c
mod_dtcl.h tcl_commands.c tcl_commands.h
docs documentation.txt
Log:
Initial commit of upload command. Things are in a bit of a broken
state at the moment. Cleaned up some extra white space too.
Revision Changes Path
1.4 +10 -10 tcl-moddtcl/apache_cookie.c
Index: apache_cookie.c
===================================================================
RCS file: /home/cvs/tcl-moddtcl/apache_cookie.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- apache_cookie.c 2001/03/15 19:36:55 1.3
+++ apache_cookie.c 2001/06/21 17:47:08 1.4
@@ -6,7 +6,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -78,7 +78,7 @@
char *retval = NULL;
int ix = key[0] == '-' ? 1 : 0;
- switch (key[ix]) {
+ switch (key[ix]) {
case 'n':
cookie_get_set(c->name, val);
break;
@@ -96,14 +96,14 @@
break;
case 's':
if(val) {
- c->secure =
+ c->secure =
!strcaseEQ(val, "off") &&
!strcaseEQ(val, "0");
}
retval = c->secure ? "on" : "";
break;
default:
- ap_log_rerror(APC_ERROR,
+ ap_log_rerror(APC_ERROR,
"[libapreq] unknown cookie pair: `%s' => `%s'", key, val);
};
@@ -114,7 +114,7 @@
{
va_list args;
ApacheRequest req;
- ApacheCookie *c =
+ ApacheCookie *c =
ap_pcalloc(r->pool, sizeof(ApacheCookie));
req.r = r;
@@ -144,7 +144,7 @@
ApacheCookieJar *ApacheCookie_parse(request_rec *r, const char *data)
{
const char *pair;
- ApacheCookieJar *retval =
+ ApacheCookieJar *retval =
ap_make_array(r->pool, 1, sizeof(ApacheCookie *));
if (!data) {
@@ -192,7 +192,7 @@
cookie_push_arr(arr, ap_pstrcat(p, name, "=", val, NULL)); \
}
-static char * escape_url(pool *p, char *val)
+static char * escape_url(pool *p, char *val)
{
char *result = ap_os_escape_path(p, val?val:"", 1);
char *end = result + strlen(result);
@@ -248,15 +248,15 @@
cookie = ap_pstrcat(p, escape_url(p, c->name), "=", NULL);
for (i=0; i<c->values->nelts; i++) {
- cookie = ap_pstrcat(p, cookie,
- escape_url(p, ((char**)c->values->elts)[i]),
+ cookie = ap_pstrcat(p, cookie,
+ escape_url(p, ((char**)c->values->elts)[i]),
(i < (c->values->nelts-1) ? "&" : NULL),
NULL);
}
retval = cookie;
for (i=0; i<values->nelts; i++) {
- retval = ap_pstrcat(p, retval, "; ",
+ retval = ap_pstrcat(p, retval, "; ",
((char**)values->elts)[i], NULL);
}
1.5 +10 -11 tcl-moddtcl/apache_multipart_buffer.c
Index: apache_multipart_buffer.c
===================================================================
RCS file: /home/cvs/tcl-moddtcl/apache_multipart_buffer.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- apache_multipart_buffer.c 2001/03/15 19:36:56 1.4
+++ apache_multipart_buffer.c 2001/06/21 17:47:09 1.5
@@ -6,7 +6,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -70,7 +70,7 @@
int needlen = strlen(needle);
int len = haystacklen;
char *ptr = haystack;
-
+
/* iterate through first character matches */
while( (ptr = memchr(ptr, needle[0], len)) ) {
/* calculate length after match */
@@ -100,10 +100,10 @@
if(self->bytes_in_buffer > 0 && self->buf_begin != self->buffer)
memmove(self->buffer, self->buf_begin, self->bytes_in_buffer);
self->buf_begin = self->buffer;
-
+
/* calculate the free space in the buffer */
bytes_to_read = self->bufsize - self->bytes_in_buffer;
-
+
/* read the required number of bytes */
if(bytes_to_read > 0) {
char *buf = self->buffer + self->bytes_in_buffer;
@@ -158,7 +158,7 @@
self->buf_begin = ptr;
self->bytes_in_buffer = 0;
}
-
+
return line;
}
@@ -171,7 +171,7 @@
fill_buffer(self);
ptr = next_line(self);
}
-
+
#ifdef DEBUG
ap_log_rerror(MPB_ERROR, "get_line: '%s'", ptr);
#endif
@@ -182,9 +182,8 @@
/* finds a boundary */
int find_boundary(multipart_buffer *self, char *boundary)
{
- int len, bound_len = strlen(boundary);
char *line;
-
+
/* loop thru lines */
while( (line = get_line(self)) ) {
#ifdef DEBUG
@@ -193,7 +192,7 @@
#endif
/* finished if we found the boundary */
- if(strcmp(line, boundary) == 0)
+ if(strEQ(line, boundary))
return 1;
}
@@ -249,7 +248,7 @@
"multipart_buffer_headers: '%s' = '%s'",
key, value);
#endif
-
+
ap_table_add(tab, key, value);
}
else {
@@ -283,7 +282,7 @@
/* maximum number of bytes we are reading */
len = max < bytes-1 ? max : bytes-1;
-
+
/* if we read any data... */
if(len > 0) {
/* copy the data */
1.7 +43 -42 tcl-moddtcl/apache_request.c
Index: apache_request.c
===================================================================
RCS file: /home/cvs/tcl-moddtcl/apache_request.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- apache_request.c 2001/06/04 09:54:46 1.6
+++ apache_request.c 2001/06/21 17:47:09 1.7
@@ -6,7 +6,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -84,7 +84,7 @@
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
- *rbuf = ap_pcalloc(r->pool, length + 1);
+ *rbuf = ap_pcalloc(r->pool, length + 1);
ap_hard_timeout("[libapreq] util_read", r);
@@ -112,7 +112,7 @@
char *tmp;
if (r->path_info && *r->path_info) {
- int path_info_start = ap_find_path_info(r->uri, r->path_info);
+ int path_info_start = ap_find_path_info(r->uri, r->path_info);
tmp = ap_pstrndup(r->pool, r->uri, path_info_start);
}
else {
@@ -133,18 +133,18 @@
return ap_table_get(req->parms, key);
}
-static int make_params(void *data, const char *key, const char *val)
-{
- array_header *arr = (array_header *)data;
- *(char **)ap_push_array(arr) = (char *)val;
- return 1;
-}
+static int make_params(void *data, const char *key, const char *val)
+{
+ array_header *arr = (array_header *)data;
+ *(char **)ap_push_array(arr) = (char *)val;
+ return 1;
+}
array_header *ApacheRequest_params(ApacheRequest *req, const char *key)
{
array_header *values = ap_make_array(req->r->pool, 4, sizeof(char *));
ApacheRequest_parse(req);
- ap_table_do(make_params, (void*)values, req->parms, key, NULL);
+ ap_table_do(make_params, (void*)values, req->parms, key, NULL);
return values;
}
@@ -155,7 +155,7 @@
int i;
for (i=0; i<values->nelts; i++) {
- retval = ap_pstrcat(req->r->pool,
+ retval = ap_pstrcat(req->r->pool,
retval ? retval : "",
((char **)values->elts)[i],
(i == (values->nelts - 1)) ? NULL : ", ",
@@ -249,7 +249,7 @@
static void split_to_parms(ApacheRequest *req, const char *data)
{
- request_rec *r = req->r;
+ request_rec *r = req->r;
const char *val;
while (*data && (val = my_urlword(r->pool, &data))) {
@@ -274,22 +274,22 @@
split_to_parms(req, r->args);
}
- if (r->method_number == M_POST) {
- const char *ct = ap_table_get(r->headers_in, "Content-type");
- if (ct && strcaseEQN(ct, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
- result = ApacheRequest_parse_urlencoded(req);
+ if (r->method_number == M_POST) {
+ const char *ct = ap_table_get(r->headers_in, "Content-type");
+ if (ct && strncaseEQ(ct, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
+ result = ApacheRequest_parse_urlencoded(req);
}
- else if (ct && strcaseEQN(ct, MULTIPART_ENCTYPE, MULTIPART_ENCTYPE_LENGTH)) {
- result = ApacheRequest_parse_multipart(req);
+ else if (ct && strncaseEQ(ct, MULTIPART_ENCTYPE, MULTIPART_ENCTYPE_LENGTH)) {
+ result = ApacheRequest_parse_multipart(req);
}
else {
- ap_log_rerror(REQ_ERROR,
- "[libapreq] unknown content-type: `%s'", ct);
+ ap_log_rerror(REQ_ERROR,
+ "[libapreq] unknown content-type: `%s'", ct);
result = HTTP_INTERNAL_SERVER_ERROR;
}
- }
+ }
else {
- result = ApacheRequest_parse_urlencoded(req);
+ result = ApacheRequest_parse_urlencoded(req);
}
req->parsed = 1;
@@ -299,15 +299,15 @@
int ApacheRequest_parse_urlencoded(ApacheRequest *req)
{
- request_rec *r = req->r;
+ request_rec *r = req->r;
int rc = OK;
- if (r->method_number == M_POST) {
+ if (r->method_number == M_POST) {
const char *data = NULL, *type;
type = ap_table_get(r->headers_in, "Content-Type");
- if (!strcaseEQN(type, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
+ if (!strncaseEQ(type, DEFAULT_ENCTYPE, DEFAULT_ENCTYPE_LENGTH)) {
return DECLINED;
}
if ((rc = util_read(req, &data)) != OK) {
@@ -327,10 +327,12 @@
if( ap_pfclose(req->r->pool, upload->fp) )
ap_log_rerror(REQ_ERROR,
- "[libapreq] close error on '%s'", upload->tempname);
+ "[libapreq] close error on '%s'", upload->tempname);
+#ifndef DEBUG
if( remove(upload->tempname) )
ap_log_rerror(REQ_ERROR,
"[libapreq] remove error on '%s'", upload->tempname);
+#endif
free(upload->tempname);
}
@@ -342,27 +344,26 @@
char prefix[] = "apreq";
char *name;
int fd, tries = 100;
-
+
while (--tries > 0) {
if ( (name = tempnam(req->temp_dir, prefix)) == NULL )
continue;
- fd = ap_popenf(r->pool, name, O_CREAT|O_EXCL|O_RDWR, 0600);
+ fd = ap_popenf(r->pool, name, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600);
if ( fd >= 0 )
break; /* success */
else
free(name);
}
-
- if ( tries == 0 || (fp = ap_pfdopen(r->pool, fd, "wb+") ) == NULL ) {
- ap_log_rerror(REQ_ERROR,
- "[libapreq] could not open temp file '%s'", name);
+
+ if ( tries == 0 || (fp = ap_pfdopen(r->pool, fd, "w+" "b") ) == NULL ) {
+ ap_log_rerror(REQ_ERROR, "[libapreq] could not create/open temp file");
if ( fd >= 0 ) { remove(name); free(name); }
return NULL;
}
upload->fp = fp;
upload->tempname = name;
- ap_register_cleanup(r->pool, (void *)upload,
+ ap_register_cleanup(r->pool, (void *)upload,
remove_tmpfile, ap_null_cleanup);
return fp;
@@ -403,14 +404,14 @@
}
(void)ap_getword(r->pool, &ct, '=');
- boundary = ap_getword_conf(r->pool, &ct);
+ boundary = ap_getword_conf(r->pool, &ct);
if (!(mbuff = multipart_buffer_new(boundary, length, r))) {
return DECLINED;
}
while (!multipart_buffer_eof(mbuff)) {
- table *header = multipart_buffer_headers(mbuff);
+ table *header = multipart_buffer_headers(mbuff);
const char *cd, *param=NULL, *filename=NULL;
char buff[FILLUNIT];
int blen, wlen;
@@ -520,7 +521,7 @@
if (*time_str == '-') {
is_neg = 1;
++time_str;
- }
+ }
else if (*time_str == '+') {
++time_str;
}
@@ -538,7 +539,7 @@
buf[ix] = '\0';
offset = atoi(buf);
- return time(NULL) +
+ return time(NULL) +
(expire_mult(*time_str) * (is_neg ? (0 - offset) : offset));
}
@@ -558,13 +559,13 @@
return ap_pstrdup(p, time_str);
}
- tms = gmtime(&when);
+ tms = gmtime(&when);
return ap_psprintf(p,
- "%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d GMT",
- ap_day_snames[tms->tm_wday],
+ "%s, %.2d%c%s%c%.2d %.2d:%.2d:%.2d GMT",
+ ap_day_snames[tms->tm_wday],
tms->tm_mday, sep, ap_month_snames[tms->tm_mon], sep,
- tms->tm_year + 1900,
- tms->tm_hour, tms->tm_min, tms->tm_sec);
+ tms->tm_year + 1900,
+ tms->tm_hour, tms->tm_min, tms->tm_sec);
}
char *ApacheRequest_expires(ApacheRequest *req, char *time_str)
1.6 +7 -2 tcl-moddtcl/apache_request.h
Index: apache_request.h
===================================================================
RCS file: /home/cvs/tcl-moddtcl/apache_request.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- apache_request.h 2001/06/04 09:54:46 1.5
+++ apache_request.h 2001/06/21 17:47:10 1.6
@@ -70,8 +70,8 @@
#define strcaseEQ(s1,s2) (!strcasecmp(s1,s2))
#endif
-#ifndef strcaseEQN
-#define strcaseEQN(s1,s2,n) (!strncasecmp(s1,s2,n))
+#ifndef strncaseEQ
+#define strncaseEQ(s1,s2,n) (!strncasecmp(s1,s2,n))
#endif
#define DEFAULT_TABLE_NELTS 10
@@ -104,6 +104,11 @@
#define ApacheRequest_upload(req) \
((req->parsed || (ApacheRequest_parse(req) == OK)) ? req->upload : NULL)
+
+
+#define ApacheUpload_FILE(upload) (upload->fp)
+
+#define ApacheUpload_size(upload) (upload->size)
#define ApacheUpload_info(upload, key) \
ap_table_get(upload->info, key)
1.32 +83 -63 tcl-moddtcl/mod_dtcl.c
Index: mod_dtcl.c
===================================================================
RCS file: /home/cvs/tcl-moddtcl/mod_dtcl.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- mod_dtcl.c 2001/06/11 14:55:01 1.31
+++ mod_dtcl.c 2001/06/21 17:47:10 1.32
@@ -58,7 +58,7 @@
* University of Illinois, Urbana-Champaign.
*/
-/* $Id: mod_dtcl.c,v 1.31 2001/06/11 14:55:01 davidw Exp $ */
+/* $Id: mod_dtcl.c,v 1.32 2001/06/21 17:47:10 davidw Exp $ */
/* mod_dtcl.c by David Welton <da...@apache.org> - originally mod_include. */
/* See http://tcl.apache.org/mod_dtcl/credits.ttml for additional credits. */
@@ -121,11 +121,21 @@
dtcl_init_handler function */
int cacheFreeSize = 0; /* free space in cache */
-static int upload_files_to_var = 0;
+int upload_files_to_var = 0;
static char *upload_dir = "/tmp/"; /* Upload directory */
static unsigned int upload_max = 0; /* Maximum amount of data that may be uploaded */
+
+/* eventually we will transfer 'global' variables in here and
+ 'de-globalize' them */
+#if 0
+typedef struct {
+} dtcl_globals;
+
+dtcl_globals globals;
+#endif
+
typedef struct {
Tcl_Interp *server_interp; /* per server Tcl interpreter */
Tcl_Obj *dtcl_global_init_script; /* run once when apache is first started */
@@ -135,7 +145,7 @@
Tcl_Obj *dtcl_after_script; /* after */
Tcl_Obj *dtcl_error_script; /* for errors */
int dtcl_cache_size;
- char *server_name;
+ char *server_name;
} dtcl_server_conf;
#define GETREQINTERP(req) ((dtcl_server_conf *)ap_get_module_config(req->server->module_config, &dtcl_module))->server_interp
@@ -185,8 +195,8 @@
static int outputproc(ClientData instancedata, char *buf, int toWrite, int *errorCodePtr)
{
memwrite(&obuffer, buf, toWrite);
- return toWrite;
-}
+ return toWrite;
+}
static int closeproc(ClientData instancedata, Tcl_Interp *interp2)
{
@@ -291,7 +301,7 @@
} else {
ap_rputs(errstr, r);
}
- }
+ }
if (htmlflag != 1)
ap_rputs(ER2, r);
@@ -334,26 +344,30 @@
/* Function to be used should we desire to upload files to a variable */
+#if 0
int dtcl_upload_hook(void *ptr, char *buf, int len, ApacheUpload *upload)
{
Tcl_Interp *interp = ptr;
- static void *oldptr;
- int flag = 0;
+ static int usenum = 0;
+ static int uploaded = 0;
- /* if there is not a new file being added, keep adding it to the
- same list element. Otherwise, start a new list element */
if (oldptr != upload)
- flag = TCL_LIST_ELEMENT|TCL_APPEND_VALUE;
- else
- flag = TCL_APPEND_VALUE;
+ {
+ } else {
+ }
+#if USE_ONLY_UPLOAD_COMMAND == 0
+
Tcl_ObjSetVar2(interp,
Tcl_NewStringObj("::request::UPLOAD", -1),
Tcl_NewStringObj("data", -1),
- Tcl_NewByteArrayObj(buf, len),
- flag);
+ Tcl_DuplicateObj(uploadstorage[usenum]),
+ 0);
+#endif /* USE_ONLY_UPLOAD_COMMAND */
return len;
-}
+}
+#endif /* 0 */
+
/* Load, cache and eval a Tcl file */
@@ -368,18 +382,18 @@
with the addition of caching code. */
char *cmdBuffer = (char *) NULL;
Tcl_Channel chan = Tcl_OpenFileChannel(interp, r->filename, "r", 0644);
- if (chan == (Tcl_Channel) NULL)
+ if (chan == (Tcl_Channel) NULL)
{
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, "couldn't read file \"", r->filename,
"\": ", Tcl_PosixError(interp), (char *) NULL);
goto error;
}
-
+
cmdBuffer = (char *) malloc(r->finfo.st_size + 1);
-
+
result = Tcl_Read(chan, cmdBuffer, r->finfo.st_size);
- if (result < 0)
+ if (result < 0)
{
Tcl_Close(interp, chan);
Tcl_AppendResult(interp, "couldn't read file \"", r->filename,
@@ -387,13 +401,13 @@
goto error;
}
cmdBuffer[result] = 0;
-
- if (Tcl_Close(interp, chan) != TCL_OK)
+
+ if (Tcl_Close(interp, chan) != TCL_OK)
goto error;
-
- Tcl_SetStringObj(outbuf, cmdBuffer, strlen(cmdBuffer));
+
+ Tcl_SetStringObj(outbuf, cmdBuffer, strlen(cmdBuffer));
free(cmdBuffer);
-
+
/* yuck */
goto end;
error:
@@ -401,7 +415,7 @@
free(cmdBuffer);
}
return TCL_ERROR;
-
+
end:
return TCL_OK;
#else
@@ -415,7 +429,7 @@
{
/* BEGIN PARSER */
char inside = 0; /* are we inside the starting/ending delimiters */
-
+
const char *strstart = STARTING_SEQUENCE;
const char *strend = ENDING_SEQUENCE;
@@ -455,7 +469,7 @@
"Encountered error in mod_dtcl getchar routine while reading %s",
r->uri);
ap_pfclose( r->pool, f);
- }
+ }
c = ch;
if (!inside)
{
@@ -470,7 +484,7 @@
Tcl_AppendToObj(outbuf, "\"\n", 2);
inside = 1;
p = 0;
- continue;
+ continue;
} else {
ungetc(nextchar, f);
}
@@ -552,13 +566,14 @@
{
Tcl_AppendToObj(outbuf, "\"\n", 2);
}
-
+
if (toplevel)
{
if (conf->dtcl_after_script)
Tcl_AppendObjToObj(outbuf, conf->dtcl_after_script);
-
- Tcl_AppendToObj(outbuf, "\n}\nnamespace delete request\n", -1);
+
+/* Tcl_AppendToObj(outbuf, "\n}\nnamespace delete request\n", -1); seems redundant */
+ Tcl_AppendToObj(outbuf, "\n}\n", -1);
}
else
Tcl_AppendToObj(outbuf, "\n", -1);
@@ -615,12 +630,13 @@
char *hashKey = NULL;
int isNew = 0;
int result = 0;
-
+
Tcl_Obj *outbuf = NULL;
Tcl_HashEntry *entry = NULL;
Tcl_Interp *interp = GETREQINTERP(r);
-
- /* Look for the script's compiled version. If it's not found, create it. */
+
+ /* Look for the script's compiled version. If it's not found,
+ create it. */
if (cacheSize)
{
hashKey = ap_psprintf(r->pool, "%s%ld%ld%d", r->filename, r->finfo.st_mtime, r->finfo.st_ctime, toplevel);
@@ -632,10 +648,10 @@
Tcl_IncrRefCount(outbuf);
if(!strcmp(r->content_type, "application/x-httpd-tcl"))
- {
+ {
/* It's a TTML file */
result = get_ttml_file(r, interp, r->filename, 1, outbuf);
- } else {
+ } else {
/* It's a plain Tcl file */
result = get_tcl_file(r, interp, r->filename, &(r->finfo), outbuf);
}
@@ -656,7 +672,7 @@
free(objCacheList[cacheSize - 1]);
memmove(objCacheList + 1, objCacheList, sizeof(char *)*(cacheSize -1));
objCacheList[0] = strdup(hashKey);
- }
+ }
} else {
outbuf = (Tcl_Obj *)Tcl_GetHashValue(entry);
}
@@ -724,14 +740,16 @@
/* Apache Request stuff */
req = ApacheRequest_new(r);
global_req = req;
+#if 0
if (upload_files_to_var)
{
req->hook_data = interp;
- req->upload_hook = dtcl_upload_hook;
+ req->upload_hook = dtcl_upload_hook;
}
-
+#endif
+
ApacheRequest___parse(req);
-
+
/* take results and create tcl variables from them */
#if USE_ONLY_VAR_COMMAND == 1
if (req->parms)
@@ -750,7 +768,7 @@
Tcl_Obj *newkey = STRING_TO_UTF_TO_OBJ(parms[i].key);
Tcl_Obj *newval = STRING_TO_UTF_TO_OBJ(parms[i].val);
Tcl_Obj *oldval = Tcl_ObjGetVar2(interp, varsobj, newkey, 0);
-
+
if (oldval == NULL)
{
Tcl_ObjSetVar2(interp, varsobj, newkey, newval, 0);
@@ -762,11 +780,11 @@
}
}
}
-
+
}
-#endif
+#endif
+#if USE_ONLY_UPLOAD_COMMAND == 1
upload = req->upload;
-
/* Loop through uploaded files */
while (upload)
{
@@ -815,9 +833,10 @@
TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
}
}
-
+
upload = upload->next;
}
+#endif /* USE_ONLY_UPLOAD_COMMAND == 1 */
get_parse_exec_file(r, 1);
/* reset globals */
@@ -840,6 +859,7 @@
Tcl_CreateObjCommand(interp, "headers", Headers, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "hgetvars", HGetVars, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "var", Var, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
+ Tcl_CreateObjCommand(interp, "upload", Upload, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "include", Include, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "parse", Parse, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
Tcl_CreateObjCommand(interp, "hflush", HFlush, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
@@ -858,13 +878,13 @@
/* Initialize TCL stuff */
interp = Tcl_CreateInterp();
- dsc->server_interp = interp; /* root interpreter */
+ dsc->server_interp = interp; /* root interpreter */
/* Create TCL commands to deal with Apache's BUFFs. */
achan = Tcl_CreateChannel(&Achan, "apacheout", NULL, TCL_WRITABLE);
system_encoding = Tcl_GetEncoding(NULL, "iso8859-1"); /* FIXME */
-
+
Tcl_SetStdChannel(achan, TCL_STDOUT);
Tcl_SetChannelOption(interp, achan, "-buffering", "none");
@@ -906,7 +926,7 @@
}
/* This is what happens if it is not set by the user */
- if(dsc->dtcl_cache_size < 0)
+ if(dsc->dtcl_cache_size < 0)
{
if (ap_max_requests_per_child != 0)
cacheSize = ap_max_requests_per_child / 2;
@@ -934,7 +954,7 @@
mydsc->server_interp = Tcl_CreateSlave(interp, sr->server_hostname, 0);
tcl_create_commands(mydsc->server_interp);
Tcl_SetChannelOption(mydsc->server_interp, achan, "-buffering", "none");
- Tcl_RegisterChannel(mydsc->server_interp, achan);
+ Tcl_RegisterChannel(mydsc->server_interp, achan);
}
mydsc->server_name = ap_pstrdup(p, sr->server_hostname);
sr = sr->next;
@@ -961,7 +981,7 @@
if (arg == NULL || arg2 == NULL)
return "Mod_Dtcl Error: Dtcl_Script requires two arguments";
-
+
objarg = Tcl_NewStringObj(arg2, -1);
Tcl_IncrRefCount(objarg);
Tcl_AppendToObj(objarg, "\n", 1);
@@ -970,11 +990,11 @@
} else if (strcmp(arg, "ChildInitScript") == 0) {
dsc->dtcl_child_init_script = objarg;
} else if (strcmp(arg, "ChildExitScript") == 0) {
- dsc->dtcl_child_exit_script = objarg;
- } else if (strcmp(arg, "BeforeScript") == 0) {
+ dsc->dtcl_child_exit_script = objarg;
+ } else if (strcmp(arg, "BeforeScript") == 0) {
if (ddc == NULL)
- dsc->dtcl_before_script = objarg;
- else
+ dsc->dtcl_before_script = objarg;
+ else
ddc->dtcl_before_script = objarg;
} else if (strcmp(arg, "AfterScript") == 0) {
if (ddc == NULL)
@@ -1026,14 +1046,14 @@
dsc = (dtcl_server_conf *) ap_get_module_config(r->server->module_config, &dtcl_module);
- if (dconf != NULL)
+ if (dconf != NULL)
{
newconfig = (dtcl_server_conf *) ap_pcalloc(r->pool, sizeof(dtcl_server_conf));
ddc = (dtcl_server_conf *) ap_get_module_config(dconf, &dtcl_module);
- newconfig->dtcl_before_script = ddc->dtcl_before_script ? ddc->dtcl_before_script : dsc->dtcl_before_script;
- newconfig->dtcl_after_script = ddc->dtcl_after_script ? ddc->dtcl_after_script : dsc->dtcl_after_script;
+ newconfig->dtcl_before_script = ddc->dtcl_before_script ? ddc->dtcl_before_script : dsc->dtcl_before_script;
+ newconfig->dtcl_after_script = ddc->dtcl_after_script ? ddc->dtcl_after_script : dsc->dtcl_after_script;
newconfig->dtcl_error_script = ddc->dtcl_error_script ? ddc->dtcl_error_script : dsc->dtcl_error_script;
-
+
return newconfig;
}
return dsc;
@@ -1071,9 +1091,9 @@
#if 0 /* this stuff should only be done once at the top level */
dsc->dtcl_global_init_script = overrides->dtcl_global_init_script ? overrides->dtcl_global_init_script : base->dtcl_global_init_script;
- dsc->dtcl_child_init_script = overrides->dtcl_child_init_script ? overrides->dtcl_child_init_script : base->dtcl_child_init_script;
+ dsc->dtcl_child_init_script = overrides->dtcl_child_init_script ? overrides->dtcl_child_init_script : base->dtcl_child_init_script;
- dsc->dtcl_child_exit_script = overrides->dtcl_child_exit_script ? overrides->dtcl_child_exit_script : base->dtcl_child_exit_script;
+ dsc->dtcl_child_exit_script = overrides->dtcl_child_exit_script ? overrides->dtcl_child_exit_script : base->dtcl_child_exit_script;
dsc->dtcl_cache_size = overrides->dtcl_cache_size ? overrides->dtcl_cache_size : base->dtcl_cache_size;
#endif
@@ -1085,7 +1105,7 @@
dsc->dtcl_error_script = overrides->dtcl_error_script ? overrides->dtcl_error_script : base->dtcl_error_script;
- dsc->server_name = overrides->server_name ? overrides->server_name : base->server_name;
+ dsc->server_name = overrides->server_name ? overrides->server_name : base->server_name;
return dsc;
}
@@ -1101,7 +1121,7 @@
sr = s;
while(sr)
- {
+ {
dsc = (dtcl_server_conf *) ap_get_module_config(sr->module_config, &dtcl_module);
if (dsc->dtcl_child_init_script != NULL)
if (Tcl_EvalObjEx(dsc->server_interp, dsc->dtcl_child_init_script, 0) != TCL_OK)
1.6 +4 -0 tcl-moddtcl/mod_dtcl.h
Index: mod_dtcl.h
===================================================================
RCS file: /home/cvs/tcl-moddtcl/mod_dtcl.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- mod_dtcl.h 2001/06/11 14:55:03 1.5
+++ mod_dtcl.h 2001/06/21 17:47:11 1.6
@@ -38,6 +38,10 @@
'var' command. */
#define USE_ONLY_VAR_COMMAND 0
+/* Turn off 'old-style' $UPLOAD variable, and use only the 'upload'
+ command. */
+#define USE_ONLY_UPLOAD_COMMAND 0
+
/* End Configuration options */
#define STARTING_SEQUENCE "<?"
1.9 +179 -7 tcl-moddtcl/tcl_commands.c
Index: tcl_commands.c
===================================================================
RCS file: /home/cvs/tcl-moddtcl/tcl_commands.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- tcl_commands.c 2001/06/11 14:55:04 1.8
+++ tcl_commands.c 2001/06/21 17:47:12 1.9
@@ -16,6 +16,7 @@
#include "apache_cookie.h"
#include "mod_dtcl.h"
+#define BUFSZ 4096
extern request_rec *global_rr;
extern obuff obuffer;
@@ -23,6 +24,8 @@
extern int buffer_output;
extern int headers_printed;
extern int cacheFreeSize;
+extern int upload_files_to_var;
+extern Tcl_Obj *uploadstorage[];
extern ApacheRequest *global_req;
@@ -63,7 +66,7 @@
{
Tcl_Channel fd;
int sz;
- char buf[2000];
+ char buf[BUFSZ];
if (objc != 2)
{
@@ -81,8 +84,8 @@
Tcl_SetChannelOption(interp, fd, "-translation", "lf");
}
/* print_headers(global_rr);
- flush_output_buffer(global_rr); */
- while ((sz = Tcl_Read(fd, buf, sizeof(buf) - 1)))
+ flush_output_buffer(global_rr); */
+ while ((sz = Tcl_Read(fd, buf, BUFSZ - 1)))
{
if (sz == -1)
{
@@ -96,7 +99,7 @@
it, depending on buffering */
memwrite(&obuffer, buf, sz);
- if (sz < sizeof(buf) - 1)
+ if (sz < BUFSZ - 1)
break;
}
return Tcl_Close(interp,fd);
@@ -372,7 +375,7 @@
Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("USER_NAME", -1), STRING_TO_UTF_TO_OBJ(ap_pstrdup(global_rr->pool, pw->pw_name)), 0);
else
Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("USER_NAME", -1),
- STRING_TO_UTF_TO_OBJ(ap_psprintf(global_rr->pool, "user#%lu", (unsigned long) global_rr->finfo.st_uid)), 0);
+ STRING_TO_UTF_TO_OBJ(ap_psprintf(global_rr->pool, "user#%lu", (unsigned long) global_rr->finfo.st_uid)), 0);
#endif
if ((t = strrchr(global_rr->filename, '/')))
@@ -454,7 +457,7 @@
Tcl_WrongNumArgs(interp, 1, objv, "(get varname|list varname|exists varname|names|number|all)");
return TCL_ERROR;
}
- command = Tcl_GetStringFromObj(objv[1], NULL);
+ command = Tcl_GetString(objv[1]);
if (!strcmp(command, "get"))
{
@@ -603,6 +606,175 @@
return TCL_OK;
}
+/*
+upload get XYZ
+ channel # returns channel
+ save (name) # returns name?
+ data # returns data
+
+with the third one reporting an error if this hasn't been enabled, or
+the first two if it has.
+
+upload info XYZ
+
+ exists
+ size
+ type
+ filename
+
+upload names
+
+gets all the upload names.
+*/
+
+int Upload(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
+{
+ char *command = NULL;
+ Tcl_Obj *result = NULL;
+ ApacheUpload *upload;
+
+ if (objc < 2 || objc > 5)
+ {
+ Tcl_WrongNumArgs(interp, 1, objv, "get ...|info ...|names");
+ return TCL_ERROR;
+ }
+ command = Tcl_GetString(objv[1]);
+
+ if (!strcmp(command, "get"))
+ {
+ char *varname = NULL;
+ if (objc < 4)
+ {
+ Tcl_WrongNumArgs(interp, 2, objv, "varname channel|save filename|var varname");
+ return TCL_ERROR;
+ }
+ varname = Tcl_GetString(objv[2]);
+ upload = ApacheUpload_find(global_req->upload, varname);
+ if (upload != NULL) /* make sure we have an upload */
+ {
+ Tcl_Channel chan;
+ char *method = Tcl_GetString(objv[3]);
+ if (!strcmp(method, "channel"))
+ {
+ if (ApacheUpload_FILE(upload) != NULL)
+ {
+ /* create and return a file channel */
+ char *channelname = NULL;
+ chan = Tcl_MakeFileChannel((ClientData *)fileno(
+ ApacheUpload_FILE(upload)), TCL_READABLE);
+ Tcl_RegisterChannel(interp, chan);
+ channelname = Tcl_GetChannelName(chan);
+ result = Tcl_NewStringObj(channelname, -1);
+ }
+ } else if (!strcmp(method, "save")) {
+ /* save data to a specified filename */
+
+ int sz;
+ char savebuffer[BUFSZ];
+ Tcl_Channel savechan = NULL;
+ Tcl_Channel chan = NULL;
+ if (objc != 5)
+ {
+ Tcl_WrongNumArgs(interp, 4, objv, "filename");
+ return TCL_ERROR;
+ }
+
+ savechan = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[4]), "w", 0600);
+ if (savechan == NULL)
+ return TCL_ERROR;
+ else
+ Tcl_SetChannelOption(interp, savechan, "-translation", "binary");
+
+ chan = Tcl_MakeFileChannel((ClientData *)fileno(
+ ApacheUpload_FILE(upload)), TCL_READABLE);
+ Tcl_SetChannelOption(interp, chan, "-translation", "binary");
+
+ while ((sz = Tcl_Read(chan, savebuffer, BUFSZ)))
+ {
+ if (sz == -1)
+ {
+ Tcl_AddErrorInfo(interp, Tcl_PosixError(interp));
+ return TCL_ERROR;
+ }
+
+ Tcl_Write(savechan, savebuffer, sz);
+ if (sz < 4096)
+ break;
+ }
+ Tcl_Close(interp, savechan);
+ result = Tcl_NewIntObj(1);
+ } else if (!strcmp(method, "data")) {
+ /* this sucks - we should use the hook, but I want to
+ get everything fixed and working first */
+ if (upload_files_to_var)
+ {
+ char *bytes = NULL;
+ Tcl_Channel chan = NULL;
+
+ bytes = Tcl_Alloc(ApacheUpload_size(upload));
+ chan = Tcl_MakeFileChannel((ClientData *)fileno(
+ ApacheUpload_FILE(upload)), TCL_READABLE);
+ Tcl_SetChannelOption(interp, chan, "-translation", "binary");
+ Tcl_SetChannelOption(interp, chan, "-encoding", "binary");
+ /* put data in a variable */
+ result = Tcl_NewObj();
+ Tcl_ReadChars(chan, result, ApacheUpload_size(upload), 0);
+ } else {
+ Tcl_AppendResult(interp, "Dtcl_UploadFilesToVar is not set", NULL);
+ return TCL_ERROR;
+ }
+ }
+ Tcl_SetObjResult(interp, result);
+ } else {
+ /* no variable found */
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("", -1));
+ }
+ } else if (!strcmp(command, "info")) {
+ char *varname = NULL;
+ char *infotype = NULL;
+ if (objc != 4)
+ {
+ Tcl_WrongNumArgs(interp, 2, objv, "varname exists|size|type|filename");
+ return TCL_ERROR;
+ }
+ varname = Tcl_GetString(objv[2]);
+ infotype = Tcl_GetString(objv[3]);
+
+ upload = ApacheUpload_find(global_req->upload, varname);
+ if (upload != NULL)
+ {
+ if (!strcmp(infotype, "exists"))
+ {
+ result = Tcl_NewIntObj(1);
+ } else if (!strcmp(infotype, "size")) {
+ result = Tcl_NewIntObj(ApacheUpload_size(upload));
+ } else if (!strcmp(infotype, "type")) {
+ char *type = NULL;
+ type = (char *)ApacheUpload_type(upload);
+ if (type)
+ result = Tcl_NewStringObj(type, -1);
+ else
+ result = Tcl_NewStringObj("", -1);
+ } else if (!strcmp(infotype, "filename")) {
+ result = Tcl_NewStringObj(upload->filename, -1);
+ } else {
+ Tcl_AddErrorInfo(interp, "unknown upload info command");
+ return TCL_ERROR;
+ }
+ } else {
+ if (!strcmp(infotype, "exists")) {
+ result = Tcl_NewIntObj(0);
+ } else {
+ Tcl_AddErrorInfo(interp, "variable doesn't exist");
+ return TCL_ERROR;
+ }
+ }
+ Tcl_SetObjResult(interp, result);
+ }
+ return TCL_OK;
+}
+
+
/* Tcl command to get, and print some information about the current
state of affairs */
@@ -612,7 +784,7 @@
tble = ap_psprintf(global_rr->pool,
"<table border=0 bgcolor=green><tr><td>\n"
"<table border=0 bgcolor=\"#000000\">\n"
- "<tr><td align=center bgcolor=blue><font color=\"#ffffff\" size=+2>dtcl_info</font><br></td></tr>\n"
+ "<tr><td align=center bgcolor=blue><font color=\"#ffffff\" size=\"+2\">dtcl_info</font><br></td></tr>\n"
"<tr><td><font color=\"#ffffff\">Free cache size: %d</font><br></td></tr>\n"
"<tr><td><font color=\"#ffffff\">PID: %d</font><br></td></tr>\n"
"</table>\n"
1.4 +2 -0 tcl-moddtcl/tcl_commands.h
Index: tcl_commands.h
===================================================================
RCS file: /home/cvs/tcl-moddtcl/tcl_commands.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- tcl_commands.h 2001/05/21 19:49:22 1.3
+++ tcl_commands.h 2001/06/21 17:47:12 1.4
@@ -17,6 +17,8 @@
int Var(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+int Upload(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
+
int Dtcl_Info(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
int No_Body(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
1.4 +1 -231 tcl-moddtcl/docs/documentation.txt
Index: documentation.txt
===================================================================
RCS file: /home/cvs/tcl-moddtcl/docs/documentation.txt,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- documentation.txt 2001/05/03 11:49:09 1.3
+++ documentation.txt 2001/06/21 17:47:17 1.4
@@ -1,233 +1,3 @@
-mod_dtcl Documentation
+
- 1) Installation
-
- 1. Check dependencies
- To install mod_dtcl, you will need Tcl 8.2 or greater and Apache
- 1.3.xx. It is known to run on Linux, FreeBSD, OpenBSD, and Solaris
- and HPUX. NT is also possible - please see the directions in the
- distribution.
- 2. Get mod_dtcl
- If you are running a Debian or FreeBSD system, there are pre-built
- packages available at:
- [1]http://www.debian.org/Packages/unstable/web/libapache-mod-dtcl.
- html or [2]http://www.freebsd.org/ports/www.html#mod_dtcl-0.8.1.1.
- Otherwise, download the sources at
- [3]http://tcl.apache.org/mod_dtcl/download/.
- 3. Uncompress the sources
- gunzip apache-1.3.X.tar.gz
- tar -xvf apache-1.3.X.tar.gz
- You don't need the Apache sources if you are building a shared
- object module. You do, however, need the header files. Some
- systems, such as Debian GNU/Linux, provide these independently -
- otherwise, you probably still need the sources.
- gunzip mod_dtcl-X.X.X.tar.gz
- tar -xvf mod_dtcl-X.X.X.tar.gz
- 4. Configuring, builddtcl.sh, etc...
- Do you want to build mod_dtcl as a shared object (such as a .so
- file on Linux, or a .dll on windows), or compile it directly as a
- part of the Apache executable? The Apache Software Foundation has
- put together a nice [4]manual which explains things in detail.
- + For shared objects
- cd ../mod_dtcl/
- Edit the builddtcl.sh script. The 3 variables you may need to
- change are:
- o TCLSH
- Name of the tclsh program on your computer.
- o APACHE
- Location of the Apache sources (for static builds only).
- o INC
- Location of the Apache headers (you will need this even
- for building shared objects).
- ./builddtcl.sh shared
- cp mod_dtcl.so
- /usr/lib/apache/wherever/the/other/shared/objects/reside For
- shared object builds, you need to copy the object into the
- directory where the other shared objects are kept for your
- Apache build. On Debian GNU/Linux systems, for instance, this
- is in /usr/lib/apache/1.3/.
- + For static builds
- cd apache-1.3.X/
- ./configure
- cd ../mod_dtcl/
- Edit the builddtcl.sh script. The 3 variables you may need to
- change are:
- o TCLSH
- Name of the tclsh program on your computer.
- o APACHE
- Location of the Apache sources (for static builds only).
- o INC
- Location of the Apache headers (you will need this even
- for building shared objects).
- ./builddtcl.sh static
- ./builddtcl.sh install
- cd ../apache-1.3.X
- ./configure --activate-module=src/modules/mod_dtcl/mod_dtcl.a
- [ other configure options ]
- export EXTRA_LIBS="-ltcl8.X -lm"
- make -e
- make install
- 5. Configure Apache
- + http.conf
- LoadModule dtcl_module /usr/lib/apache/1.3/mod_dtcl.so
- This points Apache to the shared object if mod_dtcl is being
- used as a loadable module.
- + srm.conf
- AddType application/x-httpd-tcl .ttml
- AddType application/x-dtcl-tcl .tcl (optional)
- These add the .ttml and .tcl (if desired) types to Apache, so
- that they are processed by mod_dtcl.
-
- 2) Apache Directives
-
- * Dtcl_Script GlobalInitScript "script"
- Tcl script that is run when each interpreter is initialized.
- "script" is actual Tcl script, so to run a file, you would do
- Dtcl_Script GlobalInitScript "source /var/www/foobar.tcl".
- * Dtcl_Script ChildInitScript "script"
- Script to be evaluated when each apache child is initialized. This
- is the best place to load modules.
- * Dtcl_Script ChildExitScript "script"
- Script to be evaluated when each apache child exits.
- * Dtcl_Script BeforeScript "script"
- Script to be evaluated before each .ttml page. Note that you
- cannot use hputs in the BeforeScript, but must instead use
- buffer_add.
- * Dtcl_Script AfterScript "script"
- Script to be called after each .ttml page.
- * Dtcl_Script ErrorScript "script"
- This code is called in place of the standard 'error' pages
- generated for mod_dtcl. This directive may be useful if you have
- sensitive logic that you wish to protect.
- * Dtcl_CacheSize cachesize
- Number of ttml scripts to cache as Tcl Objects. Default is
- MaxRequestsPerChild / 2, or 50, if MaxRequestsPerChild is 0.
- * Dtcl_UploadFilesToVar 1/0
- If set to 1, files will be uploaded to the variable UPLOAD(data).
- Be careful with this, as large files could use up your memory.
-
- 3) mod_dtcl specific Tcl commands and variables
-
- * buffer_add string
- Add text to output_buffer for later printing. Used internally.
- * hputs ?-error? text
- The mod_dtcl version of "puts". Outputs to the client, instead of
- to stdout. The error option permits you to send an 'error message'
- to the apache log file, at the NOTICE level.
- * hgetvars
- Get environmental, CGI and Cookie variables. This is in a seperate
- command so as not to make the server do this every time you load a
- .ttml file. ENVS, VARS, and COOKIES are the associative arrays
- created. ENVS contains environmental variables, VARS contains all
- the 'cgi' variables, and COOKIES, any cookies recieved from the
- client.
- * include filename
- Include a file without parsing it. This is the best way to include
- an HTML file or any other static content.
- * parse filename
- "Source" a .ttml file. This is the way to include other .ttml
- files.
- * hflush
- Flush the output buffers to the client. Use this if you want to
- incrementally update a page.
- * headers redirect uri
- Redirect from the current page to a new URI. Must be done in the
- first block of TCL code.
- * headers setcookie -name cookie-name -value cookie-value ?-expires
- date/time? ?-domain domain? ?-path path? ?-secure?
- This command is for setting cookies. Cookie-name is the name of
- the cookie, cookie-value is the data associated with the variable.
- Expires sets an expiration date for the cookie, and must be in the
- format 'DD-Mon-YY HH:MM:SS', path sets the path for which the
- cookie is valid, and secure specifies that the cookie is only to
- be transmitted if the connection is secure (HTTPS).
- * headers type content-type
- This command sets the "Content-type:" header returned by the
- script, which is useful if you wish to create a PNG (image), for
- example, with mod_dtcl.
- * headers set headername value
- Set arbitrary header names and values.
- * dtcl_info
- Prints information on the internals of the module in HTML.
- Currently, only the PID and size of the object cache are reported.
- * Note that these variables may be lists if more than one file is
- uploaded at a time.
- $::request::UPLOAD(filename)
- The filename of the uploaded file.
- $::request::UPLOAD(name)
- The form variable name of the upload.
- $::request::UPLOAD(size)
- The size of the uploaded file.
- $::request::UPLOAD(type)
- The content type of the file upload. Not always available!
- $::request::UPLOAD(channelname)
- The name of a Tcl channel which may be used to manipulate the
- uploaded file. If Dtcl_UploadFilesToVar is set, this variable
- doesn't get created. If no file is passed to the server, this
- variable does not exist! Be sure to check for this.
- $::request::UPLOAD(data)
- Contents of the uploaded file, if Dtcl_UploadFilesToVar is set.
-
- 4) Internals
-
- * Read the code!
- * Initialization
- When Apache is started, (or when child Apache processes are
- started if a threaded Tcl is used), tcl_init_stuff is called,
- which creates a new interpreter, and initializes various things,
- like the apache_channel channel system. The caching system is also
- set up, and if there is a GlobalScript, it is run.
- * Achan/apache_channel
- The "Apache Channel" system was created so that it is possible to
- have an actual Tcl channel that we could redirect standard output
- to. This lets us use, for instance, the regular "puts" command in
- .ttml pages. It works by creating commands that write to memory
- that is slated to be sent to the client.
- * Page parsing/execution
- In send_parsed_file Each .ttml file is loaded and run within its
- own namespace. No new interpreter is created for each page. This
- lets you share variables, and most importantly, loaded modules,
- from a common parent (such as one of the InitScripts). When a file
- is loaded, it is transformed into a Tcl script by putting
- everything outside of <? and ?> into large hputs statements. When
- the script is complete, it is then inserted into the cache, for
- future use. In fact, if the file modification information doesn't
- change, mod_dtcl will execute the cached version of the script the
- next time it is encountered.
- * Binary data
- mod_dtcl is capable of outputing binary data, such as images, or
- loading binary data with 'include'.
-
- 5) Upgrading From Older (< 0.9.3) Versions
-
- * New tags
- As of version 0.9.4, mod_dtcl uses <? and ?> instead of <+ and +>
- to delimit sections of Tcl code. By default, dtcl is still
- compiled with code to parse the <? ?> tags, but it will run faster
- if USE_OLD_TAGS is set to 0 in mod_dtcl.h. You can automatically
- change your .ttml files to the new format by using the newtags.sh
- script in the contrib/ directory. Run it at the top level of your
- DocumentRoot.
- * headers setcookie
- The headers setcookie command now uses the -name and -value flags
- for those arguments, whereas this was not necessary in the past.
-
- 6) Getting Help
-
- * Mailing list
- The mod_dtcl mailing list is the best place to go for help when
- you have problems.
- See the [5]Contact page for information on sending
- mail/subscribing.
- Mailing list archives are also available at
- [6]http://archive.covalent.net, at the bottom of the page.
-
-References
-
- 1. http://www.debian.org/Packages/unstable/web/libapache-mod-dtcl.html
- 2. http://www.freebsd.org/ports/www.html#mod_dtcl-0.8.1.1
- 3. file://localhost/home/davidw/workshop/tcl-moddtcl/docs/download/
- 4. http://httpd.apache.org/docs/dso.html
- 5. http://tcl.apache.org/mod_dtcl/contact.ttml
- 6. http://archive.covalent.net/