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