Coder's Guild Mailing List

Re: CGI in C

Posted by Weasel on 1999-04-07

Ng Oon Keat wrote:
> 
> Hi. Yes, thanks for the code. I am not familiar with Perl, so I can't even
> make any modification of the code. I did CGI scripts in C so all the codes
> are written in C. You need any C's code ?

Ok, I've tried to convert my perl code to C. It is not very beautiful
but it should work. note that there exist some real good libs to do that
but if you're intereted in my QuickNDirty implementation of this have a
look:

/*
  Just try to make some C cgi code for you 
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char gethex(char *str) /* the first 2 chars from str are taken */
{
  char value;
  
  if ((*str >= 'A') && (*str <='F')) {value = (*str-'A'+10) * 16;};
  if ((*str >= 'a') && (*str <='f')) {value = (*str-'1'+10) * 16;};
  if ((*str >= '0') && (*str <='9')) {value = (*str-'0'   ) * 16;};

  if ((*(str+1) >= 'A') && (*(str+1) <='F')) {value +=
(*(str+1)-'A'+10);};
  if ((*(str+1) >= 'a') && (*(str+1) <='f')) {value +=
(*(str+1)-'1'+10);};
  if ((*(str+1) >= '0') && (*(str+1) <='9')) {value += (*(str+1)-'0'  
);};

  return value;
}

void decode_block(char *block)
{
  char *name;
  char *value;
  char *tmp;
  char *tmp2;


  name = block;
  if (!(value = strchr(block, '='))) 
    {
      /* That's terrible, the input stream does not have the correct
form!
     Ignore this block!
      */
      return;
    };
  *value = '\0'; /* so the name part is terminated correctly */
  value++;       /* value now points to the correct place    */


  /* Now replace all '+' by ' ' */
  tmp = value;
  while (tmp=strchr(tmp, '+'))
    {
      *tmp = ' ';
    };
  
  /* decode this mime stuff */
  /* i.e. replace all %ab where ab is a hex number with the ascii code
*/

  tmp = value;
  while (tmp=strchr(tmp, '%'))
    {
      if ((((*(tmp+1) >= 'a') && (*(tmp+1) <= 'f')) ||
       ((*(tmp+1) >= 'A') && (*(tmp+1) <= 'F')) ||
       ((*(tmp+1) >= '0') && (*(tmp+1) <= '9'))) &&
      (((*(tmp+2) >= 'a') && (*(tmp+2) <= 'f')) ||
       ((*(tmp+2) >= 'A') && (*(tmp+2) <= 'F')) ||
       ((*(tmp+2) >= '0') && (*(tmp+2) <= '9'))))
    /* then it is a valid hex code */
    {
      
      *tmp = gethex(tmp+1);
      tmp2 = tmp;
      while (*(tmp2+3))
        {
          *(tmp2+1) = *(tmp2+3);
          tmp2++;
        }
      *(tmp2+1)='\0';
      
      
      tmp++;
    }
      else
    {
      /* else: this should not have happened.
         I mean: a % without following valid hex code 
         we will ignore this
      */
      tmp++;
    };
    };


  /* Do YOUR STUFF here */
  /* I simply output the data */
  printf ("name : %s\nvalue: %s\n--\n", name, value);
};

void main()
{
  char *data = 0;
  char *tmp;
  char *tmp2;
  int cnt;

  /* you may really want to put this line to somewhere else
     and change it to your needs. I just need it to demonstrate
     the usage of the gathered data just 10 lives avoce 
  */
  printf ("Content-Type: text/plain\n\n");
  




  if (!(strcmp(getenv("REQUEST_METHOD"), "GET")))
    {
      data = (char *) malloc(strlen(getenv("QUERY_STRING"))+1);
      strcpy(data, getenv("QUERY_STRING"));
    }
    else
      {
    if (getenv("CONTENT_LENGTH"))
      {
        data = (char *) malloc(atoi(getenv("CONTENT_LENGTH"))+1);
        
        /* read stdin into data */
        for (cnt=0; cnt < atoi(getenv("CONTENT_LENGTH")); cnt++)
          {
        *(data+cnt) = getchar();
          }
        
      }
      };
  
  
  printf("Hallo\n%s\n", data );
  
  if (data)
    {
      tmp = data;
      while (tmp2=strchr(tmp,'&')) /* as long as there is more then one
name/value block in the remaining part*/
        {
      *tmp2 = '\0';
      decode_block(tmp);
      tmp = tmp2+1;
    };   
      decode_block(tmp);
      
      free(data);
    };

  printf("done\n");
}


-- 
Weasel                          mailto:palfrader@xxxxxxx.xxx
Peter                   http://www.cosy.sbg.ac.at/~ppalfrad/
------------------------------------------------------------
     We have full klingon console support just in case.
                         -- Alan Cox on linux-kernel