→ Check the latest documentation for new releases often.
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.
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 license.txt 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.
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 do not send me e-mail 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.
Please submit support inquiries about CGIC via our contact page. 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.
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.
In CGIC 2.0 and 2.01,
if the environment variable HTTP_COOKIE
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
would return 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 Oleg Merezko. 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 Microsoft Windows
(#include <fcntl.h>
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.
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 (Oracle Solaris users may wish to change the
cgicTempDir
macro
in cgic.c before compiling).
The cgiFormFileName
,
cgiFormFileContentType
,
cgiFormFileSize
,
cgiFormFileOpen
,
cgiFormFileRead
, and
cgiFormFileClose
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
<input type="file">
tags are used.
CGIC 2.0
provides support for setting and examining cookies
(persistent data storage on the browser side).
The cgiCookieString
,
and cgiCookieInteger
and cgiCookies
functions retrieve cookies. The
cgiHeaderCookieSetString
and cgiHeaderCookieSetInteger
functions set cookies.
CGIC 2.0
offers a convenient way to retrieve a list of all form fields.
The new cgiFormEntries
function performs this operation.
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
cgiHtmlEscape
,
cgiHtmlEscapeData
,
cgiValueEscape
and
cgiValueEscapeData
.
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 cgiFormSubmitClicked, a convenient alternate label for the cgiFormCheckboxSingle 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.
A potentially significant buffer overflow problem has been
corrected. Jon Ribbens correctly pointed out to me (and to
the 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.
The function 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.cgiSaferSystem
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:
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.
Version 1.01 adds no major functionality but corrects significant bugs and incompatibilities:
cgiFormInteger
,
cgiFormIntegerBounded
,
cgiFormDouble
and
cgiFormDoubleBounded
now
accept negative numbers properly. They also accept positive
numbers with an explicit + sign.
Hexadecimal values containing the digit 9
are
now properly decoded.
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.
cgiFormString
and
cgiFormStringNoNewlines
no longer erroneously return cgiFormEmpty
in place of
cgiFormSuccess
.
The main
function
of cgic.c 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.
cgiRemoteUser and cgiRemoteIdent 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/GNU and Microsoft Windows environments.
CGIC is distributed via the web in two forms: as a Microsoft Windows-compatible ZIP file, and as a gzipped tar file. Most users of Microsoft Windows and related operating systems have access to commands unzip or pkunzip. All modern Unix systems come with commands gunzip and tar as standard equipment, and the package 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 the command gcc. Most Unix systems have standardized on gcc. Users of Microsoft Windows operating systems should not have ANSI C-related problems as all of the popular compilers follow the ANSI standard.
Note for Microsoft Windows: 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.
Your Web browser should inquire whether to save the file to disk when you select one of the links below.
gunzip cgic205.tar.gz tar -xf cgic205.tar
Under Microsoft 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 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.
CGIC is available via the Web both as a gzipped tar file and as a ZIP file
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. The files 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 (like http://www.example.com/cgi-bin/cgictest.cgi). Fill out the various fields in any manner you wish, then select the 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.
If none of the above proves effective, please see the section regarding support.
→ 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 cgicCGIC 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 the main
function for you. (Those who prefer different behavior
can easily modify the file 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,"<HTML><HEAD>\n"
); fprintf(cgiOut,"<TITLE>cgic test</TITLE></HEAD>\n"
); fprintf(cgiOut,"<BODY><H1>cgic test</H1>\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,"<hr>\n"
); } /* Now show the form */ ShowForm(); /* Finish up the page */ fprintf(cgiOut,"</BODY></HTML>\n"
);return
0
; }
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 function
LoadEnvironment
is invoked. This function calls
cgiReadEnvironment
to restore a captured CGI environment for debugging purposes. See
also the discussion of the capture program, which is
provided for use in CGI debugging. Because this is a test program,
the function cgiFormSubmitClicked
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.
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 function
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 cgiFormString
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 cgiHeaderCookieSetString
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 parameters cname and cvalue are of course the name 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 value cgiScriptName
(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
www.boutell.com or the entire .boutell.com
domain. In this case, the current site on which the program is running
is the only relevant site, so the value cgiServerName
is used
as the domain.
Next, the function 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/wav.
Note that the functions cgiHeaderStatus
or
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 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 the content type and other
header information to cgiOut
yourself if you prefer.
The cgiHeader
functions
are provided as a convenience.
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(); } }
The function Name
of cgictest is shown below,
in its simplest
possible form:
void
Name() {char
name[81
]; cgiFormStringNoNewlines("name", name,81
); fprintf(cgiOut,"Name: "
); cgicHtmlEscape(name); fprintf(cgiOut,"<BR>\n"
); }
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 cgiFormStringNoNewlines
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
cgiFormStringSpaceNeeded
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 cgiFormStringNoNewlines
.
→ Name
writes its HTML output
to cgiOut
, not to the standard output.
The actual name submitted by the user may contain
characters that have special meaning in HTML, specifically the
the characters [<>&].
The cgiHtmlEscape
function is used to output
the user-entered name with any occurrences of these characters
correctly escaped as <
, >
,
and &
.
Important: cgiOut
is normally equivalent
to the standard output, and there is no performance penalty for using it.
It is recommended that you write output to cgiOut
to ensure compatibility
with modified versions of the CGIC library for special
environments that do not provide the standard input and output for
each CGI connection.
Note that, for text input areas in which carriage returns are
desired, the function 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 function Address
of cgictest.c for an example.
Consider the Hungry
function, which determines whether
the user has selected the hungry
checkbox:
void
Hungry() {if
(cgiFormCheckboxSingle("hungry"
) == cgiFormSuccess) { fprintf(cgiOut,"I am Hungry!<BR>\n"
); } else { fprintf(cgiOut,"I am Not Hungry!<BR>\n"
); } }
This function takes advantage of the function
cgiFormCheckboxSingle
, which
determines whether a single checkbox has been selected.
cgiFormCheckboxSingle
accepts the name attribute of the checkbox
as its sole argument and returns cgiFormSuccess
if the checkbox is selected, or
cgiFormNotFound
if it is not.
If multiple checkboxes with the same name are in use,
consider using the functions cgiFormCheckboxMultiple
and
cgiFormStringMultiple
.
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; cgiFormDoubleBounded("temperature"
, &temperature,80.0
,120.0
,98.6
); fprintf(cgiOut,"My temperature is %f.<BR>\n"
, temperature); }
The temperature is retrieved by the function
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 cgiFormDoubleBounded
for more details.
If bounds checking
is not desired, consider using the function cgiFormDouble
instead.
Note that, for integer input, the functions
cgiFormInteger
and
cgiFormIntegerBounded
are available. The behavior of these functions is similar to
that of their floating-point counterparts above.
The SELECT
tag of HTML
is used to provide the user with
several choices. Radio buttons and checkboxes can also be used
when the number of choices is relatively small. Consider
the function Color
of cgictest.c:
char
*colors[] = {"Red"
,"Green"
,"Blue"
};void
Color() {int
colorChoice; cgiFormSelectSingle("colors"
, colors,3
, &colorChoice,0
); fprintf(cgiOut,"I am: %s<BR>\n"
, colors[colorChoice]); }
This function determines which of several colors the user chose
from a SELECT
list in the form. An array of colors is
declared; the function cgiFormSelectSingle
is then invoked to determine which, if any, of those choices
was selected. The first argument indicates the name of the input
field in the form. The second argument points to the list of
acceptable colors. The third argument indicates the number of
entries in the color array. The fourth argument points to the
variable which will accept the chosen color, and the last argument
indicates the index of the default value to be set if no
selection was submitted by the browser.
cgiFormSelectSingle
will
always indicate a reasonable selection value. However, if
the programmer wishes to know for certain that a value was
actually submitted, that the value submitted was a legal
response, and so on, the return value of cgiFormSelectSingle
can be consulted. See the full description of
cgiFormSelectSingle
for more information.
Note that radio button groups and SELECT
lists can both
be handled by this function. If you are processing radio
button groups, you may prefer to invoke the function
cgiFormRadio
, which functions
identically.
What if I do not know the acceptable choices at runtime?
If the acceptable choices are unknown until runtime,
one can simply load the choices from persistent storage. But if the acceptable
choices are not fixed at all (consider a list of country names;
new names may be added to the form at any time and it is
inconvenient to also update program code or maintain a separate list
of countries), simply invoke
cgiFormStringNoNewlines
instead to retrieve the string directly. Keep in mind that, if
you do so, validating the response to make sure it is
safe and legitimate becomes a problem for your own
program to solve.
The advantage of cgiFormSelectSingle
is that invalid
responses are never returned.
To handle multiple-selection SELECT
lists and
groups of checkboxes with the same name, see the
discussion of the function NonExButtons
of cgictest.c, immediately below.
Consider the first half of the function NonExButtons
of cgictest.c:
char
*votes[] = {"A"
,"B"
,"C"
,"D"
};void
NonExButtons() {int
voteChoices[4
];int
i;int
result;int
invalid;char
**responses; /* Method #1: check for valid votes. This is a good idea, since votes for nonexistent candidates should probably be discounted... */ fprintf(cgiOut,"Votes (method 1):<BR>\n"
); result = cgiFormCheckboxMultiple("vote"
, votes,4
, voteChoices, &invalid);if
(result == cgiFormNotFound) { fprintf(cgiOut,"I hate them all!<p>\n"
); }else
{ fprintf(cgiOut,"My preferred candidates are:\n"
); fprintf(cgiOut,"<ul>\n"
);for
(i=0
; (i <4
); i++) {if
(voteChoices[i]) { fprintf(cgiOut,"<li>%s\n"
, votes[i]); } } fprintf(cgiOut,"</ul>\n"
); } …
This function takes advantage of the function
cgiFormCheckboxMultiple
,
which is used to identify one or more selected checkboxes with
the same name. This function performs identically to the function
cgiFormSelectMultiple
.
That is, SELECT
elements with the MULTIPLE
attribute
are handled
just like a group of several checkboxes with the same name.
The first argument to cgiFormCheckboxMultiple
is the name given to all
checkbox input fields in the group. The second argument
points to an array of legitimate values; these should
correspond to the VALUE
attributes of the checkboxes
(or OPTION
elements in a SELECT
list). The third argument
indicates the number of entries in the array of
legitimate values. The fourth argument points to
an array of integers with the same number of entries
as the array of legitimate values; each entry
will be set true if that checkbox or option was selected,
false otherwise.
The last argument points to an integer which will be set to the number of invalid responses (responses not in the array of valid responses) that were submitted. If this value is not of interest, the last argument may be a null pointer (0).
Note that you can inspect the return value of the function
cgiFormCheckboxMultiple
to determine whether any choices at all were
set. See the full description of
cgiFormCheckboxMultiple
for other possible return values.
What if I do not know the acceptable choices at runtime?
If the acceptable choices are unknown until runtime,
one can simply load the choices from persistent storage. But if the acceptable
choices are not fixed at all (consider a list of ice cream flavors;
new names may be added to the form at any time and it is
inconvenient to also update program code or a separate list
of countries), a more dynamic approach is needed. Consider
the second half of the function NonExButtons
of cgictest.c:
… /* Method #2: get all the names voted for and trust them. This is good if the form will change more often than the code and invented responses are not a danger or can be checked in some other way. */ fprintf(cgiOut,"Votes (method 2):<BR>\n"
); result = cgiFormStringMultiple("vote"
, &responses);if
(result == cgiFormNotFound) { fprintf(cgiOut,"I hate them all!<p>\n"
); }else
{int
i =0
; fprintf(cgiOut,"My preferred candidates are:\n"
); fprintf(cgiOut,"<ul>\n"
);while
(responses[i]) { fprintf(cgiOut,"<li>%s\n"
, responses[i]); i++; } fprintf(cgiOut,"</ul>\n"
); } /* We must be sure to free the string array or a memory leak will occur. Simply callingfree
would free the array but not the individual strings. The functioncgiStringArrayFree
does the job completely. */ cgiStringArrayFree(responses); }
This code excerpt demonstrates an alternate way of retrieving
a list of choices. The function
cgiFormStringMultiple
is used
to retrieve an array consisting of all the strings submitted
for with a particular input field name. This works both for
SELECT
elements with the MULTIPLE
attribute and for
groups of checkboxes with the same name.
The first argument to cgiFormStringMultiple
is the name of the input field or
group of input fields in question. The second argument should
be the address of a pointer to a pointer to a string, which
is not as bad as it sounds. Consider the following simple call
of the function:
/* An array of strings; each C string is an array of characters */char
**responses; cgiFormStringMultiple("vote"
, &responses);
How do I know how many responses there are?
After the call, the last entry in the string array will be a null pointer. Thus the following simple loop can be used to walk through the array until the last entry is encountered:
int
i =0
;while
(responses[i]) { /* Do something with the string responses[i] */ i++; }
Important: The function
cgiFormStringMultiple
returns a pointer to allocated memory. Your code
should not modify the strings in the responses array or the responses
array itself; if modification is needed, the strings should be
copied. When your code is done examining the responses array,
you MUST call cgiStringArrayFree
with the array as an argument to free the memory
associated with the array. Otherwise, the memory will not be available
again until the program exists. Do not just call the
function free
; if you do, the individual strings will not be freed.
CGIC
provides functions to access files that have been uploaded
as part of a form submission. IMPORTANT: you MUST use
the ENCTYPE
attribute of your FORM
element
to multipart/form-data for this feature to work! For an
example, see the function ShowForm
of
cgictest.c, examined below.
The function File
of cgictest.c takes care of
receiving uploaded files:
void
File() { cgiFilePtr file;char
name[1024
];char
contentType[1024
];char
buffer[1024
];int
size;int
got;if
(cgiFormFileName("file"
, name,sizeof
(name)) != cgiFormSuccess) { printf("<p>No file was uploaded.<p>\n"
);return
; } fprintf(cgiOut,"The filename submitted was: "
); cgiHtmlEscape(name); fprintf(cgiOut,"<p>\n"
); cgiFormFileSize("file"
, &size); fprintf(cgiOut,"The file size was: %d bytes<p>\n"
, size); cgiFormFileContentType("file"
, contentType,sizeof
(contentType)); fprintf(cgiOut,"The alleged content type of the file was: "
); cgiHtmlEscape(contentType); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Of course, this is only the claim the browser "
"made when uploading the file. Much like the filename, "
"it cannot be trusted.<p>\n"
); fprintf(cgiOut,"The file’s contents are shown here:<p>\n"
);if
(cgiFormFileOpen("file"
, &file) != cgiFormSuccess) { fprintf(cgiOut,"Could not open the file.<p>\n"
);return
; } fprintf(cgiOut,"<pre>\n"
);while
(cgiFormFileRead(file, buffer,sizeof
(buffer), &got) == cgiFormSuccess) { cgiHtmlEscapeData(buffer, got); } fprintf(cgiOut,"</pre>\n"
); cgiFormFileClose(file); }
First, the function File
checks to determine the filename that was
submitted by the user.
→ VERY IMPORTANT: this filename may or may not bear any relation to the real name of the file on the user’s computer, may be deliberately manipulated with malicious intent, and should not be used for any purpose unless you have determined that its content is safe for your intended use and will not, at the very least, overwrite another file of importance to you, especially if you intend to use it as a file name on the server side. The CGIC library itself does not use this file name for temporary storage.
If the function cgiFormFileName
does
not succeed, no file was uploaded.
Next, the function cgiFormFileSize
is called
to determine the size of the uploaded file, in bytes.
The function File
then proceeds to query the content type of the uploaded
file. Files uploaded by the user have their own content type information,
which may be useful in determining whether the file is an image, an HTML document,
a word processing document, or a file of some other type. However,
as with the filename and any other claim made by the browser,
this information should not be blindly trusted. The browser
may upload a file with the name picture.jpg and the
content type image/jpeg, but this does not guarantee that the
actual file will contain a valid JPEG image suitable for display.
The content type submitted by the browser can be queried using the
cgiFormFileContentType
function.
Of course, CGIC also provides access to the actual uploded file.
First, the programmer calls the function cgiFormFileOpen
,
passing the address of an object of type cgiFilePtr
. If this function
succeeds, the cgiFilePtr
object becomes valid, and can be
used in subsequent calls to the function cgiFormFileRead
.
Notice that the number of bytes read may be less than the number requested,
in particular on the last successful call
before the function cgiFormFileRead
begins
to return the value cgiFormEOF
.
When the function cgiFormFileRead
no longer returns the value
cgiFormSuccess
,
the programmer calls cgiFormFileClose
to
release the object of type cgiFilePtr
.
The uploaded file data may contain anything, including binary data,
null characters, and so on. The example program uses the function
cgiHtmlEscapeData
function to output the
data with any special characters that have meaning in HTML escaped.
Most programs will save the uploaded information to a server-side file or
database.
From time to time, the programmer may not know the names of all
form fields in advance. In such situations it is convenient to
use the function cgiFormEntries
.
The function Entries
of cgictest.c demonstrates the use of the function
cgiFormEntries
:
void
Entries() {char
**array, **arrayStep; fprintf(cgiOut,"List of All Submitted Form Field Names:<p>\n"
);if
(cgiFormEntries(&array) != cgiFormSuccess) {return
; } arrayStep = array; fprintf(cgiOut,"<ul>\n"
);while
(*arrayStep) { fprintf(cgiOut,"<li>"
); cgiHtmlEscape(*arrayStep); fprintf(cgiOut,"\n"
); arrayStep++; } fprintf(cgiOut,"</ul>\n"
); cgiStringArrayFree(array); }
The function cgiFormEntries
retrieves an array of form field names.
This array consists of pointers to strings, with a final null pointer
to mark the end of the list. The code above illustrates one way of
looping through the returned strings. Note the final call to the function
cgiStringArrayFree
, which is
essential in order to return the memory used to store the strings
and the string array.
The function Cookies
of cgictest.c displays a list of all cookies
submitted by the browser with the current form submission, along
with their values:
void
Cookies() {char
**array, **arrayStep;char
cname[1024
], cvalue[1024
]; fprintf(cgiOut,"Cookies Submitted On This Call, With Values "
"(Many Browsers NEVER Submit Cookies):<p>\n"
);if
(cgiCookies(&array) != cgiFormSuccess) {return
; } arrayStep = array; fprintf(cgiOut,"<table border=1>\n"
); fprintf(cgiOut,"<tr><th>Cookie<th>Value</tr>\n"
);while
(*arrayStep) {char
value[1024
]; fprintf(cgiOut,"<tr>"
); fprintf(cgiOut,"<td>"
); cgiHtmlEscape(*arrayStep); fprintf(cgiOut,"<td>"
); cgiCookieString(*arrayStep, value,sizeof
(value)); cgiHtmlEscape(value); fprintf(cgiOut,"\n"
); arrayStep++; } fprintf(cgiOut,"</table>\n"
); cgiFormString("cname"
, cname,sizeof
(cname)); cgiFormString("cvalue"
, cvalue,sizeof
(cvalue));if
(strlen(cname)) { fprintf(cgiOut,"New Cookie Set On This Call:<p>\n"
); fprintf(cgiOut,"Name: "
); cgiHtmlEscape(cname); fprintf(cgiOut,"Value: "
); cgiHtmlEscape(cvalue); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"If your browser accepts cookies "
"(many do not), this new cookie should appear "
"in the above list the next time the form is "
"submitted.<p>\n"
); } cgiStringArrayFree(array); }
→ VERY IMPORTANT: YOUR BROWSER MIGHT NOT SUBMIT COOKIES, EVER, REGARDLESS OF WHAT VALUES YOU ENTER INTO THE TEST FORM. Many, many browsers are configured not to accept or send cookies; others are configured to send them as little as possible to meet the bare minimum requirements for entry into popular sites. Users will often refuse your cookies; make sure your code still works in that situation!
The above code uses the function cgiCookies
to retrieve a list of all currently set cookies as a null-terminated
array of strings. The function cgiCookieString
is then used to fetch the value associated with each cookie;
this function works much like cgiFormString
,
discussed earlier. Note that a cookie set as a part of the current
form submission process does not appear on this list immediately, as
it has not yet been sent back by the browser. It should appear on
future submissions, provided that the browser chooses to accept
and resend the cookie at all.
CGI programmers
often need to display HTML pages as part of the output
of CGI programs;
these HTML pages often contain forms which should submit
fields back to the same program they came from. Provided that your
web server is well-configured, this can be done conveniently using
the environment variable cgiScriptName
, as shown below.
Here is the
source code of the ShowForm
function
of cgictest.c:
void
ShowForm() { fprintf(cgiOut,"<!-- 2.0: multipart/form-data is required "
"for file uploads. -->"
); fprintf(cgiOut,"<form method=\"POST\" "
"enctype=\"multipart/form-data\" "
); fprintf(cgiOut," action=\""
); cgiValueEscape(cgiScriptName); fprintf(cgiOut,"\">\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Text Field containing Plaintext\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"<input type=\"text\" name=\"name\">Your Name\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Multiple-Line Text Field\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"<textarea NAME=\"address\" ROWS=4 COLS=40>\n"
); fprintf(cgiOut,"Default contents go here. \n"
); fprintf(cgiOut,"</textarea>\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Checkbox\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"<input type=\"checkbox\" name=\"hungry\" checked>Hungry\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Text Field containing a Numeric Value\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"<input type=\"text\" name=\"temperature\" value=\"98.6\">\n"
); fprintf(cgiOut,"Blood Temperature (80.0-120.0)\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Text Field containing an Integer Value\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"<input type=\"text\" name=\"frogs\" value=\"1\">\n"
); fprintf(cgiOut,"Frogs Eaten\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"Single-SELECT\n"
); fprintf(cgiOut,"<br>\n"
); fprintf(cgiOut,"<select name=\"colors\">\n"
); fprintf(cgiOut,"<option value=\"Red\">Red\n"
); fprintf(cgiOut,"<option value=\"Green\">Green\n"
); fprintf(cgiOut,"<option value=\"Blue\">Blue\n"
); fprintf(cgiOut,"</select>\n"
); fprintf(cgiOut,"<br>\n"
); fprintf(cgiOut,"Multiple-SELECT\n"
); fprintf(cgiOut,"<br>\n"
); fprintf(cgiOut,"<select name=\"flavors\" multiple>\n"
); fprintf(cgiOut,"<option value=\"pistachio\">Pistachio\n"
); fprintf(cgiOut,"<option value=\"walnut\">Walnut\n"
); fprintf(cgiOut,"<option value=\"creme\">Creme\n"
); fprintf(cgiOut,"</select>\n"
); fprintf(cgiOut,"<p>Exclusive Radio Button Group: Age of "
"Truck in Years\n"
); fprintf(cgiOut,"<input type=\"radio\" name=\"age\" "
"value=\"1\">1\n"
); fprintf(cgiOut,"<input type=\"radio\" name=\"age\" "
"value=\"2\">2\n"
); fprintf(cgiOut,"<input type=\"radio\" name=\"age\" "
"value=\"3\" checked>3\n"
); fprintf(cgiOut,"<input type=\"radio\" name=\"age\" "
"value=\"4\">4\n"
); fprintf(cgiOut,"<p>Nonexclusive Checkbox Group: "
"Voting for Zero through Four Candidates\n"
); fprintf(cgiOut,"<input type=\"checkbox\" name=\"vote\" "
"value=\"A\">A\n"
); fprintf(cgiOut,"<input type=\"checkbox\" name=\"vote\" "
"value=\"B\">B\n"
); fprintf(cgiOut,"<input type=\"checkbox\" name=\"vote\" "
"value=\"C\">C\n"
); fprintf(cgiOut,"<input type=\"checkbox\" name=\"vote\" "
"value=\"D\">D\n"
); fprintf(cgiOut,"<p>File Upload:\n"
); fprintf(cgiOut,"<input type=\"file\" name=\"file\" "
"value=\"\"> (Select A Local File)\n"
); fprintf(cgiOut,"<p>\n"
); fprintf(cgiOut,"<p>Set a Cookie<p>\n"
); fprintf(cgiOut,"<input name=\"cname\" "
"value=\"\"> Cookie Name\n"
); fprintf(cgiOut,"<input name=\"cvalue\" "
"value=\"\"> Cookie Value<p>\n"
); fprintf(cgiOut,"<input type=\"submit\" "
"name=\"testcgic\" value=\"Submit Request\">\n"
); fprintf(cgiOut,"<input type=\"reset\" "
"value=\"Reset Request\">\n"
); fprintf(cgiOut,"<p>Save the CGI Environment<p>\n"
); fprintf(cgiOut,"Pressing this button will submit the form, then "
"save the CGI environment so that it can be replayed later "
"by calling cgiReadEnvironment (in a debugger, for "
"instance).<p>\n"
); fprintf(cgiOut,"<input type=\"submit\" name=\"saveenvironment\" "
"value=\"Save Environment\">\n"
); fprintf(cgiOut,"</form>\n"
); }
Note the use of enctype="multipart/form-data"
in the
FORM
tag. This is absolutely required if the form
will contain file upload fields, as in the above example. Most
browsers will not even attempt file uploads without the
presence of this attribute.
The CGI specification specifies a number of environment variables which are set by the server. However, servers are somewhat unpredictable as to whether these variables will be null or point to empty strings when an environment variable is not set. Also, in order to allow the programmer to restore saved CGI environments, the CGIC library needs have a way of insulating the programmer from the actual environment variables.
Instead of calling getenv
to determine the value of a
variable such as HTTP_USER_AGENT (the browser software being used),
always use the
copies of the environment variables maintained by CGIC,
which are always valid C strings (they are never null, although
they may point to an empty string). For instance, the CGIC
variable containing the name of the browser software is
cgiUserAgent
.
The referring URL appears
in the variable cgiReferrer
.
CGIC can be used in conjunction with the gd graphics library, which can produce GIF images on the fly.
The following short sample program hints at the possibilities:
#include "cgic.h"
#include "gd.h"
char
*colors[] = {"red"
,"green"
,"blue"
};#define colorsTotal 3
int
cgiMain() {int
colorChosen; gdImagePtr im;int
r, g, b; /* Use gd to create an image */ im = gdImageCreate(64
,64
); r = gdImageColorAllocate(im,255
,0
,0
); g = gdImageColorAllocate(im,0
,255
,0
); b = gdImageColorAllocate(im,0
,0
,255
); /* Now use CGIC to find out what color the user requested */ cgiFormSelectSingle("color"
,3
, &colorChosen,0
); /* Now fill with the desired color */switch
(colorChosen) {case
0
: gdImageFill(im,32
,32
, r);break
;case
1
: gdImageFill(im,32
,32
, g);break
;case
2
: gdImageFill(im,32
,32
, b);break
; } /* Now output the image. Note the content type! */ cgiHeaderContentType("image/gif"
); /* Send the image tocgiOut
*/ gdImageGif(im,cgiOut
); /* Free the gd image */ gdImageDestroy(im);return
0
; }
Note that this program would need to be linked with both cgic.o
and libgd.a. Often programs of this type respond to one
cgiPathInfo
value or set of form fields
by returning an HTML page
with an inline image reference that, in turn, generates a GIF image.
Debugging CGI applications can be a painful task. Since CGI applications run in a special environment created by the web server, it is difficult to execute them in a debugger. However, the CGIC library provides a way of capturing "live" CGI environments to a file, and also provides a way to reload saved environments.
The provided program capture.c can be used to capture CGI
environments. Just change the first line of the cgiMain
function
of capture.c
to save the CGI environment to a filename appropriate
on your system and type make capture. Then place capture in your
CGI directory and set the form action or other link you want to test
to point to it. When the form submission or other link takes place,
capture will write the CGI environment active at that time
to
the filename you specified in the source. The function
cgiReadEnvironment
can then
be invoked on the same filename at the beginning of the cgiMain
function
of the application you want to test in order to restore the captured
environment. You can then execute your program in the debugger of your choice,
and it should perform exactly as it would have performed had
it been launched by the actual web server, including file uploads,
cookies and all other phenomena within the purview of CGIC.
→ Important: Make sure you specify the full path, as the current working directory of a CGI script may not be what you think it is!
→ Even More Important: If you call getenv
yourself
in your code, instead of using the provided
CGIC copies of the CGI environment variables, you will
not get the values you expect when running with
a saved CGI environment.
Always use the CGIC variables instead
of calling getenv
.
cgiFormString
•
cgiFormStringNoNewlines
•
cgiFormStringSpaceNeeded
•
cgiFormStringMultiple
•
cgiFormEntries
•
cgiStringArrayFree
•
cgiFormInteger
•
cgiFormIntegerBounded
•
cgiFormDouble
•
cgiFormDoubleBounded
•
cgiFormSelectSingle
•
cgiFormSelectMultiple
•
cgiFormSubmitClicked
•
cgiFormCheckboxSingle
•
cgiFormCheckboxMultiple
•
cgiFormRadio
•
cgiFormFileName
•
cgiFormFileSize
•
cgiFormFileContentType
•
cgiFormFileOpen
•
cgiFormFileRead
•
cgiFormFileClose
•
cgiHeaderLocation
•
cgiHeaderStatus
•
cgiHeaderContentType
•
cgiHeaderCookieSetString
•
cgiHeaderCookieSetInteger
•
cgiCookieString
•
cgiCookieInteger
•
cgiCookies
•
cgiHtmlEscape
•
cgiHtmlEscapeData
•
cgiValueEscape
•
cgiValueEscapeData
•
cgiMatchLanguage
•
cgiWriteEnvironment
•
cgiReadEnvironment
•
cgiMain
cgiFormString
cgiFormResultType cgiFormString(char *name, char *result, int max);
cgiFormString
attempts to retrieve the string sent for the
specified input field. The text will be copied into
the buffer specified by result, up to but not
exceeding (max − 1) bytes; a terminating null is then
added to complete the string. Regardless of the newline
format submitted by the browser, cgiFormString always
encodes each newline as a single line feed (ASCII decimal 10); as
a result the final string may be slightly shorter than indicated
by a call to cgiFormStringSpaceNeeded
but it will never be longer.
cgiFormSuccess
The string was successfully retrieved.
cgiFormTruncated
The string was retrieved truncated to fit the buffer.
cgiFormEmpty
The string was retrieved empty.
cgiFormNotFound
No such input field was submitted; result contains an empty string.
cgiFormStringNoNewlines
cgiFormResultType cgiFormStringNoNewlines(char *name, char *result, int max)
cgiFormStringNoNewlines
is exactly equivalent to cgiFormString
, except
that any carriage returns or line feeds that occur in the input
will be stripped out. The use of this function is recommended
for single-line text input fields, as some browsers will submit
carriage returns and line feeds when they should not.
cgiFormStringSpaceNeeded
cgiFormResultType cgiFormStringSpaceNeeded(char *name, int *length);
cgiFormStringSpaceNeeded
is used to determine the length of the input text
buffer needed to receive the contents of the specified input field.
This is useful if the programmer wishes to allocate sufficient memory
for input of arbitrary length. The actual length of the string
retrieved by a subsequent call to the function cgiFormString
may be slightly shorter
but will never be longer than (+*length).
cgiFormSuccess
*length contains the number of bytes of data, including the terminating null.
cgiFormNotFound
cgiFormString
gets called despite the return value.
cgiFormStringMultiple
cgiFormResultType cgiFormStringMultiple(char *name, char ***result);
cgiFormStringMultiple
is useful in the unusual case in which several
input elements in the form have the same name and, for whatever
reason, the programmer does not wish to use the checkbox, radio
button and selection menu functions provided below. This is
occasionally needed if the programmer cannot know
in advance what values might appear in a multiple-selection list
or group of checkboxes on a form. The value pointed to
by result will be set to a pointer to an array of strings; the last
entry in the array will be a null pointer. This array is allocated
by the CGIC library.
→ Important: when done working with the array,
you must call cgiStringArrayFree
with the array pointer as the
argument.
cgiFormSuccess
At least one occurrence of the name has been found.
cgiFormNotFound
No occurrences have been found.
cgiFormMemory
Not enough memory is available to allocate the array to be returned; result has been set to a null pointer.
In all cases except cgiFormMemory
, the result is set to point to a
valid array of strings, with the last element in the array being a
null pointer.
cgiFormEntries
cgiFormResultType cgiFormEntries(char ***result)
cgiFormEntries
is useful when the programmer cannot know the names
of all relevant form fields in advance. The value pointed to
by result will be set to a pointer to an array of strings; the last
entry in the array will be a null pointer. This array is allocated
by the CGIC library.
→ Important: when done working with the array,
you must call cgiStringArrayFree
with the array pointer as the
argument.
cgiFormSuccess
The result contains a valid array of strings, with the last element in the array being a null pointer.
cgiFormOutOfMemory
Out of memory. The result contains a null pointer.
cgiStringArrayFree
void cgiStringArrayFree(char **result);
cgiStringArrayFree
is used to free the memory associated with
a string array created by the functions
cgiFormStringMultiple
,
cgiFormEntries
, or
cgiFormCookies
.
cgiFormInteger
cgiFormResultType cgiFormInteger(char *name, int *result, int defaultV);
cgiFormInteger
attempts to retrieve the integer value submitted for the
specified input field. The value pointed to by result
will be set to the value submitted.
cgiFormSuccess
The value was successfully retrieved.
cgiFormEmpty
The value submitted is an empty string.
cgiFormBadType
The value submitted is not an integer.
cgiFormNotFound
No such input field was submitted.
In all cases except cgiFormSuccess
,
the value pointed to by result
has been set to the given default.
cgiFormIntegerBounded
cgiFormResultType cgiFormIntegerBounded(char *name, int *result, int min, int max, int defaultV);
cgiFormIntegerBounded
attempts to retrieve the integer submitted for the
specified input field, and constrains the result to be within
the specified bounds. The value pointed to by result
will be set to the value submitted.
cgiFormSuccess
The value has been successfully retrieved.
cgiFormConstrained
The value was out of bounds; the result was adjusted accordingly.
cgiFormEmpty
The value submitted is an empty string.
cgiFormBadType
The value submitted is not an integer.
cgiFormNotFound
No such input field was submitted.
In the latest three cases, the value pointed to by result is set to the given default.
cgiFormDouble
cgiFormResultType cgiFormDouble(char *name, double *result, double defaultV);
cgiFormDouble
attempts to retrieve the floating-point value submitted for
the specified input field. The value pointed to by result
will be set to the value submitted.
cgiFormSuccess
The value has been successfully retrieved.
cgiFormEmpty
The value submitted is an empty string.
cgiFormBadType
The value submitted is not a number.
cgiFormNotFound
No such input field was submitted.
In the latest three cases, the value pointed to by result is set to the given default.
cgiFormDoubleBounded
cgiFormResultType cgiFormDoubleBounded(char *name, double *result, double min, double max, double defaultV);
cgiFormDoubleBounded
attempts to retrieve the floating-point
value submitted for the specified input field, and constrains the
result to be within the specified bounds. The value pointed to by
result will be set to the value submitted.
cgiFormSuccess
The value has been successfully retrieved.
cgiFormConstrained
The value was out of bounds and result was adjusted accordingly.
cgiFormEmpty
The value submitted is an empty string.
cgiFormBadType
The value submitted is not a number.
cgiFormNotFound
No such input field was submitted.
In the latest three cases, the value pointed to by result is set to the given default.
cgiFormSelectSingle
cgiFormResultType cgiFormSelectSingle(char *name, char **choicesText, int choicesTotal, int *result, int defaultV);
NAME
attribute
of the SELECT
element.
cgiFormSelectSingle
retrieves the selection number associated with a SELECT
element
that does not allow multiple selections. result will contain
cgiFormSuccess
The value was successfully retrieved.
cgiFormNotFound
No selection was submitted.
cgiFormNoSuchChoice
The selection does not match any of the possibilities in the choicesText array.
cgiFormSelectMultiple
cgiFormResultType cgiFormSelectMultiple(char *name, char **choicesText, int choicesTotal, int *result, int *invalid);
NAME
attribute
of the SELECT
element.
cgiFormSelectMultiple
retrieves the selection numbers associated with a
SELECT
element that does allow multiple selections. For each choice in the
choicesText array that is selected, the corresponding integer in
the result array will be set to (1); other entries in the result
array will be set to (0).
cgiFormSuccess
At least one valid selection was successfully retrieved.
cgiFormNotFound
No valid selections were submitted.
cgiFormSubmitClicked
cgiFormResultType cgiFormSubmitClicked(char *name);
It is often desirable to know whether a particular submit button was clicked,
when multiple submit buttons with different name attributes exist.
cgiFormSubmitClicked
is an alternative name for the
cgiFormCheckboxSingle
function,
which is suitable for testing whether a particular submit button
was used.
cgiFormCheckboxSingle
cgiFormResultType cgiFormCheckboxSingle(char *name);
cgiFormCheckboxSingle
determines whether the check box with the given name
is checked.
cgiFormSuccess
The check box is checked.
cgiFormNotFound
The check box is not checked.
cgiFormCheckboxSingle
is intended for single
check boxes with a unique name; see below for functions to
deal with multiple check boxes with the same name, and
with radio buttons.
cgiFormCheckboxMultiple
cgiFormResultType cgiFormCheckboxMultiple(char *name, char **valuesText, int valuesTotal, int *result, int *invalid);
VALUE
attribute of each check box
cgiFormCheckboxMultiple
determines which checkboxes among a group
of checkboxes with the same name have been checked. This is distinct
from radio buttons (see cgiFormRadio
).
For
each choice in the valuesText array that is selected, the corresponding
integer in the result array will be set to (1); other entries in the
result array will be set to (0).
cgiFormSuccess
At least one valid check box was checked.
cgiFormNotFound
no valid check boxes were checked.
cgiFormRadio
cgiFormResultType cgiFormRadio(char *name, char **valuesText, int valuesTotal, int *result, int defaultV);
VALUE
attribute of each radio box
cgiFormRadio
determines which, if any, of a group of radio boxes with
the same name have been selected. result will contain:
cgiFormSuccess
A checked radio box was found in the group.
cgiFormNotFound
No box was checked.
cgiFormNoSuchChoice
The radio box submitted does not match any of the possibilities in the array valuesText.
cgiFormFileName
cgiFormResultType cgiFormFileName(char *name, char *fileName, int max);
cgiFormFileName
attempts to retrieve the file name uploaded by the
user for the specified form file input field.
NEVER EVER TRUST THIS FILE NAME TO BE REASONABLE AND
SAFE FOR DIRECT USE ON THE SERVER SIDE.
The text will be copied into
the buffer specified by fileName, up to but not
exceeding (max − 1) bytes; a terminating null is then
added to complete the string.
cgiFormSuccess
The string has been successfully retrieved and was not empty.
cgiFormNoFileName,
cgiFormNoFileName
The string has been successfully retrieved but empty indicating that no file was uploaded.
cgiFormTruncated
The string has been retrieved truncated to fit the buffer.
cgiFormNotFound
No such input field was submitted. An empty string has been copied to result.
cgiFormFileSize
cgiFormResultType cgiFormFileSize(char *name, int *sizeP);
cgiFormFileSize
attempts to retrieve the size, in bytes, of a
file uploaded by the browser in response to the
file input field given by the
name parameter.
cgiFormSuccess
On success, the size is stored to *sizeP.
cgiFormNotFound
The form field does not exist.
cgiFormNotAFile
The form field exists but no file was uploaded.
cgiFormFileContentType
cgiFormResultType cgiFormFileContentType(char *name, char *contentType, int max);
cgiFormString
attempts to retrieve the content type claimed by the
user for the given form file input field.
THERE IS NO GUARANTEE THAT THE CONTENT TYPE WILL BE
ACCURATE.
The content type string will be copied into
the buffer specified by contentType, up to but not
exceeding (max − 1) bytes; a terminating null is then
added to complete the string.
cgiFormSuccess
The string has been successfully retrieved and was not empty.
cgiFormNoContentType
The string has been successfully retrieved but empty indicating that no file was uploaded or the browser did not know the content type.
cgiFormTruncated
The string has been retrieved truncated to fit the buffer.
cgiFormNotFound
No such input field was submitted. An empty string has been copied to result.
cgiFormFileOpen
cgiFormResultType cgiFormFileOpen(char *name, cgiFilePtr *cfpp);
cgiFormFileOpen
attempts to open the actual uploaded file data for
the given form file input field.
cgiFormSuccess
On success, this function sets *cfpp to a valid cgiFilePtr
object for use with the function cgiFormFileRead
.
cgiFormNotFound
cgiFormNotAFile
cgiFormMemory
cgiFormIO
On failure, this function sets *cfpp to a null pointer.
cgiFormFileRead
cgiFormResultType cgiFormFileRead(cgiFilePtr cfp, char *buffer, int bufferSize, int *gotP);
cgiFormFileRead
attempts to read up to bufferSize
bytes from a cgiFilePtr
object previously opened with
cgiFormFileOpen
. If any data
is successfully read, it is copied to buffer,
and the number of bytes successfully read is stored
to *gotP.
cgiFormSuccess
Any data have been successfully read.
cgiFormEOF
At end of file.
cgiFormIO
In the event of an I/O error.
cgiFormOpenFailed
If cfp is a null pointer.
cgiFormFileClose
cgiFormResultType cgiFormFileClose(cgiFilePtr cfp);
cgiFormFileClose
closes a cgiFilePtr
object previously opened
with cgiFormFileOpen
, releasing
memory and other system resources.
cgiFormSuccess
Ordinary result.
cgiFormOpenFailed
cfp was null.
cgiHeaderLocation
void cgiHeaderLocation(char *redirectUrl);
cgiHeaderLocation
should be called if the programmer wishes to
redirect the user to a different URL. No futher output
is needed in this case.
If you wish to set cookies,
you must make your calls to
cgiHeaderCookieSetString
and
cgiHeaderCookieSetInteger
BEFORE invoking cgiHeaderLocation
.
cgiHeaderStatus
void cgiHeaderStatus(int status, char *statusMessage);
cgiHeaderStatus
should be called if the programmer wishes to
output an HTTP error status code instead of a document. The status
code is the first argument; the second argument is the status
message to be displayed to the user.
If you wish to set cookies,
you must make your calls to
cgiHeaderCookieSetString
and
cgiHeaderCookieSetInteger
BEFORE invoking cgiHeaderStatus
.
cgiHeaderContentType
void cgiHeaderContentType(char *mimeType);
cgiHeaderContentType
should be called if the programmer wishes to
output a new document in response to the user’s request. This is
the normal case. The single argument is the MIME document type
of the response; typical values are
If you wish to set cookies,
you must make your calls to
cgiHeaderCookieSetString
and
cgiHeaderCookieSetInteger
BEFORE invoking cgiHeaderContentType
.
cgiHeaderCookieSetString
void cgiHeaderCookieSetString(char *name, char *value, int lifetime, char *path, char *domain);
cgiHeaderCookieSetString
should be called when the programmer wishes
to store a piece of information in the user’s browser, so that the
stored information is again presented to the server on subsequent
accesses to the relevant site.
name | the name of the cookie to be stored | For best results in all browsers, use a short name without spaces or unusual punctuation. |
value | the value of the cookie to be stored | Again, for best results, use a short string; it is recommended that cookies be used to store a unique identifier which is then used to look up more detailed information in a database on the server side. Attempts to store elaborate information on the browser side are much more likely to fail. |
lifetime | the number of seconds that the cookie should be kept by the browser | (86400) is a single full day, (365*86400) is roughly one year. |
path | the partial URL of the Web site within which the cookie is relevant. | If the cookie should be sent to the server for every access to the entire site, set this argument to /. |
domain | the Web site name or entire domain for which this cookie should be submitted | If you choose to have the cookie sent back for the entire domain, this argument must begin with a dot, such as .boutell.com. |
cgiScriptName
and cgiServerName
provide convenient
values for path and domain arguments.
cgiHeaderCookieSetInteger
•
cgiCookieString
•
cgiCookieInteger
•
cgiCookies
cgiHeaderCookieSetInteger
void cgiHeaderCookieSetInteger(char *name, int value, int secondsToLive, char *path, char *domain);
cgiHeaderCookieSetInteger
is identical to
cgiHeaderCookieSetString
,
except that the value to be set is an integer rather than a string.
See cgiHeaderCookieSetString
for complete information.
cgiCookieString
cgiFormResultType
cgiCookieString(char *name, char *result, int max);
cgiFormString
attempts to retrieve the string sent for the
specified cookie (browser-side persistent storage). The
text will be copied into
the buffer specified by result, up to but not
exceeding (max − 1) bytes; a terminating null is then
added to complete the string.
cgiFormSuccess
The string has been successfully retrieved.
cgiFormTruncated
The string has been retrieved truncated to fit the buffer.
cgiFormEmpty
The string has been retrieved empty.
cgiFormNotFound
No such cookie has been submitted; an empty string has been copied to result.
cgiCookieInteger
cgiFormResultType
cgiCookieInteger(char *name, int *result, int defaultV);
cgiCookieInteger
attempts to retrieve the integer sent for the
specified cookie (browser-side persistent storage).
The result will contain to the value submitted.
cgiFormSuccess
The value has been successfully retrieved.
cgiFormEmpty
The value submitted is an empty string.
cgiFormBadType
The value submitted is not an integer.
cgiFormNotFound
No such input field was submitted.
In the last three cases, the result will contain the given default value.
cgiCookieString
• cgiCookies
• cgiHeaderCookieSetString
• cgiHeaderCookieSetInteger
cgiCookies
cgiFormResultType
cgiCookies(char *name, char ***result);
cgiCookies
is useful when the programmer cannot know the names
of all relevant cookies (browser-side persistent strings) in advance.
The result array is allocated
by the CGIC library.
→ Important: when done working with the array,
you must call cgiStringArrayFree
with the array pointer as the
argument.
cgiFormSuccess
The result will contain an array of strings; the last entry in the array will be a null pointer.
cgiFormOutOfMemory
Out of memory; the result will be a null pointer.
cgiHtmlEscape
cgiFormResultType
cgiHtmlEscape(char *s);
cgiHtmlEscape
outputs the specified null-terminated string to
cgiOut
,
escaping any [<&>] characters encountered correctly so that
they do not interfere with HTML markup.
cgiFormSuccess
Success.
cgiFormIO
An I/O error occurred.
cgiHtmlEscapeData
cgiFormResultType
cgiHtmlEscapeData(char *data, int len);
cgiHtmlEscapeData
is identical to cgiHtmlEscape
,
except that the data is not null-terminated. This version of the function
outputs len bytes. See cgiHtmlEscape
for more information.
cgiValueEscape
cgiFormResultType
cgiValueEscape(char *s);
cgiValueEscape
outputs the specified null-terminated string to
cgiOut
,
escaping any ["] characters encountered correctly so that
they do not interfere with the quotation marks of HTML attribute
values. This is useful when outputting a string as part of the
value
attribute of an input
tag,
or the href
attribute of a link
or form
tag.
cgiFormSuccess
Success.
cgiFormIO
An I/O error occurred.
cgiValueEscapeData
cgiFormResultType
cgiValueEscapeData(char *data, int len);
cgiValueEscapeData
is identical to cgiValueEscape
,
except that the data is not null-terminated. This version of the function
outputs len bytes. See cgiValueEscape
for more information.
cgiMatchLanguage
void cgiMatchLanguage (struct lang_pref_enum *enumerator, struct lang_pref const *const supported [02]);
cgiMatchLanguage
attempts to find and set a system locale
based on the preferences expressed by the client.
The chosen language should contain a character set embedded after a dot ('.');
you can use this information
to declare the output character set.
Contains a pointer to the current language preference;
it should initially point
to cgiAcceptLanguage
or to a copy of it.
After the call,
its value will contain the chosen language and its evaluated quality,
and the contents of the client preferences string will be destroyed.
Contains an array of locales supported by the Web application, along with a confidence level, in ascending alphabetical order. This parameter can be null, meaning that the application is not localized; in this case, every locale supported by the operating system is considered. The locales in this array should be specified in extended format (e.g. en_US.ISO-8859-1).
The set of system-supported locales is compiled at build time; however, locales that cannot be set at run time are not considered.
Loading a locale is a costly process, and this function does it many times, depending on how many preferences have been specified by the client and whether the territory code has been included (otherwise all territories where the language is spoken are considered). It would be better to be able to evaluate the availaibility of a locale without loading; however, there is no portable way to do this.
cgiWriteEnvironment
cgiEnvironmentResultType
cgiWriteEnvironment(char *filename);
cgiWriteEnvironment
can
be used to write the entire CGI environment, including
form data, to the specified output file;
cgiReadEnvironment
can then be used to restore that environment from the specified
input file for debugging. Of course, these will only work as expected
if you use the CGIC copies of the CGI environment
variables and cgiIn
and
cgiOut
rather than stdin and
stdout (also see above). These functions are useful in order
to capture real CGI situations while the Web server is running, then
recreate them in a debugging environment.
cgiEnvironmentSuccess
Success.
cgiEnvironmentIO
An I/O error occurred.
cgiEnvironmentMemory
Out of memory.
cgiReadEnvironment
cgiEnvironmentResultType
cgiReadEnvironment(char *filename);
cgiReadEnvironment
restores a CGI environment saved to the specified file by
cgiWriteEnvironment
.
Of course, these will only work as expected
if you use the CGIC copies of the CGI environment
variables and cgiIn
and
cgiOut
rather than the standard input and
output (also see above). These functions are useful in order
to capture real CGI situations while the Web server is running, then
recreate them in a debugging environment.
cgiEnvironmentSuccess
Success.
cgiEnvironmentIO
An I/O error occurred.
cgiEnvironmentMemory
Out of memory.
cgiMain
int cgiMain();
The programmer must write this function, which performs
the unique task of the program and is invoked by the true main
function, found in the CGIC library itself.
The return value from
cgiMain
will be the return value of the program. It is expected that
the user will make numerous calls to the cgiForm
functions
from within this function. See how to write
a CGIC application for details.
cgiServerSoftware
• cgiServerName
• cgiGatewayInterface
• cgiServerProtocol
• cgiServerPort
• cgiRequestMethod
• cgiPathInfo
• cgiPathTranslated
• cgiScriptName
• cgiQueryString
• cgiRemoteHost
• cgiRemoteAddr
• cgiAuthType
• cgiRemoteUser
• cgiRemoteIdent
• cgiContentType
• cgiCookie
• cgiAccept
• cgiAcceptCharset
• cgiAcceptEncoding
• cgiAcceptLanguage
• cgiUserAgent
• cgiReferrer
• cgiContentLength
• cgiOut
• cgiIn
This section provides a reference guide to the various global
variables provided by CGIC for the programmer to utilize.
These variables should always be used in preference to
standard input and output and calls to getenv
in order to ensure
compatibility with the CGIC CGI debugging features.
Most of these variables are equivalent to various CGI environment variables. The most important difference is that the CGIC environment string variables are never null pointers. They will always point to valid C strings of zero or more characters.
cgiServerSoftware
char *cgiServerSoftware;
Contains the name of the server software, or to an empty string if unknown.
cgiServerName
char *cgiServerName;
Contains the name of the server, or to an empty string if unknown.
cgiGatewayInterface
char *cgiGatewayInterface;
Contains the name of the gateway interface (usually CGI/1.1), or to an empty string if unknown.
cgiServerProtocol
char *cgiServerProtocol;
Contains the protocol in use (usually HTTP/1.0), or to an empty string if unknown.
cgiServerPort
char *cgiServerPort;
Contains the port number on which the server is listening for HTTP connections (usually 80), or an empty string if unknown.
cgiRequestMethod
char *cgiRequestMethod;
Contains the method used in the request (usually GET or POST), or an empty string if unknown (this should not happen).
cgiPathInfo
char *cgiPathInfo;
Most Web servers recognize any additional path information in
the URL of the request
beyond the name of the CGI program itself and
pass that information on to the program. cgiPathInfo
contains this
additional path information.
cgiPathTranslated
char *cgiPathTranslated;
Most Web servers recognize any additional path information in
the URL of the request
beyond the name of the CGI program itself and
pass that information on to the program.
cgiPathTranslated
contains this additional path information,
translated by the server into a
filesystem path on the local server.
cgiScriptName
char *cgiScriptName;
Contains the name under which the program was invoked.
cgiQueryString
char *cgiQueryString;
Contains any query information submitted by the user as a result
of a GET method form or an ISINDEX element. Note that this
information need not be parsed directly unless an ISINDEX element
was used; normally it is parsed automatically
by the CGIC library. Use
the cgiForm
family of functions to retrieve the values associated
with form input fields. See how to write
a CGIC application for more information.
cgiRemoteHost
char *cgiRemoteHost;
Contains the fully resolved host name of the browser, if known, or an empty string if unknown.
cgiRemoteAddr
char *cgiRemoteAddr;
Contains the dotted-decimal IP address of the browser, if known, or an empty string if unknown.
cgiAuthType
char *cgiAuthType;
Contains the type of authorization used for the request, if any, or an empty string if none or unknown.
cgiRemoteUser
char *cgiRemoteUser;
Contains the user name under which the user has
authenticated, or an empty string if no authentication has
taken place. The certainty of this information depends on
the type of authorization in use; see
cgiAuthType
.
cgiRemoteIdent
char *cgiRemoteIdent;
Contains the user name volunteered by the user via the user identification protocol, or an empty string if unknown. This information is not secure. Identification demons can be installed by users on insecure systems such as Microsoft Windows machines.
cgiContentType
char *cgiContentType;
Contains the MIME content type of the information submitted by the user, if an, or an empty string if no information was submitted. If this string is equal to application/x-www-form-urlencoded or multipart/form-data, the CGIC library will automatically examine the form data submitted. If this string has any other non-empty value, a different type of data has been submitted. This is currently very rare, as most browsers can only submit forms and file uploads which CGIC parses directly.
cgiCookie
char *cgiCookie;
Contains the raw cookie (browser-side persistent storage)
data submitted by the Web browser.
Programmers should use the functions cgiCookies
,
cgiCookieString
and
cgiCookieInteger
instead of
examining this string directly.
cgiAccept
char *cgiAccept;
Contains a comma-separated list
of MIME content type preferences
acceptable to the browser
(see cgiHeaderContentType
), or an empty string.
Unfortunately, this variable
is not supplied in a useful form by most current browsers. Programmers wishing
to make decisions based on the capabilities of the browser
are advised to check the cgiUserAgent
variable against a list of browsers and capabilities instead.
cgiAcceptCharset
char *cgiAcceptCharset;
Contains a comma-separated list of character set preferences
which you can use to choose the character set acceptable to the client.
This is rarely necessary
because most user agents will accept any known character set;
moreover,
some Web servers can transform your reply
via their internal mechanisms to meet the client’s preferences,
provided that you correctly report the output character set
using
cgiHeaderContentType
or by equivalent means.
cgiAcceptEncoding
char *cgiAcceptEncoding;
Contains a comma-separated list of encoding preferences which you can use to choose the encoding acceptable to the client, e.g. to save outgoing bandwidth. This is rarely necessary because Web servers can encode your content on the fly. If you choose to encode the content yourself, you must report it to the Web server using a message header; emitting such a header is possible but unsupported.
cgiContentLanguage
char *cgiAcceptLanguage;
Contains a comma-separated list of language preferences
which you can use to choose the interface language acceptable to the client.
You can pass this value
to cgiMatchLanguage
.
cgiUserAgent
char *cgiUserAgent;
Contains the name of the browser in use, or an empty string if this information is not available.
cgiReferrer
char *cgiReferrer;
Contains the URL of the previous page visited by the user. This is often the URL of the form that brought the user to your program. Note that reporting this information is entirely up to the browser, which may choose not do so, and may choose not to do so truthfully. However, this variable is typically accurate.
The frequently
used misspelling
is also supplied as a macro.
cgiReferer
cgiContentLength
int cgiContentLength;
The number of bytes of form or query data received.
Note that if the submission is a form or query submission
the library will read and parse all the information
directly from cgiIn
and/or cgiQueryString
. The programmer should
not do so, and indeed the handle cgiIn
will be at end-of-file
in such cases.
cgiOut
FILE *cgiOut;
CGI output handle.
The cgiHeader
functions, such as
cgiHeaderContentType
, should
be used first to output the MIME headers;
the output HTML
page, GIF image or other Web document should then be written
to cgiOut
by the programmer
using standard C I/O functions
such as fprintf and fwrite.
cgiOut
is normally equivalent
to the standard output;
however, it is recommended that cgiOut
be used to
ensure compatibility with future versions of CGIC for
specialized environments.
cgiIn
FILE *cgiIn;
CGI input handle. In 99.99% of cases, you will not need this. CGIC 2.0 supports both regular POST form submissions and multipart/form-data file upload form submissions directly.
In most cases, CGIC functions are designed to produce reasonable results even when browsers and users do unreasonable things. However, it is sometimes important to know precisely which unreasonable things took place, especially when assigning a default value or bounding a value is an inadequate solution. The following result codes are useful in making this determination.
cgiFormSuccess
Indicates that the function successfully performed at least one action (or retrieved at least one value, where applicable).
cgiFormTruncated
Indicates that a string value retrieved from the user was cut short to avoid overwriting the end of a buffer.
cgiFormBadType
Indicates that a numeric value submitted by the user was in fact not a legal number.
cgiFormEmpty
Indicates that a field was retrieved but contained no data.
cgiFormNotFound
Indicates that no value was submitted for a particular field.
cgiFormConstrained
Indicates that a numeric value was beyond the specified bounds and was forced to the lower or upper bound as appropriate.
cgiFormNoSuchChoice
Indicates that the value submitted for a single-choice field (such as a radio-button group) was not one of the acceptable values. This usually indicates a discrepancy between the form and the program.
cgiFormEOF
Returned by cgiFormFileRead
when, at the start of the call, the cgiFilePtr
object is already
positioned at the end of the uploaded file data.
cgiFormIO
Returned by cgiFormFileRead
when an I/O error occurs while reading uploaded file data.
cgiFormNotAFile
Returned in response to an attempt to manipulate a form field that is not a file upload field using a file-related function.
cgiFormNoContentType
Returned in response to an attempt to fetch the content type of a file upload field when the content type is not specified by the browser.
cgiFormNoFileName
Returned in response to an attempt to fetch the file name of a file upload field when a file name is not specified by the browser.
cgiFormOpenFailed
Returned in response to an attempt to read from a null
cgiFilePtr
object, typically when the programmer has failed to
check the result of a call to cgiFormFileOpen
.
cgiEnvironmentMemory
Indicates that an attempt to read or write the CGI environment to or from a capture file failed due to an out-of-memory error.
cgiEnvironmentSuccess
Indicates that an attempt to read or write the CGI environment to or from a capture file was successful.
cgiEnvironmentIO
Indicates that an attempt to read or write the CGI environment to or from a capture file failed due to an I/O error.
cgiEnvironmentWrongVersion
Indicates that an attempt to read from a saved debugging CGI environment produced by a pre-2.0 version of CGIC was made.
cgiAccept | cgiAuthType | cgiContentLength | cgiContentType | cgiEnvironmentIO | cgiEnvironmentMemory | cgiEnvironmentSuccess | cgiCookieInteger | cgiCookies | cgiCookieSetInteger | cgiCookieSetString | cgiCookieString | cgiHtmlEscape | cgiHtmlEscapeData | cgiValueEscape | cgiValueEscapeData | cgiFormBadType | cgiFormCheckboxMultiple() | cgiFormCheckboxSingle() | cgiFormConstrained | cgiFormDouble() | cgiFormDoubleBounded() | cgiFormEOF | cgiFormEmpty | cgiFormEntries | cgiFormFileClose | cgiFormFileContentType | cgiFormFileName | cgiFormFileOpen | cgiFormFileRead | cgiFormFileSize | cgiFormInteger() | cgiFormIntegerBounded() | cgiFormNoContentType | cgiFormNoFileName | cgiFormNoSuchChoice | cgiFormNotAFile | cgiFormNotFound | cgiFormRadio() | cgiFormSelectMultiple() | cgiFormSelectSingle() | cgiFormString() | cgiFormStringMultiple() | cgiFormStringNoNewlines() | cgiFormStringSpaceNeeded() | cgiFormSuccess | cgiFormTruncated | cgiGatewayInterface | cgiHeaderContentType() | cgiHeaderLocation() | cgiHeaderStatus() | cgiIn | cgiMain() cgiOut | cgiPathInfo | cgiPathTranslated | cgiQueryString | cgiReadEnvironment() | cgiReferrer() | cgiRemoteAddr | cgiRemoteHost | cgiRemoteIdent | cgiRemoteUser | cgiRequestMethod | cgiScriptName | cgiServerName | cgiServerPort | cgiServerProtocol | cgiServerSoftware | cgiStringArrayFree() | cgiUserAgent | cgiWriteEnvironment()