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 */