#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_core.h"
#include "http_protocol.h"
#include "http_log.h"
#include "http_main.h"
#include "util_script.h"
#include "http_conf_globals.h"

#include <tcl.h>
#include <string.h>

#include "tcl_commands.h"
#include "apache_request.h"
#include "apache_cookie.h"
#include "mod_dtcl.h"

#define BUFSZ 4096

extern module dtcl_module;

extern Tcl_Obj *uploadstorage[];

#define POOL (globals->r->pool)

/* Make a self-referencing URL  */

int MakeURL(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);

    if (objc != 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "filename");
	return TCL_ERROR;
    }
    Tcl_SetResult(interp, ap_construct_url(POOL, Tcl_GetString(objv[1]), globals->r), NULL);
    return TCL_OK;
}

/* Include and parse a file */

int Parse(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *filename;
    struct stat finfo;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (objc != 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "filename");
	return TCL_ERROR;
    }

    filename = Tcl_GetStringFromObj (objv[1], (int *)NULL);
    if (!strcmp(filename, globals->r->filename))
    {
	Tcl_AddErrorInfo(interp, "Cannot recursively call the same file!");
	return TCL_ERROR;
    }

    if (stat(filename, &finfo))
    {
	Tcl_AddErrorInfo(interp, Tcl_PosixError(interp));
	return TCL_ERROR;
    }
    if (get_parse_exec_file(globals->r, dsc, filename, 0) == TCL_OK)
	return TCL_OK;
    else
	return TCL_ERROR;
}

/* Tcl command to include flat files */

int Include(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    Tcl_Channel fd;
    int sz;
    char buf[BUFSZ];
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc =
	(dtcl_server_conf *)ap_get_module_config(globals->r->server->module_config,
						 &dtcl_module);
    Tcl_Obj *outobj;

    if (objc != 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "filename");
	return TCL_ERROR;
    }

    fd = Tcl_OpenFileChannel(interp,
			     Tcl_GetStringFromObj(objv[1], (int *)NULL), "r", 0664);

    if (fd == NULL)
    {
        return TCL_ERROR;
    } else {
	Tcl_SetChannelOption(interp, fd, "-translation", "lf");
    }
/*     print_headers(globals->r);
       flush_output_buffer(globals->r);  */

    outobj = Tcl_NewObj();
    Tcl_IncrRefCount(outobj);
    while ((sz = Tcl_ReadChars(fd, outobj, BUFSZ - 1, 0)))
    {
	if (sz == -1)
	{
	    Tcl_AddErrorInfo(interp, Tcl_PosixError(interp));
	    Tcl_DecrRefCount(outobj);
	    return TCL_ERROR;
	}

	buf[sz] = '\0';

        /* we could include code to either ap_pwrite this or memwrite
           it, depending on buffering */
	Tcl_WriteObj(*(dsc->outchannel), outobj);

	if (sz < BUFSZ - 1)
	    break;
    }
    Tcl_DecrRefCount(outobj);
    return Tcl_Close(interp, fd);
}

/* Command to *only* add to the output buffer */

int Buffer_Add(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (objc < 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "string");
	return TCL_ERROR;
    }
    Tcl_WriteObj(*(dsc->outchannel), objv[1]);
    *(dsc->content_sent) = 0;
    return TCL_OK;
}

/* Tcl command to output some text to the web server  */

int Hputs(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *arg1;
    int length;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (objc < 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "?-error? string");
	return TCL_ERROR;
    }

    arg1 = Tcl_GetStringFromObj(objv[1], &length);

    if (!strncmp("-error", arg1, 6))
    {
	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 1, objv, "?-error? string");
	    return TCL_ERROR;
	}
	ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_NOTICE,
		     globals->r->server, "Mod_Dtcl Error: %s",
		     Tcl_GetStringFromObj (objv[2], (int *)NULL));
    } else {
	Tcl_DString outstring;
	if (objc != 2)
	{
	    Tcl_WrongNumArgs(interp, 1, objv, "?-error? string");
	    return TCL_ERROR;
	}
	/* transform it from UTF to External representation */
	Tcl_UtfToExternalDString(NULL, arg1, length, &outstring);
 	arg1 = Tcl_DStringValue(&outstring);
	length = Tcl_DStringLength(&outstring);
	if (*(dsc->buffer_output) == 1)
	{
	    Tcl_DStringAppend(dsc->buffer, arg1, length);
	} else {
	    print_headers(globals->r);
	    flush_output_buffer(globals->r);
	    ap_rwrite(arg1, length, globals->r);
	}
	Tcl_DStringFree(&outstring);
    }

    return TCL_OK;
}

/* Tcl command to manipulate headers */

int Headers(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *opt;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (objc < 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }
    if (*(dsc->headers_printed) != 0)
    {
	Tcl_AddObjErrorInfo(interp, "Cannot manipulate headers - already sent", -1);
	return TCL_ERROR;
    }
    opt = Tcl_GetStringFromObj(objv[1], NULL);

    if (!strcmp("setcookie", opt)) /* ### setcookie ### */
    {
	int i;
	ApacheCookie *cookie;
	char *stringopts[12] = {NULL, NULL, NULL, NULL, NULL, NULL,
				NULL, NULL, NULL, NULL, NULL, NULL};

	if (objc < 4 || objc > 14)
	{
	    Tcl_WrongNumArgs(interp, 2, objv,
			     "-name cookie-name -value cookie-value ?-expires expires? ?-domain domain? ?-path path? ?-secure on/off?");
	    return TCL_ERROR;
	}

	/* SetCookie: foo=bar; EXPIRES=DD-Mon-YY HH:MM:SS; DOMAIN=domain; PATH=path; SECURE */

	for (i = 0; i < objc - 2; i++)
	{
	    stringopts[i] = Tcl_GetString(objv[i + 2]);
	}
	cookie = ApacheCookie_new(globals->r,
				  stringopts[0], stringopts[1],
				  stringopts[2], stringopts[3],
				  stringopts[4], stringopts[5],
				  stringopts[6], stringopts[7],
				  stringopts[8], stringopts[9],
				  stringopts[10], stringopts[11],
				  NULL);
	ApacheCookie_bake(cookie);
    }
    else if (!strcmp("redirect", opt)) /* ### redirect ### */
    {
	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "new-url");
	    return TCL_ERROR;
	}
	ap_table_set(globals->r->headers_out, "Location",
		     Tcl_GetStringFromObj (objv[2], (int *)NULL));
	globals->r->status = 301;
	return TCL_RETURN;
    }
    else if (!strcmp("set", opt)) /* ### set ### */
    {
	if (objc != 4)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "headername value");
	    return TCL_ERROR;
	}
	ap_table_set(globals->r->headers_out,
		     Tcl_GetStringFromObj (objv[2], (int *)NULL),
		     Tcl_GetStringFromObj (objv[3], (int *)NULL));
    }
    else if (!strcmp("type", opt)) /* ### set ### */
    {
	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "mime/type");
	    return TCL_ERROR;
	}
	set_header_type(globals->r, Tcl_GetStringFromObj(objv[2], (int *)NULL));
    } else if (!strcmp("numeric", opt)) /* ### numeric ### */
    {
	int st = 200;

	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "response code");
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[2], &st) != TCL_ERROR)
	    globals->r->status = st;
	else
	    return TCL_ERROR;
    } else {
	/* XXX	Tcl_WrongNumArgs(interp, 1, objv, "headers option arg ?arg ...?");  */
	return TCL_ERROR;
    }
    return TCL_OK;
}

/* turn buffering on and off */

int Buffered(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *opt = NULL;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (objc != 2)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "on/off");
	return TCL_ERROR;
    }
    opt = Tcl_GetStringFromObj(objv[1], NULL);
    if (!strncmp(opt, "on", 2))
    {
	*(dsc->buffer_output) = 1;
    } else if (!strncmp(opt, "off", 3)) {
	*(dsc->buffer_output) = 0;
	print_headers(globals->r);
	flush_output_buffer(globals->r);
    } else {
	return TCL_ERROR;
    }
    return TCL_OK;
}
/* Tcl command to flush the output stream */

int HFlush(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);

    if (objc != 1)
    {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    print_headers(globals->r);
    flush_output_buffer(globals->r);
    ap_rflush(globals->r);
    return TCL_OK;
}

/* Tcl command to get and parse any CGI and environmental variables */

/* Get the environmental variables, but do it from a tcl function, so
   we can decide whether we wish to or not */

int HGetVars(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *timefmt = DEFAULT_TIME_FORMAT;
#ifndef WIN32
    struct passwd *pw;
#endif /* ndef WIN32 */
    char *t;
    char *authorization = NULL;

    time_t date;

    int i;

    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);

    array_header *hdrs_arr;
    table_entry *hdrs;
    array_header *env_arr;
    table_entry  *env;
    Tcl_Obj *EnvsObj = NULL;

    EnvsObj = Tcl_NewStringObj("::request::ENVS", -1);
    Tcl_IncrRefCount(EnvsObj);
    date = globals->r->request_time;
    /* ensure that the system area which holds the cgi variables is empty */
    ap_clear_table(globals->r->subprocess_env);

    /* retrieve cgi variables */
    ap_add_cgi_vars(globals->r);
    ap_add_common_vars(globals->r);

    hdrs_arr = ap_table_elts(globals->r->headers_in);
    hdrs = (table_entry *) hdrs_arr->elts;

    env_arr =  ap_table_elts(globals->r->subprocess_env);
    env     = (table_entry *) env_arr->elts;

    /* Get the user/pass info for Basic authentication */
    (const char*)authorization = ap_table_get(globals->r->headers_in, "Authorization");
    if (authorization && !strcasecmp(ap_getword_nc(POOL, &authorization, ' '), "Basic"))
    {
	char *tmp;
	char *user;
	char *pass;

	tmp = ap_pbase64decode(POOL, authorization);
	user = ap_getword_nulls_nc(POOL, &tmp, ':');
	pass = tmp;
 	Tcl_ObjSetVar2(interp, Tcl_NewStringObj("::request::USER", -1),
		       Tcl_NewStringObj("user", -1),
		       STRING_TO_UTF_TO_OBJ(user, POOL),
		       0);
 	Tcl_ObjSetVar2(interp, Tcl_NewStringObj("::request::USER", -1),
		       Tcl_NewStringObj("pass", -1),
		       STRING_TO_UTF_TO_OBJ(pass, POOL),
		       0);
    }

    /* These were the "include vars"  */
    Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("DATE_LOCAL", -1),
		   STRING_TO_UTF_TO_OBJ(ap_ht_time(POOL, date, timefmt, 0), POOL), 0);
    Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("DATE_GMT", -1),
		   STRING_TO_UTF_TO_OBJ(ap_ht_time(POOL, date, timefmt, 1), POOL), 0);
    Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("LAST_MODIFIED", -1),
		   STRING_TO_UTF_TO_OBJ(ap_ht_time(POOL, globals->r->finfo.st_mtime, timefmt, 0), POOL), 0);
    Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("DOCUMENT_URI", -1),
		   STRING_TO_UTF_TO_OBJ(globals->r->uri, POOL), 0);
    Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("DOCUMENT_PATH_INFO", -1),
		   STRING_TO_UTF_TO_OBJ(globals->r->path_info, POOL), 0);

#ifndef WIN32
    pw = getpwuid(globals->r->finfo.st_uid);
    if (pw)
	Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("USER_NAME", -1),
		       STRING_TO_UTF_TO_OBJ(ap_pstrdup(POOL, pw->pw_name), POOL), 0);
    else
	Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("USER_NAME", -1),
		       STRING_TO_UTF_TO_OBJ(
			   ap_psprintf(POOL, "user#%lu",
				       (unsigned long) globals->r->finfo.st_uid), POOL), 0);
#endif

    if ((t = strrchr(globals->r->filename, '/')))
	Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("DOCUMENT_NAME", -1),
		       STRING_TO_UTF_TO_OBJ(++t, POOL), 0);
    else
	Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("DOCUMENT_NAME", -1),
		       STRING_TO_UTF_TO_OBJ(globals->r->uri, POOL), 0);

    if (globals->r->args)
    {
	char *arg_copy = ap_pstrdup(POOL, globals->r->args);
	ap_unescape_url(arg_copy);
	Tcl_ObjSetVar2(interp, EnvsObj, Tcl_NewStringObj("QUERY_STRING_UNESCAPED", -1),
		       STRING_TO_UTF_TO_OBJ(ap_escape_shell_cmd(POOL, arg_copy), POOL), 0);
    }

    /* ----------------------------  */

    /* transfer client request headers to TCL request namespace */
    for (i = 0; i < hdrs_arr->nelts; ++i)
    {
	if (!hdrs[i].key)
	    continue;
	else {
	    Tcl_ObjSetVar2(interp, EnvsObj, STRING_TO_UTF_TO_OBJ(hdrs[i].key, POOL),
			   STRING_TO_UTF_TO_OBJ(hdrs[i].val, POOL), 0);
	}
    }

    /* transfer apache internal cgi variables to TCL request namespace */
    for (i = 0; i < env_arr->nelts; ++i)
    {
	if (!env[i].key)
	    continue;
	Tcl_ObjSetVar2(interp, EnvsObj, STRING_TO_UTF_TO_OBJ(env[i].key, POOL),
		       STRING_TO_UTF_TO_OBJ(env[i].val, POOL), 0);
    }

    do { /* I do this because I want some 'local' variables */
	ApacheCookieJar *cookies = ApacheCookie_parse(globals->r, NULL);
	Tcl_Obj *cookieobj = Tcl_NewStringObj("::request::COOKIES", -1);

	for (i = 0; i < ApacheCookieJarItems(cookies); i++) {
	    ApacheCookie *c = ApacheCookieJarFetch(cookies, i);
	    int j;
	    for (j = 0; j < ApacheCookieItems(c); j++) {
		char *name = c->name;
		char *value = ApacheCookieFetch(c, j);
		Tcl_ObjSetVar2(interp, cookieobj,
			       Tcl_NewStringObj(name, -1),
			       Tcl_NewStringObj(value, -1), 0);
/* 			       STRING_TO_UTF_TO_OBJ(name, POOL),
			       STRING_TO_UTF_TO_OBJ(value, POOL), 0);  */
	    }

	}
    } while (0);

    /* cleanup system cgi variables */
    ap_clear_table(globals->r->subprocess_env);

    return TCL_OK;
}

/* Tcl command to return a particular variable.  */

/* Use:
   var get foo
   var list foo
   var names
   var number
   var all
  */

int Var(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *command;
    int i;
    Tcl_Obj *result = NULL;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    array_header *parmsarray = ap_table_elts(globals->req->parms);
    table_entry *parms = (table_entry *)parmsarray->elts;

    if (objc < 2 || objc > 3)
    {
	Tcl_WrongNumArgs(interp, 1, objv,
			 "(get varname|list varname|exists varname|names|number|all)");
	return TCL_ERROR;
    }
    command = Tcl_GetString(objv[1]);

    if (!strcmp(command, "get"))
    {
	char *key = NULL;
	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "variablename");
	    return TCL_ERROR;
	}
	key = Tcl_GetStringFromObj(objv[2], NULL);

        /* This isn't real efficient - move to hash table later
           on... */
	for (i = 0; i < parmsarray->nelts; ++i)
	{
	    if (!strncmp(key, StringToUtf(parms[i].key, POOL),
			 strlen(key) < strlen(parms[i].key) ?
			 strlen(parms[i].key) : strlen(key)))
	    {
		/* The following makes sure that we get one string,
                   with no sub lists. */
		if (result == NULL)
		{
		    result = STRING_TO_UTF_TO_OBJ(parms[i].val, POOL);
		    Tcl_IncrRefCount(result);
		} else {
		    Tcl_Obj *tmpobjv[2];
		    tmpobjv[0] = result;
		    tmpobjv[1] = STRING_TO_UTF_TO_OBJ(parms[i].val, POOL);
		    result = Tcl_ConcatObj(2, tmpobjv);
		}
	    }
	}

	if (result == NULL)
	    Tcl_AppendResult(interp, "", NULL);
	else
	    Tcl_SetObjResult(interp, result);
    } else if(!strcmp(command, "exists")) {
	char *key;
	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "variablename");
	    return TCL_ERROR;
	}
	key = Tcl_GetString(objv[2]);

        /* This isn't real efficient - move to hash table later on. */
	for (i = 0; i < parmsarray->nelts; ++i)
	{
	    if (!strncmp(key, StringToUtf(parms[i].key, POOL),
			 strlen(key) < strlen(parms[i].key) ?
			 strlen(parms[i].key) : strlen(key)))
	    {
		result = Tcl_NewIntObj(1);
		Tcl_IncrRefCount(result);
	    }
	}

	if (result == NULL)
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
	else
	    Tcl_SetObjResult(interp, result);

    } else if(!strcmp(command, "list")) {
	char *key;
	if (objc != 3)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, "variablename");
	    return TCL_ERROR;
	}
	key = Tcl_GetStringFromObj(objv[2], NULL);

        /* This isn't real efficient - move to hash table later on. */
	for (i = 0; i < parmsarray->nelts; ++i)
	{
	    if (!strncmp(key, StringToUtf(parms[i].key, POOL), 
			 strlen(key) < strlen(parms[i].key) ?
			 strlen(parms[i].key) : strlen(key)))
	    {
		if (result == NULL)
		{
		    result = Tcl_NewObj();
		    Tcl_IncrRefCount(result);
		}
		Tcl_ListObjAppendElement(interp, result,
					 STRING_TO_UTF_TO_OBJ(parms[i].val, POOL));
	    }
	}

	if (result == NULL)
	    Tcl_AppendResult(interp, "", NULL);
	else
	    Tcl_SetObjResult(interp, result);
    } else if(!strcmp(command, "names")) {
	if (objc != 2)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	result = Tcl_NewObj();
	Tcl_IncrRefCount(result);
	for (i = 0; i < parmsarray->nelts; ++i)
	{
	    Tcl_ListObjAppendElement(interp, result,
				     STRING_TO_UTF_TO_OBJ(parms[i].key, POOL));
	}

	if (result == NULL)
	    Tcl_AppendResult(interp, "", NULL);
	else
	    Tcl_SetObjResult(interp, result);

    } else if(!strcmp(command, "number")) {
	if (objc != 2)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}

	result = Tcl_NewIntObj(parmsarray->nelts);
	Tcl_IncrRefCount(result);
	Tcl_SetObjResult(interp, result);
    } else if(!strcmp(command, "all")) {
	if (objc != 2)
	{
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	result = Tcl_NewObj();
	Tcl_IncrRefCount(result);
	for (i = 0; i < parmsarray->nelts; ++i)
	{
	    Tcl_ListObjAppendElement(interp, result,
				     STRING_TO_UTF_TO_OBJ(parms[i].key, POOL));
	    Tcl_ListObjAppendElement(interp, result,
				     STRING_TO_UTF_TO_OBJ(parms[i].val, POOL));
	}

	if (result == NULL)
	    Tcl_AppendResult(interp, "", NULL);
	else
	    Tcl_SetObjResult(interp, result);


    } else {
	/* bad command  */
	Tcl_AddErrorInfo(interp, "bad option: must be one of 'get, list, names, number, all'");
	return TCL_ERROR;
    }

    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;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (objc < 2 || objc > 5)
    {
	Tcl_WrongNumArgs(interp, 1, objv, "get ...|info ...|names");
	return TCL_ERROR;
    }
    command = Tcl_GetString(objv[1]);

    result = Tcl_NewObj();
    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(globals->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);
		    Tcl_SetStringObj(result, 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);
		Tcl_SetIntObj(result, 1);
	    } else if (!strcmp(method, "data")) {
		/* this sucks - we should use the hook, but I want to
                   get everything fixed and working first */
		if (dsc->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  */
		    Tcl_ReadChars(chan, result, ApacheUpload_size(upload), 0);
		} else {
		    Tcl_AppendResult(interp, "Dtcl_UploadFilesToVar is not set", NULL);
		    return TCL_ERROR;
		}
	    }
	} else {
	    /* no variable found  */
	    Tcl_SetStringObj(result, "", -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(globals->req->upload, varname);
	if (upload != NULL)
	{
	    if (!strcmp(infotype, "exists"))
	    {
		Tcl_SetIntObj(result, 1);
	    } else if (!strcmp(infotype, "size")) {
		Tcl_SetIntObj(result, ApacheUpload_size(upload));
	    } else if (!strcmp(infotype, "type")) {
		char *type = NULL;
		type = (char *)ApacheUpload_type(upload);
		if (type)
		    Tcl_SetStringObj(result, type, -1);
		else
		    Tcl_SetStringObj(result, "", -1);
	    } else if (!strcmp(infotype, "filename")) {
		Tcl_SetStringObj(result, StringToUtf(upload->filename, POOL), -1);
	    } else {
		Tcl_AddErrorInfo(interp, "unknown upload info command, should be exists|size|type|filename");
		return TCL_ERROR;
	    }
	} else {
	    if (!strcmp(infotype, "exists")) {
		Tcl_SetIntObj(result, 0);
	    } else {
		Tcl_AddErrorInfo(interp, "variable doesn't exist");
		return TCL_ERROR;
	    }
	}
    } else if (!strcmp(command, "names")) {
	upload = ApacheRequest_upload(globals->req);
	while (upload)
	{
	    Tcl_ListObjAppendElement(interp, result,
				     STRING_TO_UTF_TO_OBJ(upload->name, POOL));
	    upload = upload->next;
	}
    } else {
	Tcl_WrongNumArgs(interp, 1, objv, "upload get|info|names");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}


/* Tcl command to get, and print some information about the current
   state of affairs */

int Dtcl_Info(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
    char *tble;
    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    tble = ap_psprintf(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><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"
		       "</td></tr></table>\n", *(dsc->cache_free), getpid());
/*     print_headers(globals->r);
       flush_output_buffer(globals->r);  */
    Tcl_WriteObj(*(dsc->outchannel), Tcl_NewStringObj(tble, -1));
    return TCL_OK;
}

/* Tcl command to erase body, so that only header is returned.
   Necessary for 304 responses */

int No_Body(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{

    dtcl_interp_globals *globals = Tcl_GetAssocData(interp, "dtcl", NULL);
    dtcl_server_conf *dsc = (dtcl_server_conf *)
	ap_get_module_config(globals->r->server->module_config, &dtcl_module);

    if (*(dsc->content_sent) == 1)
	return TCL_ERROR;

    print_headers(globals->r);
    Tcl_DStringInit(dsc->buffer);
    return TCL_OK;
}
