Приглашаем посетить
Замятин (zamyatin.lit-info.ru)

Classified ad manager

#!/usr/local/bin/perl

# Name: class_ad.cgi
#
# Version: 2.0
#
# Last Modified: 5-23-96
#
# Copyright Information: This script was written by Selena Sol
#     (selena@eff.org, http://www.eff.org/~erict) having been inspired by
#     countless other perl authors.  Feel free to copy, cite, reference,
#     sample, borrow or plagiarize the contents.  However, if you
#     don't mind, please let me know where it goes so that I can at least
#     watch and take part in the development of the memes. Information
#     wants to be free, support public domain freware.
#
# Description: This classified ad manager will simulate a classified ad 
#     newspaper section aloowing users to leave their own ads (and modify 
#     and delete them) as well as read through the classified ad database 
#     for items that they may be interested in buying (searching based 
#     on keyword).
#
# Installation: See class_ad.setup

###########################################################################
#                       Print http Header.                                #
###########################################################################

# First, print out the HTTP header.  

  print "Content-type: text/html\n\n";

###########################################################################
#                       Require Libraries.                                #
###########################################################################

# Set the path of your current library.  By default I have created a 
# Library subdirectory...but the best thing to do is put these in your 
# "Real" cgi library and reference that path here.

  $lib = "Library";

# Dump the libraries at the beginning if the INCLUDE array so that they 
# will be read before any other libraries which may have routines with 
# the same name.

  unshift (@INC, "$lib");

# Now require the necessary files with the subroutine at the end of this 
# script marked by "sub require".  We use this subroutine so that if 
# there is a problem with the require, we will get a meaningful error 
# message.  Also, include the setup file for this script which should be 
# in the same directory as this script.

  &require("$lib/cgi-lib.pl", "$lib/cgi-lib.sol",
 	   "$lib/auth-lib.pl", "./class_ad.setup", "$lib/date.pl");

###########################################################################
#                        Gather Form Data.                                #
###########################################################################

# Next use cgi-lib.pl to parse the incomming form data.  We'll pass 
# cgi-lib.pl (*form_data) so that our variable will come out as 
# $form_data{'key'} instead of $in{'$key'}.  I like to use form_data 
# because it is easier for me to remember what the variable is.

  &ReadParse(*form_data);

###########################################################################
#               Find Appropriate Data and Setup Files                     #
###########################################################################

# Then let's determine which database the client is asking us to display.  
# This script will probably have been called with data appended to the 
# URL.  This data should include the name of the setup file that we need to 
# display.  For example, we may have linked to this script using
# <A HREF = "class_ad.cgi?database=housing.setup">Housing Database</a>
# In this example, our form_data associative array will contain the 
# variable database with its associated value housing.setup.  If there is 
# such a value, we'll assign that to the variable $setup_file.  If the 
# value is empty, and the person just called this script straight out, 
# we'll assign basic.setup to $setup_file instead.  This is why you must 
# have basic.default in the Databases directory no matter what.

  if ($form_data{'database'} ne "")
    {
    $setup_file = $form_data{'database'};
    }
  else
    {
    $setup_file = "basic.setup";
    }

# Now let's require the setup file that we were asked for.  This setup 
# file will contain information specific to that database including the 
# fields to be displayed and the location of the data file.

  &require("Databases/$setup_file");

# Finally, we are going to want to reformat the name of the setup file so 
# that we can display the name of the data file in a userfriendly sort've 
# way on following pages.  If the user asked to see employment.setup, we 
# want to remember "Employment" so that we can later say, for example, "Add 
# an Item to the Employment Database" as opposed to "employment.setup database".
# So, if we were given a database name, we'll first split it into name 
# and setup.  What was once name.setup becomes name and setup.  Then we 
# take the first letter of the name out and assign it to $first_letter, and 
# the rest of the word to $rest_of_the_word.  So, $first_letter = n and 
# $rest_of_the_word = ame.  Then turn the $first_letter into an uppercase 
# letter using the translate (tr) function.  So $first_letter now equals N 
# instead of n.  Then splice them together again using (.) and you now have 
# Name.  Alot of work for such a small change, but it makes the client 
# GUI much nicer.

  if ($form_data{'database'} ne "")
    {
    ($name, $junk) = split (/\./, $form_data{'database'});
    $first_letter = substr($name,0,1);
    $rest_of_the_word = substr($name,1);
    $first_letter =~ tr/a-z/A-Z/;
    $database = $first_letter . $rest_of_the_word;
    }

#######################################################################
#                       Basic User Authentication                     #
#######################################################################

# Also, rename and incoming session file information

  if ($form_data{'session_file'} ne "")
      {
      $session_file = $form_data{'session_file'};
      }

###########################################################################
#                     Print out the frontpage.                            #
###########################################################################

# Next, print out the frontpage. We will have to print out the
# frontpage in two cases.  Firstly, if we have not yet defined a database
# to view ($form_data{'database'} eq "") or (||) if we
# have been asked specifically to return to the frontpage
# ($form_data{'return_to_frontpage'} ne "") and secondly, if we are coming
# to this script completely fresh and have not assigned any form values.
# ($ENV{'CONTENT_LENGTH'} eq "")

  if (($form_data{'database'} eq "" || 
       $form_data{'return_to_frontpage'} ne "") 
       &&
      ($ENV{'CONTENT_LENGTH'} eq ""))
    {

# If so, let's print out a basic frontpage.  I have included the cheezy 
# little graphic that I made as an example in the Images subdirectory which 
# comes with the distribution.  However, notice that we are referencing 
# this script with ?database=xxx&session_file=$session_file.  This is 
# important because we need to always remember to pass this 
# information, so the client does not get lost.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>The Classified Ad Manager</TITLE></HEAD>
    <BODY BGCOLOR = "FFFFFF" TEXT = "000000">
    <CENTER>
    <IMG SRC = "http://www.eff.org/~erict/Graphics/Scripts/class_ad_title.gif">
    <P>
    <A HREF = "/cgi-bin/imagemap/~erict/Graphics/Scripts/classified.gif">
    <IMG SRC = "http://www.eff.org/~erict/Graphics/Scripts/classified.gif" 
         ISMAP USEMAP = "#map" BORDER = "0"></A>
    <MAP NAME = "map">
    <AREA COORDS = "11,18 191,53" HREF = "$database_manager_script_url?database=employment.setup&session_file=$session_file"> 
    <AREA COORDS = "9,71 192,107" HREF = "$database_manager_script_url?database=housing.setup&session_file=$session_file">
    <AREA COORDS = "11,124 191,160" HREF = "$database_manager_script_url?database=misc.setup&session_file=$session_file">
    <AREA COORDS = "282,18 463,54" HREF = "$database_manager_script_url?database=personals.setup&session_file=$session_file">
    <AREA COORDS = "284,72 463,107" HREF = "$database_manager_script_url?database=vehicles.setup&session_file=$session_file">
    <AREA COORDS = "284,125 465,160" HREF = "mailto:selena\@eff.org">
    </MAP>
    <P>
    <A HREF = "$database_manager_script_url?database=employment.setup&session_file=$session_file">Employment</A>
    | <A HREF = "$database_manager_script_url?database=housing.setup&session_file=$session_file">Housing</A>
    | <A HREF = "$database_manager_script_url?database=misc.setup&session_file=$session_file">Misc. For Sale</A>
    | <A HREF = "$database_manager_script_url?database=personals.setup&session_file=$session_file">Personals</A>
    | <A HREF = "$database_manager_script_url?database=vehicles.setup&session_file=$session_file">Vehicles</A>
    </CENTER></BODY></HTML>
    end_of_html
    exit;
  }

###########################################################################
#                  Print out First Page of Database.                      #
###########################################################################

# If the client has just clicked on one of our links from the frontpage, 
# she will have submitted a request via GET rather than post (which is used 
# for all of the forms throught the rest of this script.  So, if the 
# request method is GET, we know that we are being asked for this page.

  if ($ENV{'REQUEST_METHOD'} eq "GET")
    {

# So let's print out a firstpage of whatever database they asked for, 
# giving them several options as to what they can do from here.  Notice 
# that here is where we use the $databse variable that we worked so hard 
# above to create.  Also, notice that we are passing database and session 
# id as hidden variables.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>The Classified Ad Manager - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>The Classified Ad Manager - $database</H2></CENTER>
    <BLOCKQUOTE>
    Welcome to the Classified Ad Manager...Feel free to enter your ads 
    here and use the modification options if your information changes...good 
    luck.
    </BLOCKQUOTE>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file" VALUE = "$session_file">    
    <INPUT TYPE = "submit" NAME = "search_form_view" 
	   VALUE = "View $database Ads">
    <INPUT TYPE = "submit" NAME = "add_form" VALUE = "Submit an Ad">    
    <INPUT TYPE = "submit" NAME = "search_form_delete" 
	   VALUE = "Delete Your Ad">  
    <INPUT TYPE = "submit" NAME = "search_form_modify" 
	   VALUE = "Modify Your Ad">
    <INPUT TYPE = "submit" NAME = "return_to_frontpage"
           VALUE = "Return to Frontpage">
    end_of_html
    exit;
    }

###########################################################################
#                      Print out Add Item Form.                           #
###########################################################################

# Now let's check to see if the client was actually asking us for the 
# form to add an entry to the database.  If so, we will need to log them
# in so that they can be assigned a session id number which we can pass
# through the authentication routine if required.  It is one thing to view
# the database, it is another to modify it!

  if ($form_data{'add_form'} ne "")
    {

# First let's check to see if the client is a user who is authorized to use
# this script.  We will use the web of routines in the library
# file session-lib.pl to do the following:
#
# 1. Ask the user to submit a userid and password.
# 2. Check that userid/password pair against the information in
#    $user_file.
# 3. If the information is invalid, dissallow enterence and provide a
#    routine for the user to apply for an account.
# 4. If the information was valid, send back to this script a "session
#    file id" corresponding to a session file which will have been created
#    by session-lib.pl and which will contain the users personal
#    information.  This script will then pass along the session id as a
#    hidden variable throught in order to make sure that the user is
#    valid.  If we were already provided with a session file via 
#    $form_data, this script must also check to make sure that it is a valid 
#    session file (it deletes them every so often as an extra security 
#    precaution)

# We'll pass the subroutine GetSessionInfo which is contained in
# auth-lib.pl three parameters, the $session_file value (which will be
# nothing if one has not been set yet), the name of this script (so it can
# provide links back) and the associative array of form data we got from
# cgi-lib.pl.

  ($session_file, $session_username, $session_group, $session_first_name,
   $session_last_name, $session_email) = &GetSessionInfo($session_file,
   $database_manager_script_url, *form_data);

# Take off the newline character for the last member in the array.

  chop $session_email;

# Since we also want to keep track of the data when new entried were 
# made, we'll also use the &get_date subroutine at the end of this script.

    &get_date;

# Print out the header of the add form.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Add a Classified Ad - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Add a Classified Ad - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    end_of_html

# Now create the input form using the subroutine create_input_form at the
# end of this script.  This subroutine will simply create an input field
# for each of the fields in the database and present it in table format.

    &create_input_form;

# Finally, print out the page footers as we did for the frontpage.

    print <<"    end_of_html";
    </TABLE><CENTER><P>
    <INPUT TYPE = "hidden" NAME = "first_name" VALUE = "$session_first_name">
    <INPUT TYPE = "hidden" NAME = "last_name" VALUE = "$session_last_name">
    <INPUT TYPE = "hidden" NAME = "email" VALUE = "$session_email">
    <INPUT TYPE = "hidden" NAME = "time" VALUE = "$date">
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file" 
	   VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "submit_addition"
	   VALUE = "Submit Addition">
    <INPUT TYPE = "submit" NAME = "return_to_frontpage"
	   VALUE = "Return to Frontpage">
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

###########################################################################
#                     Print out Search Form (Delete).                     #
###########################################################################

# If the client is asking to delete on the other hand,, let's send a form
# so that they can specify which database item they wanted deleted.

  if ($form_data{'search_form_delete'} ne "")
    {

# First, pass them through a security check.

    ($session_file, $session_username, $session_group,
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

    chop $session_email;

# Before we can begin deleteing, we need to find out which item the client
# is interested in deleting.  In order to do that we need the client to
# give us some information (which item).  Likewise, we need to tell the
# client which items are available to delete (a database listing of
# possible items). However, we can't just begin outputting all the items
# in our database.  The browser would run out of memory, and do we really
# want the client to get all of the info in the database anyways! Instead,
# we will have the client give us one or more search terms so that we can
# put together a reasonably sized list from which the client can then
# choose.  

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Query Database for Deletion - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Query Database for Deletion - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    end_of_html

# Now create the input form using the subroutine create_input_form at the
# end of this script.  (Same as the equivalent call for add, above)

    &create_input_form;

# Now add a form input for "exact match" and the form, body and html
# footers and tags. BTW, all searches are case insensitive, but the
# exact match will not match gen'eric' if the search is for eric whereas
# the non-exact search will.

    print <<"    end_of_html";
    <TR>
    <TH>Exact Match?</TH><TD>
    <INPUT TYPE = "checkbox" NAME = "exact_match" CHECKED>
    </TD></TR></TABLE><P>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file" VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "search_database_delete"
	   VALUE = "Submit Search Term">
    <P><BLOCKQUOTE>To get a full view of database, submit \"no\"
    keywords.  But beware, if there are too many items in your database,
    you will exceede the memory of your browser.
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

###########################################################################
#              Print out Search Results HTML Header (Delete).             #
###########################################################################

# Next, we need a routine to accept the cleint defined search term(s)
# and search the database, presenting a dynamically generated list of
# "hits" from which the client can then begin deleting.

  if ($form_data{'search_database_delete'} ne "")
    {

# First, pass them through security.

    ($session_file, $session_username, $session_group,
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

  chop $session_email;

# Now conduct the search and print out the results.  

# First, we'll print out the page header using the same subroutine calls
# that we used above.

  print <<"  end_of_html";
  <HTML><HEAD><TITLE>Deleting an Item from the Database - 
  $database</TITLE></HEAD>
  <BODY>
  <CENTER><H2>Deleting an Item from the Database - $database</H2></CENTER>
  <FORM METHOD = "post" ACTION = "$database_manager_script_url">
  <CENTER>
  end_of_html

###########################################################################
#                     Perform the Search (Delete)                         #
###########################################################################

# Then, begin searching the database by using the subroutine
# search_database which can be found at the end of this script.  We'll
# pass the subroutine one parameter, "delete" so that the subroutine knows
# how to output the results of the search. 

  &search_database ("delete");

# Finally, print up a list of hits in a table format.  $search_results,
# returned from &search_database, contains all of the hits already in the
# form of table rows.  The client will then be able to choose which item
# to delete and actually delete it with the  
# "if ($form_data{'submit_deletion'} ne "")" routine below

  print "<TABLE BORDER = \"1\" CELLPADDING = \"4\" CELLSPACING = \"4\">";

  print &table_header ("Delete<BR>Item");
  print &table_header (@field_names);
  print "</TR>\n";
  print "$search_results";

  print <<"  end_of_html";
  </TABLE><P>
  <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
  <INPUT TYPE = "hidden" NAME = "session_file"
         VALUE = "$session_file">
  <INPUT TYPE = "submit" NAME = "submit_deletion"
         VALUE = "Submit Deletion">
  <INPUT TYPE = "submit" NAME = "return_to_frontpage"
         VALUE = "Return to Frontpage">
  </CENTER></FORM></BODY></HTML>
  end_of_html

  exit;
  }

###########################################################################
#                     Print out Search Form (Modify).                     #
###########################################################################

# Okay, now we need to do the same thing, but for modification.

  if ($form_data{'search_form_modify'} ne "")
    {

# Pass them through security as usual.

    ($session_file, $session_username, $session_group,
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

    chop $session_email;

# Print up the familiar page header.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Query Database for Modification - 
    $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Query Database for Modification - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    end_of_html

# Now create the input form using the subroutine create_input_form at the
# end of this script.

    &create_input_form;

# Plop in the footer just as we did for delete above.

    print <<"    end_of_html";
    <TH>Exact Match?</TH><TD>
    <INPUT TYPE = "checkbox" NAME = "exact_match" CHECKED>
    </TD></TR></TABLE><P>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file"
           VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "search_database_modify"
           VALUE = "Submit Search Term">
    <P><BLOCKQUOTE>To get a full view of database, submit \"no\"
    keywords.  But beware, if there are too many items in your database,
    you will exceede the memory of your browser.
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

###########################################################################
#              Print out Search Results HTML Header (Modify).             #
###########################################################################

# Okay, just as we did for delete above, let's print out the results of
# the query for modification.

  if ($form_data{'search_database_modify'} ne "")
    {

# Pass them through security

    ($session_file, $session_username, $session_group, 
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

  chop $session_email;

# Then, conduct the search and print out the results.  First, we'll print
# out the page header using the same subroutine calls that we used above.

  print <<"  end_of_html";
  <HTML><HEAD><TITLE>Modifying an Item in the Database - 
  $database</TITLE></HEAD>
  <BODY>
  <CENTER><H2>Modifying an Item in the Database - $database</H2></CENTER>
  <FORM METHOD = "post" ACTION = "$database_manager_script_url">
  <CENTER>
  end_of_html

###########################################################################
#                     Perform the Search (Modify)                         #
###########################################################################

# First, begin searching the database using the subroutine search_database
# at the end of the script just as we did for delete. 

  &search_database ("modify");

# Next, print up a list of hits in a table format.  $search_results,
# returned from &search_database, contains all of the hits already in the
# form of table rows.

  print "<TABLE BORDER = \"1\" CELLPADDING = \"4\" CELLSPACING = \"4\">";
  print "<TH>Modify<BR>Item</TH>";

  print &table_header (@field_names);

  print "</TR>\n";
  print "$search_results";
  print "</TABLE><P>";

# Then, print out the same form that we used for the Add an Item form with
# the subroutine &create_input_form below.  

# Thus, the client will be able to specify an item to modify in the table 
# above and then type in new information with which to update in the form 
# inputs below.

    &create_input_form;

# Finally, print up the usual footer as well.

    print <<"    end_of_html";
    </TABLE><CENTER><P>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file"
           VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "submit_modification"
           VALUE = "Submit Modification">
    <INPUT TYPE = "submit" NAME = "return_to_frontpage"
           VALUE = "Return to Frontpage">
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

###########################################################################
#                     Print out Search Form (View).                       #
###########################################################################

# Here we find yet another similar routine, this time just to view the
# database.  First, print out the header.

  if ($form_data{'search_form_view'} ne "")
    {

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Classified Ad Search Engine - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Classified Ad Search Engine - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    <TABLE BORDER = "1" CELLSPACING = "4" CELLPADDING = "4">
    end_of_html

# Next we'll need to create an HTML form so that the client can submit
# keywords with which to search.  Thus, we must have one input field for
# each field in the database (except for database id and time fields which
# are set by this script and not by the administrator).  We'll get the
# list of database fields from the @field_names array defined in the
# setup file, and for every element in the array, create an input field.  

# However, we'll need to send the
# &build_input_form subroutine a few things: the Name of the field, the
# variable to be associated with that name, and the type of input we are
# going to use (ie: textarea, text, select).  Also, we don't want to send 
# it Price or Time of submission, because we will create new input boxes 
# for these based on maximum acceptable prices and minimum etc...  Pay 
# close attention to this if you are going to add other weird search 
# features, here is the first occurance of a special customizing area.

# First, take the id and time variables out of the @field_names array so
# that they will not have headers printed up.

    $id = pop (@field_names);
    $time = pop (@field_names);

# Then use build_input_form in cgi-lib.sol to create a form input field
# for every client defined database field.

    foreach $field_name (@field_names)
      {
      if ($field_name ne "Price")
        {
        if ($field_name ne "Time of Submission")
          {
           print &build_input_form("$FIELD_ARRAY{$field_name}",
                                   "$FORM_COMPONENT_ARRAY{$field_name}",
                                   $field_name);
          }
        } # End of if ($field_name ne "Price")
      } # End of foreach $field_name (@field_names)

# Next, add in the special new search boxes as well.  In 
# the .setup file for each database is a variable called $price.  If this 
# is set to yes, it means that you want the client to be able to search 
# this type of database by price. 

    if ($price eq "yes")
      {
      print <<"      end_of_html";
      <TH>Highest Acceptable Price</TH>
      <TD><INPUT TYPE = "text" NAME = "price.high" SIZE = "35" 
                 MAXLENGTH = "35">
      </TD></TR><TR>
      <TH>Lowest Acceptable Price</TH>
      <TD><INPUT TYPE = "text" NAME = "price.low" SIZE = "35" 
                 MAXLENGTH = "35" VALUE = "0.00">
      </TD></TR><TR>
      end_of_html
      }

# Add in a similar search box to allow users to search by database row age
# Then, add a form input for "exact  match" and the form, body and html
# ending tags.

    print <<"    end_of_html";
    <TH>Posted within how many days</TH>
    <TD><INPUT TYPE = "text" NAME = "num_days_ago" SIZE = "35" MAXLENGTH =
    "35" VALUE = "30">
    </TD></TR><TR>
    <TH>Exact Match?</TH>
    <TD><INPUT TYPE = "checkbox" NAME = "exact_match" CHECKED></TD>
    </TR></TABLE><P>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file" VALUE = "$session_file">    
    <INPUT TYPE = "submit"  NAME = "search_database_view"
           VALUE = "Submit Search Parameters">
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

###########################################################################
#              Print out Search Results HTML Header (View).               #
###########################################################################

# Search the database for the client to view.  This is all exactly the
# same as we've done above.

  if ($form_data{'search_database_view'} ne "")
    {
    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Viewing the Database - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Viewing the Database - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    end_of_html

###########################################################################
#                     Perform the Search (View)                           #
###########################################################################

# Now begin searching the database.  But this time, send the subroutine a
# parameter of "none" because we do not want any radio buttons in the
# resulting table.  There will be no items to select since all the client
# wants to do is view the database.

  &search_database ("none");

# Finally, print up a list of hits in a table format.  

  print <<"  end_of_html";
  <TABLE BORDER = "1" CELLPADDING = "4" CELLSPACING = "4">
  end_of_html

  print &table_header (@field_names);
  print "</TR>\n";
  print "$search_results";

  print <<"  end_of_html";
  </TABLE><CENTER><P>
  <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
  <INPUT TYPE = "hidden" NAME = "session_file"
         VALUE = "$session_file">
  <INPUT TYPE = "submit" NAME = "search_form_view"
         VALUE = "View $database Ads">
  <INPUT TYPE = "submit" NAME = "add_form" VALUE = "Submit an Ad">
  <INPUT TYPE = "submit" NAME = "search_form_delete"
         VALUE = "Delete Your Ad">
  <INPUT TYPE = "submit" NAME = "search_form_modify"
         VALUE = "Modify Your Ad">
  <INPUT TYPE = "submit" NAME = "return_to_frontpage"
         VALUE = "Return to Frontpage">
  </CENTER></FORM></BODY></HTML>
  end_of_html
  exit;
  }

#############################################################################
#                      Adding to the Database                               #
#############################################################################

# Next we will add the routine which the script can use to add a new item
# to the database.

  if ($form_data{'submit_addition'} ne "")
    {

# Pass them through security

    ($session_file, $session_username, $session_group,
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

  chop $session_email;

# In the case of an add, we'll have to assign the new database entry a 
# unique database ID number.  We'll do so by accessing the counter file 
# which keeps track of the last database id number used.  The counter 
# subroutine is located in cgi-lib.sol and will send us back a new 
# (incremented by one) number and then adjesut the counter file 
# appropriately.  The unique ID nmumber is essential for modifying the 
# database.  The counter routine takes one parameter, the location of the
# counter file.

    &counter($counter_file);

# Now, slip the id value into the %form_data associative array so that the
# following routine will add it to the new database row along with all the
# other information

    $form_data{'id'} = "$item_number";

# Take the incoming form data and format it the way our database is set 
# up to understand (ie: delimited by | and ending with a new line).  Make 
# sure to substitute new lines and line breaks with the corresponding HTML 
# so that they will be displayed correctly.  And, take out any occurances 
# of | which, if entered as part of the data would screw up our ability to 
# read the database, because there wouold appear to be too many fields in 
# the eyes of the script.

    foreach $field (@field_names)
      {
      $value = "$FIELD_ARRAY{$field}";
      $form_data{$value} =~ s/\n/<BR>/g;
      $form_data{$value} =~ s/\r\r/<P>/g;
      $form_data{$value} =~ s/\|/~~/g;

# Also, we want to format the price so that it can later be compared 
# numerically.  This means we want to trake out any $ or , that the client 
# submitted as well as any words like "or best offer" ([a-zA-Z]) or spaces 
# (\s).

      if ($field eq "Price" || $field eq "Cost (per month for rentals")
        {
        $form_data{$value} =~ s/\$//g;
        $form_data{$value} =~ s/[a-zA-Z]//g;
        $form_data{$value} =~ s/,//g;
        $form_data{$value} =~ s/\s//g;
        }

# Also, just to make the table presentation nice, let's substitute any 
# balnk fields with <CENTER>-</CENTER> so that when the table is displayed, 
# it won't have that ugly empty cell look to it.

      if ($form_data{$value} eq "")
        {
        $form_data{$value} = "<CENTER>-</CENTER>";
        }

# Finally, create and then append $new_row with the value, thus creating 
# a database row like field1|field2|field3|...

      $new_row .= "$form_data{$value}|";
      } # End of foreach $field (@field_names)

    chop $new_row; # take out the last |

# Now create a lockfile while we edit our database file.  The reason that
# we do this is so that if two people are trying to edit the datafile at
# one time, one person will not destroy the modifications made by the
# other person.  We'll create the lock file using the subroutine
# GetFileLock in cgi-lib.sol, passing it one parameter, the location of
# the lock file used by this program.  You should definitely not create
# the lock file yourself...

    &GetFileLock ("$lock_file");

# Then, open the database for appending (>>).

    open (DATABASE, ">>$data_file") || &open_error($data_file);
    print DATABASE "$new_row";
    print DATABASE "\n";
    close (DATABASE);

# Now close the $lock_file and delete it so that others may access the 
# data_file.

   &ReleaseFileLock ("$lock_file");

# Finally, send back a note to the client that they successfully added an
# item to the database.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Item Added to the Database - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Item Added to the Database - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file"
           VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "search_form_view"
           VALUE = "View $database Ads">
    <INPUT TYPE = "submit" NAME = "add_form" VALUE = "Submit an Ad">
    <INPUT TYPE = "submit" NAME = "search_form_delete"
           VALUE = "Delete Your Ad">
    <INPUT TYPE = "submit" NAME = "search_form_modify"
           VALUE = "Modify Your Ad">
    <INPUT TYPE = "submit" NAME = "return_to_frontpage"
           VALUE = "Return to Frontpage">
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

#############################################################################
#                      Deleting from the Database                           #
#############################################################################

# Now, it is time to actually make a deletion from the database.

  if ($form_data{'submit_deletion'} ne "")
    {

# Pass them through security first.

    ($session_file, $session_username, $session_group,
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

  chop $session_email;

# Open up the database and begin reading it one line at a time.

    open (DATABASE, "$data_file") || &open_error($data_file);
    while (<DATABASE>)
      {

# If this is a comment line, let's just add it straight to our $new_data 
# variable.  This variable will be used to stroe the databse rows that we 
# want printed to the database.

      if ($_ =~ /^COMMENT:/)
        {
        $new_data .= "$_";
        }

# If it is not a comment row, however, split up the row by database 
# fields and pop out the item id which should be the last field in the row.

      else
        {
        @fields = split (/\|/, $_);
        $item_id = pop(@fields);

# If the item id does not match the one submitted byt the client, go 
# ahead and add it to our $new_data variable.  If it is the same, it will 
# not be added to $new_data and thus, will be deleted by default.

        unless ($item_id eq "$form_data{'delete'}")
          {              
          $new_data .= "$_";
          }
        } # End of else
      } # End of while (<DATABASE>)

# Now close up the database, open a lock file as we did for the add 
# routine above and create a temp file containing all the rows we dumped 
# into $new_data.

    close (DATABASE);

    &GetFileLock ("$lock_file");

    open (TEMPFILE, ">$temp_file") || &open_error($temp_file);
    print TEMPFILE "$new_data";
    close (TEMPFILE);

# Then copy the temp file over the old database fiel, thereby deleting 
# the entry, since it was not added to the temp file.  Then release the 
# lock file so someone else may use it.

    rename ($temp_file, $data_file);
    &ReleaseFileLock ("$lock_file");

# Finally, print up the usual footer.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Your Item has been deleted - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Your Item has been deleted - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file"
           VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "search_form_view"
           VALUE = "View $database Ads">
    <INPUT TYPE = "submit" NAME = "add_form" VALUE = "Submit an Ad">
    <INPUT TYPE = "submit" NAME = "search_form_delete"
           VALUE = "Delete Your Ad">
    <INPUT TYPE = "submit" NAME = "search_form_modify"
           VALUE = "Modify Your Ad">
    <INPUT TYPE = "submit" NAME = "return_to_frontpage"
           VALUE = "Return to Frontpage">
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    }

#############################################################################
#                 Modifying an Item in the Database                         #
#############################################################################

# Finally we will need to take care of any modifications asked of us.

  if ($form_data{'submit_modification'} ne "")
    {

# Pass them through security as usual.

    ($session_file, $session_username, $session_group,
     $session_first_name, $session_last_name, $session_email) =
     &GetSessionInfo($session_file, $database_manager_script_url,
     *form_data);

# Take off the newline character for the last member in the array.

  chop $session_email;

# Now let's modify an item.  However, let's make sure they clicked one of 
# the radio buttons on the modification table otherwise we won't be able to 
# know which item they want modified. $form_data{'modify'} should equal
# the database id number of the item they want modified.

    if ($form_data{'modify'} eq "")
      {
      print <<"      end_of_html";
      <HTML><HEAD><TITLE>Modifying an Item in the Database - 
      $database</TITLE></HEAD>
      <BODY>
      <CENTER><H2>Modifying an Item in the Database - $database</H2></CENTER>
      <BLOCKQUOTE>
      I'm sorry, I was not able to modify the database because none of
      the radio buttons on the table was selected so I was not sure which
      item to modify.  Would you please make sure that you select an item
      "and" fill in the new information.  Please hit the back
      button and try again.  Thanks.
      </BLOCKQUOTE>
      end_of_html
      exit;
      }

# Next, open the database and read through one line at a time and add the 
# comment lines as we did for deletion to $new_data

    open (DATABASE, "$data_file") || &open_error($data_file);
    while (<DATABASE>)
      {
      if ($_ =~ /^COMMENT:/)
        {
        $new_data .= "$_";
        }

# If the line is not a comment line however, we need to pop out the 
# item_id as we did for deletion, but this time, we also want to push it 
# back into the array again after we have read it because we still want 
# to have the id in the row when we are all done...

      else
        {
        @fields = split (/\|/, $_);
        $item_id = pop(@fields);
        push (@fields, $item_id);

# If the item id equals the one submitted by the client, we are going to 
# create a new array, @old_fields equal to the current fields in the row.
 
        if ($item_id eq "$form_data{'modify'}")
          {
          @old_fields = @fields;
          }

# If not, just add the row to the database and close the database.  By 
# the end, we'll have copied every line in the database to $new_data 
# except for the item that will be modified, but we have saved that 
# line in the @old_fields array.

        else
          {              
          $new_data .= "$_";
          }
        } # End of else
      } # End of  while (<DATABASE>)

     close (DATABASE);

# Now initialize a few new variables.  $new_line is going to contain the 
# modified database row and $counter will be used to count database 
# fields in the row.

    $counter = 0;
    $new_line = "";

# Then, go through each of the fields in @field_values 
# which is a list containing each of the database fields as defined in 
# the setup file.

    until ($counter >= @field_values)
      {

# For each field, initialize the variable $value and set it equal to an 
# incremented field according to the current value of counter.

      $value = "";
      $value = "$field_values[$counter]";

# If that field, as represented by the form input is equal to zero (the 
# client did not wish to modify that field) then we will take the old value 
# (as stroed in the @old_fields array and add it to $new_line appending a | 
# at the end to denote the end of the field.

      if ($form_data{$value} eq "")
        {
        $new_line .= "$old_fields[$counter]|";
        }

# On the other hand, if the user did want to edit that field, let's format 
# the incoming data as we did for the add routine above and add the new
# data to $new_line.  

      else
        {
        $form_data{$value} =~ s/\n/<BR>/g;
        $form_data{$value} =~ s/\r\r/<P>/g;
        $form_data{$value} =~ s/\|/~~/g;

        if ($field eq "Price" || $field eq "Cost (per month for rentals")
          {
          $form_data{$value} =~ s/\$//g;
          $form_data{$value} =~ s/[a-zA-Z]//g;
          $form_data{$value} =~ s/,//g;
          $form_data{$value} =~ s/\s//g;
          }

        if ($form_data{$value} eq "")
          {
          $form_data{$value} = "<CENTER>-</CENTER>";
          }

        $new_line .= "$form_data{$value}|";
        } # End of else
      $counter++;
      } # End of until ($counter >= @field_values)
    chop $new_line; # Take off the final |

# Now open up the tempfile and print the $new_data lines and then the 
# modified database line contained in $new_line.  Then close the temp file, 
# copy the temp file over the old database file and release the lock.

    &GetFileLock ("$lock_file");
    open (TEMPFILE, ">$temp_file") || &open_error($temp_file);
    print TEMPFILE "$new_data";
    print TEMPFILE "$new_line";
    close (TEMPFILE);
    rename ($temp_file, $data_file);
    &ReleaseFileLock ("$lock_file");

# Now print up the usual footer.

    print <<"    end_of_html";
    <HTML><HEAD><TITLE>Your Item has been Modified - $database</TITLE></HEAD>
    <BODY>
    <CENTER><H2>Your Item has been Modified - $database</H2></CENTER>
    <FORM METHOD = "post" ACTION = "$database_manager_script_url">
    <CENTER>
    <INPUT TYPE = "hidden" NAME = "database" VALUE = "$form_data{'database'}">
    <INPUT TYPE = "hidden" NAME = "session_file"
           VALUE = "$session_file">
    <INPUT TYPE = "submit" NAME = "search_form_view"
           VALUE = "View $database Ads">
    <INPUT TYPE = "submit" NAME = "add_form" VALUE = "Submit an Ad">
    <INPUT TYPE = "submit" NAME = "search_form_delete"
           VALUE = "Delete Your Ad">
    <INPUT TYPE = "submit" NAME = "search_form_modify"
           VALUE = "Modify Your Ad">
    <INPUT TYPE = "submit" NAME = "return_to_frontpage"
           VALUE = "Return to Frontpage">
    </CENTER></FORM></BODY></HTML>
    end_of_html
    exit;
    } # End of if ($form_data{'submit_modification'} ne "")

#############################################################################
#                               &require                                    #
#############################################################################

# Now that we have made our way through all of the main routines, we are
# ready for our library of subroutines.

# require checks to see whether the file that we are trying to 
# require actually exists and is readable by us.  The reason for this 
# subroutine is to provide the developer with an informative error message 
# when attempting to debug the scripts.

sub require
  {

# Define $require_file as a local variable and set it equal to the 
# filename we sent when we called this routine.

  local (@require_files) = @_;

# Check to see if the file exists and is readable by us.  If so, go ahead 
# and require it.

  foreach $file (@require_files)
    {
    if (-e "$file" && -r "$file")
      {
      require "$file";
      }

# If not, send back an error message that will help us isolate the 
# problem with the script.

    else
      {
      print "I'm sorry, I was not able to open $require_file.  Would you
             please check to make sure that you gave me a valid filename
             and that the permissions on $require_file are set to allow me
             access?";
      exit;
      }
    }
  }


# create_input_form is used to generate the input forms that the client
# will use to input new data for an add or keywords for a search.

  sub create_input_form
    {

# First print out the a table header. 

    print "<TABLE BORDER = \"1\" CELLPADDING = \"4\" 
            CELLSPACING = \"4\">";

# Now we'll need to create an HTML form so that administrators can add 
# items to the database.  Thus, we must have one input field for each field 
# in the database (except for database id field which is set by this script 
# and not by the administrator).  We'll get the list of database fields 
# from the @field_names array and for every element in the array, create an 
# input field.  However, we'll need to send the &build_input_form 
# subroutine a few things: the Name of the field, the variable to be 
# associated with that name, and the type of input we are going to use 
# (ie: textarea, text, select)

    foreach $field_name (@field_names_user_defined)
      {
      $variable_name = $FIELD_ARRAY{$field_name};
      $form_type = $FORM_COMPONENT_ARRAY{$field_name};
      local ($input_form);
      $input_form = "";
      $input_form .= "<TR>\n";
      $input_form .= &table_header ("$field_name");
      $input_form .= "<TD>";
      $input_form .= &make_form_row ("$field_name", "$variable_name",
                                     "$form_type");
      $input_form .= "</TD></TR>\n";
      print  "$input_form";
      }
   } # End of sub create_input_form

# search_database is used to search the database for keyword matches.

  sub search_database
    {

# First, we will assign to the local variable $submit_type the value sent
# to us from the main routine.  This wil be either modify, delete or in
# the case of a view search, none.

    local($submit_type) = @_;

# Next, open the database file and begin checking each field in every row
# against the keywords submitted.

    open (DATABASE, "$data_file")  || &open_error($data_file);
    while (<DATABASE>)
      {
      $database_row = $_;

# Make sure to disregaurd any line that is a database comment line.

     unless ($database_row =~ /^COMMENT:/)
       {

# Set $did_we_find_a_match = no to make sure that it has not been initialized
# elsewhere.  The $did_we_find_a_match variable will be used to keep track of
# whether or not a hit was made based on the client submitted keyword. If
# a match was found, the variable is going to equal yes, but more on that
# in a bit...

     $did_we_find_a_match = "no";

# Split up the database row into the @row array and create sopme variables
# based on values specified in the setup file.

      @row = split(/\|/,$database_row);
      $row_price = "$row[$price_field_num]";
      $row_date = "$row[$date_field_num]";
      $last_name_field_number = "0";
      $row_last_name = "$row[$last_name_field_number]";
      ($month,$day,$year) = split (/-/, $row[$date_field_num]);

# Use the date.pl library to convert the row date into a julian date which
# we can use to compare to todays date and generate the number of days ago
# that the row was posted.

      $julian_day = &jday($month,$day,$year);
      ($today_month,$today_day,$today_year) = split (/-/, &get_date);
      $today = &jday($today_month,$today_day,$today_year);
      $posted_days_ago = ($today - $julian_day);

# Next, check to see if the client asked us to weed out by price or age.
# Note, the if tests will pass if the user did not submit any
# pruning value.

      if (($row_price <= $form_data{'price.high'} || 
	  $form_data{'price.high'} eq "")
          &&
          ($row_price >= $form_data{'price.low'} ||
          $form_data{'price.low'} eq "")
          &&
          ($form_data{'num_days_ago'} >= $posted_days_ago ||
	    $form_data{'num_days_ago'} eq ""))
        {

# For each key in the %form_data associative array, set $field_number =
# -1.  The reason that we want to do this is because we have both the
# pesky "submit" and "exact match" key/value pairs possibly coming in
# along with the rest of the form data.  We do not want our script to search
# the database for those fields because they don't exist!  By setting
# $field_number = -1, we'll be able to filter out such non field keys with
# the following routine.

      foreach $form_data_key (keys %form_data)
        {
        $field_number = -1;

# Now we will go through the fields in the database (@field_values),
# checking to see if there is a corresponding value coming in from the
# form ($form_data_key).  However, because arrays are counted from 0
# rather than from one, and because @field_values gives us a count of
# the array starting at one, we need to offset our counter by one.
# Thus, if the form "key" submitted is indeed a field in the database,
# $field_number ($y - 1) will be its actual location in the array.

        for ($y = 1; $y <= @field_values; $y++)
          {
          if ($form_data_key eq @field_values[$y-1] &&
              $form_data{"$form_data_key"} ne "")
            {
            $field_number = $y - 1;
            last; # Exit out of the for loop because we have verified field
            }
          } # End of for ($y = 1; $y <= @field_values; $y++)

# Now, we need to check the submitted value against the value in the
# database.  However, we need to make sure that the value is not "on" or
# "submit keyword".  If $field_number is still equal to -1, that means
# that we did not match the form data key against an actual database field
# so we should try the next key.  Otherwise, we know that we have a valid
# field to check against.  Again, $field_number must be <= -1 because of
# the array starting from 0.

        if ($field_number > -1)
          {

# Now perform the match, checking the database information against the
# submited keyword for that field.  First let's perform an exact
# match test.  If $form_data{'exact_match'} ne "on" it means that the exact
# match check box was not checked.  The match is pretty straight forward.
# If the keyword string ($form_data{"$form_data_key"}) matches (=~) a
# string in the field were searching ($row[$field_number]) case
# insensiitively (/i), then we know we got a hit!

          if ($form_data{'exact_match'} ne "on")
            {
            if ($row[$field_number] =~ /$form_data{$form_data_key}/i)
              {

# However, before we get too excited, let's make sure that they are either
# an administrator (and are allowed to see all rows), or the row they got
# a hit on is actually a row that they initially enetered and that this is
# not a general view request.  I think the first to are obvious, but the
# reason for the last test is because if the client is asking to view, we
# don't care if they entered the row or not...we want them to see
# everything. Only in the case of modify and delete do we want the extra
# level of filtering.

              if (($session_group eq "admin" ||
              $row_last_name eq "$session_last_name") &&
	      $submit_type ne "none")
                {
                $did_we_find_a_match = "yes";
                last; # Exit out of ForEach keys in FormData
                }

# However, we must also handle the case that this is a view.  It is
# basically the same routine, but covers whatever was left by the if test 
# above.

              if ($submit_type eq "none")
		{
		$did_we_find_a_match = "yes";
                last; # Exit out of ForEach keys in FormData
		}
              } # End of if (@row[$field_number]....
            } # End of if ($form_data{'exact_match'} eq "")

# On the other hand, the client may have clicked the exact match
# checkbox...

# This time, we'll proceede with an exact match using the \b though
# keeping it case insensitive (/i).  The same $did_we_find_a_match setting 
# and if tests will apply as above.

          elsif ($row[$field_number] =~ /\b$form_data{$form_data_key}\b/i)
            {
            if (($session_group eq "admin" ||
            $row_last_name eq "$session_last_name") &&
            $submit_type ne "none")
              {
              $did_we_find_a_match = "yes";
              last; # Exit out of ForEach keys in FormData
              }
            if ($submit_type eq "none")
              {
              $did_we_find_a_match = "yes";
              last; # Exit out of ForEach keys in FormData
              }
            } # End of elsif ($row[$field_number]....
          } # End of if ($field_number > -1)
        } # End of foreach $form_data_key (keys %form_data)

# Now, if we have found a match ($did_we_find_a_match equals "yes"), we
# need to create a table row for the output.  We'll create a variable
# called $search_results which is going to collect all of the hits
# formatted as table rows for the output.  A hit will add each of the
# fields of the database row to a table row.  We'll also create a variable
# called $hit_counter just to remind us that we got a hit.  If
# $hit_counter is never set to one, we will know that we need to let the
# client know that their keyword turned up nothing.

        if ($did_we_find_a_match eq "yes")
          {
          $search_results .= "<TR>";
          $hit_counter = "1";

# Gather the database id row number so we can use it, then put it back in
# the @row array.

          $db_id_number = pop (@row);
          push (@row, $db_id_number);

# Now begin creating the HTML outputted database rows.  If this is not a
# view, and it is a row which satisfies security, we will need to create a
# first column for the radio button which we will use to select a
# database row to modify or delete.

	  if (($session_group eq "admin" || 
	      $row_last_name eq "$session_last_name")
              &&
              ($submit_type ne "none"))
            {
            $search_results .= "<TD ALIGN = \"center\">\n";
            $search_results .= "<INPUT TYPE = \"radio\" 
				       NAME = \"$submit_type\"
			               VALUE = \"$db_id_number\">";
            $search_results .= "\n</TD>\n";
            } # End of if ($session_group eq "admin" ||....

# Now, fill in the HTML database table row.  In the case of viewing, we
# will add every row, and in the case of modification and deletion, we
# will only give them the appropriate rows.

          foreach $field (@row)
            {
            if ($submit_type eq "none")
              {
              $search_results .= "<TD>$field</TD>\n";
              }
            elsif ($row_last_name eq "$session_last_name" || 
	           $session_group eq "admin")
              {
              $search_results .= "<TD>$field</TD>\n";
              }
            } # End of foreach $field (@row)
          $search_results .= "</TR>\n";
          } # End of if ($did_we_find_a_match eq "yes")....
        } # End of  if (($row_price <= $form_data{'price.high'}....
      } # End of unless ($database_row =~ /^COMMENT:/)
    } # End of while (<DATABASE>)

    close (DATABASE);

# Now let's add a routine to handle the possibility that a client
# submitted keyword turns up nothing in the search. At this point, if
# $hit_counter is not equal to 1, it means that the search never turned
# up a hit.  Thus we'll send back a note to the client with a link back to
# the search form.  Notice that we'll use a hyperlink rather than a submit
# button because we want the client to access this script with out a
# CONTENT_LENGTH so that the form will pop up.  Also, we'll exit the
# routine here if no hits were found because we do not want to print up an
# empty table.

    if ($hit_counter ne "1")
      {
      print "I'm sorry, I was unable to find a match for the
             keyword(s) that you specified in a database row that you
             are authorized to see.  Feel free to
             <A HREF = \"class_ad.cgi\">try again</A>";
      print "</CENTER></BODY></HTML>";
      exit;
      }
    } # End of sub search_database

#######################################################################
#                            get_date                                 #
#######################################################################

  sub get_date
    {

   @days = ('Sunday','Monday','Tuesday','Wednesday','Thursday',
            'Friday','Saturday');
   @months = ('January','February','March','April','May','June','July',
              'August','September','October','November','December');

# Use the localtime command to get the current time, splitting it into
# variables.

   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);

# Format the variables and assign them to the final $date variable.

   if ($hour < 10) { $hour = "0$hour"; }
   if ($min < 10) { $min = "0$min"; }
   if ($sec < 10) { $sec = "0$sec"; }

   $date = "$mon-$mday-19$year";
   }