/* *************************************************************************** * * Copyright 1992-2003 by Pete Wilson All Rights Reserved * 50 Staples Street : Lowell Massachusetts 01851 : USA * http://www.pwilson.net/ pete@pwilson.net +1 978-454-4547 * * This item is free software: you can redistribute it and/or modify it as * long as you preserve this copyright notice. Pete Wilson prepared this item * hoping it might be useful, but it has NO WARRANTY WHATEVER, not even any * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * *************************************************************************** */ /* *************************************************************************** * * cgi-FORM-INPUT-DEMO.c * * CGI to demonstrate certain button/image/submit/reset properties * Revision History: * * DATE VER DESCRIPTION * ----------- ------ ---------------------------------------------------- * 5-oct-2002 1.0 original * *************************************************************************** */ /*

cgi-FORM-INPUT-DEMO.c -- report params passed to CGI from a form
*/

#include "cgi.h"

#define YELLOW  "yellow"  /* same as yellow hiliter */
#undef YELLOW
#define YELLOW  "#ffff99" /* lighter yellow */
#undef LT_GREY
#define LT_GREY "#eeeeee" /* unobtrusive grey */


typedef struct {
    char name[128];
    char val[128];
} entry;

static int cmd_line;    /* non-zero if entered via command line */
static RM this_rm;

RM *
get_request_method(void)
{
  static RM * this_rm_p;

  int i;
  RM legal_rm[] = 
  { {"UNKNOWN",UNKNOWN },
    {"GET",    GET     }, 
    {"POST",   POST    }, 
    {"CONNECT",CONNECT },
    {"DELETE", DELETE  },
    {"HEAD",   HEAD    }, 
    {"OPTIONS",OPTIONS }, 
    {"PUT",    PUT     },
    {"TRACE",  TRACE   } };
  #define N_RM sizeof(legal_rm)/sizeof(legal_rm[0])

  if (this_rm_p == NULL) 
  {
    this_rm_p    = &this_rm;
    this_rm.name = getenv("REQUEST_METHOD"); /* is there a REQUEST_METHOD? */
    if (this_rm.name   == NULL)              /* no, we were called from command line */
    {
      this_rm.name = "";
      this_rm.val = UNKNOWN;
      cmd_line    = 1;
    }
    else
    {
      for (i = 1; i < N_RM; ++i)
      {
        if (0 == strcasecmp(legal_rm[i].name, this_rm.name))
        {
          this_rm.val = legal_rm[i].val;
          break;
        }
      }
    }
  }
  return this_rm_p;
}

void getword(char *word, char *line, char stop);
char x2c(char *what);
void unescape_url(char *url);
void plustospace(char *str);

char *
map3(char ch)
{
  static char p[2] = " ";

  p[0] = (char) ch;
  if (ch == '>') return ">";
  if (ch == '<') return "<"; 
  if (ch == '&') return "&";
  return p;
}

int
ch_to_nybble(char c)
{
  if (c >= '0' && c <= '9') return c - '0';
  return (c & 7) + 9;
}

int
remap(char c1, char c2)
{
  int i, j, k;
  j = ch_to_nybble(c1);
  k = ch_to_nybble(c2);

  i = (j << 4) | k;
  return i;
}

void
start_col_with_bg_color(char * bg_color)
{

}

void
print_name_and_val(entry * entries, int m)
{
  int x, i;

  printf("%c",10);
  /* name[x] column */
  printf("%c",10);

  /* "name[x]: */
  printf("%c",10);

  /* the name itself[x] */
  printf("%c",10);

  /* the string "val[x]" */
  printf("%c",10);

  /* the value val[x] */
  printf("%c",10);
  printf("%c",10);
  printf("
%c",10); printf("%c",10); for(x=0; x <= m; x++) { printf("name[%d]:
%c",x, 10); } printf("
%c",10); printf("%c",10); for(x=0; x <= m; x++) { printf("%s
%c",entries[x].name, 10); } printf("
%c",10); printf(""); for(x=0; x <= m; x++) { printf("val[%d]:
%c",x, 10); } printf("
"); printf("
%c",10); printf(""); for(x=0; x <= m; x++) { for(i = 0; entries[x].val[i] != '\0'; ++i) { printf("%s",map3(entries[x].val[i])); } printf("
%c", 10); } printf("
"); printf("
%c",10); } int main(int argc, char * argv[]) { int i, ch, rm; char * rm_str; /* REQUEST_METHOD */ char * qu_str; /* QUERY_STRING */ char * qu_str_temp; int qu_str_len; char qu_str_literal[2000]=""; char * temp_p; int content_length; char *cl; int x, m=0; entry entries[10000]; char stdin_literal[2000] = ""; char stdin_line[1000] = ""; int stdin_len; RM * rm_ptr; printf("Content-type: text/html%c%c%c",10,10,10); /* first of all, find REQUEST_METHOD, QUERY_STRING, and stdin rm_str = getenv("REQUEST_METHOD"); */ rm_ptr = get_request_method(); rm_str = rm_ptr->name; rm = rm_ptr->val; rm_str = get_request_method()->name; rm = get_request_method()->val; qu_str = getenv("QUERY_STRING"); if (qu_str == NULL) { qu_str = ""; } qu_str_len = strlen(qu_str); cl = qu_str; /* retrieve stdin */ i = 0; while ((ch = getchar()) != EOF) { if (i < sizeof(stdin_line)-1) { stdin_line[i] = (char)ch; stdin_line[i+1] = '\0'; } ++i; } stdin_len = i; temp_p = getenv("CONTENT_LENGTH"); content_length = (temp_p != NULL) ? atoi(temp_p) : 0; printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf(""); printf("%c",10); /* show HTTP_USER_AGENT */ printf(""); printf("%c",10); printf("", (getenv("HTTP_USER_AGENT")==NULL)?"":getenv("HTTP_USER_AGENT"), 10); printf(""); /* show all argv[0 ... argc-1] */ printf("%c",10); /* and show REQUEST_METHOD */ printf(""); printf("%c", 10); printf("", YELLOW, rm_str, 10); switch (rm) { case GET: printf("%c",10); break; case POST: printf(""); /* show QUERY_STRING and strlen QUERY_STRING */ printf("%c",10); switch (rm) { case GET: printf("%c",10); } break; default: break; } printf("%c",10); /* show QUERY_STRING */ printf(""); printf("%c",10); switch (rm) { case GET: printf("%c", YELLOW, qu_str,10); printf("%c",10); break; case POST: if (0 >= strlen(qu_str)) { printf("%c", YELLOW, qu_str,10); } break; default: printf("%c",qu_str,10); printf("%c",10); break; } printf(""); /* show plain legible query string */ printf(""); printf("%c",10); switch (rm) { case GET: printf(""); printf(""); /* show tokenized query string */ /* set up entries table */ for(x=0;cl[0] != '\0';x++) { m=x; getword(entries[x].val,cl,'&'); plustospace(entries[x].val); unescape_url(entries[x].val); getword(entries[x].name,entries[x].val,'='); } /* "tokenized" show QUERY_STRING as html-printable ascii tokens */ printf(""); printf("%c", 10); switch (rm) { /* REQUEST_METHOD mapped to int */ case GET: printf(""); printf(""); printf(""); /* QUERY_STRING "as rendered" -- show QUERY_STRING honoring markup */ printf(""); printf("%c",10); printf(""); printf(""); /* "notes" column */ printf(""); /* show num_chars on stdin and CONTENT_LENGTH */ printf(""); printf("",10); i = strlen(stdin_line); switch (rm) { case GET: printf("%c", LT_GREY, i, content_length,10); if (i > 0) { printf(""); } printf("%c",10); break; case POST: printf("%c", YELLOW, i, content_length, 10); printf("",10); break; default: printf("%c",10); break; } printf(""); /* show all on stdin: do the same thing as we did for QUERY_STRING */ printf(""); printf(""); switch (rm) { case GET: printf(""); printf(""); break; case POST: printf(""); printf("%c",10); break; default: printf("%c",10); break; } printf(""); /* stdin plain legible */ printf(""); printf("%c",10); switch (rm) { case GET: printf(""); printf(""); /* stdin "tokenized" -- show stdin tokens */ printf(""); printf("%c", 10); m = 0; if (strlen(stdin_line) > 0) { cl = stdin_line; for(x=0;cl[0] != '\0';x++) { m=x; getword(entries[x].val,cl,'&'); plustospace(entries[x].val); unescape_url(entries[x].val); getword(entries[x].name,entries[x].val,'='); } printf(""); printf(""); } else { printf("", LT_GREY); } printf("%c", 10); /* stdin rendered -- show stdin_line with images */ printf(""); printf("%c",10); printf(""); printf(""); /* "notes" column */ printf(""); printf("
Parameters passed through CGI to %s in this invocation",argv[0]); printf("
Parameter NameParameter Value; raw, undecoded QUERY_STRING and STDIN have enclosing [square brackets]Notes
HTTP_USER_AGENT%s%c
"); printf("argc
"); for (i = 0; i < argc; ++i) { printf("argv[%d]
%c",i, 10); } printf("
"); printf("%d
%c",argc, 10); for (i = 0; i < argc; ++i) { printf("%s%c
", argv[i],10); } printf("
REQUEST_METHOD%s%cThe one and only GET param -- ever! -- is QUERY_STRINGAt least three POST params: stdin; tot chars on stdin; and CONTENT_LENGTH%c",10); break; default: printf("Unknown: %s%c",rm_str,10); break; } printf("
"); printf(""); printf("QUERY_STRING ptr
%c",10); printf("strlen (0x%lx)%c",(unsigned long) qu_str, 10); printf("
0x%lx
%d%c", YELLOW, (unsigned long) qu_str, qu_str_len, 10); break; case POST: if (qu_str_len <= 0) { printf("
0x%lx
%d%c", LT_GREY, (unsigned long) qu_str, qu_str_len, 10); } else { printf("
0x%lx
%d%c", YELLOW, (unsigned long) qu_str, qu_str_len, 10); printf("
This is a POST with non-empty QUERY_STRING
QUERY_STRING[%s][%s]%c", LT_GREY, qu_str, 10); printf("POST with empty QUERY_STRING%c",10); } else { printf("[%s][%s]
QS plain%c", YELLOW, 10); break; case POST: if (strlen(qu_str) <= 0) { printf("%c", LT_GREY, 10); } else { printf("%c", YELLOW, 10); } break; default: printf("%c", 10); break; } strcpy(qu_str_literal,""); for (i = 0; i < qu_str_len; ++i) { if (qu_str[i] == '+') { printf(" "); strcat(qu_str_literal," "); } else if (qu_str[i] != '%') { printf("%c",qu_str[i]); strncat(qu_str_literal, &qu_str[i], 1); } else { ch = remap(qu_str[i+1], qu_str[i+2]); if (ch == 0x3c) { qu_str_temp = "<"; strcat(qu_str_literal,"<"); } else if (ch == 0x20) { qu_str_temp = " "; strcat(qu_str_literal,"="); } else if (ch == 0x3d) { qu_str_temp = "="; strcat(qu_str_literal,"="); } else if (ch == 0x22) { qu_str_temp = """; strcat(qu_str_literal,"\""); } else if (ch == 0x2f) { qu_str_temp = "/"; strcat(qu_str_literal,"/"); } else if (ch == 0x3e) { qu_str_temp = ">"; strcat(qu_str_literal,">"); } else if (ch == 0x21) { qu_str_temp = "!"; strcat(qu_str_literal,"!"); } else if (ch == 0x3a) { qu_str_temp = ":"; strcat(stdin_literal, ":"); } else { qu_str_temp = "*"; strcat(qu_str_literal,"*"); } if (qu_str_temp == "*") { printf("[0x%x]",ch); } else printf("%s", qu_str_temp); i += 2; } } printf("
QS tokens", YELLOW); print_name_and_val(entries, m); break; case POST: if (qu_str_len > 0) { printf("", YELLOW); print_name_and_val(entries, m); } else { printf("", LT_GREY); } break; default: printf("", LT_GREY); break; } printf("
QS rendered"); if (qu_str_len > 0) { printf("%s%c",qu_str_literal, 10); } printf("
tot stdin chars
CONTENT_LENGTH%c
%d
%d
Should not have been non-zero!%d
%d
For POST, these guys better be equal%c
STDIN[", LT_GREY); i = 0; stdin_line[0] = '\0'; while ((ch = getchar()) != EOF) { if (i < sizeof(stdin_line)-1) { stdin_line[i] = (char) ch; stdin_line[i+1] = '\0'; } printf("%c", (char)ch); ++i; } printf("]This is a GET request, so stdin should be empty", YELLOW); printf("[%s]%c",stdin_line, 10); printf("
stdin plain%c", LT_GREY, 10); break; case POST: if (stdin_len <= 0) { printf("%c", LT_GREY,10); } else { printf("%c", YELLOW, 10); } break; default: printf("%c", 10); break; } strcpy(stdin_literal, ""); for (i = 0; i < stdin_len; ++i) { if (stdin_line[i] == '+') { printf(" "); strcat(stdin_literal, " "); } else if (stdin_line[i] != '%') { printf("%c",stdin_line[i]); strncat(stdin_literal, &stdin_line[i], 1); } else { ch = remap(stdin_line[i+1], stdin_line[i+2]); if (ch == 0x3c) { qu_str_temp = "<"; strcat(stdin_literal, "<"); } else if (ch == 0x3d) { qu_str_temp = "="; strcat(stdin_literal, "="); } else if (ch == 0x22) { qu_str_temp = """; strcat(stdin_literal, "\""); } else if (ch == 0x2f) { qu_str_temp = "/"; strcat(stdin_literal, "/"); } else if (ch == 0x3e) { qu_str_temp = ">"; strcat(stdin_literal, ">"); } else if (ch == 0x21) { qu_str_temp = "!"; strcat(stdin_literal, "!"); } else if (ch == 0x3a) { qu_str_temp = ":"; strcat(stdin_literal, ":"); } else { qu_str_temp = "*"; strcat(stdin_literal, "*"); } if (qu_str_temp == "*") { printf("[0x%x]",ch); } else printf("%s", qu_str_temp); i += 2; } } printf("
stdin tokens", YELLOW); print_name_and_val(entries, m); printf("
All name[] and val[] are C strings.
stdin rendered"); if (stdin_len > 0) { printf("%s%c",stdin_literal, 10); } printf("
"); printf(""); printf("%c%c",10,10); return 1; } /*
*/