
This is a set of ACM-style Programming Contest software that I wrote
for our this year's (1988)'s "Local Programming Contest".  We could not
afford to field a team to go to the Regional Contest, so we just
Po'Boy-ed it here at home.

This software is provided without any warranty whatsoever.  It's free
and free of copyright.  It's just what I did for our contest.  It'll
certainly require some version of unix, either BSD4.2 or SysV, or
compatible.  I've tested it on our Sequent B8 (BSD4.2, or very close,
NS32032), and on each of our SysV boxes, one running SysV2.1 (3b2/300)
and the other running SysV3.1 (3b2/310?) (don't ask why they're not
both running 3.1, it's a long bloody story...). No Suns available to me
(isn't that incredible?).

What we have here is a combination of shell (Bourne) scripts and
C-programs which I found useful in being a "judge" in our local
"Programming Contest".  We discussed trying to field a team to go to
the Regionals, and decided we 1) couldn't afford the gas, and 2)
couldn't win anyway.

Anyway, this software is being put on the net (if it gets past the
moderator) just to possibly inspire others to sorta goad their defunct
ACM/CS student groups (ours died with the dues increase) to come back
alive.

Installation:

Add a user to your system; his name probably should be "judges" (well,
of course, cousin, you gotta be root to do this... trust me!).  Make
sure his .profile or .login or .whatever sets his umask to 077.  The
group of user judges should be the same as his uid.  The group of the
teams should be their uids also. But, at least on Berkeley, the group
of the directories of the teams should be the same as the group of the
judges.  More on this later.

Log in as judges.  (No root privileges needed, nor desired).

Copy all this stuff from wherever you were reading it into the
"judges" directory (which is where you should be now).

Unshar the Parts.

Look at Makefile, to see if there are any pathname dependencies
I missed.  On our system, users are in /usr1, /usr2, and /usr3,
and I put judges in /usr2.  More traditional systems will
have /u, /v, etc., I guess.

Make a directory called /usr/contest with 0777 permissions; don't
worry, we're only putting easily reconstituted stuff there.  The
"score" program, for example, needs to live in a directory which
is in each of the teams' PATHs; it will be setuid judges, so it
can read the scoreboard, which will be in the judges' protected
directory.

Look at Makefile to see if you can stand P=& (parallel make).

Type
% make all

This should compile the necessary C-language programs (score, compare,
digits, seconds, and shorten) and place score and seconds into the
contest directory, along with judge, which is a shell script.

Make accounts of the form teamxx, where xx is either a single digit, or
is a double digit.  What I mean is: team2, not team02.  Insure that
their PATH includes /usr/contest.  Insure that they can mail to judges
and that judges can mail to each of them.  Insure that they can read
/tmp. (If I'm not talking to a root-priv person, forget it, and go send
all this stuff to your local administrator).  Make their passwords
whatever you want, but something you can tell them in the poop-session
before the start of the contest.

Type
% make install

If all goes well, you should be ready to go.  What I did was run
shutofflogins a half-hour before the start of the contest.  It
messes with /etc/passwd by only allowing our magic system accounts,
selected faculty, and judges, and teamxx to survive, and all others
are taken out.  It needs "nawk" to work.  This step is probably
not necessary;  I was just paranoid.  And, of course, needs to be
root to mess with /etc/passwd.

Long before start-time, edit the file "sf" to reflect the names of
your teams.  Four man teams may not fit.  Truncate them accordingly.

At start time, type
% start < sf
which will set up the scoreboard and start- and end-time files.

Teams submit judged runs by
% judge probX.pas

for example.  The digit(s) (represented by X above) in the filename
must reflect the problem number.  Extensions currently supported are
.c, .f, .p, and .pas .

The judges' account must be able to read the teams' directories and
programs.  This is why the teams directories should be readable by
group judges, but not readable by any other group, especially other
teams.  Only judges should be in group judges; and only owner and group
judges should be able to read team directories and files.

The shell-script "gr" is actually the heart of this whole deal.  It
attempts to compile and execute the teams' submissions and to grade the
output either right or wrong.  The program "compare" was written to
fill the void caused by diff -b not working the way I wanted when one
of the lines did not begin with a blank.  Also, our fortran generates
gratuitious output when a 'stop' statement is executed.  I have not
fixed this problem.  What we did was tell those teams using fortran to
avoid use of the 'stop' statement.  Running off the end of main is much
nicer.

The little C-program chexec8.c simply executes the teams' submitted
programs after compiling them into a small subdirectory.  The "8"
refers to the eighth version of this little thing.  What made this not
just a simple chdir, chroot, and exec program was a rather incredible
back-and-forth between me and a couple of my students in an advanced
class:  "I can steal the input, and I can also steal other teams'
output".  "How?" "A daemon which never exits and looks in the current
directory for interesting stuff and copies it into its internal guts
(remember that it belongs to you, "judges"), and when judges sends mail
to the other teams that somebody has solved a problem, it waits for
another instance of turkey, and then sends to the correctly named
files, an output from its own guts, properly named, as if it were the
output of a correct run of that particular problem.  First iteration
simply did the chroot.  Second piped input from above and output to
above, doing about all it could except protecting against fork().  ...
etc.  What we finally decided was: judges should run the team-program,
and should INSURE that no process owned by judges should be allowed to
live after the "first-child" of the judging chexec8 program exits.  I
currently have that simple-mindedly just issuing kill(...,9) calls to
the next 200 processes.  This will not be sufficient on a busy system,
but thats' where I left it for this time around.  The culprit would 
seem to be fork().  Really paranoid sysadmins would just remove
fork() from the system library, insure that no students who had
ever in the past been allowed to login on this system had make
copies of fork(), and ... etc.

This latter iteration on the possibility of stealing the input and or
the output of other teams' runs was what caused this software to be
more than several weeks late, and why other work, such as grading
papers, has gone undone.  Comments are solicited; versions 1 thru 7 of
chexec.c are probably floating around somewhere.  Thanks to Steve
Perry, David McGough, and Chris Spell for playing the Devil's Advocate
for chexec.

The "solutions" provided are entirely by me; some of the other judges
submitted much nicer programs, but mine were written in a semi-contest
situation of "quick and dirty", 'cause I had to write all twelve
solutions one Saturday.  Really, folks, this is not my best code ...
They are all in C, although I did re-write a few of them in Pascal and
Fortran just for testing, I then threw those versions away. (No bigotry
around here ...).


Bugs and flames to
nelson@ecsvax.uucp
...mcnc!ecsvax!nelson
(too bad it's not ...mcnc!ecsvax!uncw!nelson just yet ... we're
trying)

Jim Nelson
Mathematical Sciences Dept.
Univ. of NC at Wilmington
Wilmington, NC 28403
919-395-3300 direct, or 919-395-3290 dept. office
