home *** CD-ROM | disk | FTP | other *** search
/ Programming with VisualAge for Java / IBMVJAVA.ISO / icswin95 / httpdw32.z / cgixmp.c < prev    next >
Text File  |  1997-04-07  |  11KB  |  378 lines

  1. #ifdef _OE_
  2. #define NULL 0
  3. #pragma csect(CODE,"IMWCIXMP")
  4. #pragma comment(date)
  5. #pragma variable(IMWID,NORENT)
  6. static char IMWID[] = "IMWCIXMP " __FILE__;
  7. #endif
  8.  
  9. /* Includes */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13.  
  14. #include "icsdebug.h"    /* general-purpose debugging header    */
  15.  
  16. #if defined(OS2)
  17. #include <os2.h>
  18. #endif
  19.  
  20. #if defined(WIN32)
  21. #include <windows.h>
  22. #endif
  23.  
  24. #include "cgixmp.h"
  25.  
  26. /* Definition of structure used in linked list of variables */
  27. typedef struct _argument
  28.   {
  29.   char *VariableName;
  30.   char *Value;
  31.   struct _argument *pNext;
  32.   } PARMLIST, *PPARMLIST;
  33.  
  34. /* Function definitions */
  35. int ErrMsg (char *msg);
  36. PPARMLIST ReadArguments(int InputLength);
  37. static void PlusesToSpaces(char *Str);
  38. static int HexVal(char c);
  39. static void TranslateEscapes(char *Str);
  40.  
  41. /******************************************************************************/
  42. /*                                                                            */
  43. /* Function       : main                                                      */
  44. /*                                                                            */
  45. /* Description    : This is a CGI program which takes the output of a form    */
  46. /*                  submitted with a method of POST, and displays a list      */
  47. /*                  of the variable names and values.                         */
  48. /*                                                                            */
  49. /******************************************************************************/
  50. main(int argc, char *argv[], char *envp[])
  51.   {
  52.   char *requestMethod;
  53.   char *contentLength;
  54.   int argLength;
  55.   PPARMLIST pParm = NULL;
  56.   PPARMLIST pHead = NULL;
  57.  
  58.   /* This CGI program must be called with a method of POST */
  59. #ifdef _OE_
  60.   requestMethod = strdup(getenv("REQUEST_METHOD"));
  61. #else
  62.   requestMethod = getenv("REQUEST_METHOD");
  63. #endif
  64.  
  65.   if ((requestMethod == NULL) ||
  66.       (stricmp(requestMethod, "POST")))
  67.     {
  68.     ErrMsg(HTML_ERROR_MSG1);
  69.     }
  70.   else
  71.     {
  72.     /* Get the length of the arguments passed in to this program */
  73. #ifdef _OE_
  74.     contentLength = strdup(getenv("CONTENT_LENGTH"));
  75. #else
  76.     contentLength = getenv("CONTENT_LENGTH");
  77. #endif
  78.  
  79.     if (contentLength == NULL)
  80.       {
  81.       ErrMsg(HTML_ERROR_MSG2);
  82.       }
  83.     else
  84.       {
  85.       /* Begin output of HTML to display results of CGI program */
  86.       printf("Content-type: text/html\n\n");
  87.       printf("<html>\n");
  88.       printf("<head>\n");
  89.       printf("<title>\n");
  90.       printf(HTML_TITLE);
  91.       printf("</title>\n");
  92.       printf("</head>\n");
  93.       printf("<body>\n");
  94.       printf("<h1>\n");
  95.       printf(HTML_HEAD);
  96.       printf("</h1>\n");
  97.       printf("<hr>\n");
  98.       printf("<p>\n");
  99.  
  100.       /* Read the arguments passed in to this program and place them in */
  101.       /* a singly linked list - one link per variable                   */
  102.       argLength = atoi(contentLength);
  103.       pHead = ReadArguments(argLength);
  104.       pParm = pHead;
  105.  
  106.       /* Output the list of variable names and values */
  107.       while (pParm)
  108.         {
  109.         printf("<pre>%s = %s</pre><p>",
  110.                pParm->VariableName,
  111.                pParm->Value);
  112.  
  113.         pParm = pParm->pNext;
  114.         }
  115.  
  116.       /* Output the remainder of the HTML used to display the results */
  117.       printf("<pre>");
  118.       printf("<p>\n");
  119.       printf("<hr>\n");
  120.       printf("</body>\n");
  121.       printf("</html>\n");
  122.       }
  123.     }
  124.   }
  125.  
  126.  
  127. /******************************************************************************/
  128. /*                                                                            */
  129. /* Function       : ReadArguments                                             */
  130. /*                                                                            */
  131. /* Description    : Read the arguments from stdin that are supplied           */
  132. /*                  to a CGI program when the method is POST.                 */
  133. /*                  Breaks up the input into (Variable, Value) pairs.         */
  134. /*                  Handles translating of all the special characters         */
  135. /*                  that HTTP puts into the strings.                          */
  136. /*                                                                            */
  137. /******************************************************************************/
  138. PPARMLIST ReadArguments(int InputLength)
  139.   {
  140.   PPARMLIST pCur= NULL;
  141.   PPARMLIST pHead= NULL;
  142.   PPARMLIST pPrev= NULL;
  143.   char *Input;
  144.   char *pToken;
  145.  
  146.   if (InputLength < 1)
  147.     {
  148.     return(NULL);
  149.     }
  150.  
  151.   /* Allocate a buffer for the input */
  152.   Input = malloc(InputLength + 1);
  153.  
  154.   if (Input == NULL)
  155.     {
  156.     return(NULL);
  157.     }
  158.  
  159.   /* Read the input */
  160.   gets(Input);
  161.  
  162.   /* Variables are separated by the "&" character */
  163.   pToken = strtok(Input, "&");
  164.  
  165.   while (pToken)
  166.     {
  167.     /* Create and fill in linked list of variable information */
  168.     pCur = malloc(sizeof(PARMLIST));
  169.     pCur->VariableName = pToken;
  170.     pToken = strchr(pToken, '=');
  171.  
  172.     if (pToken)
  173.       {
  174.       *pToken = '\0';
  175.       pCur->Value = ++pToken;
  176.       PlusesToSpaces( pToken );
  177.       TranslateEscapes( pToken );
  178.       }
  179.     else
  180.       {
  181.       pCur->Value = NULL;
  182.       }
  183.  
  184.     if (pPrev)
  185.       {
  186.       pPrev->pNext = pCur;
  187.       }
  188.  
  189.     if (!pHead)
  190.       {
  191.       pHead = pCur;
  192.       }
  193.  
  194.     pPrev = pCur;
  195.     pToken = strtok(NULL, "&");
  196.     }
  197.  
  198.   if (pHead)
  199.     {
  200.     pPrev->pNext = NULL;
  201.     }
  202.  
  203.   return(pHead);
  204.   }
  205.  
  206. /******************************************************************************/
  207. /*                                                                            */
  208. /* Function       : PlusesToSpaces (STATIC)                                   */
  209. /*                                                                            */
  210. /* Description    : This one's easy. It just translates any '+'               */
  211. /*                  characters found into ' ' characters.                     */
  212. /*                                                                            */
  213. /******************************************************************************/
  214. static void PlusesToSpaces(char *Str)
  215.   {
  216.   if (Str != NULL)
  217.     {
  218.     while (*Str != '\0')
  219.       {
  220.       if (*Str == '+')
  221.         {
  222.         *Str = ' ';
  223.         }
  224.  
  225.       ++Str;
  226.       }
  227.     }
  228.   }
  229.  
  230. /******************************************************************************/
  231. /*                                                                            */
  232. /* Function       : HexVal (STATIC)                                           */
  233. /*                                                                            */
  234. /* Description    : This function returns a number that corresponds           */
  235. /*                  corresponds to the value of a character treated as        */
  236. /*                  a hex digit. Case insensitive. Characters outside         */
  237. /*                  0-9,a-f,A-F have a value of 0.                            */
  238. /*                                                                            */
  239. /******************************************************************************/
  240. static int HexVal(char c)
  241.   {
  242.   int rc;
  243.  
  244.   switch (c)
  245.     {
  246.     case '1':
  247.       rc = 1;
  248.       break;
  249.  
  250.     case '2':
  251.       rc = 2;
  252.       break;
  253.  
  254.     case '3':
  255.       rc = 3;
  256.       break;
  257.  
  258.     case '4':
  259.       rc = 4;
  260.       break;
  261.  
  262.     case '5':
  263.       rc = 5;
  264.       break;
  265.  
  266.     case '6':
  267.       rc = 6;
  268.       break;
  269.  
  270.     case '7':
  271.       rc = 7;
  272.       break;
  273.  
  274.     case '8':
  275.       rc = 8;
  276.       break;
  277.  
  278.     case '9':
  279.       rc = 9;
  280.       break;
  281.  
  282.     case 'A':
  283.     case 'a':
  284.       rc = 10;
  285.       break;
  286.  
  287.     case 'B':
  288.     case 'b':
  289.       rc = 11;
  290.       break;
  291.  
  292.     case 'C':
  293.     case 'c':
  294.       rc = 12;
  295.       break;
  296.  
  297.     case 'D':
  298.     case 'd':
  299.       rc = 13;
  300.       break;
  301.  
  302.     case 'E':
  303.     case 'e':
  304.       rc = 14;
  305.       break;
  306.  
  307.     case 'F':
  308.     case 'f':
  309.       rc = 15;
  310.       break;
  311.  
  312.     default:
  313.       rc = 0;
  314.       break;
  315.     }
  316.  
  317.   return(rc);
  318.   }
  319.  
  320. /******************************************************************************/
  321. /*                                                                            */
  322. /* Function       : TranslateEscapes (STATIC)                                 */
  323. /*                                                                            */
  324. /* Description    : Translate the escape sequences induced by HTTP. The       */
  325. /*                  sequences consist of %xx, where xx is a hex number.       */
  326. /*                  We replace the % character with the actual character      */
  327. /*                  (i.e., the one whose ASCII value is xx), and then         */
  328. /*                  shift over the rest of the string to remove the xx.       */
  329. /*                  This is done in-place.                                    */
  330. /*                                                                            */
  331. /******************************************************************************/
  332. static void TranslateEscapes(char *Str)
  333.   {
  334.   char *NextEscape;
  335.   char RealValue;
  336.   int AsciiValue;
  337.  
  338.   NextEscape = strchr(Str, '%');
  339.  
  340.   while (NextEscape != NULL)
  341.     {
  342.     AsciiValue = (16 * HexVal(NextEscape[1])) + HexVal(NextEscape[2]);
  343.     *NextEscape = (char) AsciiValue;
  344.     memmove(&NextEscape[1], &NextEscape[3], strlen(&NextEscape[3]) + 1);
  345.     NextEscape = strchr(&NextEscape[1], '%');
  346.     }
  347.   }
  348.  
  349.  
  350. /******************************************************************************/
  351. /* This function will output a message if an error occurs when attempting     */
  352. /* to display a HTML page.                                                    */
  353. /******************************************************************************/
  354. int ErrMsg (char *msg)
  355.   {
  356.   printf("Content-type: text/html\n\n");
  357.   printf("<html>\n");
  358.   printf("<head>\n");
  359.   printf("<title>\n");
  360.   printf(HTML_ERROR_TITLE);
  361.   printf("</title>\n");
  362.   printf("</head>\n");
  363.   printf("<body>\n");
  364.   printf("<h1>\n");
  365.   printf(HTML_ERROR_HEAD);
  366.   printf("</h1>\n");
  367.   printf("<hr>\n");
  368.   printf("<p>\n");
  369.   printf(HTML_ERROR_TEXT);
  370.   printf("<p>\n");
  371.   printf("<pre>%s</pre>\n<p>", msg);
  372.   printf("<p>\n");
  373.   printf("<hr>\n");
  374.   printf("</body>\n");
  375.   printf("</html>\n");
  376.   return(TRUE);
  377.   }
  378.