This is the source to a couple of test clients.  They were written for
testing, and shouldn't be used as dependable code.  The most use I'd
recommend for them as examples of how the protocol works, and perhaps as
templates

Compiling the test programs should just be a matter of "make" (ha ha!).

There are two ways of mounting a user process: the old way and
the new way.  The old way is to just run the process with the mount
point as an argument.  This has to be done as root, since the process
needs to use the mount system call.  These filesystems will unmount
themselves if you send them a SIGINT or SIGTERM.  Don't use kill -9
on them.

The new way is to use the muserfs (mount userfs) program.  This is
an suid program that calls mount for you and executes your code
as you.  Before mounting it does some checking of the mount point,
making sure that the invoking user (unless root) owns the mountpoint
and it has at least 700 permissions.  After the mount, muserfs
updates /etc/mtab so that "mount", "df", etc, will be able to find
the filesystem.  muserfs hangs around until the filesystem dies
and unmounts it.

"home" just makes a single directory with an entry for each person in
the password file.  Each entry is a symlink to their home directory.  It
does not make a very good job of updating if the passwd file is changed.
It was written to see what a minimal client could do, and make sure that
it works.  This is mounted in the new style, with muserfs.

"tmnt" (test mount -- no amphibians) echos a file tree on the
mountpoint.  It was written to test all filesystem operations.  Because
its mainly a test program, it is not well designed, not very useful, and
I haven't converted it to use muserfs (but its not hard to do).
Currently it makes "/usr" appear on the mountpoint, but it is trivial to
change the location.  It could be used as a NFS type thing over a
reliable bytestream connection (TCP socket or error-corrected modem
link), but it doesn't try very hard to deal with the filesystem
underneath it changing (partly due to kernel constraints).  Due to bad
design and poor implementation within the client, it doesn't support
hard links (I didn't make files and filenames different enough, and
haven't bothered to fix it).

WARNING:  Don't make a file tree include itself (ie, put the mount point
under /usr).  This will make a loop that will deadlock the filesystem
process and the process trying to use it.  You won't be able to kill
them - a reboot is the only recourse.  (I've also had strange bugs in
the past which reall crash the machine, but they've probably gone...
probably).

Both are partly written in C++, or more accurately, they use C++
constructs.  This was done in irritation at a bug where something was
touching something it shouldn't have.  Rather than look for it, I
converted the C I had into C++.  The bug dissapeared, but the result is
messy, and a poor use of C++.

What really needs to be done is to have a set of subroutines that or
classes that by themselves make the base of a completely useless but
working client.  With that, a filesystem writer can use them as base
classes.  The base classes should also deal with all the protocol
issues, so the client proper just has to fill out structures.

I'd also like user process filesystems to be something that ordinary
users can mount and use.  Currently the kernel side isn't robust enough
to cope with really buggy client processes.  It may not be possible, and
there may be a number of other security issues that should be addressed.
Certainly, nothing should be trusted in a user's filesystem.  

Anyway, if you have ideas or implementations of any of this, mail me.
I'd like to see anything that anyone writes.

	Jeremy Fitzhardinge <jeremy@sw.oz.au>
	May 1993
