#define BIRTHDAY_PATH "/CHANGE/THIS/PATH/birthday_data" #define BIRTHDAY_PROGRAM_URL "/CHANGE/THIS/URL/wbw2" #include #include #include #include "cgic.h" /* Month names to show the user */ char *months[12] = { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" }; /* Forward references */ void DayRequested(); void TodayRequested(); void AcceptSubmission(); void PresentOptions(); void OutputDay(int month, int day); void BirthdayOutput (int day, int month, char *name_s, char *url_s, char *email_s); void BirthdayHead (char *request); void BirthdayTail (); void RemoveSpaces (char *dest, char *src); int cgiMain () { cgiHeaderContentType("text/html"); fprintf(cgiOut, "\n\n"); /* Look for requests for particular days and submissions of new entries. If the PATH_INFO indicates neither, display today's birthdays. In all three cases, present the user's next choices afterward. */ if ((!strcmp(cgiPathInfo, "/day")) || (!strcmp(cgiPathInfo, "day"))) { DayRequested(); } else if ((!strcmp(cgiPathInfo, "/submit")) || (!strcmp(cgiPathInfo, "submit"))) { AcceptSubmission(); } else { TodayRequested(); } PresentOptions(); fprintf(cgiOut, "\n\n"); return 0; } void TodayRequested() { int month, day; struct tm *now_tm; time_t now_t; /* If we didn't find a request for a specific date, then output today's birthdays instead. */ /* Retrieve the current time */ time (&now_t); /* Break it down into month, day, year and so on */ now_tm = gmtime (&now_t); month = now_tm->tm_mon; day = now_tm->tm_mday; /* Output today's birthdays */ OutputDay(month, day); } void DayRequested() { int month, day; /* The month will be one of the twelve possible strings, of course. */ cgiFormSelectSingle("month", months, 12, &month, 0); /* The day is an integer, so just use cgiFormIntegerBounded(). */ cgiFormIntegerBounded("day", &day, 1, 31, 1); /* Output birthdays */ OutputDay(month, day); } void AcceptSubmission() { int month, day; char name[256]; char url[256]; char email[256]; char path[256]; FILE *out; /* Keep the results so we can complain if fields are missing. */ int rMonth, rDay, rName, rEmail, rUrl; /* The month will be one of the twelve possible strings, of course. */ cgiFormSelectSingle("month", months, 12, &month, 0); /* The day is an integer, so just use cgiFormIntegerBounded(). */ cgiFormIntegerBounded("day", &day, 1, 31, 1); /* Now the user's name, url and email address. */ rName = cgiFormStringNoNewlines("name", name, sizeof(name)); rUrl = cgiFormStringNoNewlines("url", url, sizeof(url)); rEmail = cgiFormStringNoNewlines("email", email, sizeof(email)); if ((rName == cgiFormNotFound) || (rMonth == cgiFormNotFound) || (rDay == cgiFormNotFound)) { /* Complain. */ fprintf(cgiOut, "Missing Fields\n"); fprintf(cgiOut, "\n

Missing Fields

\n"); fprintf(cgiOut, "Please fill out your name, your month of birth,\n"); fprintf(cgiOut, "and your day of birth, at a minimum.\n"); return; } /* All is well; add the data to the database. */ sprintf(path, "%s/%d/%d", BIRTHDAY_PATH, month+1, day); out = fopen (path, "a"); if (!out) { /* We can't access the data file to add to it. */ fprintf(cgiOut, "Can't Access Data File\n"); fprintf(cgiOut, "\n

Can't Access Data File

\n"); fprintf(cgiOut, "Please contact the administrator.\n"); return; } fprintf(out, "%s\n%s\n%s\n", name, url, email); fclose(out); fprintf(cgiOut, "WBW: Birthday added successfully.\n"); fprintf(cgiOut, "\n

WBW: Birthday added successfully.

\n"); } void OutputDay(int month, int day) { FILE *in; char path[256]; int birthdayCount = 0; fprintf(cgiOut, "WBW: birthdays for %d %s\n", day, months[month]); fprintf(cgiOut, "\n

WBW: birthdays for %d %s

\n", day, months[month]); sprintf(path, "%s/%d/%d", BIRTHDAY_PATH, month+1, day); in = fopen (path, "r"); if (in) { while (!feof (in)) { char name_s[512], url_s[512], email_s[512]; char nameS[512], urlS[512], emailS[512]; if (!fgets (name_s, 512, in)) { break; } RemoveSpaces (nameS, name_s); if (!fgets (url_s, 512, in)) { break; } RemoveSpaces (urlS, url_s); if (!fgets (email_s, 512, in)) { break; } RemoveSpaces (emailS, email_s); if (!birthdayCount) { char s[81]; sprintf(s, "%d %s", day, months[month]); BirthdayHead (s); } birthdayCount++; BirthdayOutput (day, month, nameS, urlS, emailS); } } fclose (in); if (birthdayCount) { BirthdayTail (); } else { fprintf(cgiOut, "No birthdays have been entered for this day.\n"); } } void BirthdayOutput (int day, int month, char *name_s, char *url_s, char *email_s) { fprintf(cgiOut, "
  • "); if (strlen (url_s)) { fprintf(cgiOut, "", url_s); } fprintf(cgiOut, "%d %s: ", day, months[month]); fprintf(cgiOut, "%s", name_s); if (strlen (email_s)) { fprintf(cgiOut, " %s\n", email_s); } if (strlen (url_s)) { fprintf(cgiOut, "\n"); } fprintf(cgiOut, "
  • \n"); } void BirthdayHead (char *request) { fprintf(cgiOut, "

    Birthdays for: %s

      \n", request); } void BirthdayTail () { fprintf(cgiOut, "
    \n"); fprintf(cgiOut, "

    Remember, the Birthday Server "); fprintf(cgiOut, "runs on Greenwich Mean Time.\n"); } void PresentOptions() { int i; fprintf(cgiOut, "

    \n"); fprintf(cgiOut, "


    \n"); fprintf(cgiOut, "

    Global Birthday Navigator (GBN)

    \n"); /* Make sure that PATH_INFO will distinguish this form from others */ fprintf(cgiOut, "
    \n", BIRTHDAY_PROGRAM_URL); fprintf(cgiOut, "Month: \n"); fprintf(cgiOut, "\n"); fprintf(cgiOut, "Day: \n"); fprintf(cgiOut, " \n"); fprintf(cgiOut, "
    \n"); fprintf(cgiOut, "
    \n"); fprintf(cgiOut, "

    Universal Birthday Form (UBF)

    \n"); /* Make sure that PATH_INFO will distinguish this form from others */ fprintf(cgiOut, "
    \n", BIRTHDAY_PROGRAM_URL); fprintf(cgiOut, "Month: \n"); fprintf(cgiOut, "\n\n"); fprintf(cgiOut, "Day:

    \n"); fprintf(cgiOut, "Name:

    \n"); fprintf(cgiOut, "URL:

    \n"); fprintf(cgiOut, "Email:

    \n"); fprintf(cgiOut, " \n"); fprintf(cgiOut, "\n"); fprintf(cgiOut, "

    \n"); } void RemoveSpaces(char *dest, char *src) { /* Remove all leading and trailing spaces. */ char *last; /* First, skip to the first non-space character in the source string. */ while (*src) { if (!isspace(*src)) { break; } src++; } /* Now, copy the source string to the destination string. */ strcpy(dest, src); /* Now, find the last non-space character in the destination string; move downward through the string from the end. */ if (!strlen(dest)) { return; } last = dest + strlen(dest) - 1; while (last != dest) { if (!isspace(*last)) { /* We have found the last non-space character in the string, so place a final null immediately after it. */ *(last + 1) = '\0'; break; } last--; } }