This chapter is the sequel to Chapter 11, "Introduction to Web Forms and CGI." After being introduced to CGI and seeing a working (although not very useful) example, you're probably eager to learn how CGI can really be put to work.
This chapter starts by showing you how to install and use a CGI application that is included on the CD. Then, for those of you who want to understand the inner workings of CGI and HTML forms, we'll discuss some of the details of that program, which is
written in C.
Finally, the chapter introduces several CGI programming tools that are designed to make your job easier. Whether you are just counting visitors at your site, tabulating more advanced statistics, or running a customer support form, there is bound to be
something here that will help you make your Web site interactive.
When using forms in HTML, you need a CGI script or application to handle the contents of that form. The CGI Kit contains the source code and binary for savedata.exe, a CGI application that will parse the data from your forms and save that data to a
file.
This CGI application is useful if you know how to write HTML code but don't want to dive into CGI programming. It is also useful if you are taking credit card orders on a form and do not want the data mailed through the Internet. Of course, neither way
is really safe, but if you only send the numbers from the client to the server to the savedata file instead of from the client to the server to the mail server to the post office to the POP3 mailbox, there are fewer links in the chain to be broken. If you
plan to conduct financial transactions at your site, please read Chapter 20, "Internet Robots and More Security Issues," and Chapter 15, "Commerce on the Web." Chapter 15 discusses several options for secure cash.
To install CGI Kit 1.2, unzip the file \cgi\cgikit\cgikit.zip from the CD to an appropriate directory on your hard drive.
The files listed in Table 22.1 are in CGI Kit 1.2.
Filename |
Description |
savedata.c |
C source code for savedata.exe |
savedata.mak |
Makefile for Borland C++ 4.02 |
savedata.exe |
Intel binary CGI application |
cw3211.dll |
DLL for use with savedata.exe |
feedback.htm |
Sample feedback HTML document |
|
|
Although the kit has worked reliably for several months on the Final Bit Solutions Web site, it is not a very robust application, and it certainly is not guaranteed to be bug-free. If you plan to enhance the source code yourself, be sure that you
compile it as an NT console-mode application.
CGI Kit is an enhancement to the source code that comes with the freeware EMWAC HTTP Web server for Windows NT. A Return tag has been added to the information dialog so that after your information is written to a file, you can return to the URL from
which savedata.exe was called. The nasty plus characters have been removed, so strings are now separated by spaces. Newlines are now accepted. The following fields were added to the file output: posted by:, Date:, and Time.
Here are the directions for using CGI Kit:
Recall from Chapter 11 that CGI applications can capture only the form fields that you name in the HTML document. Savedata.exe captures the form field names that you establish in your HTML document (for example, feedback.htm) and writes them to the file
that you specify with the .HFO extension. (As currently written, the code requires .HFO to be in uppercase.)
This section discusses the why and how of CGI Kit. We refer to it as a CGI system because it requires proper integration of several languages and protocols, including HTML, C, HTTP, and CGI.
Figure 22.1 shows an example form (defined in HTML) that gathers comments from the user. When the user clicks the button labeled Submit Comments, the form is designed to run the savedata CGI application on the server, which will save the form data to a
file named FEEDBACK.HFO.
Figure 22.1. Form Processing screen.
Listing 22.1 shows the HTML code that creates the form and invokes the CGI application. To achieve the greatest portability, it does not take advantage of any HTML 3.0 features.
<HEAD> <TITLE>Suggestions and Comments</TITLE> </HEAD> <BODY> <form action="http://your.ip.address.here/cgibin/savedata.exe/FEEDBACK.HFO" method="POST"> <H1>Your Comments, Questions and Feedback!</H1> Please enter your Name: <BR><INPUT TYPE=text NAME="name" SIZE = 40 MAXLENGTH=40> <BR>Email address: <BR><INPUT TYPE=text NAME="email_addr" SIZE = 40 MAXLENGTH=40> <P> Enter your comments, questions and/or suggestions in the space below:<BR> <TEXTAREA NAME=comments ROWS=6 COLS=60 MAXLENGTH=3000></TEXTAREA> <P> <input type="submit" value="Submit Comments"> </FORM> </BODY> </HTML>
The action attribute of the form is the URL of the CGI application. The action attribute of the example form is:
http://your.ip.address.here/cgibin/savedata.exe/FEEDBACK.HFO
The cgi-bin/savedata.exe portion of the action attribute executes savedata.exe, while the /FEEDBACK.HFO component is passed to the script in the PATH_INFO environment variable.
In this example, the method attribute is POST, which means the form data will be read from stdin by the CGI application.
Listing 22.2 is a sample CGI script written in C that will take the contents of a form and save it to a file. This file (savedata.c) and its compiled executable can be found in CGI Kit 1.2 on the accompanying CD.
/*********************************************************************** * File: savedata.c * * Use: CGI Script file for use with HTTPS. * * Notes: Assumes it is invoked from a form. This script writes the * information to a file defined by the PATH_INFO enviroment var. * Ensure that you compile this script as a console mode app. * Note the file that you write * to must have the extension ".HFO" in all caps. * This script is a modified version of the script that comes with EMWAC * HTTPS. * * Date: 4/4/95 * Christopher L. T. Brown clbrown@netcom.com * ***********************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <io.h> #include <time.h> #define TRUE 1 #define FALSE 0 char InputBuffer[4096]; /* Convert all cOld characters */ /* in cStr into cNew characters */ void strcvrt(char *cStr, char cOld, char cNew) { int i = 0; while(cStr[i]) { if(cStr[i] == cOld) cStr[i] = cNew; i++; } } /* The string starts with two hex */ /* characters. Return an integer */ /* formed from them. */ static int TwoHex2Int(char *pC) { int Hi, Lo, Result; Hi = pC[0]; if('0' <= Hi && Hi <= '9') Hi -= '0'; else if('a' <= Hi && Hi <= 'f') Hi -= ('a' - 10); else if('A' <= Hi && Hi <= 'F') Hi -= ('A' - 10); Lo = pC[1]; if('0' <= Lo && Lo <= '9') Lo -= '0'; else if('a' <= Lo && Lo <= 'f') Lo -= ('a' - 10); else if('A' <= Lo && Lo <= 'F') Lo -= ('A' - 10); Result = Lo + 16 * Hi; return(Result); } /* Decode the given string in-place */ /* by expanding %XX escapes. */ void urlDecode(char *p) { char *pD = p; while(*p) { if(*p == '%') /* Escape: next 2 chars are hex */ { /* representation of the actual character.*/ p++; if(isxdigit(p[0]) && isxdigit(p[1])) { *pD++ = (char)TwoHex2Int(p); p += 2; } } else *pD++ = *p++; } *pD = '\0'; } /* Return TRUE if the file is within or below the */ /* current directory. It must have a .HFO ext. */ static int FileNameIsSafe(char *FileName) { char *p = FileName; while(*p == ' ' || *p == '\t') p++; if(*p == '\\') return(FALSE); if(strstr(p, "..") != NULL) return(FALSE); if(strchr(p, ':') != NULL) return(FALSE); if(strlen(FileName) < 5) return(FALSE); if(strcmp(".HFO", FileName + strlen(FileName) -4 )!= 0) return(FALSE); return(TRUE); } /* Parse out and store field=value items. */ /* Don't use strtok! */ void StoreField(FILE *f, char *Item) { char *p; p = strchr(Item, '='); *p++ = '\0'; urlDecode(Item); urlDecode(p); strcvrt(p, '\n', ' '); strcvrt(p, '+', ' '); /* Get rid of those nasty +'s */ fprintf(f, "%s = %s\n", Item, p); } int main(void) { int ContentLength, x, i; char *p, *q, *FileName, *pRequestMethod, *URL, *whocalledme; char datebuf[9], timebuf[9]; FILE *f; /* Turn buffering off for stdin.*/ setvbuf(stdin, NULL, _IONBF, 0); /* Tell the client what we're going to send */ printf("Content-type: text/html\n\n"); FileName = getenv("PATH_INFO"); /* Get the PATH_INFO. */ if(FileName == NULL) /* Does not exist. */ { printf("<HEAD><TITLE>Error - no filename</TITLE></HEAD>\n"); printf("<BODY><H1>Error - no filename</H1>\n"); printf("There is no PATH_INFO supplied. "); printf("Please modify the action parameter in your form.\n"); printf("</BODY>\n"); exit(0); } q = FileName; /* Convert PATH_INFO to a filename */ while(*q) { if(*q == '/') *q = '\\'; q++; } if(*FileName == '\\') FileName++; urlDecode(FileName); if(!FileNameIsSafe(FileName)) /* Is it safe to use? */ { printf("<HEAD><TITLE>Error - Filename unacceptable</TITLE></HEAD>\n"); printf("<BODY><H1>Error - Filename unacceptable</H1>\n"); printf("The file %s is not acceptable.\n",FileName); printf("</BODY>\n"); exit(0); } if(access(FileName, 2) < 0) /* Does the file exist? */ { printf("<HEAD><TITLE>Error - cannot access file</TITLE></HEAD>\n"); printf("<BODY><H1>Error - cannot access file</H1>\n"); printf("The file %s could not be accessed.\n",FileName); printf("</BODY>\n"); exit(0); } f = fopen(FileName, "a"); /* Open the file.*/ if(f == NULL) /* Can't open. */ { printf("<HEAD><TITLE>Error - cannot open file</TITLE></HEAD>\n"); printf("<BODY><H1>Error - cannot open file</H1>\n"); printf("The file %s could not be opened.\n",FileName); printf("</BODY>\n"); exit(0); } /* Indicate start of next entry in file.*/ fprintf(f, "=============================\n"); /* Who called the method action? */ whocalledme = getenv("REMOTE_ADDR"); /* Write to file which url posted data. */ fprintf(f, "Posted By: "); fprintf(f, "%s\n", whocalledme); _strdate(datebuf); _strtime(timebuf); fprintf(f, "Date: %s Time: %s\n",datebuf,timebuf); /* What method were we invoked through? */ pRequestMethod = getenv("REQUEST_METHOD"); if(pRequestMethod == NULL) return(0); /* Get the data from the client */ /* according to the requested method.*/ if(strcmp(pRequestMethod,"POST") == 0) { p = getenv("CONTENT_LENGTH"); /* Read in the data from the client. */ if(p != NULL) ContentLength = atoi(p); else ContentLength = 0; if(ContentLength > sizeof(InputBuffer) -1) ContentLength = sizeof(InputBuffer) -1; i = 0; while(i < ContentLength) { x = fgetc(stdin); if(x == EOF) break; InputBuffer[i++] = x; } InputBuffer[i] = '\0'; ContentLength = i; p = getenv("CONTENT_TYPE"); if(p == NULL) return(0); if(strcmp(p, "application/x-www-form-urlencoded") == 0) { p = strtok(InputBuffer, "&"); /* Parse the data */ while(p != NULL) { StoreField(f, p); p = strtok(NULL, "&"); } } else /* Write data to file. */ fprintf(f, "Input = %s\n", InputBuffer); } else if(strcmp(pRequestMethod, "GET") == 0) { /* Parse the data in the search term.*/ p = getenv("QUERY_STRING"); if(p != NULL) { strncpy(InputBuffer, p, sizeof(InputBuffer)); p = strtok(InputBuffer, "&"); while(p != NULL) { StoreField(f, p); p = strtok(NULL, "&"); } } } if(!ferror(f)) /* Confirm to client. */ { URL = getenv("HTTP_REFERER"); /* What url called me.*/ printf("<HEAD><TITLE>Submitted OK</TITLE></HEAD>\n"); printf("<BODY><h2>The information you supplied has been accepted."); printf(" Thank You!</h2>\n"); printf("<h3><A href=\"%s\">[Return]</a></h3></BODY>\n", URL); } else { URL = getenv("HTTP_REFERER"); /* What url called me.*/ printf("<HEAD><TITLE>Server file I/O error</TITLE></HEAD>\n"); printf("<BODY><h2>The information you supplied could not be\n"); printf("accepted due to a file I/O error at the server.</h2>\n"); printf("<h3><A href=\"%s\">Return</a></h3></BODY>\n", URL); } fclose(f); /* Close the file.*/ return(0); }
Here is the list of functions in savedata.c:
CGI PerForm was designed to provide all the basic CGI functionality needed by a WWW site, without requiring C or Perl. With a simple command file, template file, and HTML form, you can create an e-mail feedback form, guest book, or even a ballot
boxor perform all three of those operations at the same time and as many times as you want. CGI PerForm was designed to work with both Windows NT and Windows 95.
You can break down an interactive WWW page into three pieces:
CGI PerForm would be the CGI application that handles the incoming data and creates the result. A result can be a combination of more than one task or command. PerForm commands are discussed later in this chapter.
CGI PerForm uses a command file you create to determine what tasks it needs to perform on the data. A different command file is created for every interactive application needed. Each command requires certain key values in order for it to perform its
task. A majority of the key values are filenames. Some of these files must already exist, such as a template file or a column file. Others are created by the command, such as a data file or the output file.
CGI PerForm takes all the incoming data supplied by the HTML form and stores it into a memory block. An HTML form supplies data in name=value pairsfor example, lastname=Smith. You can supplement the data supplied by the HTML form by
plugging in hard-coded name=value pairs in the command file. These values go into the same memory block as the submitted data. You can hard-code values in your command file to hide them or to set defaults.
The next step is to use the data. You can save the data to a data file or a databaseor combine the results with a template file to create a confirmation message or a form letter to be mailed.
The command can be performed as often as necessary with different key values. For example, you could save data submitted by a user into three different data files. These data files can have some of the same data as another, or two of them could be
identical. You can also pass variables between command blocks to create unique files to store data in at the user's request.
To install CGI PerForm, place the perform.exe file in your cgi directory. Some Web servers require you to change the extension from .exe to .cgi. You might want to put a copy of perform.exe in your path in order to run it from the command line. Note
that CGI PerForm is not a Visual Basic application. Thus, Website users must place perform.exe in the cgi-dos directory for it to work.
To use the MailFile command, you must have Blat 1.2 (or greater) installed and in your path.
In order to use CGI PerForm, you must create an HTML form to present the user interface and a command file to tell it what tasks to perform. Note that some commands (tasks) require you to create certain files first, such as a template file. You can use
the examples supplied with CGI PerForm to get started.
CGI PerForm recognizes both the POST and GET methods. Use the POST method if you plan to send relatively large amounts of data, such as information from a questionnaire.
You are required to send only one specific name=value pair in your form. You must have a line similar to this in your HTML form:
<input type=hidden name=CMDFile value=\path\file.cmdl>
where path is the absolute path to your command file. If your Web server data directory is c:\web-server\, your path should begin with \web-server\.
You can force a user to supply data in the HTML form input field by prefixing the field name with a tilde . For example:
<input name="~UserName" size=24 >
If the user does not type a value in this field, he or she will be notified that the UserName is required to process the form.
Sometimes you might want to keep your data URL-encoded when it's placed into your template file. This would be useful when generating a list of URLs that implement the GET method to pass data to a query engine. This can be done by prefixing the name of
the data field in your template file with a tilde (~). For example:
<a href="http://www.thesari.org/query?<!-- ~KeyWord 0 -->">Search for <!-- KeyWord 0 --></a>
By default, CGI PerForm leaves a template placeholder intact if a value is not found to put in its place. In some cases, this causes problems, especially when you are nesting placeholders in HTML tags. When you precede the field name in the tag with an
ampersand (&), the placeholder will be deleted if the value it references is not found.
CGI PerForm cannot be executed without a command file. This enforces value overrides and path modifications.
There are now two versions of CGI PerForm: secure and insecure. The secure version of CGI PerForm automatically forces all paths to relative paths. For example:
\data\guest.dat would become data\guest.dat
This is done for three reasons: to be used by many forms at a time and by many users at a time. Many Web servers sell accounts to users for both commercial and private use. These users might have limited access to their files; the Web server software
itself has a superset of an individual user's access rights. When a CGI application is spawned by the Web server, it inherits the rights of the Web server. If a user accidentally mistyped a path that really exists, CGI PerForm might overwrite an existing
file, causing another user grief. Second, malicious Web users might create forms on the client site with the sole purpose of wiping out a file or mailing themselves another file. The command file can be used to override any values that could be passed by a
malicious form. Third, variables cannot be passed from a form to CGI PerForm; they can only be created and defined in the command file. You may use the value of a specific field in a variable, but the path will be made relative.
The insecure version performs no path or drive modifications and is not recommended for use in a multiuser environment.
The command file is a simple ASCII file listing all the commands you want CGI PerForm to execute. The order of the commands is important, but you can perform any command as often as you like.
The command file is in this format:
[command 1] key_name1=value key_name2=value ... [command 2] key_name1=value key_name2=value ...
For a real example, here are the contents of mail.cmdl, the command file used on our sample site.
[MakeUniqueFileName] variable=%log path=log\ ext=.log [OutputFormData] OutputFile=%log tplFile=message.tpl [MailFile] FileName=%log [OutputFormData] TplFile=mail.tpl BlockName=mail
The available commands and their associated keys are as follows. Some keys are applicable to more than one command. The keys are described in a separate list following the commands. The keys are shown in each of the following subsections.
The key value pairs in this command block will override any values passed from your HTML form or will supplement those values. Place any values in this block that you do not want your users to see if they read the source of your HTML form.
This is used to clean up any extraneous files generated.
Key: FileName
This dumps the contents of the current Name=Value pairs passed by your form or stored with the Data command.
Key: OutputFile
This converts your DataFile to a more human/computer-readable format. Only a comma-delimited format is supported.
Keys: DataFile, OutputFile, SaveAs
This is used to find a value in a data file.
The FindInDataFile command is used to search a data file for a value. If not found, the Default value is used.
Keys: DataFile, ColFile, UseColumn, GetColumn, WithValue, Default, DataType, Variable
By providing a filename and a few values passed by your HTML form, you can SMTP mail any file. (This function requires BLAT to be installed.) The fields needed from the HTML form are mailto, mailfrom (you may also use e-mail), name, and subject. mailto
is the recipient, mailfrom is the sender's e-mail address, and name is the sender's name. (If mailfrom is left blank, the value of name is used, otherwise the e-mail is sent using anonymous.)
Keys: FileName, CarbonCopy
This creates a unique filename in your current directory or in one of the paths specified. (The path will not be forced to be relative to your current directory because the file created is guaranteed to be unique.) This command stores the filename in
the variable specified. The variable must begin with the percent (%) sign.
Keys: Variable, Ext, Path
This creates a variable.
Keys: Variable, UseFieldValue, Ext
This is used to write a formatted list, including all the contents of your data file, into a single file. The ReturnNumRec key specifies the first number of records to be used in the data file. LastRecOnly, when TRUE, allows only the last record
submitted to be used. If no OutputFile value is given, the output is sent directly to the client's browser.
Keys: ColFile, DataFile, TplFile, OutputFile, BlockName, DataType, LastRecOnly, ReturnNumRec
This combines the data passed by your form with your TplFile. If no OutputFile value is given, the resulting page is sent directly to the browser.
Keys: TplFile, OutputFile, BlockName
This sends a file to the browser; it works great with images.
Keys: FileName, MimeType
This is used to push a series of files to a Web browser. This is more commonly known as Server Pushing and currently works only with Netscape browsers. If the browser is not Netscape Navigator, only the first file in the list is sent. Otherwise, the
first file is skipped and all remaining files will be sent. You can specify a delay between each file (image if used for animation) in seconds. The push list should have three columns: FileName, MimeType, and Delay (with defaults: MimeType=image/gif and
Delay=1 seconds).
Key: FileName
This is used to delete a record from your data file. This will perform a case-insensitive search through the column specified by UseColumn. When found, the record is deleted and the updated DataFile is saved.
Keys: DataFile, UseColumn, WithValue, ColFile
Without the UseColumn, a full search on all columns is done. Any occurrence of the characters in the WithValue key found will cause the record to be deleted. For example, truck = firetruck.
This removes duplicate lines in your DataFile and guards against users submitting a form more than once. For this command to work properly, each line needs to be unique. You can make each line unique by logging the user's REMOTE_ADDR and the current day
of the year in your DataFile.
Key: DataFile
This forces the user's browser (such as Netscape or Mosaic) to load a page. This value must be a fully qualified URL (for example, http://foo.bar.com/). You will most likely use it to point to a file just created with the MakeOutput command. You can
provide a FileName value to have the URL generated on the fly. FileName can be a variable.
Keys: URL, FileName
This saves the data passed from your HTML form to a file.
Keys: ColFile, DataFile, DataAdd
Using the column you specify, you can sort a DataFile three ways: ALPHA, NUMERIC, or INVERT.
Keys: ColFile, DataFile, UseColumn, DataType, Sort
Using the column you specify, SumData will add all of the numeric values encountered. The sum data file will have two columns: int and float.
Keys: ColFile, DataFile, OutputFile, UseColumn
This summarizes data in a DataFile for a ballot box type application. Using the column you specify, TallyData will find all the occurrences of a value and count how may times it occurred. This will be repeated for all unique values. The tally data file
will have four columns: value, total, count, and percent.
Keys: ColFile, DataFile, OutputFile, UseColumn, IgnoreValue
Use this command to process another command file. No form data will be passed to this new process automatically. However, you may create name=value pairs to pass data; the values may be variables.
Key: CmdFile
This is a description of all the available keys and their values.
A template file is broken up into blocks to allow you to dump more than one DataFile into it. The BlockName key tells the OutputDataFile and OutputFormData commands which block to use.
The ColFile key lists the columns used and their associated DataFiles. The order of the column names in this file correspond to the order of columns in the DataFile. The column names must be the names of the input boxes in your HTML document or names of
environment variables passed by your Web server software.
When saving data to the DataFile, you might want recent input added to the top of the list. The values that can be used are TOP, BOTTOM, and ALPHA.
The DataFile key is the file in which the user-submitted data is stored. Each column is a different INPUT box in your HTML form or an environment variable value requested in your ColFile.
The output from SumData and TallyData do not have associated ColFile's. You can, however, tell certain commands to assume the DataFile if it is using one of these. The values can be SUM or TALLY.
The ExcludeList key is the path and filename of an exclusion list or an absolute path, so lists may be shared among applications and users. Each line of the file should contain unique words or phrases.
The Ext key is the extension you want to add to a unique filename created with MakeUniqueFileName. This value is not required.
The IgnoreValue key is used by the TallyData command. It forces TallyData to skip any record with this value in the specified column. For example, users are voting for the next president using a SELECT box. The first item in the Select box reads Select
a Candidate. You are guaranteed to have users vote on Select a Candidate. By using IgnoreValue, TallyData will not summarize data on this value, keeping your numbers accurate.
The GetColumn key specifies the column name from which to retrieve a value.
If you want to output only the last record in a DataFile, set the value of LastRecOnly to TRUE. FALSE is the default.
The OutputFile key is the name of a file to be generated by a command. If you use the OutputDataFile command, you could create a guest.htm from both the guest.tpl and guest.dat files.
The Path key is the absolute path to the location where you want the new unique file created. This should point only to the directory you want to use for logging purposes, because you are not allowed to access files outside of your current directory.
Used by OutputDataFile, the value of the ReturnNumRec key is the number of records returned by the command. ReturnNumRec can be used to limit a page to the first 50 items in the datafile, if the data file contains a few hundred.
SaveAs is used by ExportDataFile; its only value is CSV.
The Sort key specifies the sort type: ALPHA, NUMERIC, or INVERT.
The TplFile key points to your template file. Template files have special placeholders in which field values from a DataFile are inserted. Usually an entire DataFile is iterated through a template file to create a guest book comments page.
The UseColumn key specifies the column name to use for certain commands. In the case of OutputDataFile, this key names the column to be used for file names.
The value that the UseFieldValue key is set to is a field name. This field name's value will be used as a filename or file variable.
The Variable key specifies the name of a filename storage space you want to create. This value must begin with the percent (%) sign.
The WithValue key is a word or phrase you want to search for. If this is used with the UseColumn key, an exact case-insensitive match of this value and the value of the requested column will be sought; otherwise, any case-insensitive occurrence of the
WithValue value will be searched for. Thus, if you do not provide a column to search in (using the UseColumn key), the whole record will be searched. For example, http:// will equal http://www.whatever.com because it contains the requested character
string. If UseColumn is supplied, http:// will not equal http://www.whatever.com.
The column file is a list of field names whose values are to be stored in a DataFile. The column file can contain more than just the field names returned by an HTML form. It can also be an environment variable or a time/date format specifier. A sample
column file would be:
candidate remote_addr fmt_tm_%j
In this example, you are storing the value of the candidate voted on, the user's ip address, and the current day of the year. The output DataFile would look like this:
Richard+Lugar+%28R%29 204.96.15.37 220 Bill+Clinton+%28D%29 214.46.15.3 225 Phil+Gramm+%28R%29 204.94.65.9 226 Pat+Buchanan+%28R%29 128.194.15.10 226 Select+a+Candidate 128.194.15.10 230
Note that the data is still URL-encoded. Use the ExportDataFile command to convert this to a comma-delimited format.
The template file is a standard HTML document, except that it has special comment tags acting as placeholders for the data supplied by your users.
Within this document, you are required to have both a <!-- begin BlockName --> and <!-- end --> tag. This tells OutputDataFile or OutputFormData when to start and stop replacing tags with data in your document. BlockName tells OutputDataFile
or OutputFormData which begin/end block to use.
The comment placeholder tags have this format:
<!-- field_name1 min_width --> <!-- field_name2 min_width -->
field_name1 corresponds to a field listed in your column file (ColFile) or a field passed to CGI PerForm from a HTML form by a user. min_width is an integer specifying the number of characters required. If a field value is less than min_width
characters, the remaining space is padded with space characters; no characters will be truncated otherwise. If width is not an issue, use 0 for min_width. The spaces are important to ensure that the field names and width are read correctly.
These tags can be embedded in other standard HTML tags in order to create URLs or filenames, for example:
<a href="http://<!-- domain 0 -->/"><!-- company 0 --></a>
Here are some special fields you can place in your ColFile file. You can also place them in your template file if you want the information displayed.
fmt_tm_????
This field allows you to construct a time/date string, where ???? can be any of the following (all times will be local server times, not user times):
%a |
Abbreviated weekday name |
%A |
Full weekday name |
%b |
Abbreviated month name |
%B |
Full month name |
%c |
Date and time representation appropriate for locale |
%d |
Day of month as decimal number (0131) |
%H |
Hour in 24-hour format (0023) |
%I |
Hour in 12-hour format (0112) |
%j |
Day of year, as decimal number (001366) |
%m |
Month as decimal number (0112) |
%M |
Minute as decimal number (0059) |
%p |
Current locale's A.M./P.M. indicator for 12-hour clock |
%S |
Second as decimal number (0059) |
%U |
Week of year as decimal number, with Sunday as first day of week (0051) |
%w |
Weekday as decimal number (06; Sunday is 0) |
%W |
Week of year as decimal number, with Monday as first day of week (0051) |
%x |
Date representation for current locale |
%X |
Time representation for current locale |
%y |
Year without century, as decimal number (0099) |
%Y |
Year with century, as decimal number |
|
|
For example: fmt_tm_%B+%d,+%Y would become January 12, 1995.
The following list shows the environment variables that are recognized by CGI PerForm (see Chapter 11 for a brief description of each variable):
Variables are used to store filenames or other values created with MakeUniqueFileName and MakeVariable. These variables can be used in the Command file, Template files, or in your DataFiles. The variables will be replaced by their value where used.
Variables must begin with a percent (%) sign to be recognized. They may not be passed from an HTML form.
You may also create variables in the Data command block. Note that for security reasons, these values will be forced to relative pathnames.
Note the missing slash that converts the path from absolute to relative:
\data\log will become data\log
The push list is used for Server Push routines that can be written to display simple animations. The push list has three columns: FileName, MimeType, and Delay.
MimeType has a default value of "image/gif," and the delay is set to one second. If these values are not given in the push list, the defaults will be used. If only the first (or any other) item in the push list has a MimeType and/or a Delay,
those values will become the default for the rest of the list.
The first item in the push list does not get sent to the client if the client is Netscape Navigator. The first item is reserved for non-Netscape Web browsers.
You might want to make the first item a GIF file and the remaining items JPG files because Netscape can display JPG images just like GIF images. JPG images are usually smaller and can display more colors. Most other Web clients do not display JPG images
the same as Netscape.
If you find yourself using a lot of CGI scripts, you'll like this little utility package from Richard Graessler of Germany.
The CGI2Shell applications are intended for Windows Web servers that do not support the execution of scripts without a corresponding shell in the command line of a <FORM ACTION=> or <A HREF=> tag.
The CGI2Shell Gateway is a set of programs that enable PATH_INFO to specify the name of a CGI script that will be executed with either the POST or GET method.
Currently, the shells Perl.exe and Sh.exe and the Windows NT command interpreter CMD.exe are supported.
The CGI2Shell Gateway includes three programs, one for each shell it supports:
CGI2Sh.exe for Sh.exe CGI2Perl.exe for Perl.exe CGI2Cmd.exe for Cmd.exe (Windows NT only)
All you need to do is include the script with its path in the PATHINFO of the URL. For example:
http://host.domain/progpath/CGI2xxx.exe/scriptpath/script.ext
The shell programs must reside in the path or the same directory as CGI2xxx.exe.
You can find a set of examples online at http://137.226.92.4/rick/rick/cgi2shell.html or http://pobox.com/~rickg/.
CGIC is a library of functions for CGI development with ANSI standard C, written by Thomas Boutell. You can find more information about it at http://sunsite.unc.edu/boutell/cgic/cgic.html.
Enterprise Integration Technology has created LIBCGI to assist programmers who are writing CGI systems in C language. The library consists of about 15 functions, and it is freeware. Originally written for UNIX as part of their Webmaster's Starter Kit,
it has been ported to several other popular platforms, including Windows. As with several URLs mentioned in this book, we have not tried this product and cannot endorse it other than to suggest that you visit their site and have a look for yourself:
http://wsk.eit.com.
If you program with Borland C++ and don't mind paying for CGI and HTML tools, you should definitely drop by http://htechno.com/wdw/index.htm. A company called Specialized Technologies has developed a suite of products they call the Web Developers
Warehouse. It includes three components: TCgi, HTML Objects, and Web Wizard. TCgi is a set of C++ classes for WinCGI, which works with the O'Reilly WebSite server and the FolkWeb server included on the CD.
Visit their home page for more information. You can also try the demonstration programs, pay for the software electronically, and download it pronto.
If you've made it this far, the rest is easy. The next chapter shows you how to adapt the source code from savedata.c to be used with a Visual Basic program that can save the data into an ODBC database.