cgic html模版,cgic.html

cgic: an ANSI C library for CGI Programming

cgic 2.07: an ANSI C library for CGI Programming

IMPORTANT NOTICES:

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.

Table of Contents

Credits and License Terms

cgic is now distributed under the MIT license:

Copyright (c) 1996-2019 Thomas Boutell

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

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.

What's new in version 2.07?

Per a suggestion by Geoff Mulligan, cgic now tolerates keys without a value in URL-encoded GET and POST submissions. Although the HTML5 spec discourages it, there are existing systems in the wild that do leave the `=` off entirely if the value is an empty string. Beginning with version 2.07, `cgic` handles this as you'd expect: you get an entry with the corresponding key and an empty string as the value. A simple unit test compilation target was also added, to test this feature and rule out side effects.

What's new in version 2.06?

A long list of significant fixes generously contributed by Jeffrey Hutzelman.

These are especially important on platforms where attempting to read beyong the content length stated by the request can lead to a deadlock. Please see the commit notes.

What's new in version 2.05?

Uploaded files properly closed; corrects a resource leak and enables

file uploads to work properly on platforms with particular file

locking semantics.

What's new in version 2.04?

Documentation fixes: the cgiHtmlEscape, cgiHtmlEscapeData,

cgiValueEscape, and cgiValueEscapeData routines were named

incorrectly in the manual. No code changes in version 2.04.

What's new in version 2.03?

  • Support for setting cookies has been reimplemented. The new

    code closely follows the actual practice of web sites 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.

What's new in version 2.02?

  • 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.

What's new in version 2.01?

  • 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 <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

What's new in version 2.0?

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 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.

2. 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.

3. CGIC 2.0 offers a convenient way to retrieve a list of all form fields.

The new cgiFormEntries

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

cgiHtmlEscape,

cgiHtmlEscapeData,

cgiValueEscape and

cgiValueEscapeData.

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

cgiFormSubmitClicked,

a convenient alternate label for the

cgiFormCheckboxSingle function.

What's new in version 1.07?

A problem with the cgiFormString and related functions has been

corrected. These functions were previously incorrectly returning cgiFormTruncated

in cases where the returned string fit the buffer exactly.

What's new in version 1.06?

1. A potentially significant buffer overflow problem has been

corrected. Jon Ribbens correctly pointed out to me (and to the

Internet's bugtraq mailing list) that the cgiFormEntryString

function, which is used directly or indirectly by almost all

CGIC programs, can potentially write past the buffer passed

to it by the programmer. This bug has been corrected.

Upgrading to version 1.06 is strongly recommended.

2. The function cgiSaferSystem() has been

removed entirely. This function escaped only a few metacharacters,

while most shells have many, and there was no way to account for

the many different operating system shells that might be in use

on different operating systems. Since this led to a false sense

of security, the function has been removed. It is our recommendation

that user input should never be passed directly on the command line

unless it has been carefully shown to contain only characters

regarded as safe and appropriate by the programmer. Even then, it is

better to design your utilities to accept their input from standard

input rather than the command line.

What's new in version 1.05?

Non-exclusive commercial license fee reduced to $200.

What's new in version 1.04?

For consistency with other packages, the standard Makefile

now produces a true library for cgic (libcgic.a).

What's new in version 1.03?

Version 1.03 sends line feeds only (ascii 10) to end

Content-type:, Status:, and other HTTP protocol output lines,

instead of CR/LF sequences. The standard specifies CR/LF.

Unfortunately, too many servers reject CR/LF to make

implementation of that standard practical. No server

tested ever rejects LF alone in this context.

What's new in version 1.02?

Version 1.02 corrects bugs in previous versions:

  • cgiFormDoubleBounded specified

    its arguments in the wrong order, with surprising results.

    This bug has been corrected.

What's new in version 1.01?

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.

  • Hex 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 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.

What is cgic?

cgic is an ANSI C-language library for the creation of CGI-based

World Wide Web applications. For basic information about

the CGI standard, see the

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.

Obtaining cgic

cgic is distributed via the web in two forms: as a Windows-compatible

.ZIP file, and as a gzipped tar file. Most users of Windows and

related operating systems have access to 'unzip' or 'pkunzip'. All modern Unix

systems come with 'gunzip' and 'tar' as standard equipment, and gzip/gunzip

is not difficult to find if yours does not. Versions

of these programs for other operating systems are widely

available if you do not already have them.

Important: to use cgic, you will need an ANSI-standard

C compiler. 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.

Building cgic: a sample application

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, www.mysite.com/cgi-bin/cgictest.cgi).

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.

What to do if it won't compile

  • Are you using Visual C++ or Borland C++? Did you forget to add

    cgic.c to your project?

  • Make sure you are using an ANSI C or C++ compiler.

    (All of the Windows compilers are ANSI C compliant.)

If none of the above proves effective, please see the

section regarding support.

How to write a cgic application

Note: All cgic applications must be linked to the cgic.c module

itself. How to do this depends on your operating system; under Unix,

just use the provided Makefile as an example.

Since all CGI applications must perform certain initial

tasks, such as parsing form data and examining

environment variables, the cgic library provides its

own main() function. When you write applications that

use cgic, you will begin your own programs by writing

a cgiMain() function, which cgic will invoke when

the initial cgi work has been successfully completed. Your

program must also be sure to #include the file cgic.h.

Important: if you write your own main()

function, your program will not link properly. Your own

code should begin with cgiMain(). The library

provides main() for you. (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, "<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;

}

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

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 cgiFormSubmitClicked 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. */

cgiHeaderCookieSet(cname, cvalue,

86400, cgiScriptName, cgiServerName,

cgiCookieHttpOnly | cgiCookieSameSiteStrict);

}

}

Since this is a test program, the cgiFormString

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 cgiHeaderCookieSet

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

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.dev or the entire .boutell.dev

domain. In this case, the current site on which the program is running

is the only relevant site, so cgiServerName is used

as the domain.

The sixth argument sets extra security options, for example HttpOnly or

SameSite=Strict to prevent cross-site-scripting attacks.

Outputting the Content Type Header

Next, 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 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 own ContentType and other

header information to cgiOut 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:

 
 

void Name() {

char name[81];

cgiFormStringNoNewlines("name", name, 81);

fprintf(cgiOut, "Name: ");

cgicHtmlEscape(name);

fprintf(cgiOut, "
\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 cgiFormStringNoNewlines()

function is then invoked to retrieve the name and ensure that

carriage returns are not present in the name (despite the

incorrect behavior of some web browsers). The first argument

is the name of the input field in the form, the second argument

is the buffer to which the data should be 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

cgiFormStringSpaceNeeded()

function can be used to check the amount of space needed; the

return value of cgiFormStringNoNewlines() can also be checked

to determine whether truncation occurred. See

the full description of

cgiFormStringNoNewlines().

Handling Output

Note that Name() writes its HTML output to cgiOut, 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 cgiHtmlEscape function is used to output

the user-entered name with any occurrences of these characters

correctly escaped as &lt;, &gt;,

and &amp;.

Important: cgiOut is normally equivalent

to stdout, 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 stdin and stdout 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 Address() function of cgictest.c for an example.

Handling Single Checkboxes

Consider the Hungry() function, which determines whether

the user has selected the "hungry" checkbox:

 
 

void Hungry() {

if (cgiFormCheckboxSingle("hungry") == cgiFormSuccess) {

fprintf(cgiOut, "I'm Hungry!<BR>\n");

} else {

fprintf(cgiOut, "I'm Not Hungry!<BR>\n");

}

}

This function takes advantage of the

cgiFormCheckboxSingle() function, which

determines whether a single checkbox has been selected.

cgiFormCheckboxSingle() accepts the name attribute of the checkbox

as its sole argument and returns

cgiFormSuccess if the checkbox is selected, or

cgiFormNotFound if it is not.

If multiple checkboxes with the same name are in use,

consider the

cgiFormCheckboxMultiple() and

cgiFormStringMultiple()

functions.

Handling Numeric Input

Now consider the Temperature() function, which retrieves

a temperature in degrees (a floating-point value) and ensures

that it lies within particular bounds:

 
 

void Temperature() {

double temperature;

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

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.

Handling Single-Choice Input

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 Color() function 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 cgiFormSelectSingle()

function 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

cgiFormRadio(), which functions

identically.

"What if I won't know the acceptable choices at runtime?"

If the acceptable choices aren't known until runtime,

one can simply load the choices from disk. But if the acceptable

choices aren't 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 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 NonExButtons() function of cgictest.c, immediately below.

Handling Multiple-Choice Input

Consider the first half of the NonExButtons() function 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

cgiFormCheckboxMultiple(),

which is used to identify one or more selected checkboxes with

the same name. This function performs identically to

cgiFormSelectMultiple().

That is, <SELECT> tags 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 tags 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 the return value of cgiFormCheckboxMultiple is

inspected to determine whether any choices at all were

set. See the full description of

cgiFormCheckboxMultiple

for other possible return values.

"What if I won't know the acceptable choices at runtime?"

If the acceptable choices aren't known until runtime,

one can simply load the choices from disk. But if the acceptable

choices aren't 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 NonExButtons() function 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 calling free() would free

the array but not the individual strings. The

function cgiStringArrayFree() does the job completely. */

cgiStringArrayFree(responses);

}

This code excerpt demonstrates an alternate means 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> tags 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

isn't 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 simple loop:

 
 

int i = 0;

while (responses[i]) {

/* Do something with the string responses[i] */

i++;

}

can be used to walk through the array until the last

entry is encountered.

Important: the

cgiFormStringMultiple function

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. Don't just call the

free() function; if you do, the individual strings will not be freed.

Accessing Uploaded Files

CGIC provides functions to access files that have been uploaded

as part of a form submission. IMPORTANT: you MUST set

the enctype attribute of your form tag

to multipart/form-data for this feature to work! For an

example, see the ShowForm function of

cgictest.c, examined below.

The File function 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 File function 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 cgiFormFileName function does

not succeed, no file was uploaded.

Next, the cgiFormFileSize function is called

to determine the size of the uploaded file, in bytes.

The File function 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, HTML document,

word processing document, or other type of file. 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 cgiFormFileOpen,

passing the address of a cgiFilePtr object. If this function

succeeds, the cgiFilePtr object becomes valid, and can be

used in subsequent calls to cgiFormFileRead.

Notice that the number of bytes read may be less than the number requested,

in particular on the last successful call before cgiFormFileRead begins

to return cgiFormEOF. When cgiFormFileRead no longer returns

cgiFormSuccess,

the programmer calls cgiFormFileClose to

release the cgiFilePtr object.

The uploaded file data may contain anything, including binary data,

null characters, and so on. The example program uses the

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.

Fetching All Form Entries

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 cgiFormEntries function.

The Entries function of cgictest.c demonstrates the use of

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 cgiFormEntries function 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 above code illustrates one way of

looping through the returned strings. Note the final call to

cgiStringArrayFree, which is

essential in order to return the memory used to store the strings

and the string array.

Retrieving Cookies

The Cookies function 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 cgiCookies function

to retrieve a list of all currently set cookies as a null-terminated

array of strings. The cgiCookieString

function 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.

Displaying a Form That Submits to the Current Program

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 cgiScriptName environment variable, 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.

Examining CGI environment variables

The CGI standard 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

cgic copies of the environment variables,

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.

How can I generate images from my cgic application?

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 to cgiOut */

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: using capture

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

cgiReadEnvironment() function 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().

cgic function reference

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 will never be longer.

cgiFormString returns cgiFormSuccess if the string was

successfully retrieved,

cgiFormTruncated if the string was

retrieved but was truncated to fit the buffer,

cgiFormEmpty if the string was

retrieved but was empty, and cgiFormNotFound if no

such input field was submitted. In the last case,

an empty string is copied to result.

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.

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 cgiFormString() may be slightly shorter

but will never be longer than *result. On success, cgiFormStringSpaceNeeded()

sets the value pointed to by length to the number of bytes of data,

including the terminating null, and returns cgiFormSuccess. If no

value was submitted for the specified field, cgiFormStringSpaceNeeded sets

the value pointed to by length to 1 and returns cgiFormNotFound. 1 is

set to ensure space for an empty string (a single null

character) if cgiFormString is called despite the return value.

cgiFormResultType cgiFormStringMultiple(

char *name, char ***ptrToStringArray)

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 CGI library. Important: when done working with the array,

you must call cgiStringArrayFree() with the array pointer as the

argument. cgiFormStringMultiple() returns cgiFormSuccess if at least

one occurrence of the name is found, cgiFormNotFound

if no occurrences are found, or cgiFormMemory if not enough

memory is available to allocate the array to be returned.

In all cases except the last, ptrToStringArray is set to point to a

valid array of strings, with the last element in the array being a

null pointer; in the out-of-memory case ptrToStringArray is set to

a null pointer.

cgiFormResultType cgiFormEntries(

char ***ptrToStringArray)

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 CGI library. Important: when done working with the array,

you must call cgiStringArrayFree() with the array pointer as the

argument. cgiFormEntries() returns cgiFormSuccess except in the event of an out of memory error.

On success, ptrToStringArray is set to point to a

valid array of strings, with the last element in the array being a

null pointer; in the out-of-memory case ptrToStringArray is set to

a null pointer, and

cgiFormOutOfMemory is returned.

void cgiStringArrayFree(char **stringArray)

cgiStringArrayFree() is used to free the memory associated with

a string array created by

cgiFormStringMultiple(),

cgiFormEntries(), or

cgiFormCookies().

cgiFormResultType cgiFormInteger(

char *name, int *result, int defaultV)

cgiFormInteger() attempts to retrieve the integer sent for the

specified input field. The value pointed to by result

will be set to the value submitted. cgiFormInteger() returns

cgiFormSuccess if the value was successfully retrieved,

cgiFormEmpty if the value submitted is an empty string,

cgiFormBadType if the value submitted is not an integer,

and cgiFormNotFound if no such input field was submitted.

In the last three cases, the value pointed to by result

is set to the specified default.

cgiFormResultType cgiFormIntegerBounded(

char *name, int *result, int min, int max, int defaultV)

cgiFormIntegerBounded() attempts to retrieve the integer sent 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. cgiFormIntegerBounded() returns

cgiFormSuccess if the value was successfully retrieved,

cgiFormConstrained if the value was out of bounds and result

was adjusted accordingly, cgiFormEmpty if the value submitted is

an empty string, cgiFormBadType if the value submitted is not an

integer, and cgiFormNotFound if no such input field was submitted.

In the last three cases, the value pointed to by result

is set to the specified default.

cgiFormResultType cgiFormDouble(

char *name, double *result, double defaultV)

cgiFormDouble attempts to retrieve the floating-point value sent for

the specified input field. The value pointed to by result

will be set to the value submitted. cgiFormDouble returns

cgiFormSuccess if the value was successfully retrieved,

cgiFormEmpty if the value submitted is an empty string,

cgiFormBadType if the value submitted is not a number,

and cgiFormNotFound if no such input field was submitted.

In the last three cases, the value pointed to by result

is set to the specified default.

cgiFormResultType cgiFormDoubleBounded(

char *name, double *result, double min, double max,

double defaultV)

cgiFormDoubleBounded() attempts to retrieve the floating-point

value sent 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. cgiFormDoubleBounded() returns

cgiFormSuccess if the value was successfully retrieved,

cgiFormConstrained if the value was out of bounds and result

was adjusted accordingly, cgiFormEmpty if the value submitted is

an empty string, cgiFormBadType if the value submitted is not a

number, and cgiFormNotFound if no such input field was submitted.

In the last three cases, the value pointed to by result

is set to the specified default.

cgiFormResultType cgiFormSelectSingle(

char *name, char **choicesText, int choicesTotal,

int *result, int defaultV)

cgiFormSelectSingle() retrieves the selection number associated with a

<SELECT> element that does not allow multiple selections. name

should identify the NAME attribute of the <SELECT> element. choicesText

should point to an array of strings identifying each choice;

choicesTotal should indicate the total number of choices. The value

pointed to by result will be set to the position of the actual choice

selected within the choicesText array, if any, or to the value of

default, if no selection was submitted or an invalid selection was

made. cgiFormSelectSingle() returns cgiFormSuccess if the value was

successfully retrieved, cgiFormNotFound if no selection

was submitted, and cgiFormNoSuchChoice if the selection

does not match any of the possibilities in the choicesText array.

cgiFormResultType cgiFormSelectMultiple(

char *name, char **choicesText, int choicesTotal,

int *result, int *invalid)

cgiFormSelectMultiple() retrieves the selection numbers associated with a

<SELECT> element that does allow multiple selections. name should

identify the NAME attribute of the <SELECT> element. choicesText

should point to an array of strings identifying each choice;

choicesTotal should indicate the total number of choices. result

should point to an array of integers with as many elements as there

are strings in the choicesText array. For each choice in the

choicesText array that is selected, the corresponding integer in

the result array will be set to one; other entries in the result

array will be set to zero. cgiFormSelectMultiple() returns cgiFormSuccess

if at least one valid selection was successfully retrieved or

cgiFormNotFound if no valid selections were submitted.

The integer pointed to by invalid is set to the number of

invalid selections that were submitted, which should be zero

unless the form and the choicesText array do not agree.

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.

cgiFormResultType cgiFormCheckboxSingle(

char *name)

cgiFormCheckboxSingle determines whether the checkbox with the specified name

is checked. cgiFormCheckboxSingle returns cgiFormSuccess if the

button is checked, cgiFormNotFound if the checkbox is

not checked. cgiFormCheckboxSingle is intended for single

checkboxes with a unique name; see below for functions to

deal with multiple checkboxes with the same name, and

with radio buttons.

cgiFormResultType cgiFormCheckboxMultiple(

char *name, char **valuesText, int valuesTotal,

int *result, int *invalid)

cgiFormCheckboxMultiple() determines which checkboxes among a group

of checkboxes with the same name are checked. This is distinct

from radio buttons (see cgiFormRadio).

valuesText

should point to an array of strings identifying the VALUE

attribute of each checkbox; valuesTotal should indicate the total

number of checkboxes. result should point to an array of integers with

as many elements as there are strings in the valuesText array. For

each choice in the valuesText array that is selected, the corresponding

integer in the result array will be set to one; other entries in the

result array will be set to zero. cgiFormCheckboxMultiple returns

cgiFormSuccess if at least one valid checkbox was checked or

cgiFormNotFound if no valid checkboxes were checked.

The integer pointed to by invalid is set to the number of

invalid selections that were submitted, which should be zero

unless the form and the valuesText array do not agree.

cgiFormResultType cgiFormRadio(

char *name, char **valuesText, int valuesTotal,

int *result, int defaultV)

cgiFormRadio() determines which, if any, of a group of radio boxes with

the same name was selected. valuesText should point to an array of

strings identifying the VALUE attribute of each radio box;

valuesTotal should indicate the total number of radio boxes. The value

pointed to by result will be set to the position of the actual choice

selected within the valuesText array, if any, or to the value of

default, if no radio box was checked or an invalid selection was

made. cgiFormRadio() returns cgiFormSuccess if a checked radio box was

found in the group, cgiFormNotFound if no box was checked, and

cgiFormNoSuchChoice if the radio box submitted does not match any of

the possibilities in the valuesText array.

cgiFormResultType cgiFormFileName(

char *name, char *fileName, int max)

cgiFormFileName attempts to retrieve the file name uploaded by the

user for the specified form input field of type file.

NEVER, EVER TRUST THIS FILENAME 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. cgiFormFileName returns

cgiFormSuccess if the string was

successfully retrieved and was not empty,

cgiFormNoFileName if the string was

successfully retrieved but empty indicating that no file was uploaded,

cgiFormTruncated if the string was

retrieved but was truncated to fit the buffer,

and cgiFormNotFound if no

such input field was submitted. In the last case,

an empty string is copied to result.

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

input field of type file specified by the

name parameter. On success, the size is stored

to *sizeP, and this function returns

cgiFormSuccess. If the form

field does not exist, this function returns

cgiFormNotFound.

If the form field exists but no file was uploaded, this function

returns cgiFormNotAFile.

cgiFormResultType cgiFormFileContentType(

char *name, char *contentType, int max)

cgiFormString attempts to retrieve the content name claimed by the

user for the specified form input field of type file.

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. cgiFormFileContentType returns

cgiFormSuccess if the string was

successfully retrieved and was not empty,

cgiFormNoContentType if the string was

successfully retrieved but empty indicating that no file was uploaded

or the browser did not know the content type,

cgiFormTruncated if the string was

retrieved but was truncated to fit the buffer,

and cgiFormNotFound if no

such input field was submitted. In the last case,

an empty string is copied to result.

cgiFormResultType cgiFormFileOpen(

char *name, cgiFilePtr *cfpp)

cgiFormFileOpen attempts to open the actual uploaded file data for

the specified form field of type file. Upon success,

this function returns retrieve the content name claimed by the

user for the specified form input field of type file.

On success, this function sets *cfpp to a valid cgiFilePtr

object for use with cgiFormFileRead

and returns cgiFormSuccess.

On failure, this function sets *cfpp to a null pointer, and

returns cgiFormNotFound,

cgiFormNotAFile,

cgiFormMemory or

cgiFormIO as appropriate.

See also cgiFormFileRead

and cgiFormFileClose.

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. This function returns

cgiFormSuccess if any data

is successfully read. At end of file, this function

returns cgiFormEOF. In the event

of an I/O error, this function returns

cgiFormIO. If cfp is a null pointer,

this function returns cgiFormOpenFailed.

See also cgiFormFileOpen

and cgiFormFileClose.

cgiFormResultType cgiFormFileClose(

cgiFilePtr cfp)

cgiFormFileClose closes a cgiFilePtr object previously opened

with cgiFormFileOpen, freeing

memory and other system resources. This

function returns cgiFormSuccess

unless cfp is null, in which case

cgiFormOpenFailed is returned.

See also cgiFormFileOpen

and cgiFormFileRead.

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

cgiHeaderCookieSet

and

cgiHeaderCookieSetInteger

BEFORE invoking cgiHeaderLocation.

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

cgiHeaderCookieSet

and

cgiHeaderCookieSetInteger

BEFORE invoking cgiHeaderStatus.

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 "text/html" for HTML documents,

"text/plain" for plain ASCII without HTML tags, "image/gif" for

a GIF image and "audio/basic" for .au-format audio.

If you wish to set cookies,

you must make your calls to

cgiHeaderCookieSet

and

cgiHeaderCookieSetInteger

BEFORE invoking cgiHeaderContentType.

void cgiHeaderCookieSet(char *name, char *value,

int secondsToLive, char *path, char *domain, int options)

cgiHeaderCookieSet() 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. The first argument is the name of the

cookie to be stored; for best results in all browsers, use a short

name without spaces or unusual punctuation. The second argument is

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.

The third argument is 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. The fourth argument is 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 /. The final argument is the

web site name or entire domain for which this cookie should be

submitted; if you choose to have the cookie sent back for an

entire domain, this argument must begin with a dot, such as

.boutell.dev. The cgic variables cgiScriptName

and cgiServerName are convenient

values for the fourth and fifth arguments.

The sixth argument is a bitmask for specifying cookie security options.

It can be zero (no options) or a bitwise-OR of the following

enum cgiCookieOption values:

  • cgiCookieSecure
  • cgiCookieHttpOnly
  • cgiCookieSameSiteStrict

See HTTP cookies

for more information.

See also cgiHeaderCookieSetString,

cgiHeaderCookieSetInteger,

cgiCookieString,

cgiCookieInteger and

cgiCookies.

void cgiHeaderCookieSetString(char *name, char *value,

int secondsToLive, char *path, char *domain)

cgiHeaderCookieSetString() is kept for API compability reasons. It calls

cgiHeaderCookieSet with zero as sixth

argument, i.e. no cookie options are set.

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.

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.

cgiCookieString returns cgiFormSuccess if the string was

successfully retrieved,

cgiFormTruncated if the string was

retrieved but was truncated to fit the buffer,

cgiFormEmpty if the string was

retrieved but was empty, and cgiFormNotFound if no

such cookie was submitted. In the last case,

an empty string is copied to result.

cgiFormResultType cgiCookieInteger(

char *name, int *result, int defaultV)

See also cgiCookieInteger,

cgiCookies,

cgiHeaderCookieSet,

cgiHeaderCookieSetString, and

cgiHeaderCookieSetInteger.

cgiCookieInteger() attempts to retrieve the integer sent for the

specified cookie (browser-side persistent storage). The value

pointed to by result will be set to the value submitted.

cgiCookieInteger() returns

cgiFormSuccess if the value was successfully retrieved,

cgiFormEmpty if the value submitted is an empty string,

cgiFormBadType if the value submitted is not an integer,

and cgiFormNotFound if no such

input field was submitted. In the last three cases, the value

pointed to by result is set to the specified default.

See also cgiCookieString,

cgiCookies,

cgiHeaderCookieSet,

cgiHeaderCookieSetString, and

cgiHeaderCookieSetInteger.

cgiFormResultType cgiCookies(

char *name, char ***ptrToStringArray)

cgiCookies is useful when the programmer cannot know the names

of all relevant cookies (browser-side persistent strings) 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 CGI library. Important: when done working with the array,

you must call cgiStringArrayFree() with the array pointer as the

argument. cgiCookies() returns cgiFormSuccess except in the event of an out of memory error.

On success, ptrToStringArray is set to point to a

valid array of strings, with the last element in the array being a

null pointer; in the out-of-memory case ptrToStringArray is set to

a null pointer, and

cgiFormOutOfMemory is returned.

cgiFormResultType cgiHtmlEscape(char *s)

cgiHtmlEscape() outputs the specified null-terminated string to

cgiOut,

escaping any <, &, and > characters encountered correctly so that

they do not interfere with HTML markup. Returns

cgiFormSuccess, or

cgiFormIO in the event of an I/O error.

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.

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. This function returns

cgiFormSuccess, or

cgiFormIO in the event of an I/O error.

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.

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. Both functions

return cgiEnvironmentSuccess on

success, cgiEnvironmentIO on an I/O

error, and cgiEnvironmentMemory

on an out-of-memory error.

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 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. Both functions

return cgiEnvironmentSuccess on success,

cgiEnvironmentIO on an I/O error, and

cgiEnvironmentMemory

on an out-of-memory error.

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.

cgic variable reference

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

stdin, stdout, 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.

char *cgiServerSoftware
Points to the name of the server software,

or to an empty string if unknown.

char *cgiServerName
Points to the name of the server,

or to an empty string if unknown.

char *cgiGatewayInterface
Points to the name of the gateway interface (usually CGI/1.1),

or to an empty string if unknown.

char *cgiServerProtocol
Points to the protocol in use (usually HTTP/1.0),

or to an empty string if unknown.

char *cgiServerPort
Points to the port number on which the server is listening

for HTTP connections (usually 80), or an empty string if unknown.

char *cgiRequestMethod
Points to the method used in the request (usually GET or POST),

or an empty string if unknown (this should not happen).

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 points to this

additional path information.

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 points

to this additional path information, translated by the server into a

filesystem path on the local server.

char *cgiScriptName
Points to the name under which the program was invoked.
char *cgiQueryString
Contains any query information submitted by the user as a result

of a GET-method form or an <ISINDEX> tag. Note that this

information need not be parsed directly unless an <ISINDEX> tag

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.

char *cgiRemoteHost
Points to the fully resolved hostname of the browser, if known,

or an empty string if unknown.

char *cgiRemoteAddr
Points to the dotted-decimal IP address of the browser, if known,

or an empty string if unknown.

char *cgiAuthType
Points to the type of authorization used for the request,

if any, or an empty string if none or unknown.

char *cgiRemoteUser
Points to the user name under which the user has

authenticated; an empty string if no authentication has

taken place. The certainty of this information depends on

the type of authorization in use; see

cgiAuthType.

char *cgiRemoteIdent
Points to the user name volunteered by the user via

the user identification protocol; an empty

string if unknown. This information is not secure.

Identification demons can be installed by users on

insecure systems such as Windows machines.

char *cgiContentType
Points to the MIME content type of the information

submitted by the user, if any; 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.

char *cgiCookie
Points to 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.

char *cgiAccept
Points to a space-separated list of MIME content types

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.

char *cgiUserAgent

Points to the name of the browser in use, or an empty

string if this information is not available.

char *cgiReferrer

Points to 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 cgiReferer is also supplied as a macro.

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 cgiIn pointer will be at end-of-file

in such cases.

FILE *cgiOut
Pointer to CGI output. 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 stdout; however, it is recommended that cgiOut be used to

ensure compatibility with future versions of cgic for

specialized environments.

FILE *cgiIn
Pointer to CGI input. 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.

cgic result code reference

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.

cgic quick index

cgiAccept |

cgiAuthType |

cgiContentLength |

cgiContentType |

cgiEnvironmentIO |

cgiEnvironmentMemory |

cgiEnvironmentSuccess |

cgiCookieInteger |

cgiCookies |

cgiHeaderCookieSet |

cgiHeaderCookieSetString |

cgiHeaderCookieSetInteger |

cgiCookieString |

cgiCookieInteger |

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()

一键复制

编辑

Web IDE

原始数据

按行查看

历史

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值