#!/usr/bin/perl
my $cwd=".";
use lib ".";
################################################################
# #
# Tell-a-Friend 1.8 #
# (C) 2000-2004 Arvydas Strausas #
# For more information, see: http://www.cgibiz.com/ #
# #
################################################################
# #
# This program is free software; you can redistribute it #
# and/or modify it under the terms of the GNU General Public #
# License as published by the Free Software Foundation; either #
# version 2 of the License, or (at your option) any later #
# version. #
# #
# This program is distributed in the hope that it will be #
# useful, but WITHOUT ANY WARRANTY; without even the implied #
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR #
# PURPOSE. See the GNU General Public License for more #
# details. #
# #
################################################################
use integer;
use Socket;
use cg;
use Captcha::reCAPTCHA;
require "tell.ini";
$cg::params{"version"} = "Powered by Tell-a-Friend 1.8";
my $step = $cg::params{"step"};
my $template;
my %friends;
cg::cookie("name", $cg::params{"name"}, 2419200);
cg::cookie("email", $cg::params{"email"}, 2419200);
$cg::params{"referer"} = detect_referer();
$cg::params{"name"} = $cg::params{"email"} if !$cg::params{"name"};
$cg::params{"message"} = $ini::default_message if !$cg::params{"message"};
$cg::params{"webmaster"} = $ini::webmaster;
$cg::params{"newsletter"} = $ini::newsletter;
$cg::params{"name"} = substr($cg::params{"name"}, 0, 64);
$cg::params{"email"} = substr($cg::params{"email"}, 0, 64);
$cg::params{"message"} = substr($cg::params{"message"}, 0, 512);
begin_page();
if(is_locked()) {
$template = "locked.html";
} else {
step_1() if $step == 1;
step_0() if $step == 0;
}
end_page();
#############################################################################
# #
# B U S I N E S S L O G I C #
# #
#############################################################################
######
sub step_1 {
######
# Verify recaptcha input
my $c = Captcha::reCAPTCHA->new;
my $result = $c->check_answer('6LcF3QAAAAAAAPyE9zA1MDvg0fWzOe2OijjgEwlT', $ENV{'REMOTE_ADDR'},
$cg::params{"recaptcha_challenge_field"}, $cg::params{"recaptcha_response_field"} );
for(my $i = 0; $i < 10 && defined($_ = $cg::params{"friends_email$i"}); $i++) {
if(cg::is_email($_)) {
$friends{substr($_, 0, 64)} = substr($cg::params{"friends_name$i"} ? $cg::params{"friends_name$i"} : $_, 0, 64);
}
}
if(!cg::is_email($cg::params{"email"})) {
error($ini::S_ER_NO_EMAIL);
} elsif(!keys(%friends)) {
error($ini::S_ER_NO_FRIENDS);
} elsif(!$result->{is_valid}) {
error($ini::S_ER_RECAPTCHA);
} else {
my $mail = load_template("tell.txt");
$cg::params{"message"} = "\n$cg::params{'message'}\n" if $cg::params{"message"};
open(LOG, ">>$ini::stats_dir/tell.log") or cg::error("$ini::stats_dir/tell.log");
foreach(keys(%friends)) {
$cg::params{"friends_name"} = $friends{$_};
$cg::params{"friends_email"} = $_;
$_ = $mail; s/\$(\w+)/$cg::params{$1}/ges;
mail($cg::params{"email"}, $cg::params{"friends_email"}, $_);
print(LOG "$cg::now\t$cg::params{'referer'}\t$cg::params{'name'}\t$cg::params{'friends_name'}\n");
}
close(LOG);
mail($cg::params{"email"}, $cg::params{"email"}, parse_template("told.txt")) if $cg::params{"confirm"};
mail($ini::newsletter, $ini::newsletter, parse_template("subscribe.txt")) if cg::is_email($ini::newsletter) && $cg::params{"subscribe"};
mail($ini::webmaster, $ini::webmaster, parse_template("notify.txt")) if cg::is_email($ini::webmaster);
lock_ip();
$template = "told.html";
}
}
######
sub step_0 {
######
# recaptcha staff
my $c = Captcha::reCAPTCHA->new;
$cg::params{"recaptcha_field"}= $c->get_html( '6LcF3QAAAAAAACrk7fk4SunKLSLtNA9Rite9oFxr' );
$template = "tell.html";
}
#############################################################################
# #
# B U S I N E S S L O G I C H E L P E R S #
# #
#############################################################################
##############
sub detect_referer { # $referer
##############
my $referer;
if($ini::autodetect_referer) {
$referer = $cg::params{"referer"};
$referer = $ENV{"HTTP_REFERER"} if !$referer;
$referer = $ini::website if !$referer;
} else {
$referer = $ini::website;
}
return substr($referer, 0, 256);
}
#########
sub is_locked {
#########
my $ip = $ENV{"REMOTE_ADDR"};
my $then = (stat("$ini::ips_dir/$ip"))[9];
if($then && $cg::now - $then < $ini::ip_lockout) {
return 1;
}
return 0;
}
#######
sub lock_ip {
#######
my $ip = $ENV{"REMOTE_ADDR"};
open (IP, ">$ini::ips_dir/$ip");
close(IP);
}
#############
sub load_template { # $template ($file)
#############
my $template;
open (TEMPLATE, "$ini::templates_dir/$_[0]") or cg::error("$ini::templates_dir/$_[0]");
read (TEMPLATE, $template, -s TEMPLATE);
close(TEMPLATE);
return $template;
}
##############
sub parse_template { # $template ($file)
##############
my $s;
my $template = "";
open(TEMPLATE, "$ini::templates_dir/$_[0]") or cg::error("$ini::templates_dir/$_[0]");
while(defined($s = )) {
if(index($s, "\$friends") >= 0) {
foreach(keys(%friends)) {
$cg::params{"friends_name"} = $friends{$_};
$cg::params{"friends_email"} = $_;
$_ = $s; s/\$(\w+)/$cg::params{$1}/ges;
$template .= $_;
}
} else {
$s =~ s/\$(\w+)/$cg::params{$1}/ges;
$template .= $s;
}
}
close(TEMPLATE);
return $template;
}
####
sub mail { # ($from, $to, $body)
####
my $body = $_[2];
if($ini::sendmail) {
open (MAIL, "|$ini::sendmail -t") or cg::error($ini::sendmail);
print(MAIL $body);
close(MAIL);
} elsif($ini::smtp) {
socket(MAIL, AF_INET, SOCK_STREAM, (getprotobyname('tcp'))[2]) &&
connect(MAIL, sockaddr_in((getservbyname('smtp', 'tcp'))[2], (gethostbyname($ini::smtp))[4])) or cg::error($ini::smtp);
$_ = ;
$_ = "HELO $ini::smtp\r\n";
syswrite(MAIL, $_, length($_));
$_ = ;
$_ = "MAIL FROM: <".(cg::is_email($ini::webmaster) ? $ini::webmaster : $_[0]).">\r\n";
syswrite(MAIL, $_, length($_));
$_ = ;
$_ = "RCPT TO: <$_[1]>\r\n";
syswrite(MAIL, $_, length($_));
$_ = ;
$_ = "DATA\r\n";
syswrite(MAIL, $_, length($_));
$_ = ;
$_ = "$body\r\n.\r\n";
syswrite(MAIL, $_, length($_));
$_ = ;
$_ = "QUIT\r\n";
syswrite(MAIL, $_, length($_));
$_ = ;
close(MAIL);
}
}
#############################################################################
# #
# U S E R I N T E R F A C E H E L P E R S #
# #
#############################################################################
##########
sub begin_page {
##########
cg::content_type("text/html");
}
########
sub end_page { # {$template}
########
cg::print(parse_template($template));
}
#####
sub error { # ($info)
#####
$cg::params{"error"} = "$ini::S_ER_ERROR: $_[0]";
$step--;
}