#include #include #include #define MAX_NVPAIRS 250 #define BUF_SIZE 4096 #define WHITESPACE " \t\n\r\v\f" #define TRUE 1 #define FALSE 0 typedef struct { char *name; char *value; } nvpair; char *makeword(char *line, char stop); char *fmakeword(FILE *f, char stop, int *len); char x2c(char *what); void unescape_url(char *url); void plustospace(char *str); main(int argc, char *argv[], char *env[]) { nvpair formdata[MAX_NVPAIRS]; FILE *control; register int field=0; int content_len, num_fields, ref_url_len, path_info_len, match, fail; char *ref_url = NULL; char *path_info = NULL; char buffer[BUF_SIZE]; char *test_url, *test_value; ref_url_len = 0; ref_url = getenv("HTTP_REFERER"); if (ref_url) ref_url_len = strlen(ref_url); else ref_url = "\0"; if (ref_url_len > 0) ref_url = (char *) malloc(sizeof(char) * (ref_url_len + 1)); if (ref_url) strcpy(ref_url, getenv("HTTP_REFERER")); path_info_len = 0; path_info = getenv("PATH_TRANSLATED"); if (path_info) path_info_len = strlen(path_info); else path_info = "\0"; if (path_info_len > 0) path_info = (char *) malloc(sizeof(char) * (path_info_len + 1)); if (path_info) strcpy(path_info, getenv("PATH_TRANSLATED")); /* Make sure the METHOD is POST */ if (strcmp(getenv("REQUEST_METHOD"),"POST")) { printf ("Content-type: text/html\n\n"); printf ("\n"); printf ("Director CGI: ERROR\n"); printf ("\n"); printf ("

ERROR

\n"); printf ("

This CGI program must be referenced with a METHOD of POST.

\n"); if (ref_url_len > 0) { printf ("

This is probably an error in the construction of \n"); printf ("the previous page\n", ref_url); printf ("("mailto:" forms or other forms using the GET\n"); printf ("method are not compatible with this program).\n"); printf ("Please notify the author of that page, if possible.

\n"); } else { printf ("

This program is meant to be used in conjunction with\n"); printf ("an HTML form, and should not be invoked by a URL typed\n"); printf ("directly into the browser or via a bookmark.

\n"); } printf ("\n"); exit(1); } /* Make sure it was invoked from a form */ if (strcmp(getenv("CONTENT_TYPE"),"application/x-www-form-urlencoded")) { printf ("Content-type: text/html\n\n"); printf ("\n"); printf ("Director CGI: ERROR\n"); printf ("\n"); printf ("

ERROR

\n"); printf ("

This CGI program must be used with an HTML form.

\n"); if (ref_url_len > 0) { printf ("

This is probably an error in the construction of \n"); printf ("the previous page.\n", ref_url); printf ("Please notify the author of that page, if possible.

\n"); } printf ("\n"); exit(1); } /* Make sure we can get the control file */ if ((path_info_len <= 0) || ((control = fopen(path_info, "r")) == NULL)) { printf ("Content-type: text/html\n\n"); printf ("\n"); printf ("Director CGI: ERROR\n"); printf ("\n"); printf ("

ERROR

\n"); printf ("

This CGI program requires a control file. This file\n"); printf ("either was not specified or could not be found.

\n"); if (ref_url_len > 0) { printf ("

This is probably an error in the construction of \n"); printf ("the previous page.\n", ref_url); printf ("Please notify the author of that page, if possible.

\n"); } printf ("\n"); exit(1); } /* Get content length */ content_len = atoi(getenv("CONTENT_LENGTH")); /* Decode URL-encoded Form Data */ num_fields = 0; for (field = 0; content_len && (!feof(stdin)); field++) { num_fields++; formdata[field].value = fmakeword(stdin,'&',&content_len); plustospace(formdata[field].value); unescape_url(formdata[field].value); formdata[field].name = makeword(formdata[field].value,'='); } /* Read the control file, a line at a time */ match = FALSE; while (fgets(buffer, BUF_SIZE, control)) { /* Skip comments */ if (buffer[0] == "#") continue; /* Get the URL */ test_url = strtok(buffer, WHITESPACE); /* Test the values */ fail = FALSE; for (field = 0; field <= num_fields; field++) { test_value = strtok(NULL, WHITESPACE); if ((test_value == NULL) || (strcmp(test_value, "*") == 0)) continue; if (strcmp(test_value, formdata[field].value) == 0) continue; fail = TRUE; } if (fail) continue; else { match = TRUE; printf ("Location: %s\n\n", test_url); break; } } fclose(control); if (!match) { printf ("Content-type: text/html\n\n"); printf ("\n"); printf ("Director CGI: ERROR\n"); printf ("\n"); printf ("

ERROR

\n"); printf ("

The control file does not include a match for the form\n"); printf ("data that was specified. No destination URL was selected.

\n"); if (ref_url_len > 0) { printf ("

This is probably an error in the construction of \n"); printf ("the previous page.\n", ref_url); printf ("Please notify the author of that page, if possible.

\n"); } printf ("\n"); exit (1); } exit (0); }