itsme86 |
03-03-2005 10:53 AM |
I wrote a CGI library in C once. Hopefully this will help you out:
Code:
// cgi.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
typedef struct cgi_opts
{
char *name;
char *val;
struct cgi_opts *next;
} CGIOPT;
static CGIOPT *optlist = NULL;
typedef struct cookie
{
char *name;
char *val;
struct cookie *next;
} COOKIE;
static COOKIE *cookielist = NULL;
static int hex_to_dec(char *str)
{
char vals[] = "0123456789ABCDEF";
unsigned int num;
char *p, *q;
p = strchr(vals, *str);
q = strchr(vals, *(str+1));
if(p && q)
{
num = (p - vals) << 4;
num += q - vals;
}
else
num = 0;
return num;
}
static void cgi_decode(char *str, size_t maxlen)
{
char buf[4096], *p, *b = buf;
for(p = str;*p && b-buf < sizeof(buf)-2;p++, b++)
{
switch(*p)
{
case '+': *b = ' '; break;
case '%': *b = hex_to_dec(p+1); p += 2; break;
default:
*b = *p;
}
}
*b = '\0';
strncpy(str, buf, maxlen);
str[maxlen] = '\0';
}
void get_cgi_opts(void)
{
CGIOPT *opt;
char buf[4096], buf2[4096], *p = buf, *q = buf;
fgets(buf, sizeof(buf), stdin);
if(!*buf)
strncpy(buf, getenv("QUERY_STRING"), sizeof(buf)-1);
while(*p && *p != '\n')
p++;
if(*p == '\n')
*p = '\0';
p = buf;
while((p = strchr(q, '=')))
{
if(!(opt = malloc(sizeof(CGIOPT))))
return;
opt->next = optlist;
optlist = opt;
strncpy(buf2, q, p-q);
buf2[p-q] = '\0';
cgi_decode(buf2, sizeof(buf2));
if(!(opt->name = malloc(strlen(buf2)+1)))
{
optlist = opt->next;
free(opt);
return;
}
strcpy(opt->name, buf2);
p++;
q = strchr(p, '&');
if(!q)
q = p+strlen(p);
strncpy(buf2, p, q-p);
buf2[q-p] = '\0';
cgi_decode(buf2, sizeof(buf2));
if(!(opt->val = malloc(strlen(buf2)+1)))
{
optlist = opt->next;
free(opt->name);
free(opt);
return;
}
strcpy(opt->val, buf2);
if(q)
q++;
}
}
char *opt_val(char *name)
{
CGIOPT *opt;
for(opt = optlist;opt;opt = opt->next)
if(!strcmp(opt->name, name))
return opt->val;
return "";
}
void get_cookies(void)
{
char buf[4096], *p, *q;
COOKIE *c;
if(!(p = getenv("HTTP_COOKIE")))
return;
strcpy(buf, p);
p = buf;
do
{
if(!(c = malloc(sizeof(COOKIE))))
return;
while(isspace(*p))
p++;
if(!(q = strchr(p, '=')))
return;
*q++ = '\0';
if(!(c->name = malloc(q-p)))
{
free(c);
return;
}
strcpy(c->name, p);
p = q;
if(!(q = strchr(p, ';')))
q = p+strlen(p);
*q++ = '\0';
if(!(c->val = malloc(q-p)))
{
free(c->name);
free(c);
return;
}
strcpy(c->val, p);
p = q;
c->next = cookielist;
cookielist = c;
} while(*p);
}
char *cookie_val(char *name)
{
COOKIE *c;
for(c = cookielist;c;c = c->next)
if(!strcmp(c->name, name))
return c->val;
return "";
}
char *cgi_header(char *title)
{
static char buf[4096];
sprintf(buf, "Content-type: text/html\n\n<html>\n");
if(title)
sprintf(buf+strlen(buf), "<title>%s</title>\n", title);
return buf;
}
Code:
// cgi.h
#ifndef CGI_H_
#define CGI_H_
void get_cgi_opts(void);
char *opt_val(char *);
char *cgi_header(char *);
void get_cookies(void);
char *cookie_val(char *);
#endif //CGI_H_
|