#!/usr/bin/perl -Tw # check for student 4x4 and team # to start review # get review item number from list # Copyright 2002-2004 Dean F. Hougen. All rights reserved. $review_dir = '/home/hougen/www/classes/Spring-2004/Robotics/reviews/'; $class_file = $review_dir . 'classfile'; $sendmail = '/usr/lib/sendmail'; $num_teams = 8; 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_base += 2; } if ($review_item eq 'P3Project'){ $review_base += 4; } $review_num = $review_base + $review_offset; if ($review_num > $num_teams) { $review_num -= $num_teams; } 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-001/5023 - Intro to Intelligent Robotics - Spring 2004, Review Login

Login Page for Reviews

Note, for reviews of team projects, each person should evaluate the work of each team individually. The reviews are NOT to be done as a team. Each of you should independently look at each report and arrive at your own conclusions about the work of the teams. Think of this as homework that you are assigned to do on your own.

Note, for reviews of team projects, each person should evaluate the work of two other teams plus your own team.

For project 1, if you are in team N, the other teams you review will be N+1 and N+2. If any of the resulting values are greater than 8, subtract 8 from them. (E.g., if you are in team 7, you will review teams 7, 8, and 1.)

For project 2, if you are in team N, the other teams you review will be N+3 and N+4. If any of the resulting values are greater than 8, subtract 8 from them. (E.g., if you are in team 7, you will review teams 7, 2, and 3.)

For project 3, if you are in team N, the other teams you review will be N+5 and N+6. If any of the resulting values are greater than 8, subtract 8 from them. (E.g., if you are in team 7, you will review teams 7, 4, and 5.)

Note, for peer reviews of team members, you should evaluate yourself as well as each of your team mates.

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

OU 4 x 4:
Team Number:
Number of Members in Your Team (Including You):
OU Email Address: \@ou.edu
Item to Review:
Project 1 Task Allocation Proposal
Project 1 Time Line, Milestones, and Fallback Plan
Project 1 Peer Review of Team Members
Project 1 Technical Reviews
Project 2 Peer Review of Team Members
Project 3 Peer Review of Team Members NEW!
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) < 3 && $team_num > 0 && $team_num < 9) { 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 > 2 && $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'){ #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 = 3; } #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 2002, 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 2002, 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 2004, 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 }