#!/usr/bin/perl
#############################################################
################## YFORM.CGI version 1.9 #################
#############################################################
# Modified Friday, 8/24/2001 Ashley Bass (abass@iname.com)
#
# Added Matt's v1.9 security updates. Fixed bug with '0' not accepted in required fields.
#
# This is a modified version of Donald E. Killen's xFormMail.cgi script
# which is itself a modified version of Matthew M. Wright's FormMail.pl script.
# As with their work, this script is made available freely to anyone who can use it.
# By using this code you agree to indemnify Ashley B. Bass from any liability that
# might arise from its use.
#
# FormMail.pl sends an email response from an HTML form to a specified email address.
# xFormMail.cgi sends a courtesy reply email to the person who filled out the form.
# YFORM.CGI further lets you
# 1) specify more options for email, courtesy reply, and HTML response page
# 2) chose whether or not to send the courtesy reply
# 3) chose whether or not to save all form submissions to a text file on your sever
#
# The places where I added/changed something are introduced by an "ASHLEY:" comment.
# See the YFORM.TXT file for a list of my added fields and instructions on their use. That same
# file contains the full readme information for FormMail.pl ver 1.6 as well.
#
# If you obtained this script without the reference materials that go with it, please DL the
# entire YFORM.ZIP archive currently available at www.fyi.net/~abass/domino/free.htm
# before emailing me with any questions. Therein you will find the YFORM.TXT file and
# a SAMPFORM.HTM file to build on. Thanks.
#
#############################################################################
# xFormMail.cgi Version 1.0 #
# Modifications Copyright (c) 1996 Donald E. Killen, All Rights Reserved. #
# This version of FormMail may be used and modified free of charge by anyone #
# so long as this copyright notice and the one below by Matthew Wright remain#
# intact. By using this code you agree to indemnify Donald E. Killen from any#
# liability arising from it's use. You also agree that this code cannot be #
# sold to any third party without prior written consent of both Don Killen #
# and Matthew M. Wright. #
##############################################################################
# FormMail Version 1.9 #
# Copyright 1995-2001 Matt Wright mattw@worldwidemart.com #
# Created 06/09/95 Last Modified 08/03/01 #
# Matt's Script Archive, Inc.: http://www.worldwidemart.com/scripts/ #
##############################################################################
# COPYRIGHT NOTICE #
# Copyright 1995-2001 Matthew M. Wright All Rights Reserved. #
# #
# FormMail may be used and modified free of charge by anyone so long as this #
# copyright notice and the comments above remain intact. By using this #
# code you agree to indemnify Matthew M. Wright from any liability that #
# might arise from its use. #
# #
# Selling the code for this program without prior written consent is #
# expressly forbidden. In other words, please ask first before you try and #
# make money off of my program. #
# #
# Obtain permission before redistributing this software over the Internet or #
# in any other medium. In all cases copyright and header must remain intact #
##############################################################################
# ACCESS CONTROL FIX: Peter D. Thompson Yezek #
# http://www.securityfocus.com/archive/1/62033 #
##############################################################################
# Define Variables
# Detailed Information found In YFORM.TXT File.
# $mailprog defines the location of your sendmail program on your unix
# system.
$mailprog = '/usr/lib/sendmail';
# @referers allows forms to be located only on servers which are defined
# in this field. This fixes a security hole in the last version which
# allowed anyone on any server to use your FormMail script.
# ASHLEY: Place 'file:///' in the list to allow you to test your forms from your
# PC without having to upload them to your sever every time you change them.
#@referers = ('fyi.net','sewickley.org');
@referers = ('fyi.net','sewickley.org','file:///');
# @recipients defines the e-mail addresses or domain names that e-mail can #
# be sent to. This must be filled in correctly to prevent SPAM and allow #
# valid addresses to receive e-mail. Read the documentation to find out how #
# this variable works!!! It is EXTREMELY IMPORTANT. #
@recipients = @referers;
# ACCESS CONTROL FIX: Peter D. Thompson Yezek #
# @valid_ENV allows the sysadmin to define what environment variables can #
# be reported via the env_report directive. This was implemented to fix #
# the problem reported at http://www.securityfocus.com/bid/1187 #
@valid_ENV = ('REMOTE_HOST','REMOTE_ADDR','REMOTE_USER','HTTP_USER_AGENT');
# Done #
##### END of variable declarations ####
# Check Referring URL
&check_url;
# Retrieve Date
&get_date;
# Parse Form Contents
&parse_form;
# Check Required Fields
&check_required;
# Send E-Mail
&send_mail;
# Courtesy E-Mail to Visitor
&send_courtesy;
# Return HTML Page or Redirect User
&return_html;
#ASHLEY
#Append Database
&appendit;
sub check_url {
# Localize the check_referer flag which determines if user is valid. #
local($check_referer) = 0;
# If a referring URL was specified, for each valid referer, make sure #
# that a valid referring URL was passed to FormMail. #
if ($ENV{'HTTP_REFERER'}) {
foreach $referer (@referers) {
# ASHLEY: The second line below allows you to test your forms from
# your pc without having to put them on your server if 'file:///'
# is listed in the referer variable above.
# if ($ENV{'HTTP_REFERER'} =~ m|https?://([^/]*)$referer|i) {
if ($ENV{'HTTP_REFERER'} =~ /$referer/i) {
$check_referer = 1;
last;
}
}
}
else {
$check_referer = 1;
}
# If the HTTP_REFERER was invalid, send back an error. #
if ($check_referer != 1) { &error('bad_referer') }
}
sub get_date {
# Define arrays for the day of the week and month of the year. #
@days = ('Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday');
@months1 = ('1','2','3','4','5','6','7','8','9','10','11','12');
@months2 = ('January','February','March','April','May','June','July',
'August','September','October','November','December');
# Get the current time and format the hour, minutes and seconds. Add #
# 1900 to the year to get the full 4 digit year. #
($sec,$min,$hour,$mday,$mon,$year,$year2,$wday) = (localtime(time))[0,1,2,3,4,5,5,6];
#$time = sprintf("%02d:%02d:%02d",$hour,$min,$sec);
$time = sprintf("%02d:%02d",$hour,$min);
$year2 += 1900;
# Format the date. #
$dater = "$days[$wday], $months2[$mon] $mday, $year2 at $time";
# ASHLEY: I use the short $date for the email and database, Matts' long one for HTML response #
$date = "$months1[$mon]/$mday/$year2";
}
sub parse_form {
# Define the configuration associative array. #
%Config = ('mail_recipient','', 'mail_subject','',
# ASHLEY: I don't use 'email' and 'realname' as config fields as I want
# them to appear in all my responses from this script without bothering
# with the 'print_config' field;
# 'email','', 'realname','',
# ASHLEY: #############################
'mail_top','', 'mail_listfields','',
'mail_bottom','',
'cour_send','', 'cour_top','',
'cour_listfields','', 'cour_bottom','',
'cour_close','', 'cour_myname','',
'cour_myemail','', 'cour_mywebsite','',
'cour_subject','',
'html_title','', 'html_top','',
'html_listfields','', 'html_bottom','',
'html_redirect','',
'html_return_link_title','', 'html_return_link_url','',
'data_filename','', 'data_fields_to_log','',
'data_env_to_log','', 'data_delimiter','',
'data_listvertical','',
#######################################
'bgcolor','',
'background','', 'link_color','',
'vlink_color','', 'text_color','',
'alink_color','',
'sort','', 'print_config','',
'required','', 'env_report','',
'print_blank_fields','', 'missing_fields_redirect','');
# Determine the form's REQUEST_METHOD (GET or POST) and split the form #
# fields up into their name-value pairs. If the REQUEST_METHOD was #
# not GET or POST, send an error. #
if ($ENV{'REQUEST_METHOD'} eq 'GET') {
# Split the name-value pairs
@pairs = split(/&/, $ENV{'QUERY_STRING'});
}
elsif ($ENV{'REQUEST_METHOD'} eq 'POST') {
# Get the input
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
# Split the name-value pairs
@pairs = split(/&/, $buffer);
}
else {&error('request_method');}
# For each name-value pair: #
foreach $pair (@pairs) {
# Split the pair up into individual variables. #
($name, $value) = split(/=/, $pair);
# Decode the form encoding on the name and value variables. #
$name =~ tr/+/ /;
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
# If they try to include server side includes, erase them, so they
# aren't a security risk if the html gets returned. Another
# security hole plugged up.
$value =~ s///g;
# If the field name has been specified in the %Config array, it will #
# return a 1 for defined($Config{$name}}) and we should associate #
# this value with the appropriate configuration variable. If this #
# is not a configuration form field, put it into the associative #
# array %Form, appending the value with a ', ' if there is already a #
# value present. We also save the order of the form fields in the #
# @Field_Order array so we can use this order for the generic sort. #
if (defined($Config{$name})) {
$Config{$name} = $value;
}
else {
if ($Form{$name} && $value) {
$Form{$name} = "$Form{$name}, $value";
}
# elsif ($value) {
else {
push(@Field_Order,$name);
$Form{$name} = $value;
}
}
}
# The next six lines remove any extra spaces or new lines from the #
# configuration variables, which may have been caused if your editor #
# wraps lines after a certain length or if you used spaces between field #
# names or environment variables. #
$Config{'required'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$Config{'required'} =~ s/(\s+)?\n+(\s+)?//g;
$Config{'env_report'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$Config{'env_report'} =~ s/(\s+)?\n+(\s+)?//g;
$Config{'data_env_to_log'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$Config{'data_env_to_log'} =~ s/(\s+)?\n+(\s+)?//g;
$Config{'print_config'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$Config{'print_config'} =~ s/(\s+)?\n+(\s+)?//g;
# Split the configuration variables into individual field names. #
@Required = split(/,/,$Config{'required'});
@Env_Report = split(/,/,$Config{'env_report'});
@Data_env_to_log = split(/,/,$Config{'data_env_to_log'});
@Print_Config = split(/,/,$Config{'print_config'});
# ACCESS CONTROL FIX: Only allow ENV variables in @valid_ENV in #
# @Env_Report for security reasons. #
foreach $env_item (@Env_Report) {
foreach $valid_item (@valid_ENV) {
if ( $env_item eq $valid_item ) { push(@temp_array, $env_item) }
}
}
@Env_Report = @temp_array;
}
sub check_required {
# Localize the variables used in this subroutine. #
local($require, @error);
if ($Config{'subject'} =~ /(\n|\r)/m ||
$Config{'mail_recipient'} =~ /(\n|\r)/m) {
&error('no_recipient');
}
if(!$Config{'mail_recipient'} eq '') {
if (!$Config{'mail_recipient'}) {
if (!defined(%Form)) { &error('bad_referer') }
else { &error('no_recipient') }
}
else {
# This block of code requires that the recipient address end with #
# a valid domain or e-mail address as defined in @recipients. #
$valid_recipient = 0;
foreach $send_to (split(/,/,$Config{'mail_recipient'})) {
foreach $mail_recipient (@recipients) {
if ($send_to =~ /$mail_recipient$/i) {
push(@send_to,$send_to); last;
}
}
}
if ($send_to < 0) { &error('no_recipient') }
$Config{'mail_recipient'} = join(',',@send_to);
}
}
# For each require field defined in the form: #
foreach $require (@Required) {
# ASHLEY: I couldn't get the missing_fields error to fire if there was only a
# space character in a required field so I added the next line and all is well.
$Form{$require} =~ s/^\s*//;
# If it is a regular form field which has not been filled in or #
# filled in with a space, flag it as an error field. #
if ($Form{$require} eq '') {
push(@error,$require);
}
# If the required field is the email field, the syntax of the email #
# address if checked to make sure it passes a valid syntax. #
elsif ($require eq 'email' && !&check_email($Form{$require})) {
push(@error,$require);
}
# Otherwise, if the required field is a configuration field and it #
# has no value or has been filled in with a space, send an error. #
elsif (defined($Config{$require})) {
if (!$Config{$require}) {
push(@error,$require);
}
}
}
# If any error fields have been found, send error message to the user. #
if (@error) { &error('missing_fields', @error) }
}
sub send_mail {
if(!$Config{'mail_recipient'} eq '')
{
# Localize variables used in this subroutine. #
local($print_config,$key,$sort_order,$sorted_field,$env_report);
# Open The Mail Program
open(MAIL,"|$mailprog -t");
print MAIL "To: $Config{'mail_recipient'}\n";
# print MAIL "From: $Config{'email'} ($Config{'name'})\n";
# ASHLEY: I prefer to have the email address and realname always returned.
# I had to change 'Config' to 'Form' here as these fields are no longer in
# the Config array established in the parse_form subroutine earlier
print MAIL "From: $Form{'email'} ($Form{'name'})\n";
# Check for Message Subject
if ($Config{'mail_subject'}) { print MAIL "Subject: $Config{'mail_subject'}\n\n" }
else { print MAIL "Subject: WWW Form Submission\n\n" }
# ASHLEY: I don't want the following in my emails to myself.
# print MAIL "Below is the result of your feedback form. It was submitted by\n";
# print MAIL "$Config{'realname'} ($Config{'email'}) on $date\n";
# print MAIL "-" x 75 . "\n\n";
# ASHLEY: Here is the mailtp text which can be
# specified by the form developer; it appears above the field list.
if ($Config{'mail_top'}) {print MAIL "$Config{'mail_top'}\n\n"}
print MAIL "date: $date\n";
if (@Print_Config) {
foreach $print_config (@Print_Config) {
if ($Config{$print_config}) {print MAIL "$print_config: $Config{$print_config}\n";}
}
}
if ($Config{'mail_listfields'}) {
# Sort alphabetically if specified: #
# ASHLEY: This will PRINT_BLANK_FIELDS for the TEXT,TEXTAREA,PASSWORD
# fields only. If you want full blank_field control, use sort/order:
if ($Config{'sort'} eq 'alphabetic') {
foreach $field (sort keys %Form) {
# If the field has a value or the print blank fields option #
# is turned on, print out the form field and value. #
if ($Config{'print_blank_fields'} || $Form{$field} ||
$Form{$field} eq '0') {
print MAIL "$field: $Form{$field}\n";
}
}
}
# If a sort order is specified, sort the form fields based on that.
# THIS IS THE ONLY SORTING CHOICE THAT WILL PRINT_BLANK_FIELDS FOR
# THE INPUTS OF RADIO, CHECKBOX, OR SELECT.
elsif ($Config{'sort'} =~ /^order:.*,.*/) {
# Put Config(sort) into array so it is clean for other routines.
# Remove extraneous line breaks and spaces, remove the order: #
# directive and split the sort fields into an array. #
$sort_order = $Config{'sort'};
$sort_order =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$sort_order =~ s/(\s+)?\n+(\s+)?//g;
$sort_order =~ s/order://;
@sorted_fields = split(/,/, $sort_order);
# For each sorted field, if it has a value or the print blank #
# fields option is turned on print the form field and value. #
foreach $sorted_field (@sorted_fields) {
if ($Config{'print_blank_fields'} || $Form{$sorted_field} ||
$Form{$sorted_field} eq '0') {
print MAIL "$sorted_field: $Form{$sorted_field}\n";
}
}
}
# Otherwise, default to the order in which the fields were sent. #
# ASHLEY: This will PRINT_BLANK_FIELDS for the TEXT,TEXTAREA,PASSWORD
# fields only. If you want full blank_field control, use sort/order: #
else {
# For each form field, if it has a value or the print blank #
# fields option is turned on print the form field and value. #
foreach $field (@Field_Order) {
if ($Config{'print_blank_fields'} || $Form{$field} ||
$Form{$field} eq '0') {
print MAIL "$field: $Form{$field}\n";
}
}
}
}
# Send any specified Environment Variables to recipient. #
foreach $env_report (@Env_Report) {
if ($ENV{$env_report}) {
print MAIL "$env_report: $ENV{$env_report}\n";
}
}
# ASHLEY: Here is the mailbottom text which can be
# specified by the form developer; it appears below the field list.
if ($Config{'mail_bottom'}) {print MAIL "\n$Config{'mail_bottom'}\n"}
close (MAIL);
}
}
sub check_email {
# Initialize local email variable with input to subroutine. #
$email = $_[0];
# If the e-mail address contains: #
if ($email =~ /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/ ||
# the e-mail address contains an invalid syntax. Or, if the #
# syntax does not match the following regular expression pattern #
# it fails basic syntax verification. #
$email !~ /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z0-9]+)(\]?)$/) {
# Basic syntax requires: one or more characters before the @ sign, #
# followed by an optional '[', then any number of letters, numbers, #
# dashes or periods (valid domain/IP characters) ending in a period #
# and then 2 or 3 letters (for domain suffixes) or 1 to 3 numbers #
# (for IP addresses). An ending bracket is also allowed as it is #
# valid syntax to have an email address like: user@[255.255.255.0] #
# Return a false value, since the e-mail address did not pass valid #
# syntax. #
return 0;
}
else {
# Return a true value, e-mail verification passed. #
return 1;
}
}
# Send courtesy reply email to the visitor.
sub send_courtesy {
if ($Config{'cour_send'}) {
# ASHLEY: syntax check for submitted email so that
# you don't have to make this field required.
if ($Form{'email'} && &check_email($Form{'email'})) {
open (MAIL,"|$mailprog -t");
print MAIL "To: $Form{'email'} ($Form{'name'})\n";
print MAIL "From: $Config{'cour_myemail'} ($Config{'cour_myname'})\n";
if ($Config{'cour_subject'}) {
print MAIL "Subject: Thanks for your $Config{'cour_subject'}\n\n";
$subjflag = 1;
}
else {
print MAIL "Subject: Thank you - $date\n\n";
$subjflag = 0;
}
print MAIL "On $date you responded to ";
if ( $subjflag ) {print MAIL "the `$Config{'cour_subject'}` form.\n\n";}
else {print MAIL "a WWW form.\n\n";}
# ASHLEY: The following fields are for customizing the courtesy reply
if ($Config{'cour_top'}) {print MAIL "$Config{'cour_top'}\n\n";}
if ($Config{'cour_listfields'}) {
# Sort alphabetically if specified: #
# ASHLEY: This will PRINT_BLANK_FIELDS for the TEXT,TEXTAREA,PASSWORD
# fields only. If you want full blank_field control, use sort/order: #
if ($Config{'sort'} eq 'alphabetic') {
foreach $field (sort keys %Form) {
# If the field has a value or the print blank fields option #
# is turned on, print out the form field and value. #
if ($Config{'print_blank_fields'} || $Form{$field} ||
$Form{$field} eq '0') {
print MAIL "$field: $Form{$field}\n";
}
}
}
# If a sort order is specified, sort the form fields based on that. #
# If a sort order is specified, sort the form fields based on that.
# THIS IS THE ONLY SORTING CHOICE THAT WILL PRINT_BLANK_FIELDS FOR
# THE INPUTS OF RADIO, CHECKBOX, OR SELECT.
elsif ($Config{'sort'} =~ /^order:.*,.*/) {
# Put Config(sort) into array so it is clean for other routines.
# Remove extraneous line breaks and spaces, remove the order: #
# directive and split the sort fields into an array. #
$sort_order = $Config{'sort'};
$sort_order =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$sort_order =~ s/(\s+)?\n+(\s+)?//g;
$sort_order =~ s/order://;
@sorted_fields = split(/,/, $sort_order);
# For each sorted field, if it has a value or the print blank #
# fields option is turned on print the form field and value. #
foreach $sorted_field (@sorted_fields) {
if ($Config{'print_blank_fields'} || $Form{$sorted_field} ||
$Form{$sorted_field} eq '0') {
print MAIL "$sorted_field: $Form{$sorted_field}\n";
}
}
}
# Otherwise, default to the order in which the fields were sent. #
# ASHLEY: This will PRINT_BLANK_FIELDS for the TEXT,TEXTAREA,PASSWORD
# fields only. If you want full blank_field control, use sort/order: #
else {
# For each form field, if it has a value or the print blank #
# fields option is turned on print the form field and value. #
foreach $field (@Field_Order) {
if ($Config{'print_blank_fields'} || $Form{$field} ||
$Form{$field} eq '0') {
print MAIL "$field: $Form{$field}\n";
}
}
}
print MAIL "\n";
}
if ($Config{'cour_bottom'}) {print MAIL "$Config{'cour_bottom'}\n";}
if ($Config{'cour_close'}) {print MAIL "\n$Config{'cour_close'}";}
else {print MAIL "\n\nRegards,";}
if ($Config{'cour_myname'}) {print MAIL "\n$Config{'cour_myname'}";}
if ($Config{'cour_myemail'}) {print MAIL "\n$Config{'cour_myemail'}";}
if ($Config{'cour_mywebsite'}) {print MAIL "\n$Config{'cour_mywebsite'}";}
close (MAIL);
}
}
}
sub return_html {
local($print_config,$key,$sort_order,$sorted_field,$env_report);
if ($Config{'html_redirect'} =~ /http\:\/\/.*\..*/) {
# If the redirect option of the form contains a valid url,
# print the redirectional location header.
print "Location: $Config{'html_redirect'}\n\n";
}
else {
print "Content-type: text/html\n\n";
print "\n
\n";
# Print out title of page
if ($Config{'html_title'}) {
print " $Config{'html_title'}\n";
}
else {print " Thank You\n";}
print " \n \n \n";
if ($Config{'html_top'}) {print "$Config{'html_top'}
\n";}
else {print "Thank you for your submission
\n";}
if ($Config{'html_listfields'}) {
# print "to $Config{'mail_recipient'} on ";
print "on ";
print "$dater
\n";
# Original Table output to HTML added Don Killen 10/22/96
# Modified by ASHLEY 5/15/98
print "\n";
# Sort alphabetically if specified:
# ASHLEY: This will PRINT_BLANK_FIELDS for the TEXT,TEXTAREA,PASSWORD
# fields only. If you want full blank_field control, use sort/order: #
if ($Config{'sort'} eq 'alphabetic') {
foreach $field (sort keys %Form) {
$Form{$field} =~ s/\r\n/
/g;
# If the field has a value or the print blank fields option #
# is turned on, print out the form field and value. #
if ($Config{'print_blank_fields'} || $Form{$field} ||
$Form{$field} eq '0') {
print "\n";
print " $field: | \n";
print " $Form{$field} | \n";
print "
\n";
}
}
}
# If a sort order is specified, sort the form fields based on that.
# THIS IS THE ONLY SORTING CHOICE THAT WILL PRINT_BLANK_FIELDS FOR
# THE INPUTS OF RADIO, CHECKBOX, OR SELECT.
elsif ($Config{'sort'} =~ /^order:.*,.*/) {
# Put Config(sort) into array so it is clean for other routines.
# Remove extraneous line breaks and spaces, remove the order:
# directive and split the sort fields into an array.
$sort_order = $Config{'sort'};
$sort_order =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$sort_order =~ s/(\s+)?\n+(\s+)?//g;
$sort_order =~ s/order://;
@sorted_fields = split(/,/, $sort_order);
# For each sorted field, if it has a value or the print blank #
# fields option is turned on print the form field and value. #
foreach $sorted_field (@sorted_fields) {
$holder = $Form{$sorted_field};
$holder =~ s/\r\n/
/g;
if ($Config{'print_blank_fields'} || $Form{$sorted_field} ||
$Form{$sorted_field} eq '0') {
print "\n";
print " $sorted_field: | \n";
# print " $Form{$sorted_field} | \n";
print " $holder | \n";
print "
\n";
}
}
}
# Otherwise, default to the order in which the fields were sent. #
# ASHLEY: This option will PRINT_BLANK_FIELDS for TEXT and TEXTAREA
# fields only. If you want full blank_field control, use sort/order: #
else {
# For each form field, if it has a value or the print blank #
# fields option is turned on print the form field and value. #
foreach $field (@Field_Order) {
$Form{$field} =~ s/\r\n/
/g;
if ($Config{'print_blank_fields'} || $Form{$field} ||
$Form{$field} eq '0') {
print "\n";
print " $field: | \n";
print " $Form{$field} | \n";
print "
\n";
}
}
}
print "
\n";
print "
\n";
}
if ($Config{'html_bottom'}) {print "$Config{'html_bottom'}
\n"; }
# Check for a Return Link
if ($Config{'html_return_link_url'} =~ /http\:\/\/.*\..*/ && $Config{'html_return_link_title'}) {
# print "\n";
print "\n";
print "$Config{'html_return_link_title'}\n";
print "\n";
}
print "\n";
}
}
# ASHLEY: The code to write form submissions to a text file on your server
# This feature ONLY WORKS IF you specify fields in the "data_fields_to_log"
# and/or "data_env_to_log" in your form config.
sub appendit {
# Localize variables used in this subroutine. #
local($sort_order,$sort_env,$sorted_field,$sorted_env);
if ($Config{'data_fields_to_log'} || $Config{'data_env_to_log'}) {
if ($Config{'data_filename'})
{
if (-w $Config{'data_filename'})
{
&lockit ("$Config{'data_filename'}.lock");
open (Database, ">>$Config{'data_filename'}");
# Put Config(data_fields_to_log) into array.
# For each field, replace all Return codes in fields (unless Vertical listing)
# with ¶ (alt+0182)to avoid line breaks within our database
# rows and then print the form field and value.
$sort_order = $Config{'data_fields_to_log'};
$sort_order =~ s/(\s+|\n)?,(\s+|\n)?/,/g;
$sort_order =~ s/(\s+)?\n+(\s+)?//g;
@sorted_fields = split(/,/, $sort_order);
print Database "$date";
print Database "$Config{'data_delimiter'}"; #use this only if loggin date AND time
print Database "$time";
foreach $sorted_field (@sorted_fields) {
$holder = $Form{$sorted_field};
if ($Config{'data_listvertical'}) {
print Database "\n$sorted_field: $holder";
### the line above writes empty fields; the line below does not ####
#if ($Form{$sorted_field}) {print Database "\n$sorted_field: $holder";}
}
else {
$holder =~ s/\r\n/¶/g;
print Database "$Config{'data_delimiter'}$holder";
}
}
foreach $sorted_envfield (@Data_env_to_log) {
$holder = $ENV{$sorted_envfield};
if ($Config{'data_listvertical'}) {
print Database "\n$sorted_envfield: $holder";
### the line above writes empty fields; the line below does not ####
#if ($Form{$sorted_envfield}) {print Database "\n$sorted_field: $holder";}
}
else {
$holder =~ s/\r\n/¶/g;
print Database "$Config{'data_delimiter'}$holder";
}
}
if ($Config{'data_listvertical'}) {print Database "\n\n==============================\n\n";}
else {print Database "\n"; }
close (Database);
&unlockit ("$Config{'data_filename'}.lock");
}
}
}
}
# ASHLEY: A required routine for the database append feature
sub lockit {
local ($lock_file) = @_;
local ($endtime);
$endtime = 20;
$endtime = time + $endtime;
while (-e $lock_file && time < $endtime)
{sleep(1);}
open(LOCK_FILE, ">$lock_file") ||
&file_open_error ("$lock_file", "Lock File Routine", __FILE__, __LINE__);
}
# ASHLEY: Another required routine for the database append feature
sub unlockit {
local ($lock_file) = @_;
close(LOCK_FILE);
unlink($lock_file);
}
# ASHLEY: Another required routine for the database append feature
sub file_open_error {
local ($bad_file, $script_section, $this_file, $line_number) = @_;
print "Content-type: text/html\n\n";
&CgiDie ("I am sorry, but I was not able to access $bad_file.")
}
sub error {
# Localize variables and assign subroutine input. #
local($error,@error_fields) = @_;
local($host,$missing_field,$missing_field_list);
if ($error eq 'bad_referer') {
if ($ENV{'HTTP_REFERER'} =~ m|^https?://([\w\.]+)|i) {
$host = $1;
print "Content-type: text/html\n\n";
print <<"(END ERROR HTML)";
Bad Referrer - Access Denied
Bad Referrer - Access Denied |
The form attempting to use
YFORM.CGI
resides at $ENV{'HTTP_REFERER'}, which is not allowed to access
this cgi script.
If you are attempting to configure YFORM.CGI to run with this form, you need
to add the following to \@referers, explained in detail in the YFORM.TXT file.
Add '$host' to your \@referers array.
|
(END ERROR HTML)
}
else {
print <<"(END ERROR HTML)";
Content-type: text/html
YFORM.CGI ver 1.9
Ashley Bass
Version 1.9 - Released Saturday, 8/25/01
|
(END ERROR HTML)
}
}
elsif ($error eq 'request_method') {
print <<"(END ERROR HTML)";
Content-type: text/html
Error: Request Method
The Request Method of the Form you submitted did not match
either GET or POST. Please check the form and make sure the
method= statement is in upper case and matches GET or POST.
|
(END ERROR HTML)
}
elsif ($error eq 'no_recipient') {
print "Content-type: text/html\n\n";
print <<"(END ERROR HTML)";
Error: Invalid Recipient Email Address
Error: Invalid Recipient Email Address |
The Recipient specified in the data sent to the YFORM script is invalid. Please
make sure you have filled in the 'recipient' form field with a valid email
address that is allowed to use the YFORM script. More information on filling in Recipient form fields can be
found in the YFORM.TXT file.
|
(END ERROR HTML)
}
elsif ($error eq 'missing_fields') {
if ($Config{'missing_fields_redirect'}) {
print "Location: $Config{'missing_fields_redirect'}\n\n";
}
else {
foreach $missing_field (@error_fields) {
$missing_field_list .= " $missing_field\n";
}
print "Content-type: text/html\n\n";
print <<"(END ERROR HTML)";
Error: Invalid Submission
Error: Invalid Submission |
The following required field(s) were invalid or blank in your submission form:
These fields must be filled in before you can successfully submit the form.
Please use your browser's back button to return to the form.
|