# 3. Routines

[ Next | Up to Table of Contents | Previous ]

## 3.1. cgi-lib.h

### Library Variables

cgi-lib.h defines constants for the standard CGI environment variables. For instance, the value of the environment variable QUERY_STRING is stored in the constant `QUERY_STRING` in cgi-lib.h. Here is a list of the constants:

- SERVER_SOFTWARE
- SERVER_NAME
- GATEWAY_INTERFACE
- SERVER_PROTOCOL
- SERVER_PORT
- REQUEST_METHOD
- PATH_INFO
- PATH_TRANSLATED
- SCRIPT_NAME
- QUERY_STRING
- REMOTE_HOST
- REMOTE_ADDR
- AUTH_TYPE
- REMOTE_USER
- REMOTE_IDENT
- CONTENT_TYPE
- CONTENT_LENGTH
- HTTP_USER_AGENT

### Library functions

- short accept_image()
- void unescape_url()
- int read_cgi_input(llist *entries);
- char* cgi_val(llist l, char *name);
- char **cgi_val_multi(llist l, char *name);
- char* cgi_name(llist l, char *value);
- char **cgi_name_multi(llist l, char *value);
- int parse_cookies(llist *entries);
- void print_cgi_env();
- void print_entries(llist l);
- char* escape_input(char *str);
- short is_form_empty(llist l);
- short is_field_exists(llist l,char *str);
- short is_field_empty(llist l,char *str);

`short accept_image();`

`accept_image()` determines whether the browser will accept pictures. It does so by checking the HTTP_ACCEPT environment variable for an image MIME type. It returns a 1 if the browser will accept graphics, a 0 otherwise.

`void unescape_url();`

`unescape_url()` converts escaped URI values into their character form. `read_cgi_input()` calls this function. You will rarely if ever need to access this function directly but it is made available in case you do.

`int read_cgi_input(llist *entries);`

This routine parses the raw CGI data passed from the browser to the server and adds each associated name and value to the linked list entries. It will parse information transmitted using both the GET and POST method. If it receives no information, it will return a 0, otherwise it returns the number of entries returned. If it receives a badly encoded string, it will return -1.

If you run your CGI program that calls `read_cgi_input()` from the command line, this function will start an interactive mode so you can directly input the CGI input string. Note that this string must be properly encoded.

`read_cgi_input()` also handles HTTP file upload correctly. The file will be uploaded to the directory defined by UPLOADDIR in cgi-lib.h (/tmp by default).

`char* cgi_val(llist l, char *name);`

`cgi_val()` searches the linked list for the value of the entry named name and returns the value if it finds it. If it cannot find an entry with name name, it returns NULL.

`char** cgi_val_multi(llist l, char *name);`

Same as `cgi_val()` except will return multiple values with the same name to an array of strings. Will return NULL if it cannot find an entry with name name

`char* cgi_name(llist l, char *value);`

Same as `cgi_val()` except searches for value with specified name.

`char** cgi_name_multi(llist l, char *value);`

Analogous to `cgi_multi_val()`.

`int parse_cookies(llist *entries);`

Parses the environment variable `HTTP_COOKIE` for cookies. Returns the number of cookies parsed, zero if there are none.

`void print_cgi_env();`

Pretty prints the environment variables defined in cgi-lib.h. Prints "(null)" if the variables are empty.

`void print_entries(llist l);`

This is a generic routine which will iterate through the linked list and print each name and associated value in HTML form. It uses the <dl> list format to display the list.

`char* escape_input(char *str);`

`escape_input()` "escapes" shell metacharacters in the string. It precedes all non-alphanumeric characters with a backslash. C routines including `system()` and `popen()` open up a Bourne shell process before running. If you do not escape shell metacharacters in the input (prefix metacharacters with a backslash), then malicious users may be able to take advantage of your system.

`short is_form_empty(llist l);`

`is_form_empty()` checks to see whether no names or values were submitted. Note that this is different from submitting a blank form.

`short is_field_exists(llist l,char *str);`

Checks to see whether a field actually exists. Equivalent to checking whether cgi_val() returns "" or NULL. If it returns "", the field exists but is empty; if it returns NULL, the field does not exist.

`short is_field_empty(llist l,char *str);`

Returns 1 (true) if either the field does not exist or the field does exist but is empty.

## 3.2. html-lib.h

### Library functions

- void html_header();
- void mime_header(char *mime);
- void nph_header(char *status);
- void show_html_page(char *loc)
- void status(char *status);
- void pragma(char *msg);
- void set_cookie(char *name, char *value, char *expires, char *path,char *domain, short secure);
- void html_begin(char *title);
- void html_end();
- void h1(char *header); ... void h6(char *header);
- void hidden(char *name, char *value);

`void html_header();`

`html_header()` prints a MIME compliant header which should precede the output of any HTML document from a CGI script. It simply prints to STDOUT:

       Content-Type: text/html

and a blank line.

`void mime_header(char *mime);`

Allows you to print any MIME header. For example, if you are about to send a GIF image to the standard output from your C CGI program, precede your program with:

       mime_header("image/gif");
       /* now you can send your GIF file to stdout */

`mime_header()` simply prints `Content-Type:` followed by your specified MIME header and a blank line.

`void nph_header(char *status);`

Sends a standard HTTP header for direct communication with the client using no parse header. status is the status code followed by the status message. For instance, to send a "No Content" header, you could use:

       nph_header("204 No Content");
       html_header();

which would send:

       HTTP/1.0 204 No Content
       Server: CGI using cgihtml
       Content-Type: text/html

`nph_header()` does not send a blank line after printing the headers, so you must follow it with either another header or a blank line. Also, scripts using this function must have "nph-" preceding their filenames.

`void show_html_page(char *loc);`

Sends a "Location: " header. loc is the location of the HTML file you wish sent to the browser. For example, if you want to send the root index file from the CGI program:

         show_html_page("/index.html");

`void status(char *status);`

Sends an HTTP Status header. status is a status code followed by a status message. For instance, to send a status code of 302 (temporary redirection) followed by a location header:

       status("302 Temporarily Moved");
       show_html_page("http://hcs.harvard.edu/");

`status()` does not print a blank line following the header, so you must follow it with either another function which does output a blank line or an explicit `printf("\r\n");`.

`void pragma(char *msg);`

Sends an HTTP Pragma header. Most commonly used to tell the browser not to cache the document, ie.:

       pragma("No-cache");
       html_header();

As with `status()`, `pragma()` does not print a blank line folowing the header.

`void set_cookie(char *name, char *value, char *expires, char *path, char *domain, short secure);`

Sets a cookie using the values given in the parameters.

`void html_begin(char *title);`

`html_begin()` sends somewhat standard HTML tags which should generally be at the top of every HTML file. It will send:

       <html> <head>
       <title>title</title>
       </head>
       <body>

`void html_end();`

`html_end()` is the complement to `html_begin()`, sending the following HTML:

       </body> </html>

Note that neither `html_begin()` nor `html_end()` are necessary for your CGI scripts to output HTML, but they are good style, and I encourage use of these routines.

`void h1(char *header);`

Surrounds `header` with appropriate headline tags. Defined for h1() to h6().

`void hidden(char *name, char *value);`

Prints a hidden form field with name `name` and value `value`.

## 3.3. cgi-llist.h

For most scripts, with the exception of `list_end()`, you will most likely never have to use any of the link list routines available, since cgi-lib.h handles most common linked list manipulation almost transparently. However, you may sometimes want to manipulate the information directly or perform special functions on each entry, in which case these routines may be useful.

### Library variables

    typedef struct {
      char *name;
      char *value;
    } entrytype;

    typedef struct _node {
      entrytype entry;
      struct _node* next;
    } node;

    typedef struct {
      node* head;
    } llist;

### Library functions

- void list_create(llist *l);
- node* list_next(node* w);
- short on_list(llist *l, node* w);
- short on_list_debug(llist *l, node* w);
- void list_traverse(llist *l, void (*visit)(entrytype item));
- node* list_insafter(llist* l, node* w, entrytype item);
- void list_clear(llist* l);

`void list_create(llist *l);`

`list_create()` creates and initializes the list, and it should be called at the beginning of every CGI script using this library.

`node* list_next(node* w);`

`list_next()` returns the next node on the list.

`short on_list(llist *l, node* w);`

`on_list()` returns a 1 if the node w is on the linked list l; otherwise, it returns a 0.

`short on_list_debug(llist *l, node* w);`

The previous routine makes the assumption that my linked list routines are bug-free, a possibly bad assumption. If you are using linked list routines and `on_list()` isn't returning the correct value, try using `on_list_debug()` which makes no assumptions, is almost definitely reliable, but is a little slower than the other routine.

`void list_traverse(llist *l, void (*visit)(entrytype item));`

`list_traverse()` lets you pass a pointer to a function which will manipulate each entry on the list.

To use, you must create a function that will take as its argument a variable of type entrytype. For example, if you wanted to write your own `print_entries()` function, you could do the following:

    void print_element(entrytype item);
    {
      printf("%s = %s\n",item.name,item.value);
    }

    void print_entries(llist entries);
    {
      list_traverse(&stuff, print_element);
    }

`node* list_insafter(llist* l, node* w, entrytype item);`

`list_insafter()` adds the entry item after the node w and returns the pointer to the newly created node. I didn't bother writing a function to insert before a node since my CGI functions don't need one.

`void list_clear(llist* l);`

This routine frees up the memory used by the linked list after you are finished with it. It is imperative that you call this function at the end of every program which calls `read_cgi_input()`.

## 3.4. string-lib.h

### Library functions

- char* newstr(char *str);
- char* substr(char *str, int offset, int len);
- char* replace_ltgt(char *str);
- char *lower_case(char *buffer);

`char* newstr(char *str);`

`newstr()` allocates memory and returns a copy of `str`. Use this function to correctly allocate memory and copy strings.

`char* substr(char *str, int offset, int len);`

Analogous to the Perl `substr` function. Finds the substring of `str` at an offset of `offset` and of length `len`. A negative offset will start the substring from the end of the string.

char* replace_ltgt(char *str);

Replaces all instances of < and > in `str` with &lt; and &gt;.

char* lower_case(char *buffer);

Converts a string from upper to lower case.

[ Next | Up to Table of Contents | Previous ]

Last modified: Mon Jan 20 22:39:24 PST 1997