Solved

need cgi in c on unix

Posted on 1998-02-16
3
163 Views
Last Modified: 2013-12-25
I need a cgi program to be written in C and run on AIX.
It will take in variables from a form thru' POST method.
The CGI program will simply read inputs from the form and ouput the values to an output text file.
Any idea how I can do this?  
0
Comment
Question by:slok
  • 2
3 Comments
 
LVL 5

Accepted Solution

by:
julio011597 earned 150 total points
ID: 1831996
Here is some code borrowed from my personal library:

--//--
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/errno.h>

#define output_file "/path_to_an/output.file"

#define MAX_KEY 32    /* max length of a key string */
#define MAX_VALUE 128 /* max length of a value string */

/* the key-value pairs structure */
typedef struct {
  char key[MAX_KEY];
  char value[MAX_VALUE];
} key_value;


/* local functions */
static char *get_query(void);
static int parse_query(char *, key_value **);
static void process_query(int, key_value *, FILE *);

/* to store error messages */
static char err_str[128];

void err()
{
  fputs("<HTML><BODY>\n", stdout);
  fprintf(stdout, "<H3>%s</H3>\n", str);
  fputs("</BODY></HTML>\n", stdout);

  exit(EXIT_SUCCESS);
}

int main(void)
{
  FILE *fp;
  char *query_str; /* query string */
  key_value *pkv;  /* key_value pairs */
  int kv_no;       /* key_value pairs count */

  fputs("Content-Type: text/html\n\n", stdout);
  fflush(stdout);

  if(!(fp = fopen(output_file, "a"))) {
    strcpy(err_str, "Internal error: please contact administrator");
    out_err();
  }

  if(!(query_str = get_query())) out_err();

  if(!(kv_no = parse_query(query_str, &pkv))) out_err();
  }

  /* print out results */
  process_query(kv_no, pkv, fp);

  fclose(fp);

  return EXIT_SUCCESS;
}


static char *
get_query(void)
{
  char *temp, *str;
  size_t size;

  if(!(temp = getenv("REQUEST_METHOD"))) {
    strcpy(err_str, "Cannot get REQUEST_METHOD");
    return NULL;
  }

  if(!strcmp(temp, "POST")) {                   /* method is POST */
    if(!(temp = getenv("CONTENT_LENGTH"))) {
      strcpy(err_str, "Cannot get CONTENT_LENGTH");
      return NULL;
    }
    size = atoi(temp)+1;
    if(!(str = malloc(size+1))) { /* an extra char for faster parsing */
      sprintf(err_str, "Cannot allocate query string: %s", strerror(errno));
      return NULL;
    }
    fgets(str, size, stdin);
    return str;
  }

  /* unknown method */
  sprintf(err_str, "Unsupported REQUEST_METHOD: %s", temp);
  return NULL;
}


#define PURGE(s) do {                                          \
  register char *curs, *base;                                    \
                                                      \
  for(curs=base=(s); *curs; curs++, base++)                        \
    switch(*curs) {                                          \
      case '+':                                                \
        *base = ' ';                                          \
        break;                                                \
      case '%':                                                \
        curs++;                                                \
        *curs = *curs < 65 ? *curs - 48 : (*curs & 0xdf) - 55;            \
        curs++;                                                \
        *curs = *curs < 65 ? *curs - 48 : (*curs & 0xdf) - 55;            \
        *base = (*(curs-1) << 4) | *curs;                        \
        break;                                                \
      default:                                                \
        *base = *curs;                                          \
    }                                                      \
  *base = 0;                                                \
} while(0)

static int
parse_query(char *query_str, key_value **ppkv)
{
  register char *qstr;
  register int i, which;
  int kv_no;
  key_value *pkv;

  if(!*query_str) {
    strcpy(err_str, "Empty query");
    return 0;
  }
  strcat(query_str, "&"); /* here is the extra char */

  /* first pass to get number of key-value pairs */
  for(kv_no=0, qstr=query_str; *qstr; qstr++)
    if(*qstr == '&') kv_no++;
  if(!(*ppkv = malloc(kv_no * sizeof(key_value)))) {
    sprintf(err_str, "Cannot allocate key-value pairs: %s", strerror(errno));
    return 0;
  }

  for(i=0, which=1, pkv=*ppkv, qstr=query_str; *qstr;)
    switch(*qstr) {
      case '=':
        pkv->key[i] = 0;
        i = 0;
        which = 0;
        qstr++;
        break;
      case '&':
        if(which) {
          pkv->key[i] = 0;
          PURGE(pkv->key);
        }
        else {
          pkv->value[i] = 0;
          PURGE(pkv->value);
        }
        i = 0;
        which = 1;
        pkv++;
        qstr++;
        break;
      default:
        if(which) {
          pkv->key[i++] = *qstr;
          if(i == MAX_KEY-1) for(; *qstr!='=' && *qstr!='&'; qstr++);
          else qstr++;
        }
        else {
          pkv->value[i++] = *qstr;
          if(i == MAX_VALUE-1) for(; *qstr!='&'; qstr++);
          else qstr++;
        }
    }

  return kv_no;
}


static void
process_query(int kv_no, key_value *pkv, FILE *fp)
{
  register int i;
  register key_value *_pkv;

  fputs("<HTML><BODY>\n", stdout);
  fputs("<H3>Here's the form you submitted:<H3>\n", stdout);
  fputs("<TABLE BORDER>\n", stdout);
  fputs("<STRONG><TR><TD>Keys</TD><TD>Values</TD></TR></STRONG>\n", stdout);

  for(_pkv=pkv, i=0; i<kv_no; i++, _pkv++) {
    fprintf(fp, "%s = %s\n", _pkv->key, _pkv->value);
    fprintf(stdout, "<TR><TD>%s</TD><TD>%s</TD></TR>\n", _pkv->key, _pkv->value);
  }

  fputs("</TABLE></BODY></HTML>\n", stdout);

  fputs("----\n", fp);
}
--//--

Please, check the includes on your OS.
And be sure, if you cut and paste, to eliminate trailing blanks from the PURGE(s) macro lines (otherwise you'll get a mess of error messages).

HTH, julio

BTW, would you mind increasing a bit the points?
0
 
LVL 5

Expert Comment

by:julio011597
ID: 1831997
Sorry, where is:

void err()

should be:

void out_err(void)
0
 
LVL 3

Author Comment

by:slok
ID: 1831998
thanks... I have up the points for it.
I will try it out and get back to you.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Suggested Solutions

Preface In the first article: A Better Website Login System (http://www.experts-exchange.com/A_2902.html) I introduced the EE Collaborative Login System and its intended purpose. In this article I will discuss some of the design consideratio…
Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now