/*****************************************************************************/
/*
                            CGIplusCallout.c


Example CGIplus script illustrating the use of callouts.

Uses the CGILIB routines.

Also see CGIPLUSCALLOUTPROC.COM which directly manipulates the required
environment variables, etc., and so could be used as an example for creating
non-C-language scripts and agents.


BUILD DETAILS
-------------
See BUILD_ONE.COM procedure.

  $ @BUILD_ONE BUILD CGIPLUSCALLOUT
  $ @BUILD_ONE LINK CGIPLUSCALLOUT


COPYRIGHT
---------
Copyright (c) 1999 Mark G.Daniel
This program, comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under the conditions of the GNU GENERAL PUBLIC LICENSE, version 2.


VERSION HISTORY
---------------
06-SEP-1999  MGD  v1.0.0, initial development
*/

/*****************************************************************************/

/* standard C header files */
#include <ctype.h>
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

/*****************************************************************************/
/*
Include the CGILIB.H/.C function code from the standard WASD location if
CGILIB_INCLUDE_H/_C has not been defined.  If it has been defined then the
value must be the #include location.
*/

/* indicate required functionality */
#define CGILIB_CGIVAR_SUPPORT    1
#define CGILIB_CGIPLUS_SUPPORT   1
#define CGILIB_GENERAL_SUPPORT   1
#define CGILIB_RESPONSE_SUPPORT  1

#define CGILIB_DEBUG (0)

#ifndef CGILIB_INCLUDE_H
#   include "/ht_root/src/misc/cgilib.h"
#   include "/ht_root/src/misc/cgilib.c"
#else
#   include CGILIB_INCLUDE_H
#   include CGILIB_INCLUDE_C
#endif

/*****************************************************************************/
/*
*/

main ()
       
{
   int  status;

   /*********/
   /* begin */
   /*********/

   CgiLibEnvironmentInit (0, NULL, 0);

   /* MUST only be executed in a CGIplus environment! */
   if (!CgiLibEnvironmentIsCgiPlus ()) exit (SS$_ABORT);

   for (;;)
   {
      /* block waiting for the next request */
      CgiLibVar ("");
      ProcessRequest ();
      CgiLibCgiPlusEOF ();
   }
}

/*****************************************************************************/
/*
Main authentication request processing function.
*/

ProcessRequest ()
       
{
   static int  UsageCount = 0;

   char  ExampleFile [] = "HT_ROOT:[SRC.HTTPD]", 
         ExamplePath [] = "/ht_root/src/httpd/";

   char  Response [256];

  /*********/
   /* begin */
   /*********/

   UsageCount++;

   CgiLibResponseHeader (200, "text/html");

   fprintf (stdout,
"<B><U>CGIPLUSCALLOUT.C</U></B>\n\
<P>Usage count: %d\n\
\
<P>This script provides a simple demonstration of the CGIplus <I>callout</I>\n\
facility, used to suspend normal script output and communicate directly with\n\
the server.  This allows the script to request information from the server,\n\
or set certain script operating parameters, etc.\n\
\
<P>To begin an <I>callout</I> the CGIPLUSESC environment variable (logical\n\
name) is output as a record.  For this script it has a value of:\n\
<PRE>  %s</PRE>\n\
<P>(but of course is not static, and varies each time the script is first\n\
executed).\n\
\
<P>A single-record script request followed by a single-record server response\n\
dialog may then be engaged in.\n\
\
<P>To end an <I>callout</I> the CGIPLUSEOT environment variable (logical\n\
name) is output as a record.  For this script it has a value of:\n\
<PRE>  %s</PRE>\n\
<P>(and also will vary each time the script is first executed).\n\
\
<P>Normal script output (to the browser) is then resumed.  When in\n\
<I>callout</I> mode one or more request/responses may be made.  Normal and\n\
callout output may be interleaved during a script response, as this script\n\
illustrates.\n\
\
<P><B><U>Example Behaviour</U></B>\n\
\
<UL>\n\
\
<LI>Translating a URL-style path to a VMS file specification:\n\
<PRE>  %s</PRE>\n\
<P>The request sent to the server was:\n\
<PRE>  MAP-PATH: %s</PRE>\n",
      UsageCount, getenv("CGIPLUSESC"), getenv("CGIPLUSEOT"),
      ExamplePath, ExamplePath);

   /* provide the server attention "escape" sequence record */
   CgiLibCgiPlusESC ();
   /* remember, this dialog is record-oriented, so fflush() as necessary */
   fprintf (stdout, "MAP-PATH: %s", ExamplePath);
   fflush (stdout);
   CgiLibCgiPlusInGets (Response, sizeof(Response));
   /* provide the "escape" end-of-text sequence record */
   CgiLibCgiPlusEOT ();

   fprintf (stdout,
"<P>The full server response was:\n\
<PRE>  %s</PRE>\n\
<P> Yielding a file specification of:\n\
<PRE>  %s</PRE>\n\
\
<LI>Now a translation of a VMS file specification into a URL-style path:\n\
<PRE>  %s</PRE>\n\
<P>The request sent to the server was:\n\
<PRE>  MAP-FILE: %s</PRE>\n",
      Response, Response+4,
      ExampleFile, ExampleFile);

   CgiLibCgiPlusESC ();
   fprintf (stdout, "MAP-FILE: %s", ExampleFile);
   fflush (stdout);
   CgiLibCgiPlusInGets (Response, sizeof(Response));
   CgiLibCgiPlusEOT ();

   fprintf (stdout,
"<P>The full server response was:\n\
<PRE>  %s</PRE>\n\
<P> Yielding a path of:\n\
<PRE>  %s</PRE>\n\
\
<LI>Finally an error response to an unknown callout request:\n\
<P>The request sent to the server was:\n\
<PRE>  UNKNOWN?: %s</PRE>\n",
      Response, Response+4,
      ExampleFile);

   CgiLibCgiPlusESC ();
   fprintf (stdout, "UNKNOWN: %s", ExampleFile);
   fflush (stdout);
   CgiLibCgiPlusInGets (Response, sizeof(Response));
   CgiLibCgiPlusEOT ();

   fprintf (stdout,
"<P>The full server response was:\n\
<PRE>  %s</PRE>\n\
\
</UL>\n\
\
<B><U>Comments</U></B>\n\
<P>Success responses begin with an HTTP-like &quot;200&quot;,\n\
other responses with appropriate status codes.\n",
      Response);
}

/*****************************************************************************/

