Cover V04, I03
Article
Figure 1
Listing 1
Listing 2
Sidebar 1
Sidebar 2

may95.tar


A WWW-Based Computer Support System

John Kinsella

Since as a system administrator, I need to be able to buffer my current task against incoming queries and cries for help, it occurred to me that the WWW could be used as just such a medium for user communication.

In keeping with the growing popularity of the World Wide Wed (WWW), almost every computer in the building where I work has some form of a web browser installed. So, to allow my users to request support via the WWW, I created a set of WWW pages and wrote the perl scripts to drive them. In researching the project, I found an overabundance of information on how to design HTML (Hypertext Markup Language)-based pages, but not very much about how to develop HTML forms and process the information they produce. This article reports what I learned about the forms and their use.

Setting Up an HTML Form

HTML forms allow user input to multiple configurable options. An HTML form begins with the form tag:

<form action="/cgi-bin/enter_form" method="POST">

This tag specifies the beginning of a form. When a user submits this form, the program /cgi-bin/enter_form will receive the user's input. (This program, which is called a Common Gateway Interface (CGI) program, will be covered in more detail later.) The "method" describes how the information will be sent to the form. The POST method sends the data to the http server as a piece of data, while the GET method appends the data to the end of the URL (Universal Resource Locater). The matching tag </form> terminates the form.

The input tag defines the treatment of user input, as, for example:

<input name="input1" size=20 maxlength=30>

This tag creates an input window in the document of size 20 and restricts the user's input to no more than 30 characters. It specifies that this input will be associated with the variable name input1 when it is passed to the CGI program. The input tag can also be used for displaying buttons:

<input type=submit value="Submit form">

The tag in this example will display a button with the label "Submit form." When this button is selected, the form will be submitted to the CGI program. Similarly, if the type is set to reset, then all input fields will be reset, and their current contents will be deleted.

For a larger input area, a textarea tag can be used:

<textarea name="more_input" cols=60 rows=10></textarea>

The tag here also creates an input window in the document, but the window will span 60 columns in width and 10 rows in height. The larger input window allows a user to input a message (or just gives the user a chance to be more expressive). When the input is sent to the CGI program, it will be associated with the variable name more_input.

The last tag I want to discuss here is the select tag. This tag presents the user with a selection of two or more choices, only one of which the user can pick. The basic format of the select tag is as follows:

<select name="level" size=2>
<option value="one"> High
<option value="two" selected> Low
</select>

The example above will create a selection box that is two lines high, as defined by the size option. The box offers two selections to the user, High and Low. When the CGI program is called, the selected choice is passed with the variable level. If High was selected, then the value passed with the variable is "one". Otherwise, it is "two".

The Interaction between Form and Script

When the user submits the form, the CGI program specified in the form tag is called. The content of all of the form's variables is sent to the program via a one-line string directed to the program's standard input (see Figure 1). The basic format of this output is:

variable=value&

The variables are output in the order that they appear in the HTML form. For each variable, the variable name is printed first, then an equals sign, then the value of the variable, and then an ampersand. The next variable name follows immediately after the ampersand. Unfortunately, httpd escapes special characters by sending a percentage sign followed by the character's ASCII code in a two-digit hexadecimal form. I created several lines of perl code to handle this, as I will explain later.

Before the CGI program is called, httpd sets several environment variables. One of these variables, CONTENT_LENGTH, contains the length of the line which was sent to the CGI program on the standard input. Another variable used in the scripts is REMOTE_IDENT, which contains the remote user's user name when that information is available.

Displaying the Form

As I explain in the sidebar "Setting Up an http Server," the scripts will be able to recognize a user only if the user's host machine is running identd. Because of this, I decided to use two scripts, request_form.pl and submit_request.pl, instead of one.

The first script, request_form.pl (Listing 1), displays the form. Any link to the two scripts would go to this script first. request_form.pl uses the perl subroutine getpwnam() to see if it has a working username. If the subroutine returns a name matching the username it was passed, then the script presumes that it has legitmate information. If the script is able to figure out the user's identity, it does not display the user information input areas. If it is unable to find a username, it displays input fields asking for the user's real name, username, phone number, and location. Either way, a form is displayed. This form feeds the second perl script.

submit_request.pl (Listing 2) is the backbone of the project. This script takes input from the HTML form, slices it and dices it, and mails off a form to the system administrator when everything is finished. submit_request.pl begins by passing the contents of the environment variable REMOTE_IDENT to getpwnam(), to see if it can figure out a username. If getpwnam() is able to match what was passed to it, $have_uname is set so that the code will not try to get information about the user (phone, name, etc.) from the data httpd passes to it. The script next calls the subroutine lookup(), passing it the username so that it can look up other information about the user. At our site we keep information about users in a text database rather than in the users' password entries. This subroutine could easily be modified to parse @pwent, which contains the password entry returned by the call to getwpnam().

The script then takes the line of input from httpd and puts it it into $INPUT for future use. Now it is time to deal with the escaped characters created by httpd. I decided to handle this by creating a loop that searches the string from beginning to end, looking for percent signs. When a percent sign is found, the script copies the string up to that position into a temporary variable, converts the escaped value back to a character, then concatenates the character to the end of the temporary value. The script then concatenates the remainder of the string to the temporary string, and copies the temporary string back to $INPUT. I chose to do this work here rather than later in the script, where it could have been necessary to run the loop more than once on separate variables.

The script next calls parse_info, which, in turn, calls cut to split the contents of $INPUT into the appropiate variables. Each time cut is called, it returns the value of the next variable in the string. Since httpd sends this information in an orderly fashion, printing variables in the form as it encounters them from the top of the form down, there is no need to be concerned about the variable names.

After parsing the information parsed into the appropiate variables, the script must remove any quote marks or possible variable names from the short description. This is necessary for security reasons, since the short description will serve as the subject of the message sent to the administrator, and will be passed to the mailer on the command line. The script accomplishes this with a few replace commands. Note that if the user does not enter a one-line description, the script exits.

If the parsing goes according to plan, the script next calls the send_request subroutine. This subroutine actually sends the processed information to the system administrator. The first few lines of the subroutine generate a time and date stamp, which appears in the body of the message. The subroutine next opens a pipe to the mailer of choice and sends the request form to the pipe. It then closes the pipe, and the message is delivered to the administrator. Finally, the script prints a message to the user stating that the request has been submitted.

Conclusion

Although a WWW-based request is not the most secure way for a user to communicate a problem to a system administrator, I believe most users will find it more convenient even than mailing in a request, because the form already exists. All the user needs to do is fill in the blanks, and the computer will take care of the rest.

References

NCSA httpd source, binaries, and documentation

http://hoohoo.ncsa.uiuc.edu/

ftp://ftp.ncsa.uiuc.edu/Web/httpd/Unix/httpd/httpd_1.3R/

http://www.cern.ch

About the Author

John Kinsella is a system administrator for the State of California Department of Water Resources, as well as a student at American River community college. He will transfer to the University of California, Davis this summer to continue working on a B.S. in Computer Engineering. When not recompiling linux kernels, John can be reached at johnk@water.ca.gov.