/* -----------------------------------------------------------------------------
* handlers.c
*
* Functions for registering SWIG handler functions. Also includes
* default handlers for various error conditions.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
* Mike Sliczniak (mzsliczn@midway.uchicago.edu)
*
* Copyright (C) 1999-2000. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
static char cvsroot[] = "$Header: /home/pastacvs/cvs-rep/vermicelli/tot/src/SWILL-0.1/Source/SWILL/handlers.c,v 1.1 2005/01/27 08:46:25 dillema Exp $";
#include "swillint.h"
#include <stdarg.h>
static Hash *Handlers = 0;
/* -----------------------------------------------------------------------------
* int swill_handle()
*
* Register a handler function with the server
*
* servname = Document name used by the server (i.e., "foo.html")
* handler = Handler function
* clientdata = Data passed to the handler function
*
* Note: MIME type is guessed from the servname suffix.
*
* The servname may include options before the actual name. For example:
* "stdout:foo.html" indicates that output is going to use standard output
* ----------------------------------------------------------------------------- */
int
swill_handle(const char *servname, SwillHandler handler, void *clientdata) {
Hash *handobj;
const char *actname;
char opt[512] = { 0 };
if (!Handlers) {
Handlers = NewHash();
}
/* Check for options */
actname = strchr(servname,':');
if (actname) {
strncat(opt,servname,actname - servname);
actname++;
} else {
actname = servname;
}
handobj = NewHash();
if (*actname == '/') actname++;
Setattr(handobj,"servname",actname);
Setattr(handobj,"handler",NewVoid((void*)handler,0));
Setattr(handobj,"clientdata",NewVoid(clientdata,0));
Setattr(handobj,"mimetype", swill_guess_mimetype(servname));
if (strcmp(opt,"stdout") == 0) {
SetInt(handobj,"stdout",1);
}
Setattr(Handlers,actname,handobj);
return 0;
}
/* -----------------------------------------------------------------------------
* swill_file()
*
* Serve a registered filename
* ----------------------------------------------------------------------------- */
int
swill_file(const char *url, const char *path)
{
Hash *handobj;
if (!Handlers) {
Handlers = NewHash();
}
handobj = NewHash();
Setattr(handobj,"servname",url);
if (path) {
Setattr(handobj,"filename",path);
} else {
Setattr(handobj,"filename",url);
}
Setattr(handobj,"mimetype",swill_guess_mimetype(url));
Setattr(Handlers,url,handobj);
return 0;
}
/* -----------------------------------------------------------------------------
* swill_remove()
*
* Remove a handler
* ----------------------------------------------------------------------------- */
void
swill_remove(const char *name) {
if (!Handlers) return;
Delattr(Handlers,name);
}
/* -----------------------------------------------------------------------------
* swill_handler_reset()
*
* Reset all of the handlers
* ----------------------------------------------------------------------------- */
void
swill_handler_reset(void) {
Delete(Handlers);
Handlers = 0;
}
/* -----------------------------------------------------------------------------
* swill_handler_lookup()
*
* Look up a handler given a URI
* ----------------------------------------------------------------------------- */
Hash *
swill_handler_lookup(const String *uri) {
if (!Handlers) return 0;
return Getattr(Handlers,uri);
}
/* -----------------------------------------------------------------------------
* SwillFileNotFound()
*
* Report a file not found error to the client.
* ----------------------------------------------------------------------------- */
static char *error404msg = "\n\
<html><head><title>File not found</title></head>\n\
<body bgcolor=\"#ffffff\">\n\
<h1>File not found</h1>\n\
Document '%s' not registered with the server.\n\
Click <a href=\"/info\">here</a> for a list of available documents.\n\n\
</body></html>\n";
int
SwillFileNotFound(DOH *out, void *clientdata) {
swill_setresponse("404 File not found");
swill_setheader("Content-Type","text/html");
Printf(out,error404msg,swill_getvar("__uri__"));
return 0;
}
/* -----------------------------------------------------------------------------
* SwillAuthenticate()
*
* Ask the user to authenticate themselves with a username and password.
* ----------------------------------------------------------------------------- */
static char *error401msg = "\n\
<html><head><title>Unauthorized</title></head>\n\
<body bgcolor=\"#ffffff\">\n\
<h1>Unauthorized</h1>\n\
You don't have access to this document. Sorry.\n\
</body></html>\n";
int
SwillAuthenticate(DOH *out, void *clientdata) {
swill_setresponse("401 Unauthorized");
swill_setheader("Content-Type","text/html");
Printf(out,error401msg);
return 0;
}
/* -----------------------------------------------------------------------------
* SwillUnsupported()
*
* Unsupported HTTP method
* ----------------------------------------------------------------------------- */
static char *error501msg = "\n\
<html><head><title>Not implemented</title></head>\n\
<body bgcolor=\"#ffffff\">\n\
<h1>Not implemented</h1>\n\
The server does not support '%s' requests.\n\
</body></html>\n";
int
SwillUnsupported(DOH *out, void *clientdata) {
swill_setresponse("501 Not Implemented");
swill_setheader("Content-Type","text/html");
Printf(out,error501msg,swill_getvar("__method__"));
return 0;
}
/* -----------------------------------------------------------------------------
* SwillInternalError()
*
* Internal server error.
* ----------------------------------------------------------------------------- */
static char *error500msg = "\n\
<html><head><title>Internal Error</title></head>\n\
<body bgcolor=\"#ffffff\">\n\
<h1>Internal Error</h1>\n\
</plaintext>\n";
int
SwillInternalError(DOH *out, void *clientdata) {
swill_setresponse("500 Internal Error");
swill_setheader("Content-Type","text/html");
Printf(out,error500msg);
return 0;
}
/* -----------------------------------------------------------------------------
* SwillListHandlers()
*
* Print a list of all available handlers.
* ----------------------------------------------------------------------------- */
int
SwillListHandlers(DOH *out, void *clientdata) {
DOH *namelist, *key, *item;
int i;
swill_setheader("Content-Type","text/html");
Printf(out,"<html><head><title>%s</title></head>\n", swill_title(0));
Printf(out,"<body bgcolor=\"#ffffff\">\n");
Printf(out,"<h1>%s</h1>\n", swill_title(0));
Printf(out,"<b>Registered Handlers</b>\n");
Printf(out,"<ul>\n");
namelist = NewList();
for (key = Firstkey(Handlers); key; key = Nextkey(Handlers)) {
Append(namelist,key);
}
/* List_sort(namelist); */
for (i = 0; i < Len(namelist); i++ ) {
item = Getattr(Handlers,Getitem(namelist,i));
Printf(out,"<li> <a href=\"%s\">%s</a>\n", Getattr(item,"servname"),Getattr(item,"servname"));
}
if (Len(namelist) == 0) {
Printf(out,"<li> None\n");
}
Printf(out,"</ul>\n");
/*
if (swill_->docroot) {
Printf(out,"<p><b>Document Root</b>\n");
Printf(out,"<ul>\n");
Printf(out,"<li><a href=\"/\">%s</a>\n", swill_w->docroot);
Printf(out,"</ul>\n");
}
*/
Printf(out,"<hr>\n");
Printf(out,"<em>SWILL %d.%d</em>\n", SWILL_MAJOR_VERSION, SWILL_MINOR_VERSION);
Delete(namelist);
return 0;
}
/* -----------------------------------------------------------------------------
* swill_getvars()
*
* A high level function for grabbing form variables. The user supplies a
* format string that specifies names and conversions. For example:
*
* swill_getvars("s(name)s(email)d(number)", &name, &email, &number)
*
* Returns 0 on failure. 1 on success.
* ----------------------------------------------------------------------------- */
static const char *isolate_name(const char *c, char *t) {
int copy = 0;
while (*c) {
if (*c == '(') {
copy = 1;
c++;
continue;
}
if (*c == ')') {
*t = 0;
return c;
}
if (copy) {
*(t++) = *c;
}
c++;
}
*t = 0;
return c - 1;
}
int
swill_getargs(const char *fmt, ...) {
const char *c;
char name[256];
va_list ap;
int opt = 0;
int code = 0;
char *value = 0;
void *ptr = 0;
va_start(ap,fmt);
c = fmt;
/* Walk the fmt string and get arguments */
while (*c) {
if (*c == '|') {
opt = 1;
c++;
continue;
}
code = *c;
ptr = va_arg(ap, void *);
c = isolate_name(c,name);
value = swill_getvar(name);
if (!value) {
if (!opt) { /* Not optional. Error */
va_end(ap);
return 0;
}
c++;
continue;
}
switch(code) {
case 's': /* String */
*((char **) ptr) = value;
break;
case 'i': /* Integer */
*((int *) ptr) = (int) strtol(value,NULL,0);
break;
case 'l': /* Long */
*((long *) ptr) = atol(value);
break;
case 'h': /* Short */
*((short *) ptr) = (short) strtol(value,NULL,0);
break;
case 'b': /* Byte */
*((char *) ptr) = (char) strtol(value,NULL,0);
break;
case 'I': /* unsigned integer */
*((unsigned int *) ptr) = (unsigned int) strtoul(value, NULL, 0);
break;
case 'L': /* unsigned long */
*((unsigned long *) ptr) = (unsigned long) strtoul(value, NULL, 0);
break;
case 'H': /* unsigned short */
*((unsigned short *) ptr) = (unsigned short) strtoul(value,NULL,0);
break;
case 'B': /* unsigned byte */
*((unsigned char *) ptr) = (unsigned char) strtoul(value,NULL,0);
break;
case 'f': /* Float */
*((float *) ptr) = (float) atof(value);
break;
case 'd': /* Double */
*((double *) ptr) = atof(value);
break;
case 'p':
*((void **) ptr) = (void *) strtoul(value, NULL, 0);
break;
default:
break;
}
c++;
}
va_end(ap);
return 1;
}
void
swill_printurl(FILE *f, const char *url, const char *fmt, ...) {
const char *c;
char name[256];
va_list ap;
int code = 0;
char *svalue;
int ivalue;
unsigned int uivalue;
long lvalue;
unsigned long ulvalue;
double dvalue;
void *ptr = 0;
int first = 1;
va_start(ap,fmt);
fprintf(f,"%s",url);
c = fmt;
if (*c) {
fprintf(f,"?");
}
/* Walk the fmt string and get arguments */
while (*c) {
code = *c;
c = isolate_name(c,name);
if (!first) {
swill_fprintf(f,"&");
}
first = 0;
switch(code) {
case 's': /* String */
svalue = va_arg(ap, char *);
swill_fprintf(f,"%s=%(url)s", name, svalue);
break;
case 'i': /* Integer */
case 'h':
case 'b':
ivalue = va_arg(ap, int);
swill_fprintf(f,"%s=%(url)d", name, ivalue);
break;
case 'l': /* Long */
lvalue = va_arg(ap, long);
swill_fprintf(f,"%s=%(url)ld", name, lvalue);
break;
case 'I': /* unsigned integer */
case 'H':
case 'B':
uivalue = va_arg(ap, unsigned);
swill_fprintf(f,"%s=%(url)u", name, uivalue);
break;
case 'L': /* unsigned long */
ulvalue = va_arg(ap, unsigned long);
swill_fprintf(f,"%s=%(url)ul", name, ulvalue);
break;
case 'f': /* Float */
case 'd':
dvalue = va_arg(ap, double);
swill_fprintf(f,"%s=%(url)0.17f", name, dvalue);
break;
case 'p':
ptr = va_arg(ap, void *);
swill_fprintf(f,"%s=%(url)p", name, ptr);
break;
default:
break;
}
c++;
}
va_end(ap);
return;
}
syntax highlighted by Code2HTML, v. 0.9.1