#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "cgi_c/www.h"

#define TRUE (0==0)
#define FALSE (0!=0)

static stringArray name;  /* name[i]  is a string of char with a passed name */
static stringArray value; /* value[i] is a string of char with a passed value */
static int num;

void safeprint(FILE *f, char *s)
{
  int c;
  if (s == NULL) return;
  for (;;) {
    c = *s++;
    if (c == '\0') break;
    if (isprint(c) && (c != '"') && (c != '[') && (c != '\\')) {
      fputc(c, f);
    } else {
      if (c != 13) {
        if ((c == '"') || (c == '\\')) fprintf(f, "\\%c", c);
        else if (c == '\n') fprintf(f, "\\n"); 
        else  fprintf(f, "[%02x]", c);
      }
    }
  }
}

void dumpresults(stringArray name, stringArray value, int num)
{
  char command[1024];
  char *s, *caller, *dest, ip[128], rname[1024];
  FILE *resultfile;
  int i, quad;

    caller = getenv("REMOTE_ADDR");
    if (caller == NULL) {
      fprintf(stdout, "Not called from the web???\n");
    } else {

    s = caller;
    dest = ip;
    for (quad = 0; quad < 4; quad++) {
      i = 0;
      if (isdigit(s[i])
          && ((s[i+1] == '.') || (s[i+1] == '-') || (s[i+1] == ',') || (s[i+1] == '\0'))) {
        // insert two zeroes
        dest += sprintf(dest, "00%c%c", s[i], s[i+1]);
        i += 2; s += 2;
      } else if (isdigit(s[i]) && isdigit(s[i+1])
                  && ((s[i+2] == '.') || (s[i+2] == '-') || (s[i+2] == ',') || (s[i+2] == '\0'))) {
        // insert one zero
        dest += sprintf(dest, "0%c%c%c", s[i], s[i+1], s[i+2]);
        i += 3; s += 3;
      } else if (isdigit(s[i]) && isdigit(s[i+1]) && isdigit(s[i+2])) {
        dest += sprintf(dest, "%c%c%c%c", s[i], s[i+1], s[i+2], s[i+3]);
        i += 4; s += 4;
      } else {
        break;
      }
    }
    }
    //fprintf(stdout, "Your IP address is %s\n", ip);
    sprintf(rname, "/home/gtoal/survey/%s", ip);
    resultfile = fopen(rname, "a");
    if (resultfile == NULL) resultfile = fopen(rname, "w");
    if (resultfile == NULL) {
      printf("<H1>ERROR WRITING RESULTS TO FILE.  PLEASE PRINT THIS");
      printf(" AND SUBMIT TO Graham Toal / NCC1.510A - THANK YOU</H1>\n");
      resultfile = fopen("/dev/null", "w"); // should always work
    }
    fprintf(resultfile, "# ------------------------------------------------\n");
    fprintf(resultfile, "Q00000000 = \"%s\"\n", ip);
  for(i=0; i < num; i++) {
    if (strcmp(name[i], "action") != 0) {
      if (strcmp(name[i], "nextpage") != 0) {
        safeprint(resultfile, name[i]);
        fprintf(resultfile, " = \"");
        safeprint(resultfile, value[i]);
        fprintf(resultfile, "\"\n");
      }
    }
  }
    fclose(resultfile);
  fprintf(stdout, "<ul>\n");
  for(i=0; i < num; i++) {
    if (strcmp(name[i], "action") != 0) {
      if (strcmp(name[i], "nextpage") != 0) {
        fprintf(stdout, "<li> <code>%s = %s</code>\n",
                name[i],
                (value[i] == NULL ? "" : value[i])
        );
      }
    }
  }
  fprintf(stdout, "</ul>\nThe data above has now been saved.\n");
}

void dump_backup_copy(stringArray name, stringArray value, int num)
{
  char command[1024];
  char *s, *caller, *dest, ip[128], rname[1024];
  FILE *resultfile;
  int i, quad;

    caller = getenv("REMOTE_ADDR");
    if (caller == NULL) {
//      fprintf(stdout, "Not called from the web???\n");
    } else {

    s = caller;
    dest = ip;
    for (quad = 0; quad < 4; quad++) {
      i = 0;
      if (isdigit(s[i])
          && ((s[i+1] == '.') || (s[i+1] == '-') || (s[i+1] == ',') || (s[i+1] == '\0'))) {
        // insert two zeroes
        dest += sprintf(dest, "00%c%c", s[i], s[i+1]);
        i += 2; s += 2;
      } else if (isdigit(s[i]) && isdigit(s[i+1])
                  && ((s[i+2] == '.') || (s[i+2] == '-') || (s[i+2] == ',') || (s[i+2] == '\0'))) {
        // insert one zero
        dest += sprintf(dest, "0%c%c%c", s[i], s[i+1], s[i+2]);
        i += 3; s += 3;
      } else if (isdigit(s[i]) && isdigit(s[i+1]) && isdigit(s[i+2])) {
        dest += sprintf(dest, "%c%c%c%c", s[i], s[i+1], s[i+2], s[i+3]);
        i += 4; s += 4;
      } else {
        break;
      }
    }
    }
    //fprintf(stdout, "Your IP address is %s\n", ip);
    sprintf(rname, "/home/gtoal/survey/%s.BAK", ip);
    resultfile = fopen(rname, "a");
    if (resultfile == NULL) resultfile = fopen(rname, "w");
    if (resultfile == NULL) {
//      printf("<H1>ERROR WRITING RESULTS TO FILE.  PLEASE PRINT THIS");
//      printf(" AND SUBMIT TO Graham Toal / NCC1.510A - THANK YOU</H1>\n");
      resultfile = fopen("/dev/null", "w"); // should always work
    }
    fprintf(resultfile, "# ------------------------------------------------\n");
    fprintf(resultfile, "Q00000000 = \"%s\"\n", ip);
  for(i=0; i < num; i++) {
    if (strcmp(name[i], "action") != 0) {
      if (strcmp(name[i], "nextpage") != 0) {
        safeprint(resultfile, name[i]);
        fprintf(resultfile, " = \"");
        safeprint(resultfile, value[i]);
        fprintf(resultfile, "\"\n");
      }
    }
  }
  fclose(resultfile);
}

void dumpargs(stringArray name, stringArray value, int num)
{
  int i;
  char *s;

#ifdef NEVER
  fprintf(stdout, "<ul>\n");
  for(i=0; i < num; i++) {
    if (strcmp(name[i], "action") != 0) {
      if (strcmp(name[i], "nextpage") != 0) {
        fprintf(stdout, "<li> <code>%s = %s</code>\n",
                name[i],
                (value[i] == NULL ? "" : value[i])
        );
      }
    }
  }
  fprintf(stdout, "</ul>\n");
#endif
  for(i=0; i < num; i++) {
    if (strcmp(name[i], "action") != 0) {
      if (strcmp(name[i], "nextpage") != 0) {
        fprintf(stdout, "<INPUT TYPE=HIDDEN NAME=\"%s\" VALUE=\"%s\">\n",
                name[i],
                (value[i] == NULL ? "" : value[i])
        );
      }
    }
  }
}

char *getparam(char *target, int num, char **name, char **value)
{
  int i;
  for (i = 0; i < num; i++) {
    if ((name[i] != NULL) && (strcasecmp(target, name[i])==0)) {
      return(value[i]);
    }
  }
  return("");
}


void cgi_bin(int argc, char **argv)
{
  char command[1024];
  char *s, *caller, *dest, ip[128];
  int i, quad;
  if (strcasecmp(getenv("REQUEST_METHOD"), "GET") == 0) {
    fprintf(stdout, "Content-type: text/html\n");
    fprintf(stdout, "\n");
    fprintf(stdout, "<HTML>\n<HEAD><TITLE>Don't use GET<TITLE></HEAD>\n<BODY>\n");
    fflush(stdout);
  } else if (strcasecmp(getenv("REQUEST_METHOD"), "POST") == 0) {
    fprintf(stdout, "Content-type: text/html\n");
    fprintf(stdout, "\n");
    { FILE *file;
      static char survey[1024];
      int c, rc, nextpage;
      char *uncheckednextpage = getparam("nextpage", num, name, value);

// 1000 => choose depending on Q00000568
//      0=>16
//      1=>5
//      2=>4
// 1001 => choose depending on Q00000780
//      0 => 16
//      1 => 16
//      2 => 6
      rc = sscanf(uncheckednextpage, "%d", &nextpage);
      if (rc != 1) nextpage = 911;

      if (nextpage == 1000) {
        char *button = getparam("Q00000568", num, name, value);
        if (*button == '0') nextpage = 16;
        else if (*button == '1') nextpage = 5;
        else if (*button == '2') nextpage = 4;
        else nextpage = 5; // no choice
      } else if (nextpage == 1001) {
        char *button = getparam("Q00000780", num, name, value);
        if (*button == '0') nextpage = 16;
        else if (*button == '1') nextpage = 16;
        else if (*button == '2') nextpage = 6;
        else nextpage = 6; // no choice
      }


      sprintf(survey, "/home/httpd/html/survey/survey%d.html", nextpage);
      file = fopen(survey, "r");
      if (file == NULL) {
        fprintf(stdout, "<HTML>\n<HEAD><TITLE>Can't open page %d<TITLE></HEAD>\n<BODY>\n", nextpage);
      } else {
        for (;;) {
          c = fgetc(file);
          if (c == EOF) break;
          if (c == '$') {
            dumpargs(name, value, num);
          } else if (c == '\\') {
            dumpresults(name, value, num);
          } else {
            putchar(c);
          }
        }
        dump_backup_copy(name, value, num);
      }
    }
    fflush(stdout);
  } else {
    /* ERROR */
    fprintf(stdout, "<HTML>\n<HEAD><TITLE>ERROR<TITLE></HEAD>\n<BODY>\n");
  }

  fprintf(stdout, "</BODY></HTML>\n\n");
  exit(0);
}

int main(int argc, char **argv)
{
  num = getnamevalue(&name, &value);
  if (num == 1) {
    // bug fix
    if ((name[0] == NULL) && (value[0] == NULL)) num -= 1;
  }

  cgi_bin(argc, argv);
  exit(0);
  return(0);
}

