/ Published in: C
A simple guestbook. Compile c file to exe, put in /cgi-bin/ with txt files. Tested with TinyWeb server found here: http://www.ritlabs.com/en/products/tinyweb/
Expand |
Embed | Plain Text
/**** Beginning of file guestbook.c ****/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <ctype.h> #include <time.h> /* here are the names of data files needed */ char*header="header.txt"; char*guestbook="guestbook.txt"; char*footer="footer.txt"; /* this will hold 0 or a message for the user */ char*msg=0; /* data structure for one cgi parameter */ typedef struct{ char*name; char*value; } Arg; /* prints error message to stdout and commits seppuku */ void err(char*s){ puts("Guestbook has encountered an error!"); 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 1 character from hex*/ char decode(char*s){ return getHex(s[0])*16+getHex(s[1]); } /* to prevent making tags in html */ int safeChar(char c){ switch(c){ case '<': case '>': return 0; } return 1; } /* returns 1 if s points to 2 valid consecutive hex digits */ int isSafe(char*s){ if(!isxdigit(s[0]) || !isxdigit(s[1])) return 0; return 1; } /* decodes hex values, converts + to space, and converts newline to <br> */ 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=='%'&&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(){ } /* gets 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; } /* returns count of variables encoded in 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; } /* returns cgi parameter in array a that has name==s */ char*getArg(Arg*a,char*s){ while(a->name){ if(!strcmp(a->name,s))return fixData(a->value); ++a; } return ""; } /* returns 1 if parameter list has required inputs */ int isValid(Arg*a){ char*s1=getArg(a,"name"); char*s2=getArg(a,"text"); int b=*s1 && *s2; free(s1); free(s2); return b; } /* saves posted message to guestbook data file */ void saveOutput(Arg*a){ FILE*f=fopen(guestbook,"at"); char*s; if(!f)err("Can't save file!"); s=getArg(a,"name"); fprintf(f,"<p><div class=txt><b>%s</b>\n",s); free(s); { time_t rawtime; struct tm*timeinfo; time(&rawtime); timeinfo=localtime(&rawtime); fprintf(f," %s<br><hr>",asctime(timeinfo)); } s=getArg(a,"text"); fprintf(f,"%s",s); free(s); fputs("</div>\n\n",f); fclose(f); } /* prints a file to stdout */ void showFile(char*s){ FILE*f=fopen(s,"rt"); if(f){ while(1){ char c=getc(f); if(c==EOF)break; putchar(c); } fclose(f); } } /* prints whole page to stdout */ void showOutput(){ showFile(header); if(msg)puts(msg); showFile(guestbook); showFile(footer); } int main(){ char*i; Arg*a; init(); i=getInput(); if(i){ a=parseInput(i); if(isValid(a)){ saveOutput(a); msg="Your message has been added!"; }else msg="Invalid input!"; free(i); free(a); } showOutput(a); return 0; } /**** End of file guestbook.c ****/ /**** Beginning of file header.txt ****/ <html><head><title>Guestbook</title><style> body,.txt,input,textarea,button{color:#fff;background-color:#000;font:16px verdana} textarea{width:90%;height:256px} .txt{background-color:#008} .txt{border:1px solid #0f0;padding:4px} </style></head><body> /**** End of file header.txt ****/ /**** Beginning of file footer.txt ****/ <p><form action="guestbook.exe" method=post> <center>Name:<br><input name=name maxlength=32><p> Message:<br><textarea name=text></textarea> <p><input type=submit value="Post"> </form></center></body></html> /**** End of file footer.txt ****/
You need to login to post a comment.
