Return to Snippet

Revision: 17272
at August 30, 2009 10:12 by Zufolek


Initial Code
/*
	This CGI program shows all parameters sent to it
	Zufolek 2009
*/


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



/* structure to hold one cgi arg (or parameter)*/
typedef struct{
 char*name;
 char*value;
} Arg;


/* prints error message to stdout and terminates program */
void err(char*s){
 puts("<p>Program has encountered an error:<br>");
 puts(s);
 exit(1);
}


/* returns value of one hex digit */
int getHex(char c){
 if(isdigit(c))return c-'0';
 if(isalpha(c))return tolower(c)-'a'+10;
 return 0;
}


/* decodes a hex value */
char decode(char*s){
 return getHex(s[0])*16+getHex(s[1]);
}


/* prevents making tags in html */
int safeChar(char c){
 switch(c){
  case '<':
  case '>':
  return 0;
 }
 return 1;
}


/* checks if there are valid hex values at specified pointer */
int isSafe(char*s){
 if(!isxdigit(s[0]) || !isxdigit(s[1])) return 0;
 return 1;
}


/* decodes text in parameters */
char*fixData(char*i){
 int l=strlen(i);
 char*m=malloc(l*4+8);
 char*o=m;
 if(!m)err("Memory allocation failure for fixData");
 while(*i){
  if(*i=='+')*o=' ';
  else if(*i=='\n'){
  }else if(*i=='%'&&isSafe(i+1)){
   char d=decode(i+1);
   if(safeChar(d)){
    if(d=='\n')o+=sprintf(o,"<br>")-1;
    else if(d=='\r')--o;
    else *o=d;
   }else o+=sprintf(o,"&#%d;",d)-1;
   i+=2;
  }else *o=*i;
  ++i;
  ++o;
 }
 *o=0;
 m=realloc(m,o-m+1);
 if(!m)err("Memory reallocation failure for fixData");
 return m;
}


/* prints a basic http header to stdout */
void init(){
 printf("Content-Type: text/html\n\n");
}


/* reads input string from stdin */
char*getInput(){
 char*v=getenv("CONTENT_LENGTH");
 char*s=0;
 if(v){
  int l=atoi(v);
  if(l){
   s=malloc(l+1);
   FILE*f=stdin;
   if(!s)err("Memory allocation failure for input");
   fread(s,1,l,f);
   s[l]=0;
  }
 }
 return s;
}


/* Counts the number of parameters in input string */
int countVars(char*s){
 int n=1;
 while(*s){
  if(*s=='&')++n;
  ++s;
 }
 return n;
}


/* Moves pointer-pointer s just past next occurrence of character c,
 which is then set to 0, or returns 1 if end of string is reached */
int skipTo(char**s,char c){
 while(**s != c){
  if(!**s)return 1;
  ++*s;
 }
 **s=0;
 ++*s;
 return 0;
}


/* Parses input string for args */
Arg*parseInput(char*s){
 int l=countVars(s);
 Arg*arg=malloc((l+1)*sizeof(Arg));
 Arg*a=arg;
 if(!a)err("Memory allocation failure for args list");
 while(*s){
  a->name=s;
  if(skipTo(&s,'='))goto Done;
  a->value=s;
  if(skipTo(&s,'&'))goto Done;
  ++a;
 }
 Done:
 arg[l].name=0;/* marks the end of arg list */
 return arg;
}


/* prints all the args to stdout */
void showArgs(Arg*a){
 while(a->name){
  printf("Arg name=%s value=%s<br>\n",a->name,a->value);
  ++a;
 }
}



int main(){
 char*i;
 Arg*a;
 init();
 i=getInput();
 if(i){
  a=parseInput(i);
  showArgs(a);
  free(i);
  free(a);
 }else puts("No input parameters.");
 return 0;
}

Initial URL


Initial Description
Compile, put exe in cgi-bin folder, and post form data to it.

Initial Title
CGI program to show parameters

Initial Tags
c

Initial Language
C