/*****************************************************************************/ /* 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=, 12-APR-2003 MGD v1.4.5, link colour changed to 0000cc 15-AUG-2002 MGD v1.4.4, some accomodations for CSWS v1.2 01-JUL-2001 MGD v1.4.3, add 'SkipParameters' for direct OSU support 28-OCT-2000 MGD v1.4.2, *no changes* (leave this one as a check against the #include variant of CGILIB) 12-APR-2000 MGD v1.4.1, minor changes for CGILIB 1.4 07-AUG-1999 MGD v1.4.0, use more of the CGILIB functionality 24-APR-1999 MGD v1.3.0, use CGILIB.C, standard CGI environment (Netscape FastTrack), accomodations for OSU environment 24-JUL-1998 MGD v1.2.1, suppress table background colours if empty bugfix; action script instead of background colour! 10-MAY-1998 MGD v1.2.0, cosmetic changes 24-SEP-1996 MGD v1.1.0, allow query string containing year or increment 20-FEB-1996 MGD v1.0.0, quick hack */ /*****************************************************************************/ #define SOFTWAREVN "1.6.1" #define SOFTWARENM "CALENDAR" #ifdef __ALPHA char SoftwareID [64] = SOFTWARENM " AXP-" SOFTWAREVN; #endif #ifdef __ia64 char SoftwareID [64] = SOFTWARENM " IA64-" SOFTWAREVN; #endif #ifdef __VAX char SoftwareID [64] = SOFTWARENM " VAX-" SOFTWAREVN; #endif #ifndef __VAX # pragma nomember_alignment #endif #include #include #include #include #include #include #include #include #include #include #include #define VMSok(x) ((x) & STS$M_SUCCESS) #define VMSnok(x) !(((x) & STS$M_SUCCESS)) #define boolean int #define true 1 #define false 0 #define FI_LI __FILE__, __LINE__ #define DEFAULT_BUTTONS "Calendar Request Form" /* this macro just plugs in some script-specific code into ButtonBar() */ #define SCRIPT_SPECIFIC_BUTTON_CODE \ if (*CgiKey1Ptr || *CgiKey2Ptr) \ ButtonInternal[0] = CgiScriptNamePtr; \ else \ ButtonInternal[0] = ""; \ #define DEFAULT_PS_BGCOLOR "#ffffff" #define DEFAULT_PS_TEXT "#000000" #define DEFAULT_PS_LINK "#0000cc" #define DEFAULT_PS_VLINK "#0000cc" #define DEFAULT_PS_HEADBGCOLOR "#cccccc" #define DEFAULT_PS_HEADBORDER "0" #define DEFAULT_PS_HEADTEXT "#000000" #define DEFAULT_PS_BUTTONBGCOLOR "#ffffff" #define DEFAULT_PS_BUTTONBORDER "1" #define PS_BACKGROUND 0 #define PS_BGCOLOR 1 #define PS_TEXT 2 #define PS_LINK 3 #define PS_VLINK 4 #define PS_HEADBGCOLOR 5 #define PS_HEADTEXT 6 #define PS_HEADBORDER 7 #define PS_BUTTONBGCOLOR 8 #define PS_BUTTONBORDER 9 #define PS_BODYTAG 10 #define PS_LAYOUT 11 #define PS_HEADLOCAL 12 #define PS_HEADPADDING 13 char *PageScheme [16]; char Utility [] = "CALENDAR"; int DaysInMonth [] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; char *DayName [] = { "", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", }; char *MonthName [] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; unsigned long LibDayOfMonth = LIB$K_DAY_OF_MONTH, LibDayOfWeek = LIB$K_DAY_OF_WEEK; boolean Debug; int MonthsAcrossPage, MonthsOnLine; char *ButtonPtr = DEFAULT_BUTTONS, *CgiEnvironmentPtr, *CgiFormYearPtr, *CgiFormOtherYearPtr, *CgiKey1Ptr, *CgiKey2Ptr, *CgiScriptNamePtr, *CgiServerSoftwarePtr, *CliCalendarPtr, *CliCharsetPtr; #define MonthIncrement 23 #define MaxPageLines 8 #define PageLineLength 512 char PageLines [MaxPageLines][PageLineLength]; /*****************************************************************************/ /* 'argc/argv' are only required to support OSU, in particular CgiLibOsuInit(). */ main ( int argc, char *argv[] ) { /*********/ /* begin */ /*********/ strcat (SoftwareID+15, " ("); strcat (SoftwareID+15, CGILIB_SOFTWAREID); strcat (SoftwareID+15, ")"); if (getenv ("CALENDAR$DBUG")) Debug = true; CgiLibEnvironmentInit (argc, argv, false); CgiEnvironmentPtr = CgiLibEnvironmentName (); GetParameters (); if (CliCalendarPtr) { CalendarOnly (); exit (SS$_NORMAL); } SetPageScheme (); CgiLibResponseSetBody (PageScheme[PS_BODYTAG]); CgiLibResponseSetCharset (CliCharsetPtr); CgiLibResponseSetSoftwareID (SoftwareID); CgiLibResponseSetErrorMessage ("Reported by Calendar"); CgiScriptNamePtr = CgiLibVar ("WWW_SCRIPT_NAME"); CgiServerSoftwarePtr = CgiLibVar ("WWW_SERVER_SOFTWARE"); CgiKey1Ptr = CgiLibVar ("WWW_KEY_1"); CgiKey2Ptr = CgiLibVar ("WWW_KEY_2"); CgiFormOtherYearPtr = CgiLibVar ("WWW_FORM_OTHERYEAR"); CgiFormYearPtr = CgiLibVar ("WWW_FORM_YEAR"); if (*CgiKey1Ptr || *CgiKey2Ptr) Calendar (); else if (*CgiFormOtherYearPtr) Calendar (); else { if (*CgiFormYearPtr) Calendar (); else CalendarForm (); } exit (SS$_NORMAL); } /*****************************************************************************/ /* Get "command-line" parameters, whether from the command-line or from a configuration symbol or logical containing the equivalent. OSU scripts have the 'method', 'url' and 'protocol' supplied as P1, P2, P3 (these being detected and used by CGILIB), and are of no interest to this function. */ GetParameters () { static char CommandLine [256]; static unsigned long Flags = 0; int status, SkipParameters; unsigned short Length; char ch; char *aptr, *cptr, *clptr, *sptr; $DESCRIPTOR (CommandLineDsc, CommandLine); /*********/ /* begin */ /*********/ if (!(clptr = getenv ("CALENDAR$PARAM"))) { /* get the entire command line following the verb */ if (VMSnok (status = lib$get_foreign (&CommandLineDsc, 0, &Length, &Flags))) exit (status); (clptr = CommandLine)[Length] = '\0'; } /* if [C]SWS (VMS Apache) */ if (CgiLibEnvironmentIsApache()) { /* CSWS 1.2/3 look for something non-space outside of quotes */ for (cptr = clptr; *cptr; cptr++) { if (isspace(*cptr)) continue; if (*cptr != '\"') break; cptr++; while (*cptr && *cptr != '\"') cptr++; if (*cptr) cptr++; } /* CSWS 1.2/3 if nothing outside of quotes then ignore command line */ if (!*cptr) return; /* SWS 2.0 doesn't begin with /APACHE from DCL procedure wrapper */ if (!strsame (cptr, "/APACHE", 7)) return; } /* if OSU environment then skip P1, P2, P3 */ if (CgiLibEnvironmentIsOsu()) SkipParameters = 3; else SkipParameters = 0; aptr = NULL; ch = *clptr; for (;;) { if (aptr) *aptr = '\0'; if (!ch) break; *clptr = ch; if (Debug) fprintf (stdout, "clptr |%s|\n", clptr); while (*clptr && isspace(*clptr)) *clptr++ = '\0'; aptr = clptr; if (*clptr == '/') clptr++; while (*clptr && !isspace (*clptr) && *clptr != '/') { if (*clptr != '\"') { clptr++; continue; } cptr = clptr; clptr++; while (*clptr) { if (*clptr == '\"') if (*(clptr+1) == '\"') clptr++; else break; *cptr++ = *clptr++; } *cptr = '\0'; if (*clptr) clptr++; } ch = *clptr; if (*clptr) *clptr = '\0'; if (Debug) fprintf (stdout, "aptr |%s|\n", aptr); if (!*aptr) continue; if (SkipParameters) { SkipParameters--; continue; } if (strsame (aptr, "/APACHE", 4)) { /* just skip this marker for command-line parameters under SWS 2.0 */ continue; } if (strsame (aptr, "/BUTTONS=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; ButtonPtr = cptr; continue; } if (strsame (aptr, "/CALENDAR=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; CliCalendarPtr = cptr; continue; } if (strsame (aptr, "/CHARSET=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; CliCharsetPtr = cptr; continue; } if (strsame (aptr, "/CSWS=APACHE", -1)) { /* just ignore this Apache indicator */ continue; } if (strsame (aptr, "/DBUG", -1)) { Debug = true; continue; } if (strsame (aptr, "/DBUG", -1)) { Debug = true; continue; } if (GetPageParameter (aptr)) continue; if (*aptr != '/') { fprintf (stdout, "%%%s-E-MAXPARM, too many parameters\n \\%s\\\n", Utility, aptr); exit (STS$K_ERROR | STS$M_INHIB_MSG); } else { fprintf (stdout, "%%%s-E-IVQUAL, unrecognized qualifier\n \\%s\\\n", Utility, aptr+1); exit (STS$K_ERROR | STS$M_INHIB_MSG); } } } /*****************************************************************************/ /* Get command-line parameters associated with page scheme. */ boolean GetPageParameter (char *aptr) { char *cptr; /*********/ /* begin */ /*********/ if (strsame (aptr, "/PBACKGROUND=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_BACKGROUND] = cptr; return (true); } if (strsame (aptr, "/PBGCOLOR=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_BGCOLOR] = cptr; return (true); } if (strsame (aptr, "/PBBGCOLOR=", 5)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_BUTTONBGCOLOR] = cptr; return (true); } if (strsame (aptr, "/PBBORDER=", 5)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_BUTTONBORDER] = cptr; return (true); } if (strsame (aptr, "/PHBGCOLOR=", 5)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_HEADBGCOLOR] = cptr; return (true); } if (strsame (aptr, "/PHBORDER=", 5)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_HEADBORDER] = cptr; return (true); } if (strsame (aptr, "/PHTEXT=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_HEADTEXT] = cptr; return (true); } if (strsame (aptr, "/PLAYOUT=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_LAYOUT] = cptr; return (true); } if (strsame (aptr, "/PLINK=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_LINK] = cptr; return (true); } if (strsame (aptr, "/PHLOCAL=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_HEADLOCAL] = cptr; return (true); } if (strsame (aptr, "/PTEXT=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_TEXT] = cptr; return (true); } if (strsame (aptr, "/PVLINK=", 4)) { for (cptr = aptr; *cptr && *cptr != '='; cptr++); if (*cptr) cptr++; PageScheme[PS_VLINK] = cptr; return (true); } return (false); } /*****************************************************************************/ /* Set the page layout and colouration. */ SetPageScheme () { int size; char *sptr; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "SetPageScheme()\n"); if (!PageScheme[PS_LAYOUT]) PageScheme[PS_LAYOUT] = "1"; if (!PageScheme[PS_BACKGROUND]) PageScheme[PS_BACKGROUND] = ""; if (!PageScheme[PS_HEADLOCAL]) PageScheme[PS_HEADLOCAL] = ""; if (PageScheme[PS_LAYOUT][0] == '2') { if (!PageScheme[PS_BGCOLOR]) PageScheme[PS_BGCOLOR] = ""; if (!PageScheme[PS_TEXT]) PageScheme[PS_TEXT] = ""; if (!PageScheme[PS_LINK]) PageScheme[PS_LINK] = ""; if (!PageScheme[PS_VLINK]) PageScheme[PS_VLINK] = ""; if (!PageScheme[PS_HEADBGCOLOR]) PageScheme[PS_HEADBGCOLOR] = ""; if (!PageScheme[PS_HEADBORDER]) PageScheme[PS_HEADBORDER] = ""; if (!PageScheme[PS_HEADTEXT]) PageScheme[PS_HEADTEXT] = ""; if (!PageScheme[PS_BUTTONBGCOLOR]) PageScheme[PS_BUTTONBGCOLOR] = ""; if (!PageScheme[PS_BUTTONBORDER]) PageScheme[PS_BUTTONBORDER] = ""; } else { if (!PageScheme[PS_BGCOLOR]) PageScheme[PS_BGCOLOR] = DEFAULT_PS_BGCOLOR; if (!PageScheme[PS_TEXT]) PageScheme[PS_TEXT] = DEFAULT_PS_TEXT; if (!PageScheme[PS_LINK]) PageScheme[PS_LINK] = DEFAULT_PS_LINK; if (!PageScheme[PS_VLINK]) PageScheme[PS_VLINK] = DEFAULT_PS_VLINK; if (!PageScheme[PS_HEADBGCOLOR]) PageScheme[PS_HEADBGCOLOR] = DEFAULT_PS_HEADBGCOLOR; if (!PageScheme[PS_HEADBORDER]) PageScheme[PS_HEADBORDER] = DEFAULT_PS_HEADBORDER; if (!PageScheme[PS_HEADTEXT]) PageScheme[PS_HEADTEXT] = DEFAULT_PS_HEADTEXT; if (!PageScheme[PS_BUTTONBGCOLOR]) PageScheme[PS_BUTTONBGCOLOR] = DEFAULT_PS_BUTTONBGCOLOR; if (!PageScheme[PS_BUTTONBORDER]) PageScheme[PS_BUTTONBORDER] = DEFAULT_PS_BUTTONBORDER; } /* tag attributes */ size = strlen(PageScheme[PS_BACKGROUND]) + strlen(PageScheme[PS_BGCOLOR]) + strlen(PageScheme[PS_TEXT]) + strlen(PageScheme[PS_LINK]) + strlen(PageScheme[PS_VLINK]); if (size) { if (!(sptr = calloc (1, size+64))) exit (vaxc$errno); PageScheme[PS_BODYTAG] = sptr; if (PageScheme[PS_BACKGROUND][0]) sptr += sprintf (sptr, " BACKGROUND=\"%s\"", PageScheme[PS_BACKGROUND]); if (PageScheme[PS_BGCOLOR][0]) sptr += sprintf (sptr, " BGCOLOR=\"%s\"", PageScheme[PS_BGCOLOR]); if (PageScheme[PS_TEXT][0]) sptr += sprintf (sptr, " TEXT=\"%s\"", PageScheme[PS_TEXT]); if (PageScheme[PS_LINK][0]) sptr += sprintf (sptr, " LINK=\"%s\"", PageScheme[PS_LINK]); if (PageScheme[PS_VLINK][0]) sptr += sprintf (sptr, " VLINK=\"%s\"", PageScheme[PS_VLINK]); } else PageScheme[PS_BODYTAG] = ""; if (PageScheme[PS_HEADBGCOLOR][0]) { if (!(sptr = calloc (1, strlen(PageScheme[PS_HEADBGCOLOR])+16))) exit (vaxc$errno); sprintf (sptr, " BGCOLOR=\"%s\"", PageScheme[PS_HEADBGCOLOR]); PageScheme[PS_HEADBGCOLOR] = sptr; PageScheme[PS_HEADPADDING] = "10"; } else PageScheme[PS_HEADPADDING] = "0"; if (PageScheme[PS_BUTTONBGCOLOR][0]) { if (!(sptr = calloc (1, strlen(PageScheme[PS_BUTTONBGCOLOR])+16))) exit (vaxc$errno); sprintf (sptr, " BGCOLOR=\"%s\"", PageScheme[PS_BUTTONBGCOLOR]); PageScheme[PS_BUTTONBGCOLOR] = sptr; } } /*****************************************************************************/ /* Provides a divider for top and bottom of the content of the page. This can be a coloured bar (using ) or a horizontal rule depending on the page layout. "Buttons" providing script-internal and/or additional user-specified links ('ButtonPtr' string) can be placed with(in) this bar. All button labels are derived from 'ButtonPtr', with script-internal buttons using link-paths set up via 'ButtonInternal[]' array, or any user-specified path depending on requirement. An empty path (i.e. PathPtr[0] == '\0') obviously does not have a link created, it just displays the button label. For a button-bar at the top of the document use 1, bottom of the document use 2, and for just a bar with no buttons at all use 0. */ ButtonBar (int Top1Bottom2) { #define MAX_BUTTON_COUNT 8 static int ButtonCount = -1; static char *ButtonInternal [MAX_BUTTON_COUNT], *ButtonLabel [MAX_BUTTON_COUNT], *ButtonPath [MAX_BUTTON_COUNT]; int idx; char *PathPtr; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "ButtonBar() %d\n", Top1Bottom2); if (ButtonCount == -1) { char *cptr, *sptr; if (Debug) fprintf (stdout, "|%s|\n", ButtonPtr); cptr = ButtonPtr; for (ButtonCount = 0; ButtonCount < MAX_BUTTON_COUNT && *cptr; ButtonCount++) { for (sptr = cptr; *sptr && *sptr != '=' && *sptr != ';'; sptr++) if (*sptr == '\\') memcpy (sptr, sptr+1, strlen(sptr)); if (*sptr == '=') *sptr++ = '\0'; ButtonLabel[ButtonCount] = cptr; cptr = sptr; for (sptr = cptr; *sptr && *sptr != ';'; sptr++) if (*sptr == '\\') memcpy (sptr, sptr+1, strlen(sptr)); if (*sptr) *sptr++ = '\0'; ButtonPath[ButtonCount] = cptr; cptr = sptr; } } if (Top1Bottom2) { /***********************************/ /* set up script-specified buttons */ /***********************************/ SCRIPT_SPECIFIC_BUTTON_CODE } if (PageScheme[PS_LAYOUT][0] == '2') { /************/ /* format 2 */ /************/ if (Top1Bottom2 == 2 || !Top1Bottom2) { fprintf (stdout, "
\n"); if (!Top1Bottom2) return; } fprintf (stdout, "\n"); for (idx = 0; idx < ButtonCount; idx++) { if (!ButtonInternal[idx]) PathPtr = ButtonPath[idx]; else PathPtr = ButtonInternal[idx]; if (idx) fprintf (stdout, " "); if (PathPtr[0]) fprintf (stdout, "[%s]\n", PathPtr, ButtonLabel[idx]); else fprintf (stdout, "[%s]\n", ButtonLabel[idx]); } fprintf (stdout, "\n"); if (Top1Bottom2 == 1) fprintf (stdout, "
\n"); } else { /************/ /* format 1 */ /************/ fprintf (stdout, "
\ \
\n\ \n\ \n", PageScheme[PS_HEADBORDER], PageScheme[PS_HEADBORDER], PageScheme[PS_HEADBGCOLOR]); if (ButtonCount == 0 || !Top1Bottom2) fprintf (stdout, " \n"); else { fprintf (stdout, "
\n", PageScheme[PS_BUTTONBORDER]); for (idx = 0; idx < ButtonCount; idx++) { if (!ButtonInternal[idx]) PathPtr = ButtonPath[idx]; else PathPtr = ButtonInternal[idx]; if (PathPtr[0]) fprintf (stdout, "\n", PageScheme[PS_BUTTONBGCOLOR], PathPtr, ButtonLabel[idx]); else fprintf (stdout, "\n", PageScheme[PS_BUTTONBGCOLOR], ButtonLabel[idx]); } fprintf (stdout, "
\   %s  \   %s  
\n"); } fprintf (stdout, "\n\ \n\ \ \
\n"); } } /*****************************************************************************/ /* */ CalendarForm () { int LastYear, Year; unsigned long BinTime [2]; unsigned short NumTime [7]; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "CalendarForm()\n"); sys$gettim (&BinTime); sys$numtim (&NumTime, &BinTime); CgiLibResponseHeader (200, "text/html"); fprintf (stdout, "\n\ \n\ \n\ \n\ Calendar\n\ \n\ \n", SoftwareID, CgiEnvironmentPtr, PageScheme[PS_BODYTAG]); if (PageScheme[PS_LAYOUT][0] == '2') { fprintf (stdout, "%s\n\ Calendar Request Form\n\ \n\
\n\

\n", PageScheme[PS_HEADLOCAL]); } else { fprintf (stdout, "\n\ \n\ \n\ Calendar Request Form\n\ \n\ %s\n\
\n", PageScheme[PS_HEADBORDER], PageScheme[PS_HEADPADDING], PageScheme[PS_HEADBGCOLOR], PageScheme[PS_HEADTEXT], PageScheme[PS_HEADLOCAL]); } fprintf (stdout, "

\n\
\n\ \n\ to \n\ of \n\ ... or year \n\

\n\ months across page\n\

\n\ \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\ Calendar %d\n\ \n\ \n", SoftwareID, CgiEnvironmentPtr, Year, PageScheme[PS_BODYTAG]); if (PageScheme[PS_LAYOUT][0] == '2') { fprintf (stdout, "%s\n\ Calendar %d%s\n\ \n\


\n\
\n\
",
         PageScheme[PS_HEADLOCAL],
         Year, Range);
   }
   else
   {
      fprintf (stdout,
"\n\
%s\n\
\n\ \n\  Calendar %d%s\n\ \n\
\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\

\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); } /****************************************************************************/