#!/usr/bin/perl -w
use strict;
use warnings;
use CGI qw(:standard :cgi-lib);
$CGI::POST_MAX=102400; $CGI::DISABLE_UPLOADS = 1;
require Mail::Send;
use Fcntl ':flock'; # import LOCK_* constants
#################### GLOBAL SETUP #################################
# Parameter name manipulation, helps prevent some spam
my $nameParam = 'fdsf43';
my $phoneParam = 'xf3f3';
my $floodTime = 120; # flood protection timeout in seconds
my $floodTries = 1; # flood protection - number of requests that are allowed to be sent
my $floodFile = 'flood.ip';
my $sendEmail = 0; # should we send request e-mail?
my $emailAddress = 'callbackscript@example.com'; # to which address should we be sending requests?
my $emailSubject = 'Call Request'; # what e-mail subject should we use?
my $backButtonMessage = 'Please hit your browser\'s Back button and correct this.';
my $userHost = remote_host(); # store user's IP
my $q = new CGI;
printHTML(qq|Name field is required. $backButtonMessage|) if !defined($q->param($nameParam)) or $q->param($nameParam) eq 'Name';
printHTML(qq|Phone number field is required. $backButtonMessage|) if !defined($q->param($nameParam)) or $q->param($phoneParam) eq 'Phone number';
printHTML(qq|Name field may not be longer than 100 characters. $backButtonMessage|)
if length($q->param($nameParam)) > 100;
printHTML(qq|Phone number field may not be longer than 100 characters. $backButtonMessage|)
if length($q->param($phoneParam)) > 100;
my %userInfo = ( 'host' => remote_host(),
'name' => $q->param($nameParam),
'phone number' => $q->param($phoneParam),
'request time' => scalar (localtime(time)));
if (checkFlood($userInfo{'host'}))
{
if (defined($q->param('ajax')))
{
printHTTPHeaders();
print "FLOOD";
exit;
}
printHTML('You have already submitted your request. We will call you as soon as possible. Thank you.');
}
if ($sendEmail) { sendMail(); }
else {testScript(); }
if (defined($q->param('ajax')))
{
printHTTPHeaders();
print "OK";
exit;
}
printHTML('Your request has been submitted. We will call you as soon as possible. Thank you.');
sub testScript
{
printHTMLError ("Failed to open `test` file: $!") unless open TEST_FILE, ">", 'test';
print TEST_FILE <to($emailAddress);
$msg->subject($emailSubject . " from $userInfo{'name'} [" . localtime() . "]");
my $fh = $msg->open('sendmail');
print $fh <close; # complete the message and send it
}
sub checkFlood
{
my $userHost = shift;
my $noFlood = 0; my $yesFlood = 1;
my $separator = ':sep:';
return $noFlood
unless open FLOOD_FILE, "<", $floodFile;
my $userFloodCount = 0;
my @floodData = ();
while()
{
chomp;
my ($ip, $time) = split /\Q$separator\E/, $_, 2;
push @floodData, {'ip' => $ip, 'time' => $time }
unless (time() - $time) > $floodTime;
$userFloodCount++
if $ip eq $userHost
and (time() - $time) < $floodTime;
}
push @floodData, { 'ip' => $userHost, 'time' => time() }
if $userFloodCount <= $floodTries;
close FLOOD_FILE;
return $noFlood
unless open FLOOD_FILE, ">", $floodFile;
flock(FLOOD_FILE, LOCK_EX);
seek(FLOOD_FILE, 0, 2);
foreach my $flooder(@floodData)
{
print FLOOD_FILE $flooder->{'ip'} . $separator . $flooder->{'time'} . $/;
}
flock(FLOOD_FILE, LOCK_UN);
close FLOOD_FILE;
return $yesFlood
if $userFloodCount >= $floodTries;
return $noFlood;
}
sub printHTMLError
{
my $message = shift;
printHTTPHeaders();
print <Fatal Server Error
Fatal Server Error
A server error has occured ( $message ). Try again later. We apologize for the inconvenience.
END_HTML
exit;
}
sub printHTML
{
my $message = shift;
printHTTPHeaders();
print <Foo Bar Baz
SENT
END_HTML
exit;
}
sub printHTTPHeaders
{
print "Content-type: text/html\n\n";
}