This program allows individual users to set up network services without
having to worry about the intricacies of socket I/O.  It is similar in
function to the "rsh" program, but restricts the commands which can be
executed by remote users.  No .rhosts or password is required, since
the remote user can only execute commands from a specified (presumably
safe) list.

The service programs think they're talking to a pipe (because they are).
Stdin and stdout are redirected to the pipe; stderr is mapped to stdout.
Shell scripts can be offered as network services, but make sure you have
execute permission on them and that the line "#!/bin/sh" (or csh, or
whatever shell you're using) appears at the top of the file, or UNIX won't
recognize it as an executable-format file.

The server consists of two layers.  The bottom layer (subserver) is
executed by a user when he wants to advertise services.  It reads a
configuration file from the user's home directory, which contains a
list of service names and full path specifications.  It then checks for
the existence of the top layer (the super-server), and runs the
superserver program if it was not already active.  In any case, the
server connects to the superserver, registers its service-names, and
awaits a request.

The superserver accepts connections from remote locations, usually
initiated with the "client" program.  It reads a line of input from the
client program, which specifies the name of the desired service.  If
one of the subservers has advertised the requested service, the
superserver forks off a child process.  The child writes the name of
the requested service to the appropriate subserver, then acts as a
mailman, shuffling bytes between the remote user and the subserver
until one of them disconnects.  Meanwhile, the parent superserver
waits for another connection, and the whole bloody mess starts over.

The client-supersrv handshaking looks like this (all lines are newline-
terminated, so you could talk to supersrv with telnet, for instance):

client				supersrv
------				--------
				welcome message
service name
username (or empty line)
arg1
arg2
arg3
 .
 .
 .
argn
blank line


If a superserver process is killed, all its subservers try to restart
it until one of them succeeds.  If a server process is killed, the
superserver removes all its services from the listing.  Some braindamaged
BSD implementations can take up to five minutes to figure out that a
process has died and that its socket addresses are no longer in use, so
killing a superserver might result in a short interruption of service.

Sending a HUP signal to a server causes it to reload its database.


Wish list:

	If exec-ing a program fails because of an invalid file format, we
should try to run the program from sh, since it's probably a script without
the #!/bin/sh at the top.

	Some form of logging would be nice, so people can tell who's
using which services.

	Signal-passing and standard error support a la rsh would be neat, too.

	Support for interactive programs by automatically allocating a pty
before running a program would be helpful.  Some form of environment passing
would also need to be implemented for programs that use termcap.

If you have questions, comments, bug reports, large amounts of excess cash,
horny women, etc., send a letter to koreth@ssyx.ucsc.edu.

