cgic 2.05 would not compile properly due to packaging errors. This problem has been corrected and cgic 2.05 has been reissued.
If you have CGIC 1.05 or earlier, you should upgrade to CGIC 1.07, or to CGIC 2.02 or better, in order to obtain important security fixes.
If you have CGIC 2.0 or CGIC 2.01 and you use the cgiCookie routines, you should upgrade to CGIC 2.02 or better, in order to obtain important security fixes.
If you are using CGIC 2.0 through CGIC 2.05, you will want to upgrade to CGIC 2.05 to correct a file descriptor leak which can also, on some platforms such as Windows, prevent file uploads from working.
cgic can be used free of charge, provided that a credit notice is provided online. Alternatively, a nonexclusive can be purchased, which grants the right to use cgic without a public credit notice.
Please see the file for the details of the Basic License and Commercial License, including ordering information for the Commercial License.
Thanks are due to Robert Gustavsson, Ken Holervich, Bob Nestor, Jon Ribbens, Thomas Strangert, Wu Yongwei, and other CGIC users who have corresponded over the years. Although the implementation of multipart/form-data file upload support in CGIC 2.x is my own, I particularly wish to thank those who submitted their own implementations of this feature.
STOP! READ THIS FIRST! REALLY!
Are you getting a " error," indicating that your "cannot allow POST to this URL," or a similar message? YOU MUST CONFIGURE YOUR WEB SERVER TO ALLOW 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, unless you wish me to configure your web server for you; I can certainly do that for $50/hr, but you can probably straighten this out yourself or have your web server administrator do it.
Free Support
Please submit support inquiries about CGIC via our . Please note that we receive a large volume of inquiries and cannot always respond personally. 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.
Hourly Support
Those requiring support in detail may arrange for direct support from the author, Thomas Boutell, at the rate of $50/hr, billed directly by credit card. To make arrangements, contact us via our our secure message page. To avoid delay, be sure to specifically mention that you wish to purchase CGIC support at the hourly rate above.
Temporary files used to accept file uploads were not closed properly. This resulted in a file descriptor leak, which was unlikely to be serious because of the short lifespan of CGI programs and the fact that very few forms upload many files at once. However, on the Windows platform and possibly some others, semantics prevented file uploads from working at all with these files not properly closed. Fixed in 2.05.
Documentation fixes: the cgiHtmlEscape, cgiHtmlEscapeData, cgiValueEscape, and cgiValueEscapeData routines were named incorrectly in the manual. No code changes in version 2.04.
Support for setting cookies has been reimplemented. The new closely follows the actual practice of that successfully use cookies, rather than attempting to implement the specification. The new code can successfully set more than one cookie at a time in typical web browsers.
In CGIC 2.0 and 2.01, if the HTTP_COOKIE environment variable was exactly equal to the name of a cookie requested with cgiCookieString, with no value or equal sign or other characters present, a buffer overrun could take place. This was not normal behavior and it is unknown whether any actual web server would allow it to occur, however we have of course released a patch to correct it. Thanks to Nicolas Tomadakis.
cgiCookieString returned cgiFormTruncated when cgiFormSuccess would be appropriate. Fixed; thanks to Mathieu Villeneuve-Belair.
Cookies are now set using a simpler Set-Cookie: header, and with one header line per cookie, based on data collected by Chunfu Lai.
Memory leaks in cgiReadEnvironment fixed by Merezko Oleg. These memory leaks were not experienced in a normal CGI situation, only when reading a saved CGI environment.
Makefile supports "make install"
Compiles without warnings under both C and C++ with strict warnings and strict ANSI compliance enabled
Builds out of the box on Windows (#include was needed)
Rare problem in cgiReadEnvironment corrected; no impact on normal CGI operations
cgiCookieString now sets the result to an empty string when returning cgiFormNotFound
Minor code cleanups
1. CGIC 2.0 provides support for file upload fields. User-uploaded files are kept in temporary files, to avoid the use of excessive swap space (Solaris users may wish to change the cgicTempDir macro in cgic.c before compiling). The , , , , , and functions provide a complete interface to this new functionality. Remember, the enctype attribute of the form tag must be set to multipart/form-data when tags are used.
2. CGIC 2.0 provides support for setting and examining cookies (persistent data storage on the browser side). The , and and functions retrieve cookies. The and functions set cookies.
3. CGIC 2.0 offers a convenient way to retrieve a list of all form fields. The new function performs this operation.
4. CGIC 2.0 provides convenience functions to correctly escape text before outputting it as part of HTML, or as part of the value of a tag attribute, such as the HREF or VALUE attribute. See , , and .
5. Users have often asked the correct way to determine which submit button was clicked. This could always be accomplished in previous versions, but CGIC 2.0 also provides , a convenient alternate label for the function.
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.
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.
Non-exclusive commercial license fee reduced to $200.
For consistency with other packages, the standard Makefile now produces a true library for cgic (libcgic.a).
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.
Version 1.02 corrects bugs in previous versions:
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.
Version 1.01 adds no major functionality but corrects significant bugs and incompatibilities:
, , and now accept negative numbers properly. They also accept positive numbers with an explicit + sign.
Hex values containing the digit 9 are now properly decoded.
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.
and 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.
and are now documented accurately. They were reversed earlier.
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 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
Accepts uploaded files as well as regular form fields
Provides functions to set and retrieve "cookies" (browser-side persistent information)
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, including file uploads and cookies
cgic is compatible with any CGI-compliant server environment, and compiles without modification in Posix/Unix/Linux and Windows environments.
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. Under Unix, just obtain and use gcc. Most Unix systems have standardiszed on gcc. Users of Windows operating systems should not have ANSI C-related problems as all of the popular compilers follow the ANSI standard.
Note for Windows Programmers: you must use a modern 32-bit compiler. Visual C++ 2.0 or higher, Borland C++ and the mingw32 gcc compiler are all appropriate, as is cygwin. Do NOT use an ancient 16-bit DOS executable compiler, please.
What Operating System Does Your WEB SERVER Run?
Remember, the computer on your desk is usually NOT your web server. Compiling a Windows console executable will not give you a CGI program that can be installed on a Linux-based server.
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 cgic205.tar.gz
tar -xf cgic205.tar
This should produce the subdirectory 'cgic205', which will contain the complete cgic distribution for version 2.05, including a copy of this documentation in the file cgic.html.
Under Windows and compatible operating systems, save it, open a console ("DOS") window, and issue the following commands to unpack it:
unzip /d cgic205.zip
Or use the unzip utility of your choice.
This command also produces the subdirectory 'cgic205', which will contain the complete cgic distribution for version 2.05, including a copy of this documentation in the file cgic.html.
cgic is available via the web from
The sample application 'cgictest.c' is provided as part of the cgic distribution. This CGI program displays an input form, accepts a submission, and then displays what was submitted. In the process essentially all of cgic's features are tested.
On a Unix system, you can build cgictest simply by typing 'make cgictest.cgi'. 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.cgi, 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. Some servers are configured to recognize any file ending in .cgi as a CGI program when it is found in any subdirectory of the server's web space, but this is not always the case! 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.cgi (or cgictest.exe, under Windows) to an appropriate cgi directory, use the web browser of your choice to access the URL at which you have installed it (for instance, ). Fill out the various fields in any manner you wish, then select the SUBMIT button.
If all goes well, cgictest.cgi will respond with a page which indicates the various settings you submitted. If not, please reread the section above regarding the correct location in which to install your CGI program on your web server.
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 none of the above proves effective, please see the section regarding .
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. (Those who prefer different behavior can easily modify cgic.c.)
Consider the cgiMain function of cgictest.c:
int cgiMain() {
#ifdef DEBUG
LoadEnvironment();
#endif /* DEBUG */
/* Load a previously saved CGI scenario if that button
has been pressed. */
if (cgiFormSubmitClicked("loadenvironment") == cgiFormSuccess) {
LoadEnvironment();
}
/* Set any new cookie requested. Must be done *before*
outputting the content type. */
CookieSet();
/* Send the content type, letting the browser know this is HTML */
cgiHeaderContentType("text/html");
/* Top of the page */
fprintf(cgiOut, "\n");
fprintf(cgiOut, "cgic test\n");
fprintf(cgiOut, "
cgic test
\n");
/* If a submit button has already been clicked, act on the
submission of the form. */
if ((cgiFormSubmitClicked("testcgic") == cgiFormSuccess) ||
cgiFormSubmitClicked("saveenvironment") == cgiFormSuccess)
{
HandleSubmit();
fprintf(cgiOut, "\n");
}
/* Now show the form */
ShowForm();
/* Finish up the page */
fprintf(cgiOut, "
\n");
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 LoadEnvironment function is invoked. This function calls to restore a captured CGI environment for debugging purposes. See also the discussion of the program, which is provided for use in CGI debugging. Because this is a test program, the function is also called to check for the use of a button that requests the reloading of a saved CGI environment. A completed CGI program typically would never allow the end user to make that decision.
Setting Cookies
Next, one of the cgiHeader functions should be called. This particular program demonstrates many features, including the setting of cookies. If the programmer wishes to set a cookie, the cookie-setting function must be called first, before other headers are output. This is done by the CookieSet() function of cgictest.c:
void CookieSet()
{
char cname[1024];
char cvalue[1024];
/* Must set cookies BEFORE calling
cgiHeaderContentType */
cgiFormString("cname", cname, sizeof(cname));
cgiFormString("cvalue", cvalue, sizeof(cvalue));
if (strlen(cname)) {
/* Cookie lives for one day (or until
browser chooses to get rid of it, which
may be immediately), and applies only to
this script on this site. */
cgiHeaderCookieSetString(cname, cvalue,
86400, cgiScriptName, cgiServerName);
}
}
Since this is a test program, the function is used to fetch the name and value from the form previously filled in by the user. Normally, cookie names and values are chosen to meet the needs of the programmer and provide a means of identifying the same user again later.
The function sets the cookie by requesting that the web browser store it. There is never any guarantee that this will happen! Many browsers reject cookies completely; others do not necessarily keep them as long as requested or return them with their values intact. Always code defensively when using cookies.
The cname and cvalue parameters are of course the namd and value for the cookie. The third argument is the time, in seconds, that the cookie should "live" on the browser side before it expires; in this case it has been set to 86,400 seconds, which is exactly one day. The browser may or may not respect this setting, as with everything else about cookies.
The fourth argument identifies the "path" within the web site for which the cookie is considered valid. A cookie that should be sent back for every access to the site should be set with a path of /. In this case the cookie is relevant only to the CGI program itself, so (the URL of the CGI program, not including the domain name) is sent. Similarly, a cookie can be considered relevant to a single web site or to an entire domain, such as or the entire .boutell.com domain. In this case, the current site on which the program is running is the only relevant site, so is used as the domain.
Outputting the Content Type Header
Next, 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/wav".
Note that or 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 , 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 if you prefer. The cgiHeader functions are provided as a convenience.
Handling Form Submissions
Like many CGI programs, cgictest makes decisions about the way it should behave based on whether various submit buttons have been clicked. When either the testcgic or saveenvironment button is present, cgictest invokes the HandleSubmit function, which invokes additional functions to handle various parts of the form:
void HandleSubmit()
{
Name();
Address();
Hungry();
Temperature();
Frogs();
Color();
Flavors();
NonExButtons();
RadioButtons();
File();
Entries();
Cookies();
/* The saveenvironment button, in addition to submitting
the form, also saves the resulting CGI scenario to
disk for later replay with the 'load saved environment'
button. */
if (cgiFormSubmitClicked("saveenvironment") == cgiFormSuccess) {
SaveEnvironment();
}
}
Handling Text Input
The Name() function of cgictest is shown below, in its simplest possible form:
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 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 copied, 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 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 .
Handling Output
Note that Name() writes its HTML output to , not to stdout.
The actual name submitted by the user may or may not contain characters that have special meaning in HTML, specifically the the <, >, and & characters. The function is used to output the user-entered name with any occurrences of these characters correctly escaped as <, >, and &.
Important: is normally equivalent to stdout, and there is no performance penalty for using it. It is recommended that you write output to to ensure compatibility with modified 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 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:
This function takes advantage of the function, which determines whether a single checkbox has been selected. cgiFormCheckboxSingle() accepts the name attribute of the checkbox as its sole argument and returns if the checkbox is selected, or if it is not. If multiple checkboxes with the same name are in use, consider the and 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;
("temperature", &temperature, 80.0, 120.0, 98.6);
fprintf(, "My temperature is %f. \n", temperature);
}
The temperature is retrieved by the function . 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 for more details. If bounds checking is not desired, consider using instead.
Note that, for integer input, the functions and are available. The behavior of these functions is similar to that of their floating-point counterparts above.