/* -------------------------------------------------------------------------- */
/*
                      NAME : cgi-util.c
               DESCRIPTION : CGI utils to retrieve arguments 

                    AUTHOR : H. Withagen
                    E-MAIL : heini@w4.nl
	          WWW-SITE : http://sparkie.riv.net/w4/index.html
                  CREATION : 21-08-1995
         LAST MODIFICATION : 30-08-1995

*/ 
/* -------------------------------------------------------------------------- */
/*
     Portions developed at the National Center for Supercomputing
     Applications at the University of Illinois at Urbana-Champaign.
*/
/* -------------------------------------------------------------------------- */


#include <stdio.h>
#include <string.h>
#include "cgi-util.h"

#define LF 10
#define CR 13

#define MALLOC_BLOCK_SIZE	128

/* --------------------------------------------------------------------------- */

char *makeword(char *line, char stop) 
{
  int x = 0,y;
  char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));

  for(x = 0; ((line[x]) && (line[x] != stop)); x++)
    word[x] = line[x];

  word[x] = '\0';
  if(line[x]) x++;
  y=0;

  while(line[y++] = line[x++]);
  return word;
}

/* --------------------------------------------------------------------------- */

char *fmakeword(FILE *fp, char stop, int *length) 
{
  int wsize = MALLOC_BLOCK_SIZE, ll = 0;
  char *word = (char *) malloc(sizeof(char) * (wsize + 1));

  while(1) 
  {
    word[ll] = (char)fgetc(fp);
    if(ll == wsize) 
    {
      word[ll+1] = '\0';
      wsize += MALLOC_BLOCK_SIZE;
      word = (char *)realloc(word,sizeof(char)*(wsize+1));
    }
    (*length)--;
    if((word[ll] == stop) || (feof(fp)) || (!(*length))) 
    {
      if(word[ll] != stop) ll++;
      word[ll] = '\0';
      return word;
    }
    ll++;
  }
}

/* --------------------------------------------------------------------------- */

char x2c(char *what) 
{
  register char digit;

  digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0'));
  digit *= 16;
  digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0'));
  return(digit);
}

/* --------------------------------------------------------------------------- */

void unescape_url(char *url) 
{
  register int x,y;

  for(x = 0,y = 0; url[y]; x++, y++) 
  {
    if ( (url[x] = url[y]) == '%') 
    {
      url[x] = x2c(&url[y+1]);
      y+=2;
    }
  }
  url[x] = '\0';
}

/* --------------------------------------------------------------------------- */

void plustospace(char *str) 
{
  register int x;

  for(x=0; str[x]; x++) 
    if(str[x] == '+') str[x] = ' ';
}

/* --------------------------------------------------------------------------- */

/* retrieve arguments from both FORM POST and 
   GET inputs. For the GET input it should be of 
   the form /cgi-bin/progname?name1=val1&name2=val2 */
int retrieve_arguments(struct entry *entries)
{
  register int x,m=0;
  int cl;
  char *line, *line_ptr, *str;

  if (!strcmp((char *)getenv("REQUEST_METHOD"),"POST"))
  {
    cl = atoi((char *)getenv("CONTENT_LENGTH"));

    for(x=0;cl && (!feof(stdin));x++) 
    {
      m=x;
      entries[x].val = fmakeword(stdin,'&',&cl);
      plustospace(entries[x].val);
      unescape_url(entries[x].val);
      entries[x].name = makeword(entries[x].val,'=');
    }
    return m+1;
  }
  else
  {
    line = (char *)malloc(sizeof(char) * (strlen( (char*)getenv("QUERY_STRING") ) + 1));
    str = (char *)malloc(sizeof(char) * (strlen( (char*)getenv("QUERY_STRING") ) + 1));
    strcpy(line, (char*)getenv("QUERY_STRING"));    
    line_ptr = line;
    m = 0;
    x = 0;
    while (*line_ptr)
      if ((*line_ptr) == '&')
      {
        str[x] = '\0';
        entries[m].val = (char *)malloc(sizeof(char) * (strlen(line) + 1));
        strcpy(entries[m++].val, str);
        x = 0;
        line_ptr++;
      }
      else
      {
        str[x++] = *line_ptr;
        line_ptr++;
      }

    str[x] = '\0';
    entries[m].val = (char *)malloc(sizeof(char) * (strlen(line) + 1));
    strcpy(entries[m].val, str);

    for (x=0; x<=m; x++)
    {
      plustospace(entries[x].val);
      unescape_url(entries[x].val);
      entries[x].name = makeword(entries[x].val,'=');
    }
  
    return m+1;
  }

}

/* --------------------------------------------------------------------------- */
