#!/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 <a target=_blank href=\"http://www.cgibiz.com/\">Tell-a-Friend 1.8</a>";

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<a href='mailto:$cg::params{'email'}'>$cg::params{'name'}</a>\t<a href='mailto:$cg::params{'friends_email'}'>$cg::params{'friends_name'}</a>\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 = <TEMPLATE>)) {
      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);

      $_ = <MAIL>;
      $_ = "HELO $ini::smtp\r\n";
      syswrite(MAIL, $_, length($_));
      $_ = <MAIL>;
      $_ = "MAIL FROM: <".(cg::is_email($ini::webmaster) ? $ini::webmaster : $_[0]).">\r\n";
      syswrite(MAIL, $_, length($_));
      $_ = <MAIL>;
		$_ = "RCPT TO: <$_[1]>\r\n";
      syswrite(MAIL, $_, length($_));
      $_ = <MAIL>;
      $_ = "DATA\r\n";
      syswrite(MAIL, $_, length($_));
		$_ = <MAIL>;
		$_ = "$body\r\n.\r\n";
      syswrite(MAIL, $_, length($_));
		$_ = <MAIL>;
		$_ = "QUIT\r\n";
      syswrite(MAIL, $_, length($_));
		$_ = <MAIL>;

      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"} = "<b>$ini::S_ER_ERROR:</b> $_[0]";

   $step--;
}
