Listing 3: Utility functions for CGI program
/* File Name: util.c */
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int getnamevalue(char ***name, char ***value)
{
int cl; /* content length */
int i, l1, l2, num=1;
char *qs, *clientinput, *token;
char **nam, **val;
if(!strcmp("POST",getenv("REQUEST_METHOD"))) {
cl = atoi(getenv("CONTENT_LENGTH"));
if(cl == 0)
return 0; /* send nothing */
clientinput = (char*) malloc(sizeof(char)*(cl+1));
fgets(clientinput, cl+1, stdin);
}
else { /* GET */
qs = getenv("QUERY_STRING");
if(qs == NULL)
return 0; /* send nothing */
else {
cl = strlen(qs);
clientinput = (char*)malloc(sizeof(char)*(cl+1));
strcpy(clientinput,qs);
}
}
/* & is the name/value pair separator */
token = strchr(clientinput, '&');
while(token!=NULL) {
num++; /* obtain the total number of pairs */
token++;
token = strchr(token, '&');
}
nam = (char **)malloc(sizeof(char*)*num);
val = (char **)malloc(sizeof(char*)*num);
for (i=0,token=strtok(clientinput, "&");
token!=NULL; i++) {
l1 = strlen(token);
l2 = strcspn(token,"=");
nam[i] = (char *)malloc(sizeof(char) * (l2+1));
strncpy(nam[i], token,l2);
nam[i][l2] = '\0';
unescapechar(nam[i]);
if(l1 != l2+1 ) { /* name=value& */
val[i] = (char *)malloc(sizeof(char) * (l1-l2));
strcpy(val[i], token+l2+1);
unescapechar(val[i]);
}
else /* special case of name=& */
val[i] = NULL;
token=strtok(NULL, "&");
}
free(clientinput);
*name = nam;
*value = val;
return num; /* number of entries */
}
void delnamevalue(char **name,
char **value, int num) {
int i;
if(num==0)
return;
for (i = 0; i<num; i++) {
if(name[i])
free(name[i]);
if(value[i])
free(value[i]);
}
free(name);
free(value);
}
int unescapechar(char *url) {
int x,y;
char hex[3]; /* contains xx of %xx */
for(x=0,y=0;url[y];++x,++y) {
if(url[x] == '+')
url[x] = ' '; /* change '+' to ' ' */
else if(url[x] == '%') {
/* change xx as char */
hex[0] = url[y+1];
hex[1] = url[y+2]; hex[2] = '\0';
url[x] = strtol(hex, NULL, 16);
y+=2; /* three chars %xx as one char */
}
else
url[x] = url[y];
}
url[x] = '\0';
}
/* End of File */