#!/usr/local/bin/perl # Name: form_processor.cgi # # Version: 2.0 # # Last Modified: 5-16-96 # # Copyright Information: This script was written by Selena Sol # # Description: This form processing script allows a site # administrator to process multiple HTML forms with one script. By # taking advantage of various hidden tags which this script can # understand, the admin can use this one script to process all of her # scripts in multiple ways from dynamic email to building a database. # # Usage: This script should be placed in a directory from which the web # server is allowed to execute cgis. It should also have its # permissions set appropriately. # # Accompanying this script should be two supporting files called # cgi-lib.pl and mail-lib.pl which will be used to parse the form # variables and handle emailing. They should be kept in the same # directory as this script (or in the cgi library preferrably) and # be readable by the web server. # # Before you run this script, you need to prepare your HTML forms to send # enough information so that this script can be most efficient. # Specifically, you must send some information as hidden variables along # with the client-defined information. # # This script takes 17 hidden variables # # mailto - The email address of the person who should receive the results # of form submission. This field is REQUIRED. # html_response - This is the text of the HTML response that you would # like the client to receive after she submits her information. This # is not required, but a good idea. # email_subject - is the subject that you want to appear on the email # sent to the person who will receive the results of form submission. # This is not requied, but a good touch. # variable_order - is the order that you want all of the variables to # appear on the email sent to the person who will receive the results of # form submission. The format of this tag is a pipe delimited list # and every input field in your form MUST be represented in the list # (see example below) This is a REQUIRED field. # required_variables is a list of variables that are required. That is, # if the client does not fil out information for those input fields, she # should get an error message requesting that she go back and fill out # all the forms. This field is not required. # url_of_this_form is the url of the form that is being used to submit # information so that if the user does not submit all the required # fields, they can link back to the form to try again. Not required # background, bgcolor, text_color, link_color, vlink_color and alink_color # all relate to the body tag for all of the HTMl responses. None of # them are required but what is the good of GUI without graphics! # response_title is the title that you want to appear on the HTML # response for successes. Not required, but suggested # return_link_url is the url of the page that you want people to click on # from the HTML response page after they have submitted their # information. Not required, but suggested. # return_link_name is the text of the clickable link related to # return_link_url. Not required, but suggested # database_name is the path (relative to this script) of the data file # which is being used to store information submitted by this form. # database_delimiter is the delimiter your database uses to divide # fields. Common ones are , or : or | # # These hidden variables define how this script needs to perform...who it # should email, how to order the variables in the email message, how to # respond to the client, etc... # # Here is an example of a very short form # # Test Form #
# # # # # # # # # # # # # # # # # # #

Name (Required):
# # #

Email (Required):
# # #

Astrological Sign:
# # #

Purpose in Life:
# # #

# #
#
# In this example, the script will email selena@eff.org when someone # submits form data. It will use "Form Test (From Scripts Page)" as the # subject of the email, and return the client a little blurb with a # pointer back to Selena Sol's Script Archive. # # In the body of the email messsage it will print out the variables and # their client-defined values in the specific order name, email, sign, # and purpose of life. # I'll explain more about how the script determines the order later, but # I want to draw your attention to the way the order is predefined in the # HTML form. It is pipe delimited and all variables MUST appear in the # order you want them to be processed. ####################################################################### # Begin Processing the Form. # ####################################################################### # First, print out the HTTP header. We'll output this quickly so that we # will be able to do some of our debugging from the web and so that in # the case of a bogged down server, we won't get timed-out. print "Content-type: text/html\n\n"; ####################################################################### # Set server specifc variables. # ####################################################################### # $email_of_sender is the email address of the account from which mail # should be sent to the admin. This is only required if you have not # used a $client_email variable in your form. $email_of_sender = "email\@email.net"; # $your_server_name is the name of your web server. We will use this value # to make sure that the form that is using this script is actually on your # server...we wouldn't want everyone in the universe using your server for # form processing :) If you are not sure what this is...it is probably # the "www.foobar.com" in your URL address. This is only required if you # want the greater security $your_server_name = "www.spectro.net"; # $restricted_use is a flag that we will use to activate the above # security. If you set this to no, it means that this script will process # forms from any server on the net. This is only required if you # want the greater security $restricted_use = "no"; # $location_of_cgi-lib and $location_of_mail_lib are the locations of # the library files that should accompany this script. $location_of_cgi_lib = "/library/cgi-lib.pl"; $location_of_mail_lib = "/library/mail-lib.pl"; # $should_i_mail and $should_I_append_a_database are flags which you can # set depending on how you want the results of the form processing to be # gathered. By setting $should_i_mail = "yes" the form data will be sent # to the admin who you have already defined in above variables. If you set # $should_I_append_a_database = "yes" then the form information will be # saved in a database that you can import to whatever database you use. # The name of the database are defined with hidden variables as are the # database delimiter... $should_i_mail = "yes"; $should_I_append_a_database = "yes"; ####################################################################### # Require Libraries and Parse Form Data # ####################################################################### # Use cgi-lib.pl to read the incoming form data. However, send form_data # as a parameter to the subroutine &ReadParse in cgi-lib.pl so that the # associative array of form keys/values comes back with a descriptinve # name rather than just $in. Also require the library which we will use # to send out mail using sendmail require "$location_of_cgi_lib"; &ReadParse(*form_data); require "$location_of_mail_lib"; ####################################################################### # Security Test # ####################################################################### # Next let's figure out where the form that is requesting our attention # is located. We'll do this by accessing the environment variable # $ENV{'HTTP_REFERER'} which is equal to the url of the form in question # (ie: http://www.foobar.com/Feedback/feedback.html). We are going to take # that value and split it up into separate variables for every occurance of # "/". We do this in order to isolate www.foobar.com which we can compare # to the value of $your_server_name. Thus $referring_server is the # only varriable here we actually give a hoot about. If they are # not the same, the script # is being accessed by a form on another server. ($http, $empty, $referring_server, @path) = split (/\//, $ENV{'HTTP_REFERER'}); # Now if the $restricted_use has been set to yes, "and" the # $referring_server is not the same as $your_server_name it means that we # have had an illegal attempted access and we will deny the use of this # script. if ($restricted_use eq "yes") { if ($referring_server ne "$your_server_name") { &html_header("Form Error - Wrong Server"); print "I'm sorry, you are not allowed to use this form processing script from a server other than $your_server_name

"; print "As far as I can tell, you are coming from: $referring_server"; print "

$restricted_use = restrictered use
"; print ""; exit; } } ####################################################################### # Get Variable Order # ####################################################################### # Now break up the variable_order variable that was sent to us from the # form. It should look something like name|email|sign|purpose| and will # have been defined by whoever wrote the form which calls this script # We'll take that variable and split it into array elements everytime we # see a | so that @form_variables might look like ("name", "email", # "sign", "purpose"). @form_variables = split (/\|/, $form_data{'variable_order'}); ####################################################################### # Check Required Fields # ####################################################################### # Now let's do the same thing we did for variable order, but for required # variables. @required_variables = split (/\|/, $form_data{'required_variables'}); # Now that we have the list of required variables, let's check to make # sure that the client submitted values for each of those variables. If # the user did not, then they get a note explaining the problem and a list # of required variables so they won't do it again...asd well as a pointer # back to the form. If you edit this note, make sure to "escape" any # occurances of @ or " with a backslash (ie: # print "selena\@eff.org"; foreach $variable (@required_variables) { if ($form_data{$variable} eq "") { &html_header("Form Error - Missing Data"); print "Woops, I'm sorry, the following fields are required: "; print "

"; foreach $variable (@required_variables) { print "$variable
"; } # End of foreach $variable (@required_variables) print "
"; print "Please go back to the form and make sure you fill out all the required information."; print ""; exit; } # End of if ($form_data{$variable} eq "") } # End of foreach $variable (@required_variables) ####################################################################### # Email the Results to the Admin # ####################################################################### if ($should_i_mail eq "yes") { # If we have set the $should_i_mail to yes in the define variables area, # then we want to send the results of the form to some admin alos defined... # So break out the email address that was sent to us from the form into # both the email we should send the processed form data to as well as the # server which runs their email. Also, rename the Email Subject if ($form_data{'mailto'} ne "") { $email_to = "$form_data{'mailto'}"; } $email_subject = "$form_data{'email_subject'}"; # Then begin building the body of the email message that we will send. # We'll create a variables called $email_body which will store the # information that we are going to mail. First we'll note the time with a # little routine written by Matt Wright. Notice also the use of .= which # tells the script to append the new information to the end of the # old...thus $email_body just keeps getting longer and longer as new info # is tagged to the end of the old... $email_body = "This data was submitted on: "; $email_body .= &get_date; $email_body .="\n\n"; # For every form variable, we should add the variable name and their # values in the order specified by $form_data{'variable_order'}. foreach $variable (@form_variables) { $email_body .= "$variable = $form_data{$variable}\n"; } if ($form_data{'client_email'} ne "") { $email_of_sender = "$form_data{'client_email'}"; } # Now, use the send_mail routine in mail-lib.pl to send the data. The # send_mail routine takes 6 parameters, all of which have already been # defined and explained. &send_mail("$email_of_sender","$email_to", "$email_subject", "$email_body"); } # End of if ($should_i_mail eq "yes") ####################################################################### # Append a Database # ####################################################################### # If the $should_I_append_a_database has been set to yes, we will need to # append to the database specified in the hidden field database_name # specified in the form. if ($should_I_append_a_database eq "yes") { # Check to see if the Database actually exists! (-e) $database = "$form_data{'database_name'}"; if (-e $database) { # If the database actually exists, open it for appending >> and set the # $counter variable equal to zero...we will use the $counter variable to # keep track of the number of fields sent from the form so that we will # know when the database row actually ends. open (DATABASE, ">>$database"); $counter = "0"; # For every fields sent in from the form foreach $variable (@form_variables) { # Increment the counter by one. $counter++; # Append the value of the variable to the growing $database_row variable. $database_row .= "$form_data{$variable}"; # If this is not the last item in the row, we should also divide each # field with the database delimiter. When counter equals the number of # elements in @form_variables, then we will know that it is the end of the # row and we need not append another delimiter. if ($counter <= @form_variables) { $database_row .= "$form_data{'database_delimiter'}"; } } # End of foreach $variable (@form_variables) # Now append the database with the new row...and don't forget the newline # at the end of the row. print DATABASE "$database_row\n"; close (DATABASE); } # End of if (-e $database) # If the database file did not exist, however, we need to send an error # message back to the user. Most likely, the hidden form variable was not # correct (the path is wrong) or the permissions of the file or its # directory are not set to be read.writable by the web server. else { &html_header("Form Error - Database Does Not Exist"); print "I'm sorry, I am having trouble finding the database that this informatioon should be sent to. Please contact $form_data{'mailto'} and let them know that there has been a problem. Thank you very much."; print ""; exit; } } # End of if ($should_I_append_a_database eq "yes") ####################################################################### # Respond to the Client # ####################################################################### # Now print up a response to the client. &html_header($form_data{'response_title'}); print "$form_data{'html_response'}"; print "

You sent us the follwing data:

"; foreach $variable (@form_variables) { print "$variable = $form_data{$variable}
"; } print "

Please return to "; print "$form_data{'return_link_name'}"; print ""; print ""; exit; ####################################################################### # 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 = "$days[$wday], $months[$mon] $mday, 19$year at $hour\:$min\:$sec"; } ####################################################################### # html_header # ####################################################################### sub html_header { # Assign the title variable coming in from the subroutine call to the # local variable $title. local($title) = @_; # Print out the header. print "$title"; print "

$title
"; }