#!/usr/bin/perl use CGI qw/:standard/; use CGI::Carp(fatalsToBrowser); $cgi = new CGI; for($cgi->param()) { $F{$_} = $cgi->param($_); } my ($html); # holds html template # bootcha out if'n ya ain't lookin for no raffle if(param('forum') ne 'raffle') { print "Location:http://www.nationalgeographic.com/ngforkids/\n\n"; } print header; # get url and script name my $url = url(); my $script_name = script_name(); # read params my $forum = param('forum'); # forum name my $op = param('op'); # operation my $start |= param('start'); # starting message # these a'bee defin-ed here so's ya don't gotta type 'em out so many gauldurn times # but can, instead, loop over them as such: for(@fields) { print "$_
\n"; } # or wateva joo wana do wif dem @fields = ('fname','lname','t_grade','t_subject','schoolname','schoolstreet','schoolcity','schoolstate','schoolzip','schoolphone','t_email','wantupdates'); # make 'post' el action-o default-o $op='post' if not $op; # where's the template that has the form in it?! where is it?! huh?!!!1 my $post_template = 'post.html'; # oh. # read common config file require 'common.conf'; # gimmie dat forum config jonx # if'n it's 'round these hear parts! if(-e "$forum/$forum.conf") { require "$forum/$forum.conf"; } # noconffileforyougoaway! else { &no_forum;exit; } my $mail_program = "/usr/lib/sendmail -i -t"; # max msg per page $max = 10; # messages directory for this forum my $message_dir = "$forum/entries"; if($op eq 'post'){ # are all required fields are filled in? if(all_required()) { # yes: create entry file on server, print 'thanks' page &create_message; $template = 'thanks.html'; $html = &slurp($template); } else { # no: pout, sulk, and return user to entry form $template = "$forum/$post_template"; $html = &slurp($template); $html = &post_page($html); } } elsif($op eq 'edit'){ my $username = param('username'); my $password = param('password'); if(&authenticate($username,$password)){ if($message = param('message')){ if(param('action') eq 'Edit'){ $html = &slurp("$forum/edit.html"); $html = &message_edit_page($html,$message,$username,$password); } elsif(param('action') eq 'Delete'){ &delete_message($message); } elsif(param('action') =~ /^Update/){ if(param('action') =~ /Live/) { &update_message($message,1); } else { &update_message($message,0); } } elsif(param('action') eq 'Unpost'){ &unpost_message($message); } } if(param('action') ne 'Edit') { $html = &slurp("$forum/edit_list.html"); $html = &edit_page($html,$username,$password); } } else { $html = &slurp("$forum/password.html"); } } $html =~ s//$script_name/g; $html =~ s//$forum/g; print $html; #### SUBROUTINES #### # returns contents of file $filename sub slurp{ my $filename = shift; local $/; open FH, "< $filename"; my $text = ; close FH; return $text; } # read in and print out post template # used to insert timestamp in served page # timestamp is now set to time server recieves form (in &create_message) # so this sub does basically nothing... # (since and aren't in the post template) sub post_page { my ($html) = @_; # get current time and date for(@fields) { $$_ = param($_); $html =~ s/<$_>/$$_/g; } if($fields_missing) { $html =~ s///g if $fields_missing; $html =~ s/<\/tr error\-\->/<\/tr>/g if $fields_missing; } if($t_grade = param('t_grade')) { $html =~ s/$t_grade t_grade/selected/ge; } if($t_subject = param('t_subject')) { $html =~ s/$t_subject t_subject/selected/ge; } if($schoolstate = param('schoolstate')) { $html =~ s/$schoolstate schoolstate/selected/ge; } $post_date_time = &get_date_time; $format_date_time = &format_date_time($post_date_time); $html =~ s//$post_date_time/g; $html =~ s//$format_date_time/g; return $html; } # prints list of messages, filtered based on user input (ALL, UM, UP, LIVE) sub edit_page { my ($html,$username,$password) = @_; my $message_loop; # make sure values required to keep state are present in all forms $html =~ s//$username/g; $html =~ s//$password/g; $html =~ s//$script_name/g; $html =~ s//$start/; $html =~ s//$forum/g; $html =~ m@(.*)@s; my $loop_template = $1; $edit_mode |= param('edit_mode'); $html =~ s//$edit_mode/g; print < Edit Page JS_HACK # edit modes: ALL, UM, UP, LIVE # filtering # @msg = `ls $message_dir/*.msg`; if($edit_mode eq 'UM') { @files = `ls $message_dir/UM*.msg`; } elsif($edit_mode eq 'UP') { @files = `ls $message_dir/UP*.msg`; } elsif($edit_mode eq 'LIVE') { @files = `ls $message_dir/*.msg | grep -v U`; } else { @files = `ls $message_dir/*.msg`; } foreach(@files) { chomp($_); s/$message_dir\///eg; } # custom sort alg. so unmoderated message numbers don't get # sorted down to the end and re-used, then overwritten @files = reverse sort fn_cmp @files; # loop over correct set of message filenames if(param('start')) { $q = param('start'); } else { $q = 0; } for($q;$q<($start+$max);$q++) { last if($q>$#files); &get_message_data("$message_dir/$files[$q]"); my ($message_id,$ext) = split /\./,$files[$q]; if($message_id =~ /^[A-Z]/) { $message_id = substr($message_id,0,8); } else { $message_id = substr($message_id,0,6); } my $tmp = $loop_template; my @l_fields = ('status','fname','lname','message_date_time','schoolname','schoolstreet','schoolcity','schoolstate','schoolzip','schoolphone'); $tmp =~ s//$files[$q]/g; if($files[$q] =~ /^[A-Z]/) { $status = "NOT Live"; } else { $status = "Live"; } for(@l_fields) { $tmp =~ s/<$_>/$$_/ge; }; $tmp =~ s//$message_id/g; $tmp =~ s/\]\-\->/
teaches grade \[$t_grade\]<\/b>/g if $t_grade; $tmp =~ s/\]\-\->/
teaches subject \[$t_subject\]<\/b>/g if $t_subject; $tmp =~ s/\]\-\->/
email \[$t_email\] \(Okay to contact\)<\/b>/g if $t_email and $wantupdates ne 'no'; $message_loop .= $tmp; } $html =~ s@(.*)@$message_loop@s; # deal with navigation $start = param('start'); $prev = $start - $max; $next = $start + $max; if ($prev < 0){ $html =~ s/.*/ /s; } else { $html =~ s//$prev/; } if ($next >= $#files){ $html =~ s/.*/ /s; } else { $html =~ s//$next/; } return $html; } # prints info for message $message.msg sub message_edit_page { my ($html,$message,$username,$password) = @_; if($message =~ /^UM/) { $msg_status = 'UnModerated (NOT Live)'; } elsif($message =~ /^UP/) { $msg_status = 'UnPosted (NOT Live)'; } elsif($message =~ /^[^A-Z]*/) { $msg_status = 'Live Message'; } $html =~ s//$username/g; $html =~ s//$password/g; $html =~ s//$script_name/g; $html =~ s//$forum/g; $html =~ s//$start/; $html =~ s//

$message/g; $html =~ s//$msg_status<\/h3>/g; &get_message_data("$message_dir/$message.msg"); my @l_fields = ('t_grade','t_subject','schoolname','schoolstreet','schoolstate','schoolcity','schoolzip','schoolphone','t_email','wantupdates'); for(@l_fields) { $html =~ s/<$_>/$$_/ge; } $html =~ s//$message/g; $html =~ s//$message_date_time/g; $html =~ s//$fname $lname/g; return $html; } # load values for message $filename into appropriate global vars sub get_message_data { local($filename) = @_; open (MESSAGEFILE, "$filename") || die "Could not open $filename\n: $!"; # set all globals for access by calling function for(@fields) { $$_ = '';chomp($$_ = ); } $message_date_time = ; close(MESSAGEFILE); } # return formatted date and, uh, time # given $date_time in format returned from &get_date_time sub format_date_time { my ($date_time) = @_; my (@long_month) = ("Bad month", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"); my ($year, $mon, $mday, $hour, $min, $sec) = split(/:/, $date_time); my $date = "$long_month[$mon] $mday, $year"; my $ampm = "AM"; $ampm = "PM" if ($hour > 11); if ($hour > 12) {$hour -= 12} else {$hour =~ s/^0//g;} my $time = "$hour:$min $ampm"; $dt = "$date $time"; return $dt; } # what time is it? sub get_date_time { my ($sec, $min, $hour, $mday, $mon); my ($year, $wday, $yday, $isdst); my ($ampm, $currentdatetime, $dateTime); ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); $year = 1900 + $year; $mon++; if ($min < 10) { $min = "0" . $min; } if ($sec < 10) { $sec = "0" . $sec; } $dateTime = "$year:$mon:$mday:$hour:$min:$sec"; return $dateTime; } # return 1 for valid or 0 for invalid login sub authenticate{ my ($username,$password) = @_; my $mod_flag = 0; my $fb_flag = 0; my $flag = 0; foreach (@moderator_email){ $mod_flag = 1 if $_ eq $username; } foreach (@feedback_email){ $fb_flag = 1 if $_ eq $username; } $flag = 1 if ($mod_flag || $fb_flag) && $password eq $moderator_password; return $flag; } # make a new message sub create_message { my $msg = ''; # $whatever = &taint_check(param('whatever')); for(@fields) { &taint_check(param($_)); } # build $msg, which is what gets fed directly to the flat file storing this info for(@fields) { $msg .= param($_)."\n"; } $message_date_time = format_date_time(get_date_time()); $msg .= "$message_date_time\n"; @files = `ls $message_dir/*.msg`; foreach(@files) { chomp;s/$message_dir\///e; } foreach(@files) { s/^[A-Z]*//; } @files = sort @files; # make new filename $highNumber = substr($files[@files - 1],0,6); $highNumber++; $highNumber = sprintf("%6d",$highNumber); $highNumber =~ tr/ /0/; $highNumber = "000001" if ($highNumber eq "000000"); $messageName = "$highNumber" . ".msg"; if($email_moderator eq 'on') { } else { $messageName = 'UM'.$messageName; } open(WRITEMSG, ">$message_dir/$messageName") || die("Could't open $messageName for writing"); print WRITEMSG $msg; close (WRITEMSG); if ($email_moderator eq 'on'){ my $from = ' '; my $to = join ',',@moderator_email; my $subject = qq(New forum message); my $message = qq($msg\n); $message .= qq(To edit message click below and enter your email and password:\n); $message .= qq($url?forum=$forum&op=edit); &send_mail($from, $to, $subject, $message); } } # update changes to message $message.msg sub update_message { $message = shift; my $put_live = shift; $message_file = "$message_dir/$message.msg"; if($put_live && $message =~ /^[A-Z]+/) { unlink $message_file || die "Couldn't delete $message: $!\n"; $message =~ s/^[A-Z]+//; $message_file = "$message_dir/$message.msg"; } my @l_fields = ('message_date_time','name','t_grade','t_subject','schoolname','schoolname','schoolstate','schoolcity','schoolzip','schoolphone','t_email','wantupdates'); for(@l_fields) { $$_ = param($_); $$_ =~ s/\r|\n//g; } ($fname,$lname) = split ' ',$name; # build $msg, which is what gets fed directly to the flat file storing this info $msg = "$fname\n$lname\n"; for(@fields) { $msg .= param($_)."\n" unless $_ eq 'fname' or $_ eq 'lname'; } $msg .= "$message_date_time\n"; open(WRITEMSG, ">$message_file") || die("Could't open $message_file for writing"); print WRITEMSG $msg; close (WRITEMSG); } # update changes to message $message.msg and add prefix 'UP' to message if live sub unpost_message { $message = shift; $message_file = "$message_dir/$message.msg"; if($message !~ /^UP/) { unlink $message_file || die "Couldn't delete $message: $!\n"; $message = "UP".$message; $message_file = "$message_dir/$message.msg"; } my @l_fields = ('message_date_time','name','t_grade','t_subject','schoolname','schoolname','schoolstate','schoolcity','schoolzip','schoolphone','t_email','wantupdates'); for(@l_fields) { $$_ = param($_); $$_ =~ s/\r|\n//g; } ($fname,$lname) = split ' ',$name; # build $msg, which is what gets fed directly to the flat file storing this info $msg = "$fname\n$lname\n"; for(@fields) { $msg .= param($_)."\n" unless $_ eq 'fname' or $_ eq 'lname'; } $msg .= "$message_date_time\n"; open(WRITEMSG, ">$message_file") || die("Could't open $message_file for writing"); print WRITEMSG $msg; close (WRITEMSG); } # makes the message go bye-bye sub delete_message{ $message = shift; $message_file = "$message_dir/$message.msg"; unlink "$message_file" || die "Couldn't delete $message_file: $!"; } # remove suspicious characters from message input fields sub taint_check{ my $str = shift; $str =~ s/javascript://g; $str =~ s/\|//g; $str =~ s/\*/\&\#042\;/g; $str =~ s/\!/\&\#033\;/g; $str =~ s/\/\&\#062\;/g; $str =~ s/\?/\&\#063\;/g; $str =~ s/\$/\&\#036\;/g; $str =~ s/\r|\n//g; return $str; } ########################################################### # # subroutine: send_mail # Usage: # &send_mail("me@myhouse.com","you@yourhouse.com","them@theirhouse.com","Mysubject", "My message"); # # Parameters: # $from = Full Email address of sender # $to = Full Email address of receiver # $cc = Full Email address of cc # $subject = Subject of message # $messagebody = Body of message including newlines. # # Output: # None # ############################################################ sub send_mail { my($from, $to, $subject, $messagebody, $cc) = @_; # open(SENDMAIL, "|$mail_program ") or die "Can't fork for sendmail: $!\n"; # # print SENDMAIL qq(From: $from\n); # print SENDMAIL qq(To: $to\n); # print SENDMAIL qq(CC: $cc\n) if $cc; # print SENDMAIL qq(Subject: $subject\n\n); # print SENDMAIL qq($messagebody\n); # close(SENDMAIL); } ########################################################### # # subroutine: email_feedback # Usage: # # # Parameters: # # # Output: # None # ############################################################ sub email_feedback { my $name = param('name'); my $email = param('email'); my $subject = param('subject'); my $from = "$email"; my $to = join ',',@feedback_email; #my $cc = join ',',@moderator_email; my $message = qq(forum: $forum\nname: $name\nemail: $email\n\n$message\n); &send_mail($from, $to, $subject, $message); } # returns 1 if all required fields are filled in, 0 if some are missing sub all_required { my @req_fields = ('fname','lname','schoolname','schoolstreet','schoolcity','schoolstate','schoolzip','schoolphone','wantupdates'); for(@req_fields) { if(not defined $cgi->param($_) or $cgi->param($_) eq '') { $fields_missing = 1 if param('flag'); return 0; } } $fields_missing = 0; return 1; } # custom sort function: # sorts internal numbers without regard for leading alphabetical characters # ex: UM000007 and 000003 would normally not be sorted correctly sub fn_cmp { my $eval_str = '$a <=> $b'; if(length($a)>10) { $tmp_a = $a; $tmp_a =~ s/^[A-Z]+//; $eval_str =~ s/a/tmp_a/; } if(length($b)>10) { $tmp_b = $b; $tmp_b =~ s/^[A-Z]+//; $eval_str =~ s/b/tmp_b/; } return eval($eval_str); }