#include "cgic.h" /* Change this, if necessary, to point to the location of the sendmail binary on your system. */ #define SENDMAIL "/lib/sendmail -t" /* CHANGE THIS to your email address. */ #define RECIPIENT "CHANGE@ADDRESS.COM" int cgiMain() { /* Large enough buffers for any reasonable real name and email address. */ char name[256]; char email[256]; /* The version "number". */ char version[32]; /* The user's system. */ char userSystem[32]; /* The bug report itself may be quite large, so we'll allocate space once we know how large it is. */ char *bug; /* Space needed for the bug string. */ int needed; /* Keep the results so we can complain if fields are missing. */ int rName, rEmail, rComments, rVersion, rSystem; FILE *out; /* Output the usual MIME header. */ cgiHeaderContentType("text/html"); /* Start the HTML document. */ fprintf(cgiOut, "\n\n"); /* cgiFormStringNoNewlines() will never overflow buffers or write a non-terminated string. Also, even if the user's browser is defective, it will not return any carriage returns or line feeds. */ rName = cgiFormStringNoNewlines("name", name, sizeof(name)); rEmail = cgiFormStringNoNewlines("email", email, sizeof(email)); /* A "falsified" version number would not particularly matter in this case, so we'll just get the string instead of using cgiFormSelectSingle. */ rVersion = cgiFormStringNoNewlines("version", version, sizeof(version)); /* The same goes for the system. */ rSystem = cgiFormStringNoNewlines("system", userSystem, sizeof(userSystem)); /* cgiFormStringSpaceNeeded returns the number of bytes of space guaranteed to be adequate for the string in question, including the terminating null. */ rComments = cgiFormStringSpaceNeeded("bug", &needed); /* Now check for missing fields. Since any well-behaved browser will submit the default for each option menu if nothing was actually chosen by the user, we check for the "PLEASE CHOOSE ONE" strings as well as for a missing field. */ if ((rName == cgiFormNotFound) || (rEmail == cgiFormNotFound) || (rComments == cgiFormNotFound) || (rSystem == cgiFormNotFound) || (rVersion == cgiFormNotFound) || (!strcmp(userSystem, "PLEASE CHOOSE ONE")) || (!strcmp(version, "PLEASE CHOOSE ONE"))) { /* If any field is missing, complain! */ fprintf(cgiOut, "Please fill out all the fields\n"); fprintf(cgiOut, "\n"); fprintf(cgiOut, "

Please fill out all the fields

\n"); fprintf(cgiOut, "Please indicate your name, email address, software version\n"); fprintf(cgiOut, "number, and system, and submit the form again.\n"); fprintf(cgiOut, "\n"); return 0; } /* So far, so good. Allocate space for the bug. Since we are dynamically allocating the space, we will need to free the space later. */ bug = (char *) malloc(needed); /* In this case, we do want to allow new lines, so we call cgiFormString. cgiFormString will guarantee that line breaks are always represented simply by line feeds, even if the user's browser does something creative. */ cgiFormString("bug", bug, needed); /* OK, send email to the user responsible for bug reports. Use the popen() Unix function, which executes the specified program and writes to its standard input through a "pipe". */ out = popen(SENDMAIL, "w"); fprintf(out, "From: %s <%s>\n", name, email); fprintf(out, "To: %s\n", RECIPIENT); fprintf(out, "Subject: bug report\n"); fprintf(out, "\n"); fprintf(out, "This bug report was submitted via the WWW-Email gateway.\n"); fprintf(out, "--\n\n"); fprintf(out, "System: %s\n", userSystem); fprintf(out, "Version: %s\n", version); fprintf(out, "%s\n", bug); /* Always close pipes with pclose(), not fclose(). */ pclose(out); /* Say thanks. */ fprintf(cgiOut, "Thank you, %s\n", name); fprintf(cgiOut, "\n"); fprintf(cgiOut, "

Thank you, %s

\n", name); fprintf(cgiOut, "Thank you for your bug report.\n"); fprintf(cgiOut, "\n"); /* Free the memory we used for the bug report. */ free(bug); /* We're done. */ return 0; }