Previous Page TOC Next Page



- 30 -
CGI: Server-Side Scripting
by Sean F. Leinen


As you've probably seen, the World Wide Web has skyrocketed in popularity, in most part due to its incredible ease of use and capability to present information in a meaningful manner. With its graphical front end, extensive layout capabilities (that is, information can be formatted in a pleasing form), and easy method of navigating through the information by merely clicking on text, the World Wide Web has made it easier for everyone to enjoy the Internet. You don't need a degree to navigate and retrieve information from the Internet, which is in stark contrast to the likes of FTP, Gopher, and Telnet; with those tools, you have to know what you are doing to get to the information you want.

With this explosion in popularity, users of the Web are demanding more from it. No longer does it suffice to put up a Web page with predetermined (static) hypertext links that seem to dictate a certain work flow. More and more, Web users want the ability to not only view information, but to interact with the Web server that they are visiting. This calls for the next level of Web authoring: a dynamic site that not only displays information, but allows input from its users. A good example of this is the ubiquitous search engine; it's very hard to find Web sites without one nowadays. A search engine enables visitors to a Web site to search that site for the information that they are looking for, without having to drill down through many layers of that site. All they have to do is type in what they're looking for and click a button. The Web server then takes what they've typed in and produces the information they want.

The World Wide Web provides this two-way interaction in the form of something called CGI (Common Gateway Interface). CGI is not a software package or programming language; instead, it is a protocol—a way of talking between the Web server and the Web browser client. CGI is the most common means of processing fill-in forms (the forms themselves are pure HTML, not CGI), dynamically creating Web pages (for example, massaging the results of a database query into a Web page on-the-fly), or implementing other Internet technologies into a Web page. This is done with programs and/or scripts on the Web server that are triggered when an event takes place, for example, when the user clicks the Submit button on a search engine. Even though you might hear of CGI scripts, keep in mind that CGI itself is not a programming or scripting language; these programs or scripts can be written in many languages: C, PERL, Pascal, Visual Basic, REXX, and even DOS batch files. A good way to clarify this distinction is to think of the fact that the fill-in form the user sees on his/her browser is not CGI, nor is the program or script itself that is triggered on the server when the user submits the form; the method of triggering that program or script—now that is CGI.

The programs and scripts on the server can be written in any language that provides the capability to read environment variables on the server or read standard input piped into it from the Web browser client. These two capabilities, reading environment variables and reading standard input, are very important in that they determine how viable and flexible a certain programming language is for CGI scripting. These two capabilities are discussed later in this chapter, after a review of the basics of CGI and a demonstration of how to write simple scripts in DOS batch language, PERL, and C. Each language's viability to CGI is explained, along with some things you might want to take into consideration when constructing a dynamic Web site.

HTML Forms and CGI Scripts


It's easy to see that the Web, even without CGI, uses a form of client/server technology; that is, documents resident on the server are downloaded and viewed by the client. For example, when you view a site with your Web browser, you're viewing documents delivered to your machine by the server. Click on a hyperlink, and a connection is made to that document's parent server to deliver the document to your Web browser (and subsequently to your screen). This is a form of one-way communication in that documents really only go one way—from the server to you. CGI enables the other direction to happen: type in some information and/or click some buttons on a form displayed in the browser, and this information gets "posted" back to the server. The server then takes that data and does something with it—inserts it into a database, adds your name to a mailing list, searches a database for what you typed in, and so on.

A Web site using CGI is heavy on the server execution end; most of the work is done by the server executing a program or script that is resident on it. For that matter, programs that have to be compiled (like Pascal or C/C++) must be compiled for the operating system and the hardware that the Web site server is running. As an example, if the client is running Windows and the Web server is running a flavor of UNIX, any executables used for CGI must be compiled for that flavor of UNIX. In fact, in the case of operating systems that run on different hardware (UNIX, Windows NT, and so on), CGI executables need to be compiled for the Web server's hardware as well. UNIX executables compiled for Solaris on an x86/Pentium cannot be used for a Web server running Solaris on a SparcStation 20, while Windows NT AlphaAXP executables cannot be used for a Web server running Windows NT on an x86/Pentium/Pentium Pro machine.

It is for this reason that scripting languages like PERL, REXX, and various others are more common for use in CGI—scripts created on one platform can be used on another with little or no modification, because they're just ASCII text. This is in keeping with the fact that the data that is exchanged between the Web server and the Web browser is generic as well—usually ASCII text or a binary format that is common and easily handled on numerous platforms. Compiled executables (and shared/dynamically linked libraries for that matter) are usually relegated to heavily visited sites, where the executable's compact size and great speed become more crucial for good performance and throughput.

A simple example of an interactive Web page is one that enables the user to click a button to have a real-time event take place on the Web server, and then view the results. Consider Figure 30.1; this is the most basic form of an interactive Web page. It consists of only explanatory text and a button. What can be misleading about this simple page is that the button triggers a batch file to execute on the Web server, giving real-time information on demand instead of a prewritten document.

Figure 30.1. A very simple interactive Web page that executes a script on the server upon clicking the button.

The HTML code for creating the page shown in Figure 30.1 is very easy. I could have spruced up this page some by adding colors, pictures, and so on, but I chose to keep it simple to focus on the mechanics of CGI. In Listing 30.1, take a look at where the real link to CGI takes place: the <FORM> section. As can be guessed by looking at this section, this is a very simple fill-in form, but without the fill-in fields.

Listing 30.1. HTML listing for the page shown in Figure 30.1.




<HTML>



<HEAD>



<TITLE>Basic CGI Scripting</TITLE>



</HEAD>



<BODY>



<CENTER><H1>Example Interactive Page</H1></CENTER>



<HR>



This page illustrates, in its most basic form, the ability for the viewer to



interact with this web server.  By merely clicking on a button, a script can



be triggered to do something on the server.



<HR>



<FORM ACTION="/cgi-bin/srvrstat.bat">



Click <INPUT TYPE="SUBMIT" VALUE="this button"> to execute a script on this



server.



</FORM>



</BODY>



</HTML>

The first line of the <FORM> section, the <FORM> tag itself, shows one of the items that is responsible for the interactivity: ACTION. The ACTION parameter instructs the Web server to invoke the program or script specified ("/cgi-bin/srvrstat.bat" in this case) after a Submit button is clicked. Embedded within the sentence that's inside of the <FORM> section is an INPUT tag with two parameters: TYPE and VALUE. The INPUT tag is the other item responsible for the interactivity. It presents to the user the gadget/field that interacts with the Web site. In this case, that happens to be of type SUBMIT, which is always displayed as a button in Web browsers. The VALUE parameter tells the Web browser what text to put on the face of that Submit button. In this example that's "this button", because I placed it in the middle of the sentence for continuity.

What does this page do? Figure 30.2 show what happens when the button is clicked.

Figure 30.2. Clicking on the page's button executes a little batch file on the Web server, displaying the information shown.

The "script" that did that is actually a DOS batch file. The listing for this batch file is shown in Listing 30.2. If you haven't had much experience with CGI scripting, this might be the first time you've seen a DOS batch file used—but it can be done. This just goes to show that CGI scripts can use any programming or scripting language, not just PERL or C.

Listing 30.2. DOS batch file that produces the output shown in Figure 30.2. This is the "/cgi-bin/srvrstat.bat" pointed to by the ACTION parameter.




@echo off



REM  ------------------------------------------------------------------------



REM  Since the "less than" and "greater than" characters in the HTML tags



REM  can't be printed with a simple "echo" statement, we have to resort to



REM  something else.  The "prompt" command can be used to display characters



REM  that can't be displayed with a simple "echo" statement.  We can use the



REM  "prompt" command to store the HTML tags, and by turning command echoing



REM  "on", a blank line in this batch file will cause the contents of



REM  "prompt" (the HTML tags) to display.  The key is strategic placement of



REM  these blank lines; in order for this trick to work, a blank line *must*



REM  occur after each "prompt" command.  Only use one blank line after each



REM  "prompt" command; otherwise, the stored value (i.e.: HTML tag) will



REM  duplicate for each additional blank line encountered, and the result



REM  will be an HTML document with duplicate tags.  Also, while command echo



REM  is "on", the commands themselves will display on standard output



REM  (causing them to appear in the HTML document itself); this is easily



REM  fixed by suppressing them with an "@" character at the beginning of



REM  their line.



REM



REM  Below saves current command prompt, turns command echo "on", and begins



REM  outputting the HTML document.  "$l" (that's "dollar el") and "$g" cause



REM  "prompt" to display the "less than" and "greater than" characters



REM  respectively for each HTML tag.  For performance optimization reasons,



REM  HTML tags were group together in the same "prompt" command string,



REM  wherever possible, to save on the total number of commands executed.



REM  Notice the placement of the single blank lines immediately underneath



REM  every "prompt" command - very important, or the HTML tags won't appear!



REM  ------------------------------------------------------------------------



set savprompt=%prompt%



echo Content-type: text/html



@echo on



@prompt $lHTML$g $lHEAD$g $lTITLE$g



@echo Batch File As A CGI Server Script



@prompt $l/TITLE$g $l/HEAD$g $lBODY$g $lH1$g $lCENTER$g



@echo Results From Batch File Execution



@prompt $l/CENTER$g $l/H1$g $lHR$g $lB$g



@echo. | time | find /v "Enter new time"



@prompt $lBR$g



@echo. | date | find /v "Enter new date"



@prompt $lP$g



@echo This server's current operating system:



@prompt $l/B$g



@ver



@prompt $lP$g $lB$g



@echo Current variables set in this server's environment:



@prompt $l/B$g $lPRE$g



@set



@prompt $l/PRE$g $l/BODY$g $l/HTML$g



@echo off



REM  After setting command echo "off", restore the saved command prompt,



REM  and finish.



set prompt=%savprompt%



exit

Analyzing this batch file, you can see that it executes the DOS commands date (to display the date), time (to display the time), ver (to display the operating system version), and set (to display the environment) on the server, and then uses constructive methods to wrap valid HTML syntax around the output of those commands in order to display them back to the Web browser. Even though this particular example doesn't really do anything useful, it's a simple example illustrating what a dynamic Web page is—one that displays real-time data (such as the output of a command or series of commands executed on the server) instead of returning a static hard-coded HTML document.

One thing you would notice if you executed the batch file (clicked the button on the Web page) is how long it took to produce output. Herein lies one of the reasons why DOS batch file programming is not conducive for use as CGI scripts: batch files carry a lot of overhead and are not as fast as a dedicated scripting or programming language like PERL or C. Another thing you would probably notice is some of the "prompt trickery" necessary just to print HTML tags; without the aid of robust text manipulation tools external to the built-in DOS command set (for example, commercial, shareware, and public domain add-ons), it is extremely difficult to do most of the things required to create a useful Web page using batch files. CGI scripting calls for a real industrial strength scripting or programming language in these cases, like PERL or C.

Practical Extraction and Report Language (PERL)


PERL is an interpretive scripting language; that is, it doesn't compile, but rather reads and executes from scripts you write. Its most powerful and useful feature is its capability to scan text files (or input piped into it), extract information from those files (or that input), and produce reports based on that information. Some of the best features of C, UNIX's sed (stream editor), awk (Aho, Weinberger, & Kernighan—a powerful text manipulation utility), and [k]sh (UNIX Bourne/Korn shell scripting)—can be found in PERL. If you're familiar with any of those languages, you might easily recognize some of the PERL semantics; if so, you'll probably find you won't have any difficulty with PERL. PERL expression syntax closely follows C syntax, although some operating system-specific syntax is allowed; in other words, there is more than one way to "skin a cat" in PERL. For example, to spawn an external command and read its output, the following syntax are both acceptable:

The first is generally more acceptable; it can be used as-is on any platform PERL runs on as long as the command it's spawning exists. The second is a carry-over from UNIX shell scripting, but it can be used as well.

The latest version of PERL is Version 5. The software itself is free (public domain), and can be downloaded from




http://www.perl.hip.com./

If you have trouble connecting to that site (DNS name resolution failures or whatever), you can also try




http://www.perl.hip.com.yvr.net./

The current build of PERL (as of this writing) is build 109, and it's in the form of a ZIP file called 109-i86.zip (i86 meaning that this copy is compiled for Intel x86/Pentium/PentiumPRO; versions for other hardware are there as well). This 109-i86.zip is a pure Win 32 implementation of PERL; it can be used with equal success under both Windows 95 and Windows NT. It's highly recommended that you download the latest build you find on the site, as new features and patches continually appear with each new build. After it's downloaded, create the directory where you ultimately want the PERL software to reside, and unzip the file into that directory with your ZIP software's Create subdirectories option enabled (for example, using the -d qualifier of PKUNZIP.EXE). Next, run the resulting INSTALL.BAT file and answer the prompts to finish the PERL installation. This installs the appropriate registry keys into your machine's registry, as well as adds the \BIN subdirectory of the PERL installation directory to your PATH statement. You'll have to log-off and then back on to get the new environment.

Understanding How HTML Forms and CGI Scripts Work Together


Now to look at where a much more powerful and infinitely faster PERL CGI script can be used; unlike DOS batch files, this script can be partnered with full-fledged HTML forms like the one shown in Figure 30.3. The code for the form is provided in Listing 30.3.

Figure 30.3. An example form that the user can use to provide information back to the Web server. Notice it's already partially filled out.

Listing 30.3. The HTML code smplform.htm that displays the form shown in Figure 30.3.




<HTML>



<HEAD>



<TITLE>CGI-PERL Form Example</TITLE>



</HEAD>



<BODY>



This is an example form which uses PERL to parse its input.



<P>



<HR>



<P>



<FORM METHOD="POST" ACTION="/cgi-bin/smplform.pl">



<CENTER>



<FONT SIZE=+2>Tell Us About Yourself</FONT>



</CENTER>



<HR>



What is your name: <INPUT TYPE="text" NAME="name"><P>



What is your favorite color:



<SELECT NAME="color">



<OPTION SELECTED>red



<OPTION>green



<OPTION>blue



<OPTION>yellow



<OPTION>orange



</SELECT>



<P>



What is your gender: <INPUT TYPE="radio" NAME="gender" VALUE="male" CHECKED>



Male or<INPUT TYPE="radio" NAME="gender" VALUE="female">Female



<P>



What do you have to say for yourself?



<TEXTAREA NAME="text" ROWS=5 COLS=60></TEXTAREA>



<P>



Click <INPUT TYPE="submit" VALUE="here"> to submit your information.



</FORM>



</BODY>



</HTML>

As you can see from Figure 30.3, this form implements all four types of form input gadgets: a fill-in field for the person's name, a drop-down multiselect gadget to select a favorite color from, a radio button (toggle) to select the gender, a text input window for multiline text, and finally the Submit button itself. Take a look at each input type, starting with the fill-in field for the person's name. Notice that for the name fill-in field the TYPE parameter for the <INPUT> tag is set to "text". A type of "text" enables the user to type in it, but only one line of text.

For the input type specified for the favorite color, there is a different sort of input device: a <SELECT> gadget. This is a drop-down menu that is populated with choices specified by <OPTION> tags immediately following the <SELECT> tag itself. The item that appears as the default choice is denoted by the <OPTION SELECTED> tag, but users can merely use the pull-down device on the gadget to select the item they want. Note that this gadget is completed with a </SELECT> tag.

The third gadget is the toggle button used to select the gender; this is called a radio button, because only one of the choices it presents can be selected at a time (an attempt to select another item results in the first choice being unselected). This type of gadget is denoted by an <INPUT TYPE="radio"> tag. The way this one works is that you'd use one of these tags for each radio button choice you want to present to the user (that is, you'd use a separate <INPUT TYPE="radio"> tag for each of the choices you want to be a part of that gadget, like that shown in Listing 30.3). A default selection can be denoted by inserting the CHECKED parameter at the end of the <INPUT TYPE="radio"> tag used for the choice you want to be the default, in the way that Listing 30.3 shows "male" as the default choice for that feedback form's radio button. The fourth gadget, the text fill-in box where the user answers the question "What do you have to say for yourself?", is a close relative of the fill-in field where the user enters his or her name, but the <TEXTAREA> tag tells the browser that this is going to be a box that will accept multiline text (meaning the user can press the Enter key inside of it for new lines). This gadget is completed with a matching </TEXTAREA> tag. Finally, the fifth and last gadget is one that you should already be familiar from the last Web page discussion: the Submit button itself.

All in all, filling in the form as depicted in Figure 30.3 results in the server feedback page shown in Figure 30.4.

Figure 30.4. Filling in the form as depicted in Figure 30.3 results in this server feedback page when the Submit button is clicked.

The <NAME> and <VALUE> Tags


Now that you've learned about the different types of form gadgets, you might be wondering about the other parameters for them—things like NAME and VALUE. Within each of the form's gadgets, you'll notice a NAME parameter. This parameter is important not for the look and feel of the form (that is, omitting it has no effect on how the form displays), but rather for how the form is going to feed the data back to the server's CGI script when the user clicks the Submit button.

The NAME parameter actually identifies a variable name that gets sent back to the server when the user submits the form. Along with that variable name, its value is sent as well. This takes the form of "{variable_name}={value}"; the same type of syntax you'd expect from any programming/scripting language. So for example, if the user picked the color red from the drop-down multiselect gadget, when the form is submitted, the following is sent back to the server:




color=red

The variable name color was determined by the drop-down selection list's NAME="color" parameter, while red was determined by the color selection the user picked.

The radio button gadget also provides one additional parameter that is of importance: VALUE. Because the radio button gadget doesn't have any fill-in fields or drop-down selections to associate with a value to send back to the server, each button in a radio button gadget is given the VALUE parameter to differentiate it from the other choices of the radio button gadget. This way, when a user selects one of the radio button choices, its unique VALUE is sent back to the server. In our sample gender radio button, one of the following is sent back to the server, depending on the user's choice:




gender=male

or




gender=female

Once again, the variable name gender was determined by the radio button's NAME="gender" parameter, but this time, the value male or female was determined by the VALUE parameter of the button chosen by the user in the radio button group.

CGI Strings and the METHOD Parameter


Now that you've seen the various tags in an HTML form and what they do, how do you think the information is fed to the CGI script? Are the variables fed to the script one at a time, in the order that the gadgets appear on the form? Nope. Believe it or not, all the variable definitions are concatenated together as one long string with an ampersand (&) separating each variable, and the whole shebang is fed back to the script. For instance, say you filled out the form as shown in Figure 30.3. When you click on the Submit button, the following string would be fed back to the server:




name=Sean+Leinen&color=orange&gender=male&text=No+matter+where+I+seem+to+go,+there+I+am!

Notice how each variable definition is separated by an ampersand character (&), and that all spaces have been replaced with a plus character (+). This is to ensure a contiguous data stream for the string and to avoid having a space character misinterpreted by the server as the end of the string. This is called a form variable definition string. You, as the CGI server side script author, have to build intelligence into your script to break down that form variable definition string into its separate variable definitions, remove the plus characters, and substitute back the spaces where they belong.

OK, so far, so good; you might not like what you hear about having to manually parse such a long string just to get the variable definitions, but at least it's starting to make a little sense how the form submits the data to the server. Speaking of which, have you wondered just how this string makes its way to the script? Is it fed to the script as a command line parameter, or is it fed into the script's standard input (piped in)? That depends on the METHOD parameter in the <FORM> tag; whether it's set for GET or POST. To be fair, the two METHOD values GET and POST are quite similar; they both do the same job of getting the variable definition string to the server, and in the end, either one will probably work for your script.

GET causes the long variable definition string to be passed as a command line argument to the CGI script, and when the server receives this, it strips-off that command line argument and places it in an environment variable called QUERY_STRING. Again, it's up to you, as the CGI server-side script author, to read that environment variable from your script and parse it. So, if you were to change the METHOD value to GET (go ahead, give it a whirl if you've got Web server software running) in our "smplform.htm", the following would happen when you submitted the form:

Now it would be up to your script to read in that environment variable and break the long variable definition string down into its individual form variables. Yuck! Luckily, PERL Version 5 includes the library "cgi-lib.pl", written by Steven E. Brenner, which does this dirty work for you. If you've installed PERL correctly, substituting GET for POST will work just fine ("cgi-lib.pl" recognizes the change), and you'll still get the results page depicted in Figure 30.4.

POST, on the other hand, sends the long variable definition string into the standard input of our script. That is, it is piped into your script directly. You, as the CGI server side script author, have to prepare the script to receive input and parse the long variable definition string to get at the individual form gadget values.

Concerning both methods; whichever one you choose should depend largely on how much data the form is to read from the user and what the script is going to do with it. For example, large forms with lots of input fields should use the POST method (because some operating systems have upper limits on environment space), while small forms with relatively few fields should use the GET method.

Listing 30.4. PERL script that receives the form data and parses it to create the server feedback page depicted in Figure 30.4. This script relies on PERL's included "cgi-lib.pl", which makes things much easier.




# A small demonstration PERL script to demonstrate the use of the



# PERL cgi-lib.pl library in conjunction with an HTML form.



require "cgi-lib.pl";



MAIN:



{



# Read in all the variables set by the form, using the "ReadParse()"



# subroutine defined in "cgi-lib.pl".



  &ReadParse(*input);



# Print the header for the resulting HTML document, using the



# "PrintHeader()" subroutine defined in "cgi-lib.pl".



  print &PrintHeader;



  print "<HTML><HEAD>\n";



  print "<TITLE>PERL Script Output From The Feedback Form</TITLE>\n";



  print "</HEAD>\n<BODY>\n";



# Process the text entered in the "what do you have to say for yourself"



# field; insert the <BR> tag after each line of multiline input.



  ($text = $input{'text'}) =~ s/\n/\n<BR>/g;



                                   # add <BR>'s after carriage returns



                                   # to multline input



print <<ENDOFTEXT;



<H1>Results of the feedback form</H1>



You, $input{'name'}, whose favorite color is $input{'color'} and gender is



$input{'gender'}, has this to say for yourself: <P>"$text"



ENDOFTEXT



# Here's where we can print out a list of all of the variables set from



# the form.



 print "<HR>Here is a list of the variables passed from the form...";



  print &PrintVariables(%input);



# Close the document cleanly.



  print "</BODY></HTML>\n";



}

Listing 30.5. C code for the same PERL script depicted in Listing 30.4. In this C code, the form variable definition string is being manually parsed.




#include <stdio.h>



#include <stdlib.h>



#include <string.h>



#include <alloc.h>



#include <dos.h>



/*  Function to replace the "+"s with spaces in each variable's data.



 */



void replace_spaces(char *var_name) {



    int  i;



    char *buffer;



    buffer = (char *)calloc(strlen(var_name)+1, sizeof(char));



    for (i=0; i<strlen(var_name); i++) {



        switch (var_name[i]) {



            case '+':



                buffer[i] = ' ';



                break;



            default:



                buffer[i] = var_name[i];



        }



    }



    strcpy(var_name, buffer);



    free(buffer);



}



/*  Main body of the program.



 */



void main(void) {



    char *CGI_string=NULL, request_method[5];



    char *name=NULL, *color=NULL, *gender=NULL, *saying=NULL;



    int  content_length=0;



    /*  Read in the "REQUEST_METHOD" environment variable, which stores



     *  either "GET" or "POST".



     */



    strcpy(request_method, getenv("REQUEST_METHOD"));



    /*  Determine if this is a "GET" or a "POST", allocate enough memory



     *  to store the CGI form variable definition string, and read in the



     *  CGI form variable definition string from the appropriate source.



     *  The source for a "GET" would be the "QUERY_STRING" environment



     *  variable, while the source for a "POST" would be standard input.



     *  The below "if" block only specifically checks for "POST", since



     *  anything other than "POST" automatically defaults to "GET".



     */



    if (!strcmp(request_method, "POST")) {



        content_length = atoi(getenv("CONTENT_LENGTH"));



        CGI_string = (char *)calloc(content_length+1, sizeof(char));



        scanf("%s", CGI_string);



    } else {



        content_length = strlen(getenv("QUERY_STRING"));



        CGI_string = (char *)calloc(content_length+1, sizeof(char));



        strcpy(CGI_string, getenv("QUERY_STRING"));



    }



    /*  Allocate memory for each field variable to be of the total size of



     *  the entire form variable definition string.  This is in case the



     *  whole form variable definition string might consist of only one



     *  variable (the other variables possibly not being set).



     */



    name = (char *)calloc(content_length+1, sizeof(char));



    color = (char *)calloc(content_length+1, sizeof(char));



    gender = (char *)calloc(content_length+1, sizeof(char));



    saying = (char *)calloc(content_length+1, sizeof(char));



    /*  Break up the form variable definition string into its individual



     *  components.



     */



    if(strtok(CGI_string, "=") != NULL) {



        strcpy(name, strtok(NULL,"&"));



        replace_spaces(name);



    }



    if(strtok(NULL, "=") != NULL) {



        strcpy(color, strtok(NULL,"&"));



        replace_spaces(color);



    }



    if(strtok(NULL, "=") != NULL) {



        strcpy(gender, strtok(NULL,"&"));



        replace_spaces(gender);



    }



    if(strtok(NULL, "=") != NULL) {



        strcpy(saying, strtok(NULL,"&"));



        replace_spaces(saying);



    }



    /*  Begin formatting and outputting the HTML document.



     */



    printf("Content-type: text/html\n\n");



    printf("<HTML>\n");



    printf("<HEAD>\n");



    printf("<TITLE>\n");



    printf("C Program Output From The Feedback Form\n");



    printf("</TITLE>\n");



    printf("</HEAD>\n");



    printf("<BODY>\n");



    printf("<H1>Results of the feedback form</H1>\n");



    printf("<BR>\n");



    printf("You, %s, whose favorite color is %s ", name, color);



    printf("and gender is %s, ", gender);



    printf("has this to say for yourself: <P>%s", saying);



    printf("</BODY>\n");



    printf("</HTML>\n");



    free(CGI_string);



    free(name);



    free(color);



    free(gender);



    free(saying);



}

In Listing 30.4, the form variable definition string is manually parsed. There are C libraries available to make this easier, and you might want to try the following sites to obtain them:




http://sunsite.unc.edu./boutell/cgic/cgic.html




http://wsk.eit.com./wsk/dist/doc/libcgi/libcgi.html

What's Next?


You've taken a good look at the basics of CGI; starting from how CGI fits the demand for more interactive web pages, moving on to CGI's inner workings and how to implement CGI scripts, and finally seeing examples of CGI scripts written in DOS batch language, PERL, and C. Along the way you've learned that CGI itself is not a scripting or programming language, but rather a protocol—a method of communication between the web server software and the web browser client.

You've also learned the various HTML tags responsible for the look and feel of an interactive web page; tags such as <FORM> and <INPUT>, as well as METHOD parameters used with them to inform the web server of how to handle the data once the user submits it—parameters such as GET and POST. You'll now move on to more advanced methods of building interactive web pages in the next two chapters. Chapter 31, "Unleashing the Power of VBScript," introduces you to VBScript, the core technology used to build web pages based on Microsoft's ActiveX. Chapter 32, "Using JavaScript in Your Web Pages," introduces you to JavaScript, a scripting language that you can use to build Java applets into your web pages.

Previous Page Page Top TOC Next Page