Sample Assignment: Using Your Polynomial in a CGI Program
(Chapter 5)



Data Structures and Other Objects Using C++
Third Edition
by Michael Main and Walter Savitch
ISBN 0-321-19716-X

The Assignment:
In this assignment, you will use your polynomial class as part of a larger CGI program. CGI stands for "common gateway interface" but its really just a flashy acronym that means a program that process the information submitted by a web form. Your CGI program will allow me to point my web browser at a form that you will post on the internet. On the form, I'll enter some coefficients for a polynomial and then I'll click the submit button. Your program will then draw a gif file with a graph of my polynomial.

Note:
Although I will write some significant notes here, there will undoubtedly be items that are not covered by these notes. It's important for you to attend recitation and class to understand other items because I don't have any other reading material to cover missed classes.

Purposes:
Show you how to create a simple web-based program.

What the Program Will Do When It's Completed:
Before you start, you might want to take a look at my completed program, available at: http://csel.cs.colorado.edu/~main/poly.html.

Set up your web directories:
In order to post CGI programs to the web, you'll need to create two special directories in your undergraduate account. Here are the commands you'll need to execute, starting at the root of your account:

  1. Create a public_html directory and make it readable:
        mkdir public_html
        chmod 755 public_html
        
  2. Within your public_html directory, create a cgi-bin directory:
        cd public_html
        mkdir cgi-bin
        chmod 755 cgi-bin
        

Grab a copy of my poly.html file:
Copy my poly.html file into your public_html directory. From within your public_html directory, you can accomplish this with the command:
    cp ~main/public_html/poly.html poly.html
    chmod 644 poly.html
    
Use the editor to open up this file. If you know a bit about html programming, then you'll understand what I've done. For now though, you don't need to understand much: Just change my name (Michael Main) to yours at the top of the file. Then find this line:
    ACTION="http://csel.cs.colorado.edu/cgi-bin/cgiwrap/~main/polycgi"
    
This line tells the web server where to find the program that will process the form information. You should change the name ~main to the tilde character (~) followed by your login name instead of main.

Apart from this one change, you won't need to know any html programming for this assignment, but you might want to learn some for fun, using a tutorial such as http://www.mit.edu/afs/athena/user/w/s/wsmart/WEB/tutorial/HTMLtutor.html.

Set Up Your Working Directory:
Since this is a web-based program, you'll need to work in the undergraduate lab so that you can post your results on the web. Make this working directory underneath your root (not within your public_html directory). Change to that directory (with the cd command), and copy your most recent version of the polynomial (poly2.cxx and poly2.h) into the directory. Note: If you use ftp to transfer the files from a PC you should first type the command ascii before transfering the files. This will correctly handle the different forms of end-line that are used.

Get the CGI.h header file:
Grab the CGI.h header file from www.cs.colorado.edu/~main/projects/CGI.h, and put it in your working directory. This file contains a small class called cgi that simplifys writing a CGI program. The file was written by S. Martin at Marketrends Productions ( www.marketrends.net/C++/).

General Idea of Using CGI.h:
In general, a CGI program that uses CGI.h will follow this pattern:

  1. #include "CGI.h"

  2. Within the main program, declare one object of type cgi, for example:
        cgi polyinfo;
        
  3. Within your program, you can activate member functions of the cgi object to get information from the form that you are processing or to write information back to the user of the form.

Your Polynomial CGI Program
Your polynomial program will read the information that comes from the poly.html form. It will create a polynomial with the specified coefficients and then create a gif file with a graph of that polynomial. Finally, your program will output an html page that includes the gif file. Discussions of these steps and other issues are given below.

Include Files
Your program polycgi.cxx will need:
    #include <cstdlib>  // Provides EXIT_SUCCESS, atof
    #include <iostream> // Provides cout
    #include <string>   // Provides string class
    #include "CGI.h"    // From www.marketrends.net/C++/
    #include "poly2.h"  // My polynomial class
    using namespace std;
    using namespace main_savitch_5;
    

The Main Program Variables
Your main function won't be long, perhaps 40 lines. I suggest that you organize things with these variables in main: CGI polyinfo; polynomial p; double low_x, high_x, low_y, high_y; string filename; // Name of the gif file we'll create string write_to; // Complete name of gif file, including directory name string url; // Complete name of gif file to put in a web page const string COLON(":"); // Will be used to form part of the file names.

Step 1 of Main: Set the polynomial and the bounds
You need to set the coefficients of your polynomial for exponents zero through four. This information comes from the form with keys called coef0, coef1, coef2, coef3 and coef4. To convert the form information from a C-style string to a double number, you can use the atof function (ascii-to-float). For example, this expression will provide the coefficient for the square term:
    atof(polyinfo.get_value("coef2"));
    
You'll set the values for the four bounds in a similar way using these keys for the get_value member function: "low_x", "high_x", "low_y" and "high_y".

Step 2 of Main: Erase old gif files
Each time the CGI program runs, it will create a gif file. Since you don't want to clutter the hard drive with billions of gif files, it's a good idea to erase any old gif files before doing anything else. You can use the system command to execute a Unix command that will erase these files:
    system("rm -f ../poly*.gif");
    
The rm -f means to remove files with no warning messages if there is an error. The ../poly*.gif gets any file that starts with poly and ends with .gif in the directory that is one level up (indicated by the ../. As you'll see in a moment, these gif files will be present in your public_html directory, whereas the CGI program is running in public_html/cgi-bin, and this is why you need to specify that the files are "one level up".

Step 3 of Main: Calculate the file names
The name of the gif file that you write can be calculated by patching togethr a bunch of small strings with the + operator of the C++ string type. We want the name to begin with "poly" and end with ".gif". In between, we'll put all the information about the coefficients. Here's the idea:
    filename = "poly" + colon
        +      polyinfo.get_value("coef0") + colon
        +      polyinfo.get_value("coef1") + colon
        +      polyinfo.get_value("coef2") + colon
        +      polyinfo.get_value("coef3") + colon
        +      polyinfo.get_value("coef4") + colon
        +      polyinfo.get_value("low_x") + colon
        +      polyinfo.get_value("high_x") + colon
        +      polyinfo.get_value("low_y") + colon
        +      polyinfo.get_value("high_y") + colon
        +      ".gif";
    
Each number is separated from the next one by a colon. This will result in some long and strange file names such as this:
    poly:1:0:1)2:0:-2:2:-4:4:.gif
    
After you create this basic file name, create two more names:

Step 4 of Main: Make the gif
Call the make_gif function to actually write that gif file. Use write_to.c_str( ) as the name of the file. (The c_str converts it from a C++ string to an ordinary C-style string.)

Step 5 of Main: Print the html page to send back to the user
I'll explain these steps in class. Use your real name where it says STUDENT NAME.
    polyinfo.start_html("STUDENT NAME", "Polynomial Display", "white");
    cout << "<H2>Graph of Your Polynomial</H2>" << endl;
    cout << "Polynomial: " << p << endl;
    cout << "<BR>Range of x: " << low_x << " to " << high_x << endl;
    cout << "<BR>Range of y: " << low_y << " to " << high_y << endl;
    cout << "<P><IMG SRC =\"" << url << "\" ALIGN=\"CENTER\">" << endl;
    polyinfo.end_html( );
    

Put the pieces together
Make sure that you have the latest version of g++. If you are uncertain about this, you can type g++ --version. The answer should be 2.95.2 or later. If not, then you can reset your .cshrc file by typing the command reset-world, then log out and log back in.

All your compilations must occur on one of the Solaris PC machines listed at the bottom of http://csel.cs.colorado.edu/udp/machines.html. For example, if you want to do your compilations on swallow, then you should first do a secure remote login to swallow, like this:

    slogin swallow
    
You have to use these Solaris PC machines because the executables they generate are the right format for our csel web server.

You'll compile your file in the usual way. For example, my makefile has these items (with tabs before the g++ commands, of course):

    polycgi: polycgi.o poly2.o
            g++ -gstabs -Wall polycgi.o poly2.o -o polycgi
   
    polycgi.o: polycgi.cxx poly2.h CGI.h
            g++ -gstabs -Wall -c polycgi.cxx

    poly2.o: poly2.cxx poly2.h
            g++ -gstabs -Wall -c poly2.cxx
    

After you compile your polycgi, you should copy the executable to your cgi-bin directory and make sure that the world can execute it with these commands:

    cp polycgi ~/public_html/cgi-bin
    chmod 755 ~/public_html/cgi-bin/polycgi
    

Debugging
Debugging CGI programs usually uses special tools. But with a simple program you can debug by putting cout statements into the main program. The results of these cout statements will appear on the page that is displayed when you submit your form.

Where do you go to submit that form and run the program? The answer is this URL, with your login name...

    http://csel.cs.colorado.edu/~LOGINNAME/poly.html
    


Michael Main (main@colorado.edu)