#!/usr/bin/perl # sendform.cgi # v1.31 # September 2 1999 # Copyright 1996, 1998, 1999 by Rod Clark # cgi-lib routines copyright (c) 1995 Steven E. Brenner # v1.31 - Sep 2 1999 # - fixed bug that rejected otherwise good referrer domain names in uppercase # v1.3 - May 10 1999 # - can send raw data only, minus usual accompanying human-readable info # - send more than one e-mail blurb to user # - replace variables in blurb texts and echo page # - can define text strings for blank checkboxes, when no data from form # - sending mail to the user is optional # v1.23 - November 13, 1998 # - Revised display of year (4 digits) # v1.22 - October 25, 1998 # - concatenate multiple SubjectField values # - concatenate a fixed subject with SubjectField values, # by using both "subject" and "SubjectFields" # v1.21 - June 10, 1998 # - Fixed a bug that always displayed the entire URL of the referring # page in lowercase, in e-mail to the user. (It should have forced # only the domain name to lowercase. If the user had clicked on a URL # in the e-mail message that should have contained uppercase # characters, then the page wouldn't have been found, and the user # would have had to search for the page or use the menus to find it.) # v1.2 # - Added more extensive required fields processing. # - Can now use "name" instead of "first_name" and last_name" # (unlike "first_name", doesn't print "name" as blurb salutation). # - Added "to_name" and "cc_name" to help with return e-mail replies. # - Converts line breaks to spaces in SubjectField, for e-mail. # - Revised null multiple separator in ReadParse. #=============================================================== # configuration #================================================================ # You'll need to set the following variables. #----- # Uncomment one of these two @GoodReferrers lines. # (omit "www" prefix if people can use your URLs without it) # NOTE: Enter these domain names in lowercase. However, the script # allows incoming domain names to be in uppercase or mixed case. # For using forms on one server: @GoodReferrers = ('scn.org'); # For using forms on any of several servers: # @GoodReferrers = ('yourdomain.com', 'another.com'); #----- # Where mail from the form is sent, if not otherwise specified. # Applies only if you don't use "to" or "MailtoAddress" on the form. # It's also the default for the mailto link on the generic thanks page. # NOTE: There's no need to escape the @ in the address here by using \@ $DefaultMailtoPrompt = "Questions:"; $DefaultTo = 'webadm@scn.org'; $DefaultToName = 'SCN Web Admin'; #----- # Automatically send a copy of the form data to the user? # (can override this default on the form) $DefaultSendCopyToUser = 1; #----- # Subject line to use if none is specified on the form: $DefaultSubject = "Web Form Data"; #----- # When one of these words is used alone as the subject, the # subject line of the mail sent to the recipient will be blank. # Examples: # # or $BlankSubjectWords = "none|blank"; #----- # Path to mail program: # To find this out, type "which sendmail" at the Unix prompt. # (If you see a "Form Error" message during installation, a bad path to # sendmail is the most likely cause.) # -oi avoids ending input at a . on a line by itself # -oeq avoids some difficulties if address is invalid # # You can use another mail program, if you set it to the equivalent # of sendmail's -t parameter. $MailProgram = '/usr/sbin/sendmail -t -oi -oeq'; # $MailProgram = '/usr/lib/sendmail -t -oi -oeq'; #----- # Default return prompt to display on the default echo page: # (Applies only if you don't specify your own echo page, don't use # redirection, and don't specify a return link on the form with a # hidden ReturnLinkURL, and HTTP_REFERER is not present.) $DefaultReturnLinkURL = "http://www.scn.org/"; $DefaultReturnLinkTitle = "Seattle Community Network"; #----- # Default background color and image for the generic thanks page # and other generated pages (error page, required fields page, etc.) # You can override these with "Bgcolor" and "Background" form variables. # CAUTION: Leaving $DefaultBgcolor blank ("") produces black. $DefaultBgcolor = "#FFFFFF"; # If you don't have a background image, set this to "" because using a # nonexistent filename may cause the dreaded "Internal Server Error". $DefaultBackground = ""; # $DefaultBackground = "/images/tan.gif"; #----- # File extensions that can be used for echo pages: # This prevents reading other than HTML files. # Add other legitimate HTML file extensions that your server may use. # $GoodFileExts = "\.htm|\.html|\.shtml|\.stm"; $GoodFileExts = "\.htm|\.html"; $DefaultThanksMessage = "This is what you entered on the form.\n"; #----- # Note included in mail confirmation to user: $DefaultUserMailNote = "For your records, this is what you entered on the form."; # =============================================================== # You shouldn't have to change any of the following settings, # but check them anyway. #----- # Use this word as the value of blank required fields. # This is equivalent to value="" but works with more browsers. # $RequiredWord = "required"; #----- # This separates multiple items on the subject line, when using both # a fixed subject and a SubjectField, or multiple subject fields. # $SubjectItemSeparator = ", "; $SubjectItemSeparator = " - "; #----- DATA # this is what separates multiple values in a single field # (for example, when multiple items are selected in a pull-down menu) $ItemSeparatorString = ", "; #----- REPLACE VARS $VarDelimiter = "\&"; #================================================================ # end of configuration #================================================================ &CheckReferrer; &GetTime; &ParseForm; &CheckRequiredFields; &BuildWholeMailName; &AddSubjectField; &BuildRawDataLines; &InitializeReplaceFields; &SendMail; &PrintEchoPageOrRedirect; #================================================================ # subroutines #================================================================ sub CheckReferrer { $Referrer = $ENV{'HTTP_REFERER'}; $ReferrerOK = 0; if ($Referrer) { $NumGoodReferrers = @GoodReferrers; for ($RefIndex = 0; $RefIndex < $NumGoodReferrers; $RefIndex++) { if ($Referrer =~ /$GoodReferrers[$RefIndex]/i) { $ReferrerOK = 1; } } } else { $ReferrerOK = 1; } if (!$ReferrerOK) { $ErrorMessage = "The form at $Referrer is outside our domain. Access is denied."; push (@Errors, $ErrorMessage); &PrintErrorPage; exit; } } sub GetTime { @Days = ('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday', 'Saturday'); @Months = ('January','February','March','April','May','June','July', 'August','September','October','November','December'); ($Sec, $Min, $Hour, $MonthDay, $Month, $Year, $WeekDay, $YearDay, $IsDST) = localtime (time); if ($Hour < 10) { {$Hour = "0$Hour";} } if ($Min < 10) { {$Min = "0$Min";} } $Year = 1900 + $Year; $Time = "$Hour\:$Min on $Days[$WeekDay], $Months[$Month] $MonthDay, $Year"; if ($MonthDay < 10) { {$MonthDay = "0$MonthDay";} } } sub ParseForm { &ReadParse; foreach $Part (@in) { # convert hex values (e.g. %0A) to ASCII characters $Part =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; ($Key, $Val) = split (/=/, $Part, 2); $Val = &CleanVariable ($Val); $Part = ($Key."=".$Val); push (@CleanIn, $Part); # ScriptPairs, not echoed as part of user data # "email" isn't in ScriptPairs (see UserPairs) if (($Key eq 'to') || ($Key eq 'to_name') || ($Key eq 'cc') || ($Key eq 'cc_name') || ($Key eq 'subject') || ($Key eq 'SubjectField') || ($Key eq 'Required') || ($Key eq 'SkipBlankFields') || ($Key eq 'MailLastNameFirst') || ($Key eq 'SendRawData') || ($Key eq 'RawDataFields') || ($Key eq 'RedirectURL') || ($Key eq 'EchoFilePath') || ($Key eq 'BlurbFilePath') || ($Key eq 'ThanksMessage') || ($Key eq 'SendCopyToUser') || ($Key eq 'ReturnLinkURL') || ($Key eq 'ReturnLinkTitle') || ($Key eq 'MailtoPrompt') || ($Key eq 'MailtoName') || ($Key eq 'MailtoAddress') || ($Key eq 'Bgcolor') || ($Key eq 'Background') || ($Key eq 'SuppressDataListInUserMail') #----- REPLACE TEXT || ($Key eq 'ReplaceBlankDefaults')) #----- REPLACE TEXT { push (@ScriptPairs, $Key."=".$Val); } else { push (@UserPairs, $Key."=".$Val); } } @in = @CleanIn; undef (@CleanIn); $to = $in{'to'}; $to_name = $in{'to_name'}; $cc = $in{'cc'}; $cc_name = $in{'cc_name'}; $email = $in{'email'}; # equivalent to "from" $first_name = $in{'first_name'}; $last_name = $in{'last_name'}; $name = $in{'name'}; $subject = $in{'subject'}; $ReturnLinkURL = $in{'ReturnLinkURL'}; $ReturnLinkTitle = $in{'ReturnLinkTitle'}; $RedirectURL = $in{'RedirectURL'}; $SubjectField = $in{'SubjectField'}; $SkipBlankFields = $in{'SkipBlankFields'}; $MailLastNameFirst = $in{'MailLastNameFirst'}; $ThanksMessage = $in{'ThanksMessage'}; if (!$ThanksMessage) { $ThanksMessage = $DefaultThanksMessage; } $SendCopyToUser = $in{'SendCopyToUser'}; if (!$SendCopyToUser) { $SendCopyToUser = $DefaultSendCopyToUser; } elsif ($SendCopyToUser =~ /^yes$/i) { $SendCopyToUser = 1; } else { $SendCopyToUser = 0; } $SendRawData = $in{'SendRawData'}; # (the default is always not to do this) if ($SendRawData =~ /^yes$/i) { $SendRawData = 1; } else { $SendRawData = 0; } $RawDataFields = $in{'RawDataFields'}; if ($RawDataFields =~ /,/) { @RawDataFields = split (/,/, $RawDataFields); } else { push (@RawDataFields, $RawDataFields); } $MailtoPrompt = $in{'MailtoPrompt'}; if (!$MailtoPrompt) { $MailtoPrompt = $DefaultMailtoPrompt ; } $MailtoName = $in{'MailtoName'}; $MailtoAddress = $in{'MailtoAddress'}; $Required = $in{'Required'}; # remove spaces $Required =~ s/ +//g; @RequiredFields = split (/,/, $Required); #-----REPLACE TEXT $SuppressDataListInUserMail = $in{'SuppressDataListInUserMail'}; #-----REPLACE TEXT $ReplaceBlankDefaults = $in{'ReplaceBlankDefaults'}; @ReplaceBlankDefaults = split (/,/, $ReplaceBlankDefaults); $Bgcolor = $in{'Bgcolor'}; if (!$Bgcolor) { $Bgcolor = $DefaultBgcolor; } $Background = $in{'Background'}; if (!$Background) { $Background = $DefaultBackground; } $EchoFilePath = $in{'EchoFilePath'}; # disallow most special chars, and paths starting with . if (($EchoFilePath =~ /[^a-zA-Z0-9-\$_\.\/]/) || ($EchoFilePath =~ /^\./)) { $EchoFilePath = ''; } $BlurbFilePath = $in{'BlurbFilePath'}; @BlurbFilePaths = split (/,/, $BlurbFilePath); foreach $BlurbFilePath (@BlurbFilePaths) { # disallow most special chars, and paths starting with . if (($BlurbFilePath =~ /[^a-zA-Z0-9-\$_\.\/]/) || ($BlurbFilePath =~ /^\./)) { $BlurbFilePath = ''; } else { push (@CleanBlurbFilePaths, $BlurbFilePath); } } @BlurbFilePaths = @CleanBlurbFilePaths; } sub CleanVariable { local ($CleanedVariable) = @_; $CleanedVariable =~ s// /g; $CleanedVariable =~ s/>/ /g; $CleanedVariable =~ s/>/ /g; $CleanedVariable =~ s/%3E/ /g; $CleanedVariable =~ s/%3e/ /g; $CleanedVariable =~ s/"/'/g; $CleanedVariable =~ s/"/'/g; $CleanedVariable =~ s/"/'/g; $CleanedVariable =~ s/%22/'/g; $CleanedVariable =~ s/%0C/\r/g; $CleanedVariable =~ s/%0c/\r/g; $CleanedVariable =~ s/%09/ /g; $CleanedVariable =~ s/ / /g; $CleanedVariable =~ s/\t/ /g; $CleanedVariable =~ s/\r\n\r\n/

/g; $CleanedVariable =~ s/\r\n\n/

/g; $CleanedVariable =~ s/\n\n/

/g; $CleanedVariable =~ s/\r\r/

/g; $CleanedVariable =~ s/\r\n/
/g; $CleanedVariable =~ s/\n/
/g; $CleanedVariable =~ s/\r/
/g; # collapse whitespace (is this desirable here?) # $CleanedVariable =~ s/\s+/ /; # remove leading and trailing whitespace $CleanedVariable =~ s/^\s+//; $CleanedVariable =~ s/\s+$//; return ($CleanedVariable); } sub EntifyVariable { local ($ToEntify) = @_; $ToEntify =~ s//>/g; $ToEntify =~ s/"/"/g; return ($ToEntify); } sub CheckRequiredFields { if (!$to && !$MailtoAddress && !$cc && !$DefaultTo) { $ErrorMessage = "This form cannot be sent to its intended recipient.\nPlease send e-mail directly."; push (@Errors, $ErrorMessage); &PrintErrorPage; exit; } else { if ($email =~ /\S/) { if ($email =~ /^[\w-.]+\@[\w-.]+$/) { $EmailOK = 1; } else { $MissingMessage = "Your e-mail address ($email) isn't in the usual someone\@some.com form of Internet e-mail addresses. Please make sure it's correct."; push (@MissingMessages, $MissingMessage); } } if ($Required) { foreach $RequiredField (@RequiredFields) { $RequiredFieldOK = 0; $RequiredFieldFoundMissing = 0; foreach $UserPair (@UserPairs) { ($UserKey, $UserVal) = split (/=/, $UserPair, 2); if ($RequiredField eq $UserKey) { if ((!$UserVal) || ($UserVal =~ /^\s+$/) || ($UserVal eq $RequiredWord)) { $MissingMessage = "The required $RequiredField field is missing. Please include it on the form."; push (@MissingMessages, $MissingMessage); $RequiredFieldFoundMissing = 1; } else { $RequiredFieldOK = 1; } } } if ((!$RequiredFieldOK) && (!$RequiredFieldFoundMissing)) { if (!$in{'$RequiredField'}) { $MissingMessage = "The required $RequiredField field is missing. Please include it on the form."; push (@MissingMessages, $MissingMessage); } } } } $FieldsMissing = @MissingMessages; if ($FieldsMissing) { &PrintRequiredFieldsPage; exit; } } } sub PrintEchoPageOrRedirect { if ($RedirectURL) { print "Location: $RedirectURL\n\n"; } &PrintEchoPage; } sub PrintEchoPage { # check that the echo file is an HTML file if ($EchoFilePath =~ /$GoodFileExts$/) { &PrintUserEchoPage; } else { &PrintGenericThanksPage; } } sub PrintUserEchoPage { # Print $EchoFilePath file until encounter # Then print the user pairs from the form. # Then print the rest of the file. # If is not found, then print the file # without inserting standard list of variables from the form. # # But if variables (e.g. &VariableName) are present on the page, # replace them with form data. if (open (ECHOFILE, $EchoFilePath)) { &PrintHeader; $EchoFileLine = ; while ($EchoFileLine ne '') { if (($EchoFileLine =~ //i)) { print "Subject: $MailedSubject
\n"; print "$MailerMessage
\n"; print "

\n"; if ($SendRawData) { &PrintRawData; } else { &PrintUserPairs; } } else { $EchoFileLine = &ReplaceVarsInLine ($EchoFileLine); print "$EchoFileLine"; } $EchoFileLine = ; } close (ECHOFILE); } else { &PrintGenericThanksPage; } } sub PrintGenericThanksPage { &PrintHeader; print < Thank You

Thank You

$ThanksMessage ENDPRINT if ($SendRawData) { print "
\n"; &PrintRawData; print "
\n"; } else { print "$MailerMessage
\n"; print "Subject: $MailedSubject\n"; print "

\n"; print "

\n"; &PrintUserPairs; print "
\n"; } print "
\n"; &PrintMailto; print "

\n"; &PrintReturnLink; &PrintPageFooter; } sub PrintRequiredFieldsPage { &PrintHeader; print < Please Fill Out Required Fields

Please Fill Out Required Fields


Press your browser's Back button to return to the form. \n"; print "\n"; print "
\n"; &PrintMailto; print "

\n"; &PrintPageFooter; } sub PrintErrorPage { &PrintHeader; print < Form Error

Form Error