#!/usr/bin/env perl # -*- mode: Perl;-*- # Version 4.20.8 # See the file COPYING in the main distribution directory for copyright notice. unshift (@INC, '/home/ff/cs61b/grading-software/share/lib'); if (! exists $ENV{'MASTERDIR'}) { do "acquireDir.pl"; askForMaster($#ARGV+1, 1, 1, "Usage: submit ASSIGNMENT\n E.g., submit hw1", "Enter the name of the course for which you are submitting" . "\n an assignment (e.g., ee245, cs164): "); } require "GradingBase.pl"; CmndLine ("fbu:t:", 1, 1); require "GradingCommon.pl"; $me = MyLogin (); if ($opt_u and $AUTHORIZED{$me}) { $me = $opt_u; } else { if ($opt_u and $me ne $opt_u) { Fatal ("You are not authorized to submit assignments for $opt_u."); } } $assgn = shift; if (! StudentExists ($me)) { Fatal ("$me is not registered as a student in $COURSE."); } if ($assgn !~ /^[-a-zA-Z0-9_.]+$/) { Fatal ("Invalid format for assignment name: $assgn."); } if (! AssignmentExists ($assgn)) { Fatal ("There is no assignment $assgn. The valid\n" . "assignment names currently are\n\t" . join (", ", @ASSIGNMENT_LIST) . "."); } elsif (! $ASSGN_SUBMIT{$assgn}) { Note ("At the moment, assignment $assgn does not allow for " . "electronic submission.") unless $opt_b; if (not $opt_b and Yorn ("Would you like to submit anyway?")) { Note ("OK, but you should inform the instructor of this glitch."); } else { Fatal ("There is no electronic submission for assignment $assgn."); } } undef %fileSet; undef %partners; if ($opt_t) { if (not $ASSGN_PARTNERS{$assgn}) { Fatal ("This assignment does not have partners, so you may not " . "specify a team."); } if (not TeamExists ($opt_t)) { Fatal ("There is no team $opt_t."); } foreach $login (split (/\s+/, TeamMembers ($opt_t))) { $partners{$login} = 1; } if (not $partners{$me}) { Fatal ("You are not registered as a member of $opt_t."); } delete $partners{$me}; } elsif ($opt_b and $ASSGN_PARTNERS{$assgn}) { if (not (-f "MY.PARTNERS" and -r _)) { Fatal ("Assignment has partnerships: must be a MY.PARTNERS file " . "for batch submission.") } } elsif ($ASSGN_PARTNERS{$assgn}) { Note ("Please enter the logins of your partner(s), if any."); Note ("Enter '.' to stop."); while (1) { $partner = Fetch ("Login: "); next if ($partner eq $me); last if ($partner eq "."); if (! StudentExists ($partner)) { Warn ("$partner is not registered as a $COURSE student, and " . "is being ignored."); next; } $partners{$partner} = 1; } } if ($ASSGN_PARTNERS{$assgn}) { if (! %partners) { if (!Yorn ("You have no partners, correct?")) { Fatal ("Submission FAILS."); } } else { print STDERR "Your partners' logins are "; foreach (keys %partners) { print STDERR "$_ "; } print STDERR "\n"; if (! Yorn ("Is this correct?")) { Fatal ("Submission FAILS."); } } unlink ("MY.PARTNERS"); @partnerList = ($me, sort (keys (%partners))); System ("echo " . join (" ", @partnerList) . " > MY.PARTNERS"); Note ("Created MY.PARTNERS file."); $fileSet{"./MY.PARTNERS"} = 1; } else { @partnerList = (); } Note ("Looking for files to turn in...."); sub Traverse { my $dir = shift; my $size; my @candidates; my $full; if (opendir (TRAVERSE_DIR, $dir)) { @candidates = readdir (TRAVERSE_DIR); closedir (TRAVERSE_DIR); Candidate: foreach (@candidates) { $full = "$dir/$_"; next if (/^\.\.?$/); if (/[#;\[\]\?'"|\n`\\ \t&]/) { Note ("Skipping file name $_, which contains strange characters"); next; } $f = $full; $f =~ s{^\./}{}; $mustAccept = 0; foreach $acc (split (/ /, $ASSGN_REQUIRED{$assgn})) { if ($f =~ m{^${acc}$}) { if (-d $full) { Fatal ("Required file $f must not be a directory."); next; } $size = (stat (_))[7]; if ($size > $MAX_ALLOWED_FILE_SIZE) { Fatal ("Required file $f is too big (>$MAX_ALLOWED_FILE_SIZE bytes)"); next; } $requiredSet{$acc} = 1; if (not $fileSet{$full}) { $fileSet{$full} = 1; Note ("Submitting $f."); } $mustAccept = 1; } } if (not $mustAccept) { foreach $rej (split (/ /, $ASSGN_REJECT{$assgn})) { next Candidate if ($f =~ m{$rej}); } foreach $rej (split (/ /, $ASSGN_REJECTL{$assgn})) { next Candidate if ($f =~ m{$rej} && -l $full); } foreach $acc (split (/ /, $ASSGN_ACCEPT{$assgn})) { if ($f =~ m{$acc}) { if (-d $full) { Note ("Looking at files in directory $full."); Traverse ($full); } elsif (-f _) { $size = (stat (_))[7]; if ($size > $MAX_ALLOWED_FILE_SIZE) { Note("Skipping file $f: more than $MAX_ALLOWED_FILE_SIZE bytes long."); next; } Note ("Submitting $full."); $fileSet{$full} = 1; } next Candidate; } } if (-d $full) { if ($opt_b or Yorn ("Look at files in directory $full?")) { Traverse ($full); } else { Note ("Skipping directory $full."); } } elsif (-f _ and not $fileSet{$full}) { my $size = (stat (_))[7]; if ($size > $MAX_ALLOWED_FILE_SIZE) { Note("Skipping file $f: more than $MAX_ALLOWED_FILE_SIZE bytes long."); next; } if ($opt_b or Yorn ("Turn in $full". ($size > 50_000 ? " (it's $size bytes long)" : "") . "? ")) { $fileSet{$full} = 1; } } } } } } &Traverse ("."); if (! %fileSet) { Fatal ("Nothing submitted. Submission FAILS."); } foreach $pat (split (/ /, $ASSGN_REQUIRED{$assgn})) { if (not $requiredSet{$pat}) { Fatal ("You must turn in a file $pat for this assignment.\n" . "Here is the complete list of files you must turn in:\n " . $ASSGN_REQUIRED{$assgn} . "\n" . "Error: submission FAILED."); } } while (1) { @allFiles = sort (keys %fileSet); print STDERR "The files you have submitted are:"; for ($i = 0; $i <= $#allFiles; $i += 1) { print STDERR "\n\t" if ($i % 4 == 0); print STDERR "$allFiles[$i] "; } print STDERR "\n"; if ($opt_b or Yorn ("Is this correct?")) { last; } else { if (!Yorn ("Would you like to submit additional files?")) { Fatal ("Submission FAILS by request."); } while (1) { print STDERR "Additional file to submit: "; $resp = ; $resp =~ s/^\s*(.*?)\s*$/$1/; last if ($resp eq ""); if (! -r $resp) { print STDERR "Can't read $resp; rejected.\n"; next; } if (! -f _) { print STDERR "$resp is not a plain file; rejected.\n"; next; } if ($resp !~ "^/") { $resp = "./$resp"; } $fileSet{"$resp"} = 1; } } } $fileArg = ""; foreach (@allFiles) { $fileArg .= " " . ShellQuote ($_); } $tmpdir = "/tmp/subm$$"; AddClean ($tmpdir); if (-x "$PRETEST_DIR/$assgn") { TEST: { $passed = 0; Note ("Performing sanity check on your submission"); System ("/bin/rm -rf $tmpdir"); System ("mkdir $tmpdir && chmod 0700 $tmpdir " . "&& tar chf - $fileArg | ( cd $tmpdir; tar xf - )") || do { Warn ("Could not set up test."); last TEST; }; System ("cd $tmpdir; $PRETEST_DIR/$assgn") && ($passed = 1); } System ("/bin/rm -rf $tmpdir"); if ($passed) { Note ("Sanity checks passed."); } else { Note ("Error: Insanity detected.\n" . " You can carry on and submit anyway, but you may not get\n" . " much credit for the assignment."); if (($opt_b and $opt_f) or Yorn ("Continue submission anyway?")) { Warn ("Your submission is likely to be faulty.") unless $opt_b; } else { Fatal ("Submission canceled."); } } } Note ("Copying submission of assignment $assgn...."); { $partnerList = join (' ', @partnerList); if ($opt_u) { open (GRADER, "|$SUBMIT_PROG -u $me -s 'Submission for assignment ${assgn}' " . $partnerList) or last; } else { open (GRADER, "|$SUBMIT_PROG -s 'Submission for assignment ${assgn}' $partnerList") or last; } if ($partnerList) { print GRADER ">>PARTNERS: $partnerList\n\n"; } open (ENCODER, "tar chf - $fileArg | gzip -c | uuencode ${assgn}-handin.tar.gz|") or last; while () { print GRADER $_; } close ENCODER or last; close GRADER or last; Note ("Submission complete."); exit 0; }; Fatal ("There was some problem submitting to the class account.\n" . "Assignment NOT SUBMITTED.");