#!/usr/bin/perl -w # -Tw # check for student 4x4 and team # to start review # get review item number from list # Copyright 2002-2011 Dean F. Hougen. All rights reserved. $review_dir = '/home/hougen/www/classes/Fall-2011/Robotics/reviews/'; $class_file = $review_dir . 'classfile'; $sendmail = '/usr/lib/sendmail'; $num_teams = 5; use CGI; use Fcntl qw(:DEFAULT :flock); $review = new CGI; $ENV{'PATH'} = '/usr/bin:/usr/lib'; delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; # sub untaint; # sub user_login_form; # sub validate_login; # sub user_review_form; # sub thank_you; $action = $review->param('action'); if (!$action) { # there is no action, must be the first time here, present login form user_login_form(); } elsif ($action eq 'LOGIN'){ validate_login(); $review_num = $review_base; user_review_form(); } elsif ($action eq 'SUBMIT'){ validate_login(); process_review_form(); $review_offset++; if ($review_item eq 'P2Project' || $review_item eq 'P3Project'){ $review_base += 0; $review_num = $review_base + $review_offset; if ($review_num > $num_teams) { $review_num -= $num_teams; } } else { $review_num = $review_base + $review_offset; } if ($review_offset < $num_reviews) { user_review_form(); } elsif ($review_offset == $num_reviews) { thank_you(); } else { die "Invalid Review Num: $review_num\n"; } } else { # action is undefined error_page ("

Error Running Script -- undefined action: $action.

"); } ####################################################################### sub user_login_form{ print "Content-type: text/html\n\n"; print <<"EOF"; CS 4023/5023 - Intro to Intelligent Robotics - Spring 2009, Review Login

Login Page for Reviews

Please note that you should evaluate yourself as well as your team mates.

Enter your OU 4x4; team number; team size; and full, formal, official OU email address (e.g., "Dean.F.Hougen-1" rather than just "hougen").

OU 4 x 4:
Team Number:
Number of Members in Your Team (Including You):
OU Email Address: \@ou.edu
EOF } # end of user_login_form ####################################################################### sub validate_login{ #process the login information $four_by_four = $review->param('four_by_four'); $team_num = $review->param('team_num'); $team_size = $review->param('team_size'); $review_item = $review->param('review_item'); $review_offset = $review->param('review_offset'); $review_num = $review->param('review_num'); $email_addr = $review->param('email_addr'); #check for length of 4x4 unless (length($four_by_four) > 5 && length($four_by_four) < 9) { error_page("

Error Logging In -- Invalid Login Information.

4 x 4 Given: $four_by_four

"); } #untaint 4x4 $four_by_four = untaint($four_by_four); #check for length of Team Number unless (length($team_num) < 2 && $team_num > 0 && $team_num <= $num_teams) { error_page("

Error Logging In -- Invalid Login Information.

Team Number Given: $team_num

"); } #untaint Team Number $team_num = untaint($team_num); #check for length of Team Size unless (length($team_size) < 2 && $team_size > 1 && $team_size < 6) { error_page("

Error Logging In -- Invalid Login Information.

Team Size Given: $team_size

"); } #untaint Team Size $team_size = untaint($team_size); #untaint Review Item $review_item = untaint($review_item); #determine number of times through form # if ($review_item eq 'P1Tasks' || $review_item eq 'P1Time' # || $review_item eq 'P1Project'){ # $num_reviews = $num_teams; # } # else { # $num_reviews = $team_size; # } if ($review_item eq 'P1Peer' || $review_item eq 'P2Peer' || $review_item eq 'P3Peer' || $review_item eq 'P4Peer' || $review_item eq 'FinalProjectPeer'){ #for peer reviews of teammates, start with 1 and go to the number #of team members $num_reviews = $team_size; $review_base = 1; } else { #for reviews of team materials, start with own team number and #review three other teams (four reviews total) $review_base = $team_num; $num_reviews = 4; } #untaint Email Address $email_addr = untaint($email_addr); #combine 4x4 and Team Number into a single data item $login_code = $four_by_four . $team_num . $email_addr ; #$login_code = $four_by_four . $team_num; #debug_page("Login code is: $login_code"); #open class file non-destructively, read in entries #entry format is "4x4#email_addr" on each line $found = 0; sysopen(STUDENTS, "$class_file", O_RDONLY) or die "Can't open $class_file: $!"; flock(STUDENTS, LOCK_SH) or die "Can't get shared lock on $class_file: $!"; while() { #debug_page("item is: $_"); if ($login_code . "\n" eq $_) { $found = 1; #debug_page("Found is true!"); } } close(STUDENTS) or die "Can't close $class_file: $!"; # $student_list .= $_; # } # close(STUDENTS) or die "Can't close $class_file: $!"; # # debug_page("Student list is: $student_list"); # # #see if login info matches file # # $found = 0; # foreach $student ($student_list) { # debug_page("Student is: $student"); # if ($student eq $login_code) { # $found = 1; # debug_page("Found is true!"); # } # } #debug_page("Found is: $found"); unless (1 == $found){ error_page("

Error Logging In -- Invalid Login Information.

4 x 4 Given: $four_by_four
Team Number Given: $team_num
OU Email Address Given: $email_addr\@ou.edu

"); } } ####################################################################### sub process_review_form{ #process the review form $review_data = ''; foreach $field ($review->param) { if (length($field) > 20){ die "Sabotaged Form\n"; } $field = untaint($field); foreach $value ($review->param($field)) { $value = untaint($value); #we want to make sure no field is blank; unfortunately, perl #cannot tell the difference between 0 and no value, and we want #review_offset to start at 0, so we have to exclude that #variable from our check if (((!$field eq 'review_offset') && (!$value)) || $value eq '-1'){ error_page("

Cannot Leave Any Fields Blank: $field

"); } if (length($value) > 1000){ error_page("

Error In Form Data -- Invalid Information.

Data Value (must be 1000 characters or less): $value

"); } $review_data .= "$field: $value\n"; } } #generate file name from data $filename = $review_dir . $review_item . $login_code . $review_num; #open file, write, and close sysopen(REVIEW_FILE, "$filename", O_CREAT | O_EXCL | O_WRONLY) or error_page ("

Error Saving Review -- Already Completed.

We already have this review on file for you. If this is incorrect, please contact Prof. Hougen.

"); flock(REVIEW_FILE, LOCK_EX) or error_page ("

Error Saving Review -- Locking Error

Can't get exclusive lock on $filename: $!

"); print REVIEW_FILE $review_data or error_page ("

Error Saving Review -- Writing Error

Can't write to $filename: $!

"); close(REVIEW_FILE) or error_page ("

Error Saving Review -- Close Error

Can't close $filename: $!

"); } ####################################################################### sub user_review_form{ #the file name to open is built from the review item name $filename = $review_item . '.html'; print "Content-type: text/html\n\n"; sysopen(FORM_FILE, "$filename", O_RDONLY) or die "Can't open $filename: $!"; flock(FORM_FILE, LOCK_SH) or die "Can't get shared lock on $filename: $!"; while() { #debug_page("item is: $_"); if ($_ eq "

This is the form for team X.

\n"){ print "

This is the form for team $review_num.

\n"; } elsif ($_ eq "

Form for team member X

\n"){ print "

Form for team member $review_num\n"; } else { print; } } close(FORM_FILE) or die "Can't close $filename: $!"; print <<"EOF"; EOF } ####################################################################### sub untaint{ my $local_var = $_[0]; unless ($local_var =~ /^([^<]*)$/) { die "Couldn't untaint entry: $local_var\n"; } #print $1; return $1; } ####################################################################### sub error_page{ print "Content-type: text/html\n\n"; print <<"EOF"; CS 4023/5023 - Intro to Intelligent Robotics - Spring 2009, Form Error @_

Please back up and try again.

EOF die "Error: @_\n"; } ####################################################################### sub debug_page{ print "Content-type: text/html\n\n"; print <<"EOF"; CS 4023/5023 - Intro to Intelligent Robotics - Spring 2009, Debug Page @_ EOF } ####################################################################### sub thank_you{ open(MAIL, "|$sendmail -t") or error_page ("Can't open pipe to $sendmail: $!\n"); print MAIL "To: $email_addr\@ou.edu\n"; print MAIL "From: Dean Hougen \n"; print MAIL "Cc: Dean Hougen \n"; print MAIL "Subject: Review Form Submission Complete\n\n"; print MAIL "You have completed the reviews for $review_item.\n\n"; print MAIL "Thank you,\n"; print MAIL "Prof. Hougen\n"; close(MAIL) or error_page ("Can't close pipe to $sendmail: $!\n"); print "Content-type: text/html\n\n"; print <<"EOF"; CS 4023/5023 - Intro to Intelligent Robotics - Spring 2009, Review Completion

Thank you for completing the review process for $review_item.

You will soon receive an email verifying your completion of this process.

EOF }