/*****************************************************************************/
/*
                               CGIcallout.c


Very simple, "standard" CGI script illustrating the use of callouts.

Also see CGICALLOUTPROC.COM which is a similar example in DCL.

Remember, the behaviour of these scripts can be WATCHed to gain further insight
into how this is implemented.


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

  $ @BUILD_ONE BUILD CGICALLOUT
  $ @BUILD_ONE LINK CGICALLOUT


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 <errno.h>
#include <stdio.h>
#include <string.h>

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

main ()
       
{
   int  status;
   char  *CgiPlusEscPtr,
         *CgiPlusEotPtr,
         *CgiPathInfoPtr,
         *FileNamePtr;
   char  CalloutResponse [256];
   FILE  *CgiPlusIn;

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

   /* get the callout escape sequences */
   CgiPlusEscPtr = getenv ("CGIPLUSESC");
   CgiPlusEotPtr = getenv ("CGIPLUSEOT");
   if (CgiPlusEscPtr == NULL || CgiPlusEotPtr == NULL)
   {
      puts ("Error: callout environment not detected!\n");
      exit (1);
   }
   /* open the stream that provides the server callout response */
   if ((CgiPlusIn = fopen ("CGIPLUSIN:", "r")) == NULL)
   {
      status = vaxc$errno;
      puts ("Error: opening CGIPLUSIN stream!\n");
      exit (status);
   }

   /***************/
   /* page output */
   /***************/

   /* "standard" CGI response header (plus start of page) */
   puts (
"Content-Type: text/plain\n\
\n\
CGI variable symbols:\n");

   /* just show the CGI variables (DCL symbols) */
   system ("SHOW SYMBOL WWW_*");

   CgiPathInfoPtr = getenv ("WWW_PATH_INFO");
   if (CgiPathInfoPtr == NULL) CgiPathInfoPtr = "";

   printf (
"\n\
\n\
Map path \"%s\"%s to a file specification.\n\
\n\
  This will be done using a callout of \"MAP-PATH: %s\"\n\
\n",
      CgiPathInfoPtr,
      CgiPathInfoPtr[0] ? "" : " (empty path, will be an error)",
      CgiPathInfoPtr);

   /****************************************************/
   /* here's the actual callout (expanded for clarity) */
   /****************************************************/

   /* first, the "escape" sequence record */
   printf ("%s\n", CgiPlusEscPtr);

   /* next, write the callout request to the server */
   fprintf (stdout, "MAP-PATH: %s\n", CgiPathInfoPtr);

   /* last, the "end-of-text" sequence record */
   printf ("%s\n", CgiPlusEotPtr);

   /* read the callout response sent by the server */
   fgets (CalloutResponse, sizeof(CalloutResponse), CgiPlusIn);
   /* just trim the trailing newline from the response record */
   *(strchr (CalloutResponse, '\n')) = '\0';

   /***************/
   /* page output */
   /***************/

   printf (
"  The server responded with: \"%s\"\n\
\n\
  %c%c%c is a %s code, hence the %s is \"%s\"\n",
      CalloutResponse,
      CalloutResponse[0], CalloutResponse[1], CalloutResponse[2],
      CalloutResponse[0] == '2' ? "success" : "error",
      CalloutResponse[0] == '2' ? "file specification" : "error message",
      CalloutResponse+4);

   if (CalloutResponse[0] == '2')
   {
      FileNamePtr = CalloutResponse + 4;
      printf (
"\n\
\n\
Now map this file specification back to a path.\n\
\n\
  This will be done using a callout of \"MAP-FILE: %s\"\n\
\n",
         FileNamePtr);

      /*************************************************/
      /* here's the second callout (more concise form) */
      /*************************************************/

      /* this works with record-oriented <stdout> (the default) */ 
      printf ("%s\n%s: %s\n%s\n",
              CgiPlusEscPtr,
              "MAP-FILE", FileNamePtr,
              CgiPlusEotPtr);

      fgets (CalloutResponse, sizeof(CalloutResponse), CgiPlusIn);
      /* just trim the trailing newline from the record */
      *(strchr (CalloutResponse, '\n')) = '\0';

      /***************/
      /* page output */
      /***************/

      printf (
"  The server responded with: \"%s\"\n\
\n\
  %c%c%c is a %s code, hence the %s is \"%s\"\n\
\n",
         CalloutResponse,
         CalloutResponse[0], CalloutResponse[1], CalloutResponse[2],
         CalloutResponse[0] == '2' ? "success" : "error",
         CalloutResponse[0] == '2' ? "path" : "error message",
         CalloutResponse+4);
   }
   else
   {
      printf (
"\n\
\n\
As an error occured in the first callout, the second, to map it back to a\n\
path, will not be done.  \
Append a path to the script URL and see what happens!\n");
   }

   /***************************************/
   /* explicit records for binary streams */
   /***************************************/

   /*
      Callouts may still be used even if the output stream has
      been made binary (not record-oriented, in C a "ctx=bin").
      Explicit fflush()es are required to provide the "records".
      (note: this may be WATCHed but produces no page output!)
   */

   fflush (stdout);
   puts (CgiPlusEscPtr);
   fflush (stdout);

   puts ("NOOP:");
   fflush (stdout);

   puts (CgiPlusEotPtr);
   fflush (stdout);

   fgets (CalloutResponse, sizeof(CalloutResponse), CgiPlusIn);
}

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

