/*****************************************************************************/ /* CGIplusDemo.c Simple program that can be used in both standard CGI and CGIplus environments. The standard CGI section merely echoes the remote host name (lacking any mechanism to list all variables ... apart perhaps from a SHOW SYMBOL WWW_*). The CGIplus section uses two methods to access the CGI variables. One just reads CGIPLUSIN checking each line for the required variable (and displaying them as it goes). The other uses a more sophisticated function that processes the CGIplus variables and the allows queries on variable names, etc. This function is presented as a template in CGIplusSkel.c Defining the logical name CGIPLUSDEMO$STRUCT causes this demo to use 'struct' mode rather than 'record mode' for for passing the CGIplus variables. COPYRIGHT --------- Copyright (C) 1997-2021 Mark G.Daniel Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. VERSION HISTORY (update SOFTWAREVN as well!) --------------- 06-OCT-2004 MGD v1.4.0, CGILIB object module 23-DEC-2003 MGD v1.3.2, minor conditional mods to support IA64 30-NOV-2002 MGD v1.3.1, bugfix; every second CGIplus request incorrectly having the variables read by CgiPlusReader(); 05-APR-2001 MGD v1.3.0, demo/test CGIplus variable 'struct', body via CGIPLUSIN 24-APR-1999 MGD v1.2.0, use CGILIB.C 21-JUN-1998 MGD v1.1.0, revision of CgiVar() 08-JUN-1997 MGD v1.0.0, initial development */ /*****************************************************************************/ #define SOFTWAREVN "1.4.0" #define SOFTWARENM "CGIPLUSDEMO" #ifdef __ALPHA # define SOFTWAREID SOFTWARENM " AXP-" SOFTWAREVN #endif #ifdef __ia64 # define SOFTWAREID SOFTWARENM " IA64-" SOFTWAREVN #endif #ifdef __VAX # define SOFTWAREID SOFTWARENM " VAX-" SOFTWAREVN #endif #ifdef __x86_64 # define SOFTWAREID SOFTWARENM " X86-" SOFTWAREVN #endif #ifndef __VAX # pragma nomember_alignment #endif #include #include #include #include #include #include #include char Utility [] = "CGIPLUSDEMO"; int Debug, IsCgiPlus, UsageCounter, UseCgiPlusVarStruct; char *CgiPlusEofPtr; char FirstUsedDateTime [32], NowDateTime [32]; unsigned long UnixTime; struct tm *UnixTmPtr; /*****************************************************************************/ /* */ main () { /*********/ /* begin */ /*********/ if (getenv ("CGIPLUSDEMO$DBUG")) Debug = 1; CgiLibEnvironmentSetDebug (Debug); UseCgiPlusVarStruct = (int)getenv("CGIPLUSDEMO$STRUCT"); time (&UnixTime); UnixTmPtr = localtime (&UnixTime); if (!strftime (FirstUsedDateTime, sizeof(FirstUsedDateTime), "%a, %d %b %Y %T", UnixTmPtr)) strcpy (FirstUsedDateTime, "[error]"); /* demonstrate the ease with which it may operate in both environments */ IsCgiPlus = (CgiPlusEofPtr = getenv("CGIPLUSEOF")); do { time (&UnixTime); UnixTmPtr = localtime (&UnixTime); if (!strftime (NowDateTime, sizeof(NowDateTime), "%a, %d %b %Y %T", UnixTmPtr)) strcpy (NowDateTime, "[error]"); if (IsCgiPlus) CgiPlusDemo (); else CgiStandardDemo (); } while (IsCgiPlus); exit (1); } /*****************************************************************************/ /* Using standard CGI. Get CGI variable data using getenv(), not using the function CgiLibVar() illustrated below. */ CgiStandardDemo () { char *cptr; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "CgiStandardDemo()\n"); fprintf (stdout, "Content-Type: text/plain\n\ Expires: Thu, 01 Jan 1970 00:00:01 GMT\n\ \n\ Number of times used: %d (standard CGI)\n\ First used: %s\n\ Now: %s\n\ \n", ++UsageCounter, FirstUsedDateTime, NowDateTime); if (cptr = getenv("WWW_REMOTE_ADDR")) fprintf (stdout, "Remote-Addr: %s\n", cptr); else fprintf (stdout, "Remote-Addr: NOT FOUND!\n"); } /*****************************************************************************/ /* Alternate between the two methods of obtaining CGI variables in the CGIplus environment. First, using the function CgiLibVar(), which allows specific variable names to be queried. Second, using a simple read of , checking for the variable names required. */ CgiPlusDemo () { static int WasCgiPlusVarStruct = 0; char *cptr; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "CgiPlusDemo()\n"); if (UseCgiPlusVarStruct) { /* wait for the next request */ CgiLibVar (""); fprintf (stdout, "Content-Type: text/plain\n\ Expires: Thu, 01 Jan 1970 00:00:01 GMT\n\ \n\ Number of times used: %d (CGIplus)\n\ First used: %s\n\ Now: %s\n\ Using: CgiLibVar() in %s mode\n\ \n", ++UsageCounter, FirstUsedDateTime, NowDateTime, WasCgiPlusVarStruct ? "STRUCT" : "RECORD"); /* list all CGIplus variables names and values one-by-one */ while (cptr = CgiLibVar ("*")) { if (!strncmp (cptr, "WWW_REMOTE_HOST=", 16)) fprintf (stdout, "Remote-Host: %s\n", cptr+16); else fprintf (stdout, "|%s|\n", cptr); } /* query on the supplied variable name */ fprintf (stdout, "\n"); if (*(cptr = CgiLibVar ("WWW_REMOTE_ADDR"))) fprintf (stdout, "Remote-Addr: %s\n", cptr); else fprintf (stdout, "Remote-Addr: NOT FOUND!\n"); /* illustrate variable query when not found */ if (*(cptr = CgiLibVar ("WWW_BOGUS_VARIABLE"))) fprintf (stdout, "Bogus-Variable: %s\n", cptr); else fprintf (stdout, "Bogus-Variable: NOT FOUND!\n"); if (UseCgiPlusVarStruct) { if (!WasCgiPlusVarStruct) CgiLibCgiPlusSetVarStruct (); WasCgiPlusVarStruct = 1; } else if (WasCgiPlusVarStruct) { CgiLibCgiPlusSetVarRecord (); WasCgiPlusVarStruct = 0; } } else { /* process the variables using a simple read loop */ CgiPlusReader (); } /* record-oriented , no need to flush, write end-of-output line */ fprintf (stdout, "%s\n", CgiPlusEofPtr); } /*****************************************************************************/ /* CGIplus variable access method 1 (simple). Use a simple loop to read lines from standard input. Detect specific CGI variables by checking the leading section of these lines for the required variable name. The value may then be extracted from the remaining section. */ CgiPlusReader () { # define CGIPLUS_LINE_SIZE 1024 int LineCount = 0; char *cptr; char Line [CGIPLUS_LINE_SIZE]; FILE *CgiPlusIn; /*********/ /* begin */ /*********/ if (Debug) fprintf (stdout, "CgiPlusReader()\n"); if (!(CgiPlusIn = fopen (getenv("CGIPLUSIN"), "r"))) exit (vaxc$errno); /* wait for request, discard initial record */ if (!(fgets (Line, sizeof(Line), CgiPlusIn))) exit (vaxc$errno); fprintf (stdout, "Content-Type: text/plain\n\ \n\ Number of times used: %d (CGIplus)\n\ First used: %s\n\ Now: %s\n\ Using: CgiPlusReader()\n\ \n", ++UsageCounter, FirstUsedDateTime, NowDateTime); for (;;) { if ((fgets (Line, sizeof(Line), CgiPlusIn))) exit (vaxc$errno); /* first empty line signals the end of CGIplus variables */ if (Line[0] == '\n') break; /* remove the trailing newline */ for (cptr = Line; *cptr && *cptr != '\n'; cptr++); *cptr = '\0'; /* select only the variable(s) we are interested in */ if (!strncmp (Line, "WWW_REMOTE_HOST=", 16)) fprintf (stdout, "Remote-Host: %s\n", Line+16); else fprintf (stdout, "|%s|\n", Line); } fclose (CgiPlusIn); } /*****************************************************************************/