/* Name.c Author: Howard Seltman Date: 7 March 2007 Purpose: General html form to text database utility Compile: cc -Wall -ocgiwrite cgiwrite.c CGI names are whatever you want (up to 50 of them) plus "dbname" and optionally "returnURL". Test Usage: echo "a=factor&d=analysis&dbname=mydb.txt" | cgiwrite Debug Usage: #define TESTLINE --- HTML Usage:

Data collection for foobar

Foo information:

Name: Size:

Bar information

Name: Size:

Setup in Unix/Linux (for security reasons): In the cgi directory, edit or create dbPermissions.txt. Each line is the name of a "database" file, then a space, then the maximum number of bytes allowed (to prevent evildoers from overloading your file system). Then create the empty database (say FooBar.txt) with a command like "touch FooBar.txt" followed by "chmod g+w FooBar.txt". For privacy, also do "chmod g-r FooBar.txt". Additional hidden field allowed: will cause IP address of submitter to go into the database. Additional hidden field allowed: will cause a timestamp to go into the database. Additional hidden field allowed: will cause a successful data submission to jump directly to this web page. Change defines below if you want more than 2048 characters total input per form or 512 per field or 50 fields. */ #include #include #include #include #include #include #include #include #include #define LINE_LEN 2048 #define ITEM_LEN 512 #define MAX_FIELDS 50 #define xtod(c) ((c>='0' && c<='9')?c-'0':((tolower(c)>='a' && \ tolower(c)<='f')?tolower(c)-'a'+10:0)) #define DEFAULT_RETURN_URL "http://www.stat.cmu.edu/" #define PERMISSIONS "dbPermissions.txt" #define TIME_MAX 60 /*#define TESTLINE "a=factor&d=analysis&dbname=mydb.txt&Timestamp=TS"*/ int main(int argc, char **argv, char **environ) { char line[LINE_LEN], dbname[LINE_LEN]="", returnURL[LINE_LEN]="", redirect[LINE_LEN]=""; char *atozfields[MAX_FIELDS]; char *pc, *pcr, *pcw, *pcip; int len; FILE *db; int i, itmp, incount=0; int maxbytes=0, filebytes=0, addbytes; struct stat statbuf; struct tm *tmptr; time_t tm; char timestring[TIME_MAX]; /* allocated a to z space */ if ((atozfields[0]=malloc(sizeof(char)*MAX_FIELDS*ITEM_LEN))==0) { printf("Content-type: text/html\n\n"); printf("\n\nError: Can't allocate enough memory.\n<\\body>\n<\\html>\n"); printf("

Stat Home\n", DEFAULT_RETURN_URL); return EXIT_FAILURE; } for (i=0; i\n", pc); } } pc=strtok(0,"&"); } if (returnURL[0]=='\0') { strncpy(returnURL,DEFAULT_RETURN_URL,ITEM_LEN); returnURL[ITEM_LEN-1]='\0'; } if (dbname[0]=='\0') { printf("Content-type: text/html\n\n"); printf("dbname not specified in HTML.\n

\n"); printf("

Return\n", returnURL); return EXIT_FAILURE; } /* Check permissions */ if ((db=fopen(PERMISSIONS,"r"))==NULL) { printf("Content-type: text/html\n\n"); printf("Error: Can't open permissions file.\n

\n"); printf("

Return\n", returnURL); return EXIT_FAILURE; } len=strlen(dbname); while (!feof(db)) { if (fgets(line, LINE_LEN, db)==0) break; if (strncmp(dbname,line,len)!=0) continue; if (strlen(line)\n", dbname); printf("

Return\n", returnURL); return EXIT_FAILURE; } /* Check length (and existence) of output db */ i=stat(dbname, &statbuf); if (i!=0) { if (errno != ENOENT) { printf("Content-type: text/html\n\n"); printf("Error: No permission to write file %s.\n

\n", dbname); printf("

Return\n", returnURL); return EXIT_FAILURE; } } else { filebytes=(int)statbuf.st_size; } if (filebytes>maxbytes) { printf("Content-type: text/html\n\n"); printf("Error: database %s is full.\n

\n", dbname); printf("

Return\n", returnURL); return EXIT_FAILURE; } /* Open db */ if ((db=fopen(dbname,"a"))==NULL) { printf("Content-type: text/html\n\n"); printf("Error: Can't open database %s.\n

\n", dbname); printf("

Return\n", returnURL); return EXIT_FAILURE; } /* Write data in db */ for (i=0; iSorry\n"); printf("

Sorry, your data was not saved; %s is at maximum size

",dbname); printf("

Return\n", returnURL); fclose(db); return EXIT_FAILURE; } fprintf(db, "\n"); fclose(db); /* write HTML */ if (redirect[0]=='\0') { printf("Content-type: text/html\n\n"); printf("Thank you\n"); printf("

Thank you for submitting your data

"); printf("

Return\n", returnURL); } else { printf("Location: %s\n\n", redirect); } return EXIT_SUCCESS; }