formecho.c
#include <stdlib.h>
#include <stdio.h>
#include "cgihelp.h"
void DisplayErrorHTML();
int main() {
int n = 1;
char *key;
char *value;
if ( !InitInput(1000) )
DisplayErrorHTML();
printf("Content-Type: text/html\n\n");
printf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 4.0//EN\">\n\n");
printf("<HTML>\n\n<HEAD>\n");
printf(" <TITLE>Formecho Output</TITLE>\n");
printf("</HEAD>\n\n");
printf("<BODY>\n\n");
printf("<TABLE BORDER=1 CELLPADDING=10px>\n\n");
printf(" <TR>\n");
printf(" <TH>Key</TH>\n\n");
printf(" <TH>Value</HT>\n\n");
printf(" </TR>\n\n");
while ( (key = GetIndexedKey(n)) && (value = GetIndexedValue(n)) ) {
printf(" <TR>\n");
printf(" <TD>%s</TD>\n", key);
printf(" <TD>%s</TD>\n", value);
printf(" </TR>\n\n");
++n;
}
printf("</TABLE>\n\n");
printf("</BODY>\n\n</HTML>\n\n");
FreeCGI();
return 0;
}
void DisplayErrorHTML() {
printf("Content-Type: text/html\n\n");
printf("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 4.0//EN\">\n\n");
printf("<HTML>\n\n<HEAD>\n");
printf(" <TITLE>Formecho Output</TITLE>\n");
printf("</HEAD>\n\n");
printf("<BODY>\n\n");
printf("<H2>Error!</H2>\n\n");
printf("<P>An error has occurred. Please contact the ");
printf("site administrator.\n\n<BR><HR><BR>\n\n");
printf("</BODY>\n\n</HTML>\n");
exit(EXIT_FAILURE);
}
cgihelp.h
#ifndef PG_CGIHELP
#define PG_CGIHELP
#define ERR_BADREQUEST (1)
#define ERR_BADMALLOC (2)
int InitInput (int maxbuffer);
char * GetValue (char *key);
char * GetIndexedValue(int index);
char * GetIndexedKey (int index);
void FreeCGI ();
#endif
cgihelp.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cgihelp.h"
void cleanurl(char *str);
typedef struct varlist {
char *key;
char *value;
struct varlist *next;
} varlist;
varlist* varstart;
int InitInput(int maxbuffer) {
varlist *var;
char *input;
if ( !(input = malloc(sizeof(char) * maxbuffer)) )
return ERR_BADMALLOC;
memset(input, '\0', sizeof(char) * maxbuffer);
if ( !strcmp(getenv("REQUEST_METHOD"), "GET") )
strncpy(input, getenv("QUERY_STRING"), maxbuffer - 1);
else if ( !strcmp(getenv("REQUEST_METHOD"), "POST") )
fgets(input, maxbuffer, stdin);
else
return ERR_BADREQUEST;
if ( ! (varstart = malloc(sizeof(varlist)) ) )
return ERR_BADMALLOC;
var = varstart;
if ( (input = strtok(input, "=")) ) {
while ( var ) {
if ( !(var->key = malloc(sizeof(char) * strlen(input))) )
return ERR_BADMALLOC;
strcpy(var->key, input);
cleanurl(var->key);
input = strtok(NULL, "&");
if ( !(var->value = malloc(sizeof(char) * strlen(input))) )
return ERR_BADMALLOC;
strcpy(var->value, input);
cleanurl(var->value);
if ( (input = strtok(NULL, "=")) ) {
if ( !(var->next = malloc(sizeof(varlist))) )
return ERR_BADMALLOC;
}
else {
var->next = NULL;
}
var = var->next;
}
}
else {
free(varstart);
varstart = NULL;
}
free(input);
return 0;
}
char * GetValue(char *key) {
varlist *var = varstart;
while ( var ) {
if ( !strcmp(key, var->key) )
return var->value;
var = var->next;
}
return NULL;
}
char * GetIndexedKey(int index) {
int n;
varlist *var = varstart;
for ( n = 1; n < index; ++n )
if ( var->next == NULL )
return NULL;
else
var = var->next;
return var->key;
}
char * GetIndexedValue(int index) {
int n;
varlist *var = varstart;
for ( n = 1; n < index; ++n )
if ( var->next == NULL )
return NULL;
else
var = var->next;
return var->value;
}
void FreeCGI() {
varlist *var = varstart;
while ( var ) {
free(var->key);
free(var->value);
var = var->next;
free(varstart);
varstart = var;
}
}
void cleanurl(char *str) {
char asciinum[3] = {0};
int i = 0, c;
while ( str[i] ) {
if ( str[i] == '+' )
str[i] = ' ';
else if ( str[i] == '%' ) {
asciinum[0] = str[i+1];
asciinum[1] = str[i+2];
str[i] = strtol(asciinum, NULL, 16);
c = i+1;
do {
str[c] = str[c+2];
} while ( str[2+(c++)] );
}
++i;
}
}
Please send all comments, suggestions, bug reports etc to mail@paulgriffiths.net