cgic: an ANSI C library for CGI Programming
By [1]Thomas Boutell
_[2]The LATEST documentation is available here. Check often for new
releases._
Table of Contents
_NOTICE: If your current version is 1.05 or earlier, the current
release contains important security fixes. Upgrading is STRONGLY
RECOMMENDED._ (Yes, the upgrade is free.)
* [3]Credits and license terms
* [4]How to get support
* [5]What's new in version 1.07?
* [6]What's new in version 1.06?
* [7]What is cgic?
* [8]Obtaining cgic
* [9]Building and testing cgic: a sample application
* [10]What to do if it won't compile
* [11]How to write a cgic application
* [12]How can I generate images from my cgic application?
* [13]CGI debugging features: using capture
* [14]cgic function reference
* [15]cgic variable reference
* [16]cgic result code reference
* [17]cgic quick index
Credits and License Terms
cgic can be used free of charge, _provided that a credit notice is
provided online._ Alternatively, a nonexclusive Commercial License can
be purchased, which grants the right to use cgic without a public
credit notice.
Please see the file [18]license.txt for the details of the Basic
License and Commercial License, including ordering information for the
Commercial License.
Thanks are due to Ken Holervich, Jon Ribbens and other CGIC users who
have corresponded over the years.
How to Get Support
STOP! READ THIS FIRST! REALLY!
Are you getting a "server error," indicating that your web server
"cannot allow POST to this URL," or a similar message? _YOU MUST
CONFIGURE YOUR WEB SERVER TO ALLOW CGI PROGRAMS, AND YOU MUST INSTALL
CGI PROGRAMS IN THE LOCATION (OR WITH THE EXTENSION) THAT YOUR WEB
SERVER EXPECTS TO SEE._ Please don't send me email about this. It is
strictly between you and your web server's documentation, or between
you and your ISP. Thanks!
Anyone can mail questions about the gd and cgic libraries to
boutell@boutell.com. However, I receive a very large volume of email
on many subjects, and while I do my best to respond to all queries
this can take some time. Sometimes the response must take the form of
an eventual new release or an addition to a FAQ or other document, as
opposed to an detailed individual response.
The old "priority support" offer for CGIC has been discontinued, due
to the impracticality of billing for it.
What's new in version 1.07?
A problem with the cgiFormString and related functions has been
corrected. These functions were previously incorrectly returning
cgiFormTruncated in cases where the returned string fit the buffer
exactly.
What's new in version 1.06?
1. A potentially significant buffer overflow problem has been
corrected. Jon Ribbens correctly pointed out to me (and to the
Internet's bugtraq mailing list) that the cgiFormEntryString function,
which is used directly or indirectly by almost all CGIC programs, can
potentially write past the buffer passed to it by the programmer. This
bug has been corrected. Upgrading to version 1.06 is _strongly
recommended._
2. The function cgiSaferSystem() has been removed entirely. This
function escaped only a few metacharacters, while most shells have
many, and there was no way to account for the many different operating
system shells that might be in use on different operating systems.
Since this led to a false sense of security, the function has been
removed. It is our recommendation that user input should never be
passed directly on the command line unless it has been carefully shown
to contain only characters regarded as safe and appropriate by the
programmer. Even then, it is better to design your utilities to accept
their input from standard input rather than the command line.
What's new in version 1.05?
Non-exclusive commercial license fee reduced to $200.
What's new in version 1.04?
For consistency with other packages, the standard Makefile now
produces a true library for cgic (libcgic.a).
What's new in version 1.03?
Version 1.03 sends line feeds only (ascii 10) to end Content-type:,
Status:, and other HTTP protocol output lines, instead of CR/LF
sequences. The standard specifies CR/LF. Unfortunately, too many
servers reject CR/LF to make implementation of that standard
practical. No server tested ever rejects LF alone in this context.
What's new in version 1.02?
Version 1.02 corrects bugs in previous versions:
* [19]cgiFormDoubleBounded specified its arguments in the wrong
order, with surprising results. This bug has been corrected.
* Many small changes have been made to increase compatibility. cgic
now compiles with no warnings under the compilers available at
boutell.com.
What's new in version 1.01?
Version 1.01 adds no major functionality but corrects significant bugs
and incompatibilities:
* [20]cgiFormInteger, [21]cgiFormIntegerBounded, [22]cgiFormDouble
and [23]cgiFormDoubleBounded now accept negative numbers properly.
They also accept positive numbers with an explicit + sign.
* Hex values containing the digit 9 are now properly decoded.
* [24]cgiFormString now represents each newline as a single line
feed (ascii 10 decimal) as described in the documentation, not a
carriage return (ascii 13 decimal) as in version 1.0. The latter
approach pleased no one.
* [25]cgiFormString and [26]cgiFormStringNoNewlines no longer
erroneously return cgiFormEmpty in place of cgiFormSuccess.
* The main() function of cgic now flushes standard output and sleeps
for one second before exiting in order to inhibit problems with
the completion of I/O on some platforms. This was not a cgic bug
per se, but has been reported as a common problem with CGI when
used with the CERN server. This change should improve
compatibility.
* The single selection example in the testform.html example now
works properly. This was an error in the form itself, not cgic.
* [27]cgiRemoteUser and [28]cgiRemoteIdent are now documented
accurately. They were reversed earlier.
What is cgic?
cgic is an ANSI C-language library for the creation of CGI-based World
Wide Web applications. For basic information about the CGI standard,
see the [29]CGI documentation at NCSA.
cgic performs the following tasks:
* Parses form data, correcting for defective and/or inconsistent
browsers
* Transparently accepts both GET and POST form data
* Handles line breaks in form fields in a consistent manner
* Provides string, integer, floating-point, and single- and
multiple-choice functions to retrieve form data
* Provides bounds checking for numeric fields
* Loads CGI environment variables into C strings which are always
non-null
* Provides a way to capture CGI situations for replay in a debugging
environment
cgic should be compatible with any CGI-compliant server environment.
Obtaining cgic
cgic is distributed via the web in two forms: as a Windows-compatible
.ZIP file, and as a gzipped tar file. Most users of Windows and
related operating systems have access to 'unzip' or 'pkunzip'. All
modern Unix systems come with 'gunzip' and 'tar' as standard
equipment, and gzip/gunzip is not difficult to find if yours does not.
Versions of these programs for other operating systems are widely
available if you do not already have them.
_Important:_ to use cgic, you will need an ANSI-standard C compiler.
The Sun cc distributed with SunOS 4.1.3 is _not_ ANSI-standard. Unix
users may wish to obtain gcc, which is free and widely available, or
purchase Sun's development package, which also includes a proper
compiler. Users of Windows-related operating systems should not have
ANSI C-related problems as all of the popular compilers follow the
ANSI standard.
_Note for Windows Programmers:_ cgic should work in a 16-bit
environment but is not designed to cater to such an environment. Form
fields which require more than 64K individually will not work as
expected unless the huge memory model is used. Using a 32-bit compiler
and operating environment is strongly recommended.
Your web browser should inquire whether to save the file to disk when
you select one of the links below. Under Unix and compatible operating
systems, save it, then issue the following commands to unpack it:
gunzip cgic107.tar.gz
tar -xf cgic107.tar
This should produce the subdirectory 'cgic107', which will contain the
complete cgic distribution for version 1.07, including a copy of this
documentation in the file cgic.html.
Under Windows and compatible operating systems, save it, open a DOS
window, and issue the following commands to unpack it:
pkunzip /d cgic107.zip
This command also produces the subdirectory 'cgic107', which will
contain the complete cgic distribution for version 1.07, including a
copy of this documentation in the file CGIC.HTM.
cgic is available via the web from www.boutell.com:
* [30]Obtain cgic: gzipped tar file
* [31]Obtain cgic: .ZIP file
Building cgic: a sample application
The sample application 'cgictest.c' is provided as part of the cgic
distribution. This CGI program accepts input submitted by the form
cgictest.html.
On a Unix system, you can build cgictest simply by typing 'make
cgictest'. cgic.c and cgictest.c will be compiled and linked together
to produce the cgictest application. Under non-Unix operating systems,
you will need to create and compile an appropriate project containing
the files cgic.c and cgictest.c.
_IMPORTANT:_ after compiling cgictest, you will need to place it in a
location on your server system which is designated by your server
administrator as an appropriate location for CGI scripts. Also, the
URL of the action of the sample form in testform.html must be changed
to correctly indicate the location of cgictest on your web server. The
right locations for CGI programs vary greatly from one server to
another. Resolving this issue is between you, your web server
administrator, and your web server documentation. Before submitting a
bug report for cgic, make certain that the CGI example programs which
came with your server _do_ work for you. Otherwise it is very likely
that you have a server configuration problem.
Once you have moved cgictest to an appropriate cgi directory and
edited form.html to properly refer to its location, use the web
browser of your choice to access form.html. Fill out the various
fields in any manner you wish, then select the SUBMIT button.
If all goes well, cgictest will respond with a page which indicates
the various settings you submitted. If not, please see the second
paragraph above.
What to do if it won't compile
* _Are you using Visual C++ or Borland C++? Did you forget to add
cgic.c to your project?_
* _Make sure you are using an ANSI C or C++ compiler._ (All of the
Windows compilers are ANSI C compliant.)
* If your compiler can't find the #include file unistd.h, define the
preprocessor macro NO_UNISTD and recompile. (A place for defining
macros is provided in the project settings of all the Windows
compilers.)
If none of the above proves effective, please see the section
regarding [32]support.
How to write a cgic application
_Note: _All cgic applications must be linked to the cgic.c module
itself. How to do this depends on your operating system; under Unix,
just use the provided Makefile as an example.
Since all CGI applications must perform certain initial tasks, such as
parsing form data and examining environment variables, the cgic
library provides its own main() function. When you write applications
that use cgic, you will begin your own programs by writing a cgiMain()
function, which cgic will invoke when the initial cgi work has been
successfully completed. Your program must also be sure to #include the
file cgic.h.
_Important:_ if you write your own main() function, your program will
not link properly. Your own code should begin with cgiMain(). The
library provides main() for you.
Consider the cgiMain function of cgictest.c:
int cgiMain() {
#if DEBUG
/* Load a saved CGI scenario if we're debugging */
[33]cgiReadEnvironment("/path/to/capcgi.dat");
#endif
/* Important: we must indicate the type of document */
[34]cgiHeaderContentType("text/html");
/* Now invoke other functions to handle each part of the form */
fprintf([35]cgiOut, "
\n");
Name();
Address();
Hungry();
Temperature();
Frogs();
Color();
Flavors();
NonExButtons();
RadioButtons();
fprintf([38]cgiOut, "\n");
/* This value will be the exit code of the program; 0
generally indicates success among Unix and DOS programs */
return 0;
}
Note the DEBUG #ifdef. If DEBUG is defined at compile time, either by
inserting the line "#define DEBUG 1" into the program or by setting it
in the Makefile or other development environment, then the
[39]cgiReadEnvironment() function will be called to restore a captured
CGI environment for debugging purposes. See the discussion of the
[40]capture program, which is provided for use in CGI debugging.
Outputting the Header
Next, one of the cgiHeader functions should be called. In this
program, [41]cgiHeaderContentType() is called to indicate the MIME
type of the document being output, in this case "text/html" (a normal
HTML document). A few other common MIME types are "image/gif",
"image/jpeg" and "audio/basic".
Note that [42]cgiHeaderStatus() or [43]cgiHeaderLocation() could have
been invoked instead to output an error code or redirect the request
to a different URL. Only one of the cgiHeader functions should be
called in a single execution of the program.
_Important:_ one of the cgiHeader functions, usually
[44]cgiHeaderContentType(), _must_ be invoked before outputting any
other response to the user. Otherwise, the result will not be a valid
document and the browser's behavior will be unpredictable. You may, of
course, output your own ContentType and other header information to
[45]cgiOut if you prefer. The cgiHeader functions are provided as a
convenience.
Next, cgiMain() invokes various functions to handle individual parts
of the form. When the function is finished, it returns 0, the usual
return code for a successful program.
Handling Text Input
The Name() function of cgictest is shown below:
void Name() {
char name[81];
[46]cgiFormStringNoNewlines("name", name, 81);
fprintf([47]cgiOut, "Name: %s \n", name);
}
The purpose of this function is to retrieve and display the name that
was input by the user. Since the programmer has decided that names
should be permitted to have up to 80 characters, a buffer of 81
characters has been declared (allowing for the final null character).
The [48]cgiFormStringNoNewlines() function is then invoked to retrieve
the name and ensure that carriage returns are not present in the name
(despite the incorrect behavior of some web browsers). The first
argument is the name of the input field in the form, the second
argument is the buffer to which the data should be copies, and the
third argument is the size of the buffer. cgic will never write beyond
the size of the buffer, and will always provide a null-terminated
string in response; if the buffer is too small, the string will be
shortened. If this is not acceptable, the
[49]cgiFormStringSpaceNeeded() function can be used to check the
amount of space needed; the return value of cgiFormStringNoNewlines()
can also be checked to determine whether truncation occurred. See the
full description of [50]cgiFormStringNoNewlines().
Handling Output
Note that Name() writes its HTML output to [51]cgiOut, not to stdout.
_Important:_ [52]cgiOut is normally equivalent to stdout, and there is
no performance penalty for using it. It is recommended that you write
output to [53]cgiOut to ensure compatibility with future versions of
the cgic library for special environments that do not provide stdin
and stdout for each cgi connection.
Note that, for text input areas in which carriage returns _are_
desired, the function [54]cgiFormString should be used instead.
cgiFormString ensures that line breaks are always represented by a
single carriage return (ascii decimal 13), making life easier for the
programmer. See the source code to the Address() function of
cgictest.c for an example.
Handling Single Checkboxes
Consider the Hungry() function, which determines whether the user has
selected the "hungry" checkbox:
void Hungry() {
if ([55]cgiFormCheckboxSingle("hungry") == [56]cgiFormSuccess) {
fprintf(cgiOut, "I'm Hungry! \n");
} else {
fprintf(cgiOut, "I'm Not Hungry! \n");
}
}
This function takes advantage of the [57]cgiFormCheckboxSingle()
function, which determines whether a single checkbox has been
selected. cgiFormCheckboxSingle() accepts the name attribute of the
checkbox as its sole argument and returns [58]cgiFormSuccess if the
checkbox is selected, or [59]cgiFormNotFound if it is not. If multiple
checkboxes with the same name are in use, consider the
[60]cgiFormCheckboxMultiple() and [61]cgiFormStringMultiple()
functions.
Handling Numeric Input
Now consider the Temperature() function, which retrieves a temperature
in degrees (a floating-point value) and ensures that it lies within
particular bounds:
void Temperature() {
double temperature;
[62]cgiFormDoubleBounded("temperature", &temperature, 80.0, 120.0, 98.6
);
fprintf([63]cgiOut, "My temperature is %f. \n", temperature);
}
The temperature is retrieved by the function
[64]cgiFormDoubleBounded(). The first argument is the name of the
temperature input field in the form; the second argument points to the
address of the variable that will contain the result. The next two
arguments are the lower and upper bounds, respectively. The final
argument is the default value to be returned if the user did not
submit a value.
This function always retrieves a reasonable value within the specified
bounds; values above or below bounds are constrained to fit the
bounds. However, the return value of cgiFormDoubleBounded can be
checked to make sure the actual user entry was in bounds, not blank,
and so forth; see the description of [65]cgiFormDoubleBounded() for
more details. If bounds checking is not desired, consider using
[66]cgiFormDouble() instead.
Note that, for integer input, the functions [67]cgiFormInteger and
[68]cgiFormIntegerBounded are available. The behavior of these
functions is similar to that of their floating-point counterparts
above.
Handling Single-Choice Input
The