#!/usr/local/bin/perl -w
############################################################
#
# spread.cgi - Auto-generated from fsa2cgi
#
# Sends notification about the site to recipients
# whose e-mail addressees are submitted via form
#
############################################################
require 5.002;
#use strict;
use Socket;
require "client_lib.pl";
require "spread_html.pl";
use CGI qw(:standard);
use Fcntl;
use File::Basename;
init_vars();
$spread_file = "$datadir/spread.txt";
# The site is driven by a Finite State Automaton, or FSA.
# The fsa_state_machine contains key/value pairs where the key is comprised
# of two numbers, fsa_cur_state and fsa_token, separated by __ .
# The value is fsa_next_state.
#
%fsa_state_machine = (
INIT__START_TOKEN => INIT ,
INIT__SEND_TOKEN => INIT ,
INIT__ERR_TOKEN => INIT ,
);
%state_hash = (
INIT => "0000" ,
FINISH => "0001" ,
);
%token_hash = (
START_TOKEN => "0000" ,
SEND_TOKEN => "0001" ,
ERR_TOKEN => "0002" ,
CONTINUE_TOKEN => "0003" ,
);
###########################################################################
###########################################################################
#
$NO_MSG = " ";
$OK = 1;
$BAD = 0;
$STOP = 0;
$CONTINUE = 1;
###############################################################################
###############################################################################
#
# Start of main code. After some initialization, we parse out the token
# and use it along with $in{'fsa_cur_state'} to determine the transition
# action to take and the next state.
#
###############################################################################
###############################################################################
CGI::ReadParse();
print CGI::PrintHeader();
init_vars();
my $fsa_status = $CONTINUE;
my $fsa_msg = $NO_MSG;
my ($fsa_cur_state,$fsa_token,$fsa_next_state);
srand(time || $$);
$fsa_cur_state = get_cur_state();
$fsa_token = parse_token();
while ($fsa_status != $STOP)
{
($fsa_status,$fsa_next_state,$fsa_trans_sub_name) =
set_fsa($fsa_cur_state,$fsa_token);
($fsa_status,$fsa_token,$fsa_msg) = &$fsa_trans_sub_name($fsa_cur_state,
$fsa_next_state,$fsa_msg) if $fsa_status == $CONTINUE;
}
###############################################################################
#
# get_cur_state() = determines the current state upon code entry
#
###############################################################################
sub get_cur_state
{
my $cur_state;
$cur_state = $state_hash{'INIT'} if !defined($in{'fsa_cur_state'});
$cur_state = $in{'fsa_cur_state'} if defined($in{'fsa_cur_state'});
return $cur_state;
}
###############################################################################
#
# parse_token()
# This determines what the current token based on which button was hit.
# Returns: value of this token (see %token_hash)
#
###############################################################################
sub parse_token
{
my $default_token;
my $field;
$default_token=get_default_token($fsa_cur_state);
print_fsa_err("Bad Default token") if $default_token eq "ERR_TOKEN";
return $token_hash{'SEND_TOKEN'} if &get_image_button ne "";
return($token_hash{$default_token});
}
###############################################################################
#
# get_default_token()
#
# returns a default token value if user just hits enter on a form
#
###############################################################################
sub get_default_token
{
my ($cur_state) = @_;
return "START_TOKEN" if $cur_state eq $state_hash{"INIT"};
}
###############################################################################
# set_fsa: compute next state and get transition sub name
# First, lookup the names of both the current state and token,
# then get the next state and derive the transition code sub name
###############################################################################
sub set_fsa
{
my ($fsa_cur_state,$fsa_token) = @_;
my $fsa_status = $CONTINUE;
my ($fsa_state_name,$fsa_next_state,$fsa_trans_sub_name);
my ($state_key, $token_key);
foreach $state_key ( keys %state_hash )
{
if( $state_hash{$state_key} == $fsa_cur_state)
{
$fsa_state_name = $state_key;
last;
}
}
foreach $token_key ( keys %token_hash )
{
if( $token_hash{$token_key} == $fsa_token)
{
$fsa_state_name .= "__$token_key";
last;
}
}
if (defined($fsa_state_machine{$fsa_state_name}))
{
$fsa_next_state = $state_hash{$fsa_state_machine{$fsa_state_name}};
$fsa_trans_sub_name = "${fsa_state_name}_trans";
}
else
{
print_fsa_err("Undefined Next State",$fsa_cur_state,$fsa_token)
if !defined($fsa_state_machine{$fsa_state_name});
$fsa_status = $STOP;
}
return ($fsa_status,$fsa_next_state,$fsa_trans_sub_name);
}
###############################################################################
# print_fsa_err
###############################################################################
sub print_fsa_err
{
my ($msg,$cur_state,$token,$next_state) = @_;
display_html("$s_temp_1");
print "";
print "The system encountered an unrecoverable error.\n";
print "
\n";
print "Please contact $client_name with the following information:
\n";
print "Current State = $cur_state
\n" if defined $cur_state;
print "Current Token = $token
\n" if defined $token;
print "Next State = $next_state
\n" if defined $next_state;
print "Message = $msg
\n";
display_html("$s_temp_2");
}
###########################################################################
# Start of Transition Code
###########################################################################
###########################################################################
# INIT__START_TOKEN => INIT
###########################################################################
sub INIT__START_TOKEN_trans
{
my ($cur_state,$next_state,$msg) = @_;
my $rtn_val = $STOP;
my $rtn_tok = $token_hash{'CONTINUE_TOKEN'};
if($rtn_tok == $token_hash{'CONTINUE_TOKEN'})
{
show_init ($cur_state,$next_state,$msg);
$msg=$NO_MSG;
}
$rtn_val = $CONTINUE if $rtn_tok != $token_hash{'CONTINUE_TOKEN'};
return ($rtn_val,$rtn_tok,$msg);
}
###########################################################################
# INIT__SEND_TOKEN => FINISH
###########################################################################
sub INIT__SEND_TOKEN_trans
{
my ($cur_state,$next_state,$msg) = @_;
my $rtn_val = $STOP;
my $rtn_tok = $token_hash{'CONTINUE_TOKEN'};
my @recips;
($rtn_tok,$msg) = check_form('INIT');
if($rtn_tok == $token_hash{'CONTINUE_TOKEN'})
{
push @recips,"$in{'name1'}||$in{'email1'}"
if defined($in{'email1'}) && $in{'email1'} ne "";
push @recips,"$in{'name2'}||$in{'email2'}"
if defined($in{'email2'}) && $in{'email2'} ne "";
push @recips,"$in{'name3'}||$in{'email3'}"
if defined($in{'email3'}) && $in{'email3'} ne "";
send_spreadmail(@recips);
if($rtn_tok == $token_hash{'CONTINUE_TOKEN'})
{
show_init($cur_state,$next_state,"Your message has been sent.");
$msg=$NO_MSG;
}
}
$rtn_val = $CONTINUE if $rtn_tok != $token_hash{'CONTINUE_TOKEN'};
return ($rtn_val,$rtn_tok,$msg);
}
###########################################################################
# INIT__ERR_TOKEN => INIT
###########################################################################
sub INIT__ERR_TOKEN_trans
{
my ($cur_state,$next_state,$msg) = @_;
my $rtn_val = $STOP;
my $rtn_tok = $token_hash{'CONTINUE_TOKEN'};
if($rtn_tok == $token_hash{'CONTINUE_TOKEN'})
{
show_init($cur_state,$next_state,$msg);
$msg=$NO_MSG;
}
$rtn_val = $CONTINUE if $rtn_tok != $token_hash{'CONTINUE_TOKEN'};
return ($rtn_val,$rtn_tok,$msg);
}
###########################################################################
# End of Transition Code
###########################################################################
###########################################################################
# check_form: Edit Check fields on forms
###########################################################################
sub check_form
{
my ($form) = @_;
my $rtn_tok = $token_hash{'CONTINUE_TOKEN'};
my $msg = $NO_MSG;
for($form)
{
/INIT/ and do
{
if(!defined($in{'sendername'}) || $in{'sendername'} eq "")
{
$msg .= "Your Name is required.
";
}
if(!defined($in{'senderemail'}) || $in{'senderemail'} eq "")
{
$msg .= "Your E-Mail address is required.
";
}
elsif($in{'senderemail'} !~ /\@/)
{
$msg .= "Your E-mail address is invalid: $in{'senderemail'}.
";
}
if(defined($in{'name1'}) && $in{'name1'} ne "")
{
if(!defined($in{'email1'}) || $in{'email1'} eq "")
{
$msg .= "E-Mail address 1 is required.
";
}
elsif($in{'email1'} !~ /\@/)
{
$msg .= "Invalid E-mail address $in{'email1'}.
";
}
}
elsif(defined($in{'email1'}) && $in{'email1'} ne "")
{
$msg .= "Name 1 is required.
";
}
if(defined($in{'name2'}) && $in{'name2'} ne "")
{
if(!defined($in{'email2'}) || $in{'email2'} eq "")
{
$msg .= "E-Mail address 2 is required.
";
}
elsif($in{'email2'} !~ /\@/)
{
$msg .= "Invalid E-mail address $in{'email2'}.
";
}
}
elsif(defined($in{'email2'}) && $in{'email2'} ne "")
{
$msg .= "Name 2 is required.
";
}
if(defined($in{'name3'}) && $in{'name3'} ne "")
{
if(!defined($in{'email3'}) || $in{'email3'} eq "")
{
$msg .= "E-Mail address 3 is required.
";
}
elsif($in{'email3'} !~ /\@/)
{
$msg .= "Invalid E-mail address $in{'email3'}.
";
}
}
elsif(defined($in{'email3'}) && $in{'email3'} ne "")
{
$msg .= "Name 3 is required.
";
}
};
}
$rtn_tok = $token_hash{'ERR_TOKEN'} if $msg ne $NO_MSG;
return($rtn_tok,$msg);
}
#####################################################################
# send_spreadmail - sends email to all recipients
#####################################################################
sub send_spreadmail
{
my (@recips) = @_;
my ($remote,$port,$iaddr,$paddr,$proto,$line);
my ($buffer, $list);
my $subject = "A great new language website\!\!";
my ($body) = "";
my ($name,$email);
$body = "A message from $in{'sendername'} ($in{'senderemail'}):\n\n";
open SFH, "$spread_file";
while()
{
$body .= $_;
}
close SFH;
$body .= "\n.\n";
#$remote = $mail_server;
#$remote = mail.alacritus.com;
$remote = "localhost";
$port = 25;
$iaddr = inet_aton($remote);
$paddr = sockaddr_in($port,$iaddr);
$proto = getprotobyname('tcp');
socket(SOCK,PF_INET,SOCK_STREAM,$proto) or die "Socket: $!\n";
connect(SOCK,$paddr) or die "Connect: $!\n";
$line = ;
send SOCK,"HELO $client_mailsrv_id\n",0; # make sure to init.
# $client_mailsrv_id sonewhere in
# main script Library, etc.
$line = ;
foreach $addr ( @recips )
{
($name,$email) = split /\|\|/,$addr;
send SOCK, "MAIL From: $spread_addr\n",0;
$line = ;
send SOCK, "RCPT To: $email\n",0;
send SOCK, "RCPT To: $spread_addr\n",0;
$line = ;
send SOCK, "DATA\n",0;
$line = ;
send SOCK, "Subject: $subject\nDear $name,\n\n$body",0;
$line = ;
}
send SOCK, "QUIT\n",0;
close(SOCK);
}
###########################################################################
# Read image button
###########################################################################
sub get_image_button
{
my $rtn_val = "";
$rtn_val="1" if defined($in{'sib.x'});
return($rtn_val);
}
###########################################################################
# Get rid of warings from -w flag
###########################################################################
sub no_once_warning
{
$red = "";
$s_temp_1 = "";
$s_temp_2 = "";
$client_name = "";
$OK = 1;
$BAD = 0;
$client_mailsrv_id = "";
$spread_addr = "";
$mail_server = "";
}