/*****************************************************************************/ /* calendar.c CGI-compliant script to produce a calendar. Page colouration may be specified via the appropriate command-line qualifiers (or corresponding logical name). Defaults for any not specified. Specifiy as /WHATEVER="" to NOT specify the corresponding colour (i.e. leave it to the browser). See "Qualifiers" section below, and also about the logical name "CALENDAR$PARAM". An example of changing the page colour to white and the banner to red! /PBGCOLOR="#ffffff" /PHBGCOLOR="#ff0000" The script can format a page in either of two layouts. 1. Tables are used to create a coloured header and button bar (DEFAULT). Default colours are white page with grey heading and button outlines. 2. Textual header, horizontal rules and a textual button bar. No default colours. QUERY STRINGS ALLOWED --------------------- ?1999 specific year (anything greater than 99) ?0 current year ?1 current year plus one, two, etc., up to 99 ?+1 same as above ?-1 current year minus one, two, etc., up to -99 COMMAND-LINE USE ---------------- To include a
..delimited calendar inside other script output use the /CALENDAR qualifier. This takes two, comma-separated parameters. The first; the year to be output (empty or zero generates the current year). The second; the number of months across the page. Examples: $ CALENDAR = "$CGI-BIN:[000000]CALENDAR" $ CALENDAR /CALENDAR=2003,3 $ CALENDAR /CALENDAR=0,3 $ CALENDAR /CALENDAR CGI VARIABLE NAMES ------------------ WWW_KEY_1 query string containing year or increment to current WWW_KEY_2 will contain increment if "?+1" is used WWW_PATH_INFO the URL path component WWW_PATH_TRANSLATED the VMS equivalent of the URL path component WWW_QUERY_STRING any of the form components WWW_SCRIPT_NAME the name of the script being executed WWW_FORM_ACROSS number of months across page WWW_FORM_FROMMONTH beginning with month (1 == jan, 12 = dec) WWW_FORM_TOMONTH ending with month WWW_FORM_OTHERYEAR explicitly specified year from form WWW_FORM_YEAR year selected from selection box in form LOGICAL NAMES ------------- CALENDAR$DBUG turns on all "if (Debug)" statements CALENDAR$PARAM equivalent to (overrides) the command line parameters/qualifiers (define as a system-wide logical) QUALIFIERS ---------- /BUTTONS= string containing button labels/paths /CALENDAR= allows a calendar-only to be produced (see above) /DBUG turns on all "if (Debug)" statements /PBACKGROUND= background image path /PBGCOLOR= background colour /PBBGCOLOR= button background color /PBBORDER= width of button border /PHBGCOLOR= heading background color /PHBORDER= width of heading and button-bar border /PHLOCAL= local information to be included in header /PHTEXT= heading text colour /PLAYOUT= 1 is coloured header & buttons, 2 is text & horizontal rules /PLINK= link colour /PTEXT= text colour /PVLINK= visited link colour BUILD ----- See BUILD_CALENDAR.COM VERSION HISTORY --------------- 10-MAY-2005 MGD v1.6.1, SWS 2.0 ignore query string components supplied as command-line parameters differently to CSWS 1.2/3 06-OCT-2004 MGD v1.6.0, CGILIB object module 23-DEC-2003 MGD v1.5.1, minor conditional mods to support IA64 02-OCT-2003 MGD v1.5.0, /CALENDAR=
\n",
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBORDER],
PageScheme[PS_HEADBGCOLOR]);
if (ButtonCount == 0 || !Top1Bottom2)
fprintf (stdout, " \n");
else
{
fprintf (stdout,
"
|
\n", PageScheme[PS_HEADLOCAL]); } else { fprintf (stdout, "
\n\ \n\ Calendar Request Form\n\ \n\ | %s
\n\ \n\\n\
\n"); ButtonBar (2); fprintf (stdout, "\n\n"); } /****************************************************************************/ /* */ Calendar () { int status, Day, FromMonth, Month, ToMonth, Year; unsigned long BinTime [2]; unsigned short NumTime [7]; char *cptr; char Range [32]; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "Calendar()\n"); sys$gettim (&BinTime); sys$numtim (&NumTime, &BinTime); if (*CgiKey1Ptr) { Year = atoi(CgiKey1Ptr); if (Year >= -99 && Year <= 99) Year = NumTime[0] + Year; } else if (*CgiKey2Ptr) { Year = atoi(CgiKey2Ptr); if (Year >= -99 && Year <= 99) Year = NumTime[0] + Year; } else if (*CgiFormOtherYearPtr) Year = atoi(CgiFormOtherYearPtr); else Year = atoi(CgiFormYearPtr); if (!Year) Year = NumTime[0]; if (Year < 1859 || Year > 9999) { CgiLibResponseError (FI_LI, 0, "Year out of range (1859 to 9999)."); exit (SS$_NORMAL); } cptr = CgiLibVar ("WWW_FORM_FROMMONTH"); if (*cptr) FromMonth = atoi(cptr); else FromMonth = 1; if (FromMonth < 1 || FromMonth > 12) { CgiLibResponseError (FI_LI, 0, "From month out of range."); exit (SS$_NORMAL); } cptr = CgiLibVar ("WWW_FORM_TOMONTH"); if (*cptr) ToMonth = atoi(cptr); else ToMonth = 12; if (ToMonth < 1 || ToMonth > 12) { CgiLibResponseError (FI_LI, 0, "To month out of range."); exit (SS$_NORMAL); } if (FromMonth > ToMonth) { CgiLibResponseError (FI_LI, 0, "From month greater than to out of range."); exit (SS$_NORMAL); } cptr = CgiLibVar ("WWW_FORM_ACROSS"); if (*cptr) MonthsAcrossPage = atoi(cptr); else MonthsAcrossPage = 3; if (MonthsAcrossPage < 1 || MonthsAcrossPage > 12) { CgiLibResponseError (FI_LI, 0, "Months across page out of range."); exit (SS$_NORMAL); } if (FromMonth > 1 || ToMonth < 12) sprintf (Range, " %s to %s", MonthName[FromMonth], MonthName[ToMonth]); else Range[0] = '\0'; CgiLibResponseHeader (200, "text/html"); fprintf (stdout, "\n\
\n\ \n\ \n\\n\", PageScheme[PS_HEADLOCAL], Year, Range); } else { fprintf (stdout, "\n\
\n\\n\ \n\ \n\ Calendar %d%s\n\ \n\ %s\n\\n\", PageScheme[PS_HEADBORDER], PageScheme[PS_HEADPADDING], PageScheme[PS_HEADBGCOLOR], PageScheme[PS_HEADTEXT], Year, Range, PageScheme[PS_HEADLOCAL]); } NumTime[0] = Year; NumTime[1] = NumTime[2] = 1; NumTime[3] = NumTime[4] = NumTime[5] = NumTime[6] = 0; if (!MonthsAcrossPage) MonthsAcrossPage = 3; for (Month = FromMonth; Month <= ToMonth; Month++) AddMonth (Year, Month); if (MonthsOnLine) OutputPageLines (); fprintf (stdout, "\n\\n"); if (*CgiKey1Ptr || *CgiKey2Ptr) ButtonBar (2); else ButtonBar (0); fprintf (stdout, "\n\n"); } /****************************************************************************/ /* */ CalendarOnly () { int status, FromMonth, Month, ToMonth, Year; unsigned long BinTime [2]; unsigned short NumTime [7]; char *cptr; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "CalendarOnly() |%s|\n", CliCalendarPtr); cptr = CliCalendarPtr; Year = atoi(cptr); while (isdigit(*cptr)) cptr++; while (*cptr && !isdigit(*cptr)) cptr++; MonthsAcrossPage = atoi(cptr); FromMonth = 1; ToMonth = 12; sys$gettim (&BinTime); sys$numtim (&NumTime, &BinTime); if (!Year) Year = NumTime[0]; NumTime[0] = Year; NumTime[1] = NumTime[2] = 1; NumTime[3] = NumTime[4] = NumTime[5] = NumTime[6] = 0; if (!MonthsAcrossPage) MonthsAcrossPage = 3; fprintf (stdout, "
"); for (Month = FromMonth; Month <= ToMonth; Month++) AddMonth (Year, Month); if (MonthsOnLine) OutputPageLines (); fprintf (stdout, ""); } /*****************************************************************************/ /* */ AddMonth ( int Year, int Month ) { int ccnt, lcnt, status, Count, DaysInThisMonth; unsigned long DayOfMonth, DayOfWeek; unsigned long BinTime [2]; unsigned short NumTime [7]; char *cptr; char Line [256]; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "AddMonth() %d %d\n", Year, Month); if (!MonthsOnLine || MonthsOnLine >= MonthsAcrossPage) { if (MonthsOnLine >= MonthsAcrossPage) OutputPageLines (); for (lcnt = 0; lcnt < MaxPageLines; lcnt++) { if (Debug) fprintf (stdout, "lcnt: %d\n", lcnt); memset (PageLines[lcnt], ' ', PageLineLength); PageLines[lcnt][PageLineLength-1] = '\0'; } MonthsOnLine = 0; } lcnt = 0; memset (NumTime, 0, sizeof(NumTime)); NumTime[0] = Year; NumTime[1] = Month; DaysInThisMonth = DaysInMonth[Month]; if (Month == 2) { /* if the time conversion returns an error then it's not a leap year! */ NumTime[2] = 29; status = lib$cvt_vectim (&NumTime, &BinTime); if (VMSnok (status) && status != LIB$_IVTIME) { CgiLibResponseError (FI_LI, status, "lib$cvt_vectim()"); exit (SS$_NORMAL); } if (VMSok (status)) DaysInThisMonth = 29; } /* the the day of the week the month starts on */ NumTime[2] = 1; if (VMSnok (status = lib$cvt_vectim (&NumTime, &BinTime))) { CgiLibResponseError (FI_LI, status, "lib$cvt_vectim()"); exit (SS$_NORMAL); } if (VMSnok (status = lib$cvt_from_internal_time (&LibDayOfWeek, &DayOfWeek, &BinTime))) { CgiLibResponseError (FI_LI, status, "lib$cvt_from_internal_time()"); exit (SS$_NORMAL); } /* we count our week days traditionally (Sunday to Saturday) */ if (DayOfWeek == 7) DayOfWeek = 1; else DayOfWeek++; if (Debug) fprintf (stdout, "DayOfWeek: %d DaysInThisMonth: %d\n", DayOfWeek, DaysInThisMonth); /*********/ /* month */ /*********/ cptr = PageLines[lcnt++] + MonthsOnLine * MonthIncrement; for (Count = 0; Count < MonthsOnLine; Count++) cptr += 7; ccnt = sprintf (cptr, "%*s%s", (20 - strlen(MonthName[Month])) / 2, "", MonthName[Month]); cptr[ccnt] = ' '; /*************/ /* day names */ /*************/ cptr = PageLines[lcnt++] + MonthsOnLine * MonthIncrement; for (Count = 0; Count < MonthsOnLine; Count++) cptr += 7; memcpy (cptr, "", 3); cptr += 3; for (Count = 1; Count <= 7; Count++) { if (Count > 1) *cptr++ = ' '; memcpy (cptr, DayName[Count], 2); cptr += 2; } memcpy (cptr, "", 4); /**********************/ /* leading empty days */ /**********************/ cptr = PageLines[lcnt++] + MonthsOnLine * MonthIncrement; for (Count = 1; Count < DayOfWeek; Count++) { memcpy (cptr, " ", 3); if (Count == 1) cptr += 2; else cptr += 3; } /********/ /* days */ /********/ for (DayOfMonth = 1; DayOfMonth <= DaysInThisMonth; DayOfMonth++) { if (Count == 1) cptr += sprintf (cptr, "%2d", DayOfMonth); else cptr += sprintf (cptr, " %2d", DayOfMonth); *cptr = ' '; if (Count++ >= 7) { cptr = PageLines[lcnt++] + MonthsOnLine * MonthIncrement; Count = 1; } } MonthsOnLine++; } /*****************************************************************************/ /* */ OutputPageLines () { int lcnt; char *cptr; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "OutputPageLines()\n"); if (!MonthsOnLine) return; fprintf (stdout, "\n"); for (lcnt = 0; lcnt < MaxPageLines; lcnt++) { if (Debug) fprintf (stdout, "lcnt: %d\n", lcnt); for (cptr = PageLines[lcnt]; *cptr && *cptr == ' '; cptr++); if (!*cptr) break; while (*cptr) cptr++; if (cptr > PageLines[lcnt]) cptr--; while (*cptr == ' ' && cptr > PageLines[lcnt]) cptr--; if (cptr > PageLines[lcnt]) cptr++; *cptr = '\0'; fprintf (stdout, "%s\n", PageLines[lcnt]); } MonthsOnLine = 0; } /****************************************************************************/ /* Does a case-insensitive, character-by-character string compare and returns true if two strings are the same, or false if not. If a maximum number of characters are specified only those will be compared, if the entire strings should be compared then specify the number of characters as 0. */ boolean strsame ( char *sptr1, char *sptr2, int count ) { while (*sptr1 && *sptr2) { if (toupper (*sptr1++) != toupper (*sptr2++)) return (false); if (count) if (!--count) return (true); } if (*sptr1 || *sptr2) return (false); else return (true); } /****************************************************************************/