This page has been accessed times.

CGI Primer

This page is for you if you want to get into CGI, and have some programming background, but don't know how to get started.

What is CGI?

CGI is an acronym for Common Gateway Interface. It lets you build Web pages that go way beyond what you can do with just HTML alone. The two biggest pluses are: the user can now talk back to your Web pages, and since the pages come from a program instead of a static HTML file, all the old limits go away.

Links to Other Items of Interest


The Example Program

The example uses a PERL script (one of the shells available under UNIX), with the following features:

References

1. Get source files(FTP).
2. Perl FAQ.
3. Perl man page (telnet to light and do man 1 perl).

Installing The Example Program


You must create a new directory within your www tree.
In this example, we'll call it /home/www/your-user-name/pl. There will be four files in all:

light:/home/www/your-user-name/pl$ ls -lA
-rw----r--   1 mhp      users          16 Sep  9 00:00 .htaccess
-rw----r--   1 mhp      users        1199 Sep  9 00:00 formmail.html
-rw----rw-   1 mhp      users           3 Sep  9 00:00 hits.1
-rw----rw-   1 mhp      users           3 Sep  9 00:00 hits.2
-rwx---r-x   1 mhp      users        6654 Sep  9 00:00 p2.pl.cgi
-rwx---r-x   1 mhp      users         123 Sep  9 00:00 odometer.cgi

STEP-BY-STEP INTSTRUCTIONS:

(Substitute your own username)
1a) mkdir /home/www/your-user-name/pl
1b) cd /home/www/your-user-name/pl
2)  Copy the files as shown above into this new directory
3)  Edit the file p2.pl.cgi and change the 2 lines
    as instructed.  You must specify the directory name from step 1a
    and your E-mail address.
3a) Edit the file odometer.cgi and change the 1 line
    as instructed.  You must specify the file path name of the hits
    file.
4)  You must have the right file permissions:
    chmod 604 .htaccess
    chmod 604 formmail.html
    chmod 606 hits.1
    chmod 606 hits.2
    chmod 705 p2.pl.cgi
    chmod 705 odometer.cgi
    chmod 701 .
5)  That's it!  Now try out the URL using your Web browser:
    http://www.lightlink.com/your-user-name/pl/p2.pl.cgi


.htaccess

Options ExecCGI

formmail.html

<HTML>
<TITLE>Title</TITLE>
<PRE>
# ------------------------------------------------------------
# Form-mail.pl, by Reuven M. Lerner (reuven@the-tech.mit.edu).
#
# Last updated: 9/8/95 by MHP
#
# Form-mail provides a mechanism by which users of a World-
# Wide Web browser may submit comments to the webmasters
# (or anyone else) at a site.  It should be compatible with
# any CGI-compatible HTTP server.
#
</PRE>
<FORM ACTION="p2.pl.cgi" METHOD="POST">
<H2>SAMPLE HOME PAGE - Form Mail</H2>
Please fill in the information below, and then click <strong>Submit
</strong> when done.<P>
In this example, the server will check to make sure that the user enters
a valid E-mail address into the <strong> address </strong> box. If
so, the server will E-mail a message back to you.
If nothing is entered, the server will complain.
<BR>
Your Email Address<INPUT TYPE="text" NAME="address"><BR>
User Name<INPUT TYPE="text" NAME="username"><BR>
Any Comments?<INPUT TYPE="text" NAME="comments"><BR>
Your Real Name<INPUT TYPE="text" NAME="realname"><BR>
Information Desired:<INPUT TYPE="text" NAME="whichinfo"><BR>
data<INPUT TYPE="text" NAME="data"><BR>
<INPUT TYPE="submit" VALUE="Done - Submit">
</FORM>
<P>

hits.1

0

p2.pl.cgi

#!/usr/bin/perl -- -*-perl-*-

# *************************************************************
# You MUST customize these for your own environment!
# *************************************************************

# This should be changed to your cgi testing directory!
$home_dir = "/home/www/your-user-name/pl";

# This should be set to your E-mail address!
$recipient = 'your-user-name@mhp.lightlink.com';

# *************************************************************
# End of items which need to be custimzed
# *************************************************************

# ------------------------------------------------------------
# Modifications 9/8/95 by MHP can only be modified and/or redistributed
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.
# ------------------------------------------------------------

# ------------------------------------------------------------
# Form-mail.pl, by Reuven M. Lerner (reuven@the-tech.mit.edu).
#
# Last updated: March 14, 1994
#
# Form-mail provides a mechanism by which users of a World-
# Wide Web browser may submit comments to the webmasters
# (or anyone else) at a site.  It should be compatible with
# any CGI-compatible HTTP server.
#
# Please read the README file that came with this distribution
# for further details.
# ------------------------------------------------------------

# ------------------------------------------------------------
# This package is Copyright 1994 by The Tech.

# Form-mail is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2, or (at your option) any
# later version.

# Form-mail is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with Form-mail; see the file COPYING.  If not, write to the Free
# Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
# ------------------------------------------------------------

# *************************************************************
# Defines
# *************************************************************

# hits counter file
$hits_file = "$home_dir/hits.1";

# The form html file name
$html_file = "$home_dir/formmail.html";

$LOCK_SH = 1;
$LOCK_EX = 2;
$LOCK_NB = 4;
$LOCK_UN = 8;

# This should match the mail program on your system.
$mailprog = '/usr/lib/sendmail';

# *************************************************************
# Start Program Code.
# *************************************************************

# Print out a content-type for HTTP/1.0 compatibility
print "Content-type: text/html\n\n";

# Print a title and initial heading - everything printed from now on
# uses regular html rules
print "<Head><Title>Thank you</Title></Head>";
print "<Body>";

# Check if this is just an ordinary "get" or a post of the form
$method = $ENV{'REQUEST_METHOD'};
if ($method eq "POST") {
   do get_postings();
} else {
   # Hit counter
   do hits();
   print "<H2>Number of times this page has been accessed: $hits_count</H2><HR>\n";
   print "<H2>Number of times this page has been accessed: <IMG SRC=\"./odometer.cgi\"></H2><HR>\n";
   do print_form();
}

# *************************************************************
# End Program.
# *************************************************************

# *************************************************************
# Start of subroutines
# *************************************************************

sub get_postings {
   # Get the input
   read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

   # Split the name-value pairs
   @pairs = split(/&/, $buffer);

   foreach $pair (@pairs)
   {
       ($name, $value) = split(/=/, $pair);

       # Un-Webify plus signs and %-encoding
       $value =~ tr/+/ /;
       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

       # Stop people from using subshells to execute commands
       # Not a big deal when using sendmail, but very important
       # when using UCB mail (aka mailx).
       # $value =~ s/~!/ ~!/g;

       # Uncomment for debugging purposes
       # print "Setting $name to $value<P>";

       $FORM{$name} = $value;
   }

   # If the E-mail address does not contain an at-sign (`@'), then
   # do not continue - instead return an "error" message.
   # A `grep' is not the best way to do this! ;-)
   `echo $FORM{'address'} | grep "\@" > /dev/null`;
   $rc = $?;
   if ($rc ne 0) {
      do blank_response();
      do print_form();
      return;
   }

   # Now send mail to $recipient

   open (MAIL, "|$mailprog $recipient") || die "Can't open $mailprog!\n";
   print MAIL "Reply-to: $FORM{'username'} ($FORM{'realname'})\n";
   print MAIL "Subject: WWW catalogue request\n\n";
   print MAIL "Person's address was given as follows:\n";
   print MAIL "$FORM{'address'}";
   print MAIL "\n-----------------------------------------------------------\n";
   print MAIL "This person wants:\n";
   print MAIL "$FORM{'whichinfo'}\n\n";
   print MAIL "More Data was: $FORM{'data'}\n";
   print MAIL "$FORM{'username'} sent the following\n";
   print MAIL "comments:\n\n";
   print MAIL  "------------------------------------------------------------\n";
   print MAIL "$FORM{'comments'}";
   print MAIL "\n------------------------------------------------------------\n";
   print MAIL "Server protocol: $ENV{'SERVER_PROTOCOL'}\n";
   print MAIL "Remote host: $ENV{'REMOTE_HOST'}\n";
   print MAIL "Remote IP address: $ENV{'REMOTE_ADDR'}\n";
   close (MAIL);

   # Make the person feel good for writing to us
   print "Thank you for sending your information request!<P>";
   print "Return to our <A HREF=\"p2.pl.cgi\">home page</A>, if you want.<P>";
}

# subroutine blank_response
sub blank_response
{
    print "<strong>Your comments appear to be blank,</strong> and thus were not sent ";
    print "to our webmasters.  Please re-enter your comments.<BR><HR>\n";
}

sub print_form {
   open (FORM, "$html_file") || return;
   while (<FORM>) { print; }
   close(FORM);
}

sub lock {
    flock(HITS,$LOCK_EX);
    # and, in case someone appended
    # while we were waiting... rewind file
    seek(HITS, 0, 0);
}

sub unlock {
    flock(HITS,$LOCK_UN);
}

# subroutine hits: if open ok, read, add one, rewind, rewrite, close.
sub hits {
   $hits_count = 0;
   if (open(HITS, "+<$hits_file")) {
      do lock();
      $hits_count = <HITS>
      $hits_count++;
      seek(HITS, 0, 0);
      print HITS "$hits_count\n";
      close(HITS);
      do unlock();
   }
}


odometer.cgi

#!/bin/sh
#change following line to reference the path name of your hits file.
HITS_FILE="/home/www/your-user-name/pl/hits.2"
#
/home/www/cgi-bin/count $HITS_FILE


© Portions Copyright 1995, Max H. Parke <mhp@lightlink.com>
Except for the "odometer-style hits counter", which is shareware (see below), this is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.
It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.


README.count

*** mhp modified to use argv[1] for file instead of hardcoded file name.
*** also better error checking
*** Note: You do not need to compile this!  Just use the odometer.cgi
*** script, above.
*** 10/16/95

SHAREWARE count.c ver 2.0
written by Chris Stephens
please distribute, enjoy and register if you use.
(C) 1995

This code was tested and worked under NCSA's Httpd for Unix.  So hopefully, you will not have any problems compiling and using the code.  You should have two files, the .c file and this readme file.

What the script does:  This script reads a number from a file, increments it and rewrites it to the same file.  It then builds an X-bitmap image of the number similar to the odometer in your car.  This bitmap is then sent back to the html calling the script in a <IMG SRc=>. Therefore, you DO NOT have to modify the system configuration files or have server-side includes turned on. You only need access to execute cgis.

The .c file will need path info added in 2 places.  These places are documented in the c file.
Then simply do a make on the file and compile it.  Once it is compiled, place it in your cgi-bin folder or some other folder that you can run cgis from.  

Usage:  In the program that you want the counter in place a

<img src=script.name.&.path.goes.here> This runs the script and put the odometer in the
correct place.

Enjoy,

Chris..

--------------------------------------------------------------------------------
Registration Information

count.c is shareware, this means if you use it, you really should register it.

count.c is $10 for education institutions and $20 for others.

If you live outside the US and can not pay in US $, mail the equivalent of the amount in your currency and I'll have it exchanged here.

Please Mail the total amount and order form to:

     Chris Stephens
    127 S. 13th Ave.
     Hopewell, VA USA
                    23860
--------------------------------------------------------------------------------
Order Form

Name:_________________________________

Email:_________________________________

Address:___________________________________________________________
__________________________________________________________________
__________________________________________________________________
__________________________________________________________________

Product registering:__________________________________________________

URL:______________________________________________________________


Purchased for:_________________________________

Total Amount:__________________________________