#!/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 = ""; }