diff -ru hurd-0.0/ChangeLog hurd-0.1/ChangeLog
--- hurd-0.0/ChangeLog	Fri Aug  2 11:36:42 1996
+++ hurd-0.1/ChangeLog	Fri Sep  6 17:03:32 1996
@@ -1,6 +1,99 @@
-Fri Aug  2 11:02:11 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+Fri Sep  6 17:00:23 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* INSTALL: Update to version 0.1.
+	* README: Likewise.
+
+Thu Sep  5 11:04:38 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+	
+	* version.h: New file.
+	* sh-version.sed: New file.
+	* Makefile (DIST_FILES): Add version.h and sh-version.sed.
+
+Wed Sep  4 16:25:24 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makeconf
+	($(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs))):
+	`$(includdir)' --> `$(includedir)'
+
+Wed Sep  4 08:56:04 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* configure.in (asm_syntax): New variable, canonicalized from
+	host_cpu.  AC_SUBST it.
+	* config.make.in (asm_syntax): New variable, from @asm_syntax@.
+
+Sun Sep  1 14:03:20 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makeconf ($(target): %$(target-suffix)): Add dependency on
+	$(BUGADDR), and $(BUGADDR_REF) to the flags.
+	(BUGADDR, BUGADDR_REF): New variables.
+	* Makefile (lib-subdirs): Add libhurdbugaddr.
+	* libhurdbugaddr: New directory.
+	
+Thu Aug 29 14:14:04 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makeconf [doinst == one] (install): Don't depend on
+ 	$(installationdir).
+	[doinst==one] ($(installationdir)/$(target)): Do depend on
+ 	$(installationdir).
+	[doinst == many] (install): Don't depend on $(installationdir).
+  	$(addprefix $(installationdir)/,$(targets)): Depend on
+ 	$(installationdir).
+	[makemode == library] (install): Don't depend on $(libdir),
+ 	$(includedir), or $(includedir)/$(installhdrsubdir).
+	[makemode == library] ($(libdir)/$(libname.a)): Depend on
+ 	$(libdir).
+	[makemode == library] ($(libdir)/$(libname).so): Likewise.
+	[makemode == library] $(addprefix
+ 	$(includedir)/$(installhdrsubdir)/,$(installhdrs)): Depend on
+ 	$(includdir)/$(installhdrsubdir)
+	[makemode == library] $(includedir)/$(installhdrsubdir): Depend on
+	$(includedir).
+	[makemode == library] (install-headers): Don't depend on
+	$(includedir)/$(installhdrsubdir) or $(includedir).
+
+	* INSTALL: Tell people to delete Mach's mach_init.h if it got
+	installed. 
+
+Wed Aug 28 11:22:28 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* INSTALL: Say to use `no_deps=t' when installing headers.
+
+Tue Aug 13 17:54:53 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makeconf ($(target)): Add $($@-LDLIBS) $(LDLIBS) to libs.
+
+Tue Aug 13 14:05:54 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makeconf (vpath %.defs): Remove reference for mach and device
+	headers. 
+	(mach_defs_names, device_defs,names, mach_defs, device_defs): New
+	variables. 
+	($(mach_defs), $(device_defs)): New rules.
+	* config.make.in (install_prefix, install_includedir): Delete
+	variables. 
+	* configure.in (install_prefix): Delete AC_SUBST.
+
+Mon Aug 12 12:51:03 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makeconf: Comment out the lines that cause recursive makes into
+	library subdirs.
+
+Thu Aug  8 13:14:44 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* configure.in: Add AC_SUBST for `install_prefix'.
+	* config.make.in (install_prefix, install_includedir): New
+	variables.	
+	* Makeconf (vpath %.defs): Look for these in install_includedir.
+	
+Wed Aug  7 14:57:55 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makefile (prog-subdirs): Add `nfsd'.
+
+Tue Aug  6 12:20:37 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* Released source version 0.0.
+
+Fri Aug  2 11:02:11 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* Makefile (cp-linked-files): Add missing hyphen to rule.
 	(dist): Delete directory named for VERSION, not old var DATE.
diff -ru hurd-0.0/INSTALL hurd-0.1/INSTALL
--- hurd-0.0/INSTALL	Mon Aug  5 11:54:05 1996
+++ hurd-0.1/INSTALL	Fri Sep  6 17:01:49 1996
@@ -1,5 +1,5 @@
 -*- Text -*-
-GNU Hurd 0.0
+GNU Hurd 0.1
 
 This is the Hurd.  Welcome.
 
@@ -19,8 +19,9 @@
 version of the Hurd will interoperate together, then see the
 instructions "Bulding the Hurd by itself" below.
 
-The Hurd version 0.0 is known to work with version 1.93 of the GNU C
-Library.
+The Hurd version 0.1 is known to work with version 1.93 of the GNU C
+Library--but not the normal released copy.  We suggest you use the
+copy distributed with GNU 0.0.
 
 Bug reports for the GNU Hurd should be sent to the mailing list
 `bug-hurd@prep.ai.mit.edu'.  Please do not send requests for
@@ -66,10 +67,13 @@
 3. Do `make install' in <mach4-build>/mig.  ONLY.
 
 4. Do `make install' in <mach4-build>/include.  ONLY.
+   This may have installed an include file called mach_init.h.  If so,
+   delete it; you want to use the one that libc will install, and if
+   this file exists, libc might not install its version.
 
 5. Configure the Hurd with `configure'.
 
-6. In the Hurd directory, type `make install-hdrs'.
+6. In the Hurd directory, type `make install-hdrs no_deps=t'.
 
 7. Configure libc.
 
@@ -88,7 +92,7 @@
 1. `cd' to the directory containing the Hurd's source code and type
    `./configure' to configure the Hurd.
 
-2. Type `make install-hdrs' to install the Hurd's header files.
+2. Type `make install-hdrs no_deps=t' to install the Hurd's header files.
 
 3. Follow the instructions in the GNU C Library for configuring and
    installing GNU libc.
diff -ru hurd-0.0/Makeconf hurd-0.1/Makeconf
--- hurd-0.0/Makeconf	Tue Jul 30 13:55:09 1996
+++ hurd-0.1/Makeconf	Thu Sep  5 10:12:15 1996
@@ -67,7 +67,6 @@
 endif
 CPPFLAGS += -I. $(srcdirinc) -I.. $(top_srcdirinc) -I$(top_srcdir)/include -D_GNU_SOURCE
 CFLAGS += -Wall -g -O3
-
 
 # Local programs:
 MKINSTALLDIRS = $(top_srcdir)/mkinstalldirs
@@ -120,8 +119,11 @@
  endif
 endif
 
+# This is a hack to give all hurd utilities a default bug-reporting
+# address (defined in libhurdbugaddr/bugaddr.c).
+BUGADDR = $(..)libhurdbugaddr/libhurdbugaddr.a
+BUGADDR_REF = -uargp_program_bug_address
 
-
 # Standard targets
 
 .PHONY: all install libs relink clean
@@ -129,14 +131,15 @@
 # Installation
 ifeq ($(doinst),one)
 all: $(target)
-install: $(installationdir)/$(target) $(installationdir)
-$(installationdir)/$(target): $(target)
+install: $(installationdir)/$(target)
+$(installationdir)/$(target): $(target) $(installationdir)
 	$(INSTALL_PROGRAM) $(INSTALL-$<-ops) $< $@
 endif
 
 ifeq ($(doinst),many)
 all: $(targets)
-install: $(addprefix $(installationdir)/,$(targets)) $(installationdir)
+install: $(addprefix $(installationdir)/,$(targets))
+$(addprefix $(installationdir)/,$(targets)): $(installationdir)
 $(addprefix $(installationdir)/,$(targets)): $(installationdir)/%: %
 	$(INSTALL_PROGRAM) $(INSTALL-$<-ops) $< $@
 endif
@@ -145,11 +148,11 @@
 all: libs
 install libs: add-to-librecord
 add-to-librecord: $(targets)
-install: $(addprefix $(libdir)/,$(targets)) $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)) $(libdir) $(includedir) $(includedir)/$(installhdrsubdir)
+install: $(addprefix $(libdir)/,$(targets)) $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)) 
 
-install-headers: $(includedir)/$(installhdrsubdir) $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)) $(includedir)
+install-headers: $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)) 
 
-$(includedir)/$(installhdrsubdir):
+$(includedir)/$(installhdrsubdir): $(includedir)
 	$(MKINSTALLDIRS) $@
 
 # Arrange to have the headers installed locally anytime we build the library.
@@ -166,12 +169,14 @@
 endif
 libs: $(INSTALLED_LOCAL_HEADERS)
 
-$(libdir)/$(libname).a: $(libname).a
+$(libdir)/$(libname).a: $(libname).a $(libdir)
 	$(INSTALL_DATA) $(libname).a $(libdir)/$(libname).a
 	$(RANLIB) $(libdir)/$(libname).a
-$(libdir)/$(libname).so: $(libname).so
+$(libdir)/$(libname).so: $(libname).so $(libdir)
 	$(INSTALL_DATA) $(libname).so $(libdir)/$(libname).so
 
+$(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)): $(includedir)/$(installhdrsubdir)
+
 $(addprefix $(includedir)/$(installhdrsubdir)/,$(installhdrs)): $(includedir)/$(installhdrsubdir)/%: %
 	$(INSTALL_DATA) $< $@
 
@@ -212,10 +217,11 @@
 # dependencies of other shared objects it encounters.
 rpath := -Wl,-rpath-link=.:$(subst $. ,:,$(dir $(wildcard ../lib*/lib*.so)))
 
-$(target): %$(target-suffix):
-	$(CC) $(rpath) $(CFLAGS) $($@-CFLAGS) $(LDFLAGS) $($@-LDFLAGS) -o $@ \
+$(target): %$(target-suffix): $(BUGADDR)
+	$(CC) $(rpath) $(CFLAGS) $($@-CFLAGS) $(LDFLAGS) $($@-LDFLAGS) $(BUGADDR_REF) \
+	      -o $@ \
 	      '-Wl,-(' $(filter %.o,$^) \
-		       $(foreach lib,$(filter-out %.o,$+),${_libsubst}) \
+		       $(foreach lib,$(filter-out %.o,$+),${_libsubst}) $($@-LDLIBS) $(LDLIBS) \
 	      '-Wl,-)'
 
 ifeq ($(makemode),library)
@@ -292,8 +298,8 @@
 # Building libraries from other directories.  We force both libraries to be
 # built if either is, because it will use the appropriate one even if the other
 # is specified in someone's dependency list.   
-../%.a ../%.so: FORCE
-	$(MAKE) -C $(dir $@) libs
+#../%.a ../%.so: FORCE
+#	$(MAKE) -C $(dir $@) libs
 
 # Tell make where to find other -l libraries that we use
 vpath libutil.% $(libdir)/
@@ -330,9 +336,23 @@
 	| $(MIGCOM) $(MIGCOMUFLAGS) $($*-MIGCOMUFLAGS) \
 		    -user $*User.c -server /dev/null -header $*_U.h
 
-
 # Where to find .defs files.
-vpath %.defs $(top_srcdir)/hurd $(includedir)/mach $(includedir)/device
+vpath %.defs $(top_srcdir)/hurd
+
+# These we want to find in the libc include directory...
+mach_defs_names = bootstrap default_pager default_pager_helper exc mach mach4 \
+	mach_host mach_norma mach_port mach_timer_reply memory_object \
+	memory_object_default norma_task notify
+device_defs_names = dev_forward device device_reply device_request
+
+mach_defs = $(addsuffix .defs,$(mach_defs_names))
+device_defs = $(addsuffix .defs,$(device_defs_names))
+
+$(mach_defs): %.defs:
+	echo '#include <mach/$@>' > $@
+$(device_defs): %.defs:
+	echo '#include <device/$@>' > $@
+
 
 FORCE:
 
diff -ru hurd-0.0/Makefile hurd-0.1/Makefile
--- hurd-0.0/Makefile	Fri Aug  2 11:36:14 1996
+++ hurd-0.1/Makefile	Thu Sep  5 12:16:09 1996
@@ -26,11 +26,11 @@
 
 lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \
 	      libpager libfshelp libdiskfs libtrivfs libps \
-	      libnetfs libpipe libstore libmom
+	      libnetfs libpipe libstore libmom libhurdbugaddr
 prog-subdirs = auth boot exec fstests init \
 	       proc term ufs utils sutils trans ufs-fsck \
 	       devio ufs-utils ext2fs benchmarks pflocal defpager \
-	       login nfs pfinet daemons
+	       login nfs pfinet daemons nfsd
 other-subdirs = hurd doc config release include
 subdirs = $(lib-subdirs) $(prog-subdirs) $(other-subdirs)
 subdirs-nodist =
@@ -40,7 +40,7 @@
 			  $(prog-subdirs))
 DIST_FILES = COPYING Makeconf config.make.in configure.in configure \
 	     hurd.boot build.mk.in build.mkcf.in SETUP \
-	     README NEWS tasks INSTALL INSTALL-cross
+	     README NEWS tasks INSTALL INSTALL-cross version.h sh-version.sed
 
 all: $(addsuffix -all,$(lib-subdirs) $(working-prog-subdirs))
 
diff -ru hurd-0.0/NEWS hurd-0.1/NEWS
--- hurd-0.0/NEWS	Mon Apr 15 15:03:54 1996
+++ hurd-0.1/NEWS	Fri Sep  6 17:04:08 1996
@@ -1,575 +1,70 @@
 -*- Text -*-
 
-April 15, 1995
+6 September 1996
+Version 0.1.
 
-It's hard to summarize, so much has happened.
+Summary of important externally visible changes since version 0.0:
 
-We have NFS, a network, and jillions of stuff.  Basically things just
-work.  Except for a jillion little nits, this is very nearly an alpha
-release.  Not quite, but nearly.
+Many miscellaneous bugs have been fixed.
 
+Missing source files in 0.0 have been correctly added to the
+distribution. 
 
+Configuration now knows that various 386 equivalents use the same
+assembly files.
 
-
-The `boot' program now accepts an option ``-D DIR'' which specifies a
-directory prefix for the file names given in the boot script (hurd.boot).
-So the way to boot is now:
-	$ boot.a -D .../hurd-image hurd.boot sd0a
-
-
-October 5, 1995
-
-The Hurd distribution now uses a `configure' script in the standard GNU
-style.  As with other GNU packages, you can configure in the source
-directory or in a separate build directory (though not both with the same
-source directory); all you should need to do is `configure i386-gnu'.  The
-Hurd does not compile in any file names using $(prefix), so you can specify
-the prefix where you will install things with the `--prefix' option; e.g.,
-`configure --prefix=/gd4/hurdinst i386-gnu'.  You should no longer need to
-edit any makefiles.  You can choose the tool names by setting variables in
-the environment when running configure (CC, LD, AR, RANLIB, OBJCOPY, MIG);
-the default is to search your $PATH for HOST-TOOL (e.g. i386-gnu-gcc), and
-failing that just TOOL (e.g. gcc), so you will win automagically if you
-simply use the same host alias in the `configure' command line as you used
-for the target alias to configure gcc and binutils (i.e. i386-gnu).
-
-The file_truncate RPC (in fs.defs) has been renamed file_set_size and
-now is expected to extend files as well as truncate them, in the
-manner of recent BSD releases' ftruncate.  file_pathconf has been
-moved from fs.defs to io.defs and renamed io_pathconf.  The `core'
-interface has been renamed `crash'.
-
-We are now using a new terminal driver that is multi-threaded.  It is
-also much more simple internally than the older version, but otherwise
-supports no new features.
-
-Everything is now dynamically linked except the bootstrap filesystem.  Any
-old statically linked binaries should be replaced.  WARNING: In the next
-snapshot changes in the exec server may prevent older statically linked
-binaries from running.
-
-The exec server by default now only supports ELF; if you have older
-a.out binaries you want to run, you need to reenable BFD support in
-the exec Makefile.  (Old a.out binaries should be replaced anyhow,
-with dynamically linked ELF binaries, for the reasons in described in
-the warning above.)
-
-The bootstrap hack in the directory boot now understands boot scripts;
-this kind of boot script will also be used by an upcoming release of
-Mach4.  Also, because the exec server is now dynamically linked, it is
-necessary to install the exec server itself on the Hurd partition (in
-/hurd/exec); that was not necessary before, so it is possible that old
-working Hurd partitions might not have it.
-
-Some problems and trivial bugs in fsck are fixed.
-
-A few bugs in libdiskfs, libpipe, pflocal, and trans were fixed of no
-particular consequence.
-
-Shutdown of filesystems now works reliably and safely.
-
-Libports now provides stubs to do the normal thing for the interrupt and
-notify interfaces.  Because of the interruption semantic, cthreads
-multiplexing of multiple cthreads onto fewer kernel threads can no longer
-be used; this means that ports_manage_port_operations_multithread no longer
-pays attention to the WIRE_CTHREADS flag.
-
-Cthreads now supports an implication semantic for conditions; this
-enables a condition variable to be created which is the disjunction of
-other condition variables.
-
-Trivfs now supports errors and blocking on open much better.
-
-A rare but serious bug in the pager has been fixed; along with this,
-another minor deficiency in the kernel has become apparent.
-
-The Makefiles are more generic and deal with shared libraries better. 
-
-A serious bug has been fixed in ext2fs.  
+There is now an nfsd; it has not be well-tested.  It would be nice if
+some people would run it and try things out.  It does not yet support
+Hurd-specific features.
 
-
-
-July 23, 1995
+Exec now compiles correctly even when you don't have BFD installed.
 
-Shared libraries now work; use -static to link programs and avoid the
-shared libraries.  The Hurd programs are normally built static; this
-will probably change soon.
+Ext2fs format interpretation problems have been fixed.  This means it
+can be suitably used to boot with.
 
-The ext2fs server now works, as do the tools to manipulate ext2fs
-filesystems.  A snapshot of the tools will be made soon under separate
-cover.  Many thanks to Ted Ts'o for his valuable work on the tools.
+init now properly understands SIGHUP and SIGTERM, and does the right
+thing correctly.
 
-Readers of the Makefiles will notice that we now generate dependencies
-automatically.
+Much code has been written in nfs towards supporting version 3 of the
+protocol, but it's not done yet.  Don't try and turn it on.
 
-The old netserv library is gone.
+Version information in uname is now calculated differently.
 
-The `boot' hack has been modified slightly to avoid the normalq libc startup
-files, because they no longer work with UX.
+Some improvements have been made in the SETUP script.
 
-Some small bugs have been fixed in the devio server.
+sync, reboot, and halt now do argument parsing and understand --help
+and --version.
 
-The ports library has been totally rewritten; new features permit
-servers to have greater control over thread RPC's and port creation.
+The new `e2os' program has been added to change the "creator OS" field
+on an ext2fs filesystem.
 
-The fshelp library now does most of the work for translator
-interaction; it's simpler now too.  Filesystems have much less work to
-do; the relevant code in libdiskfs is now understanble instead of
-unparseable chaos.
+Bugs in term and libtrivfs have been fixed, allowing emacs shell mode
+to work cleanly.  Other minor bugs have also been fixed.
 
-The ports library provides for timeouts; the diskfs library almost
-uses it, but because of a bug, it's disabled for now.
+ufs and ext2fs now do directory search rotoring to speed repeated and
+sequential directory lookups.  
 
-Filesystems are now expected to sync themselves if necessary; the new
-fsys_set_options RPC provides for changeing (or cancelling) the sync
-intervale.  The diskfs library does this for you.  The update program
-is no longer necessary.
+ufs now notes correctly if a disk cannot be written to and turns on
+the readonly flag automatically in this case.  (Useful for floppies.) 
 
-A small bug in the proc server has been hacked around; the real fix
-will come later.
+ufs statfs information (printed by df) should now be correct.
 
-Many important bugs in the C library have been fixed since the last
-snapshot; perhaps all of them.  ;-)
-
-
+A serious bug in ufs fsck when dealing with large directories has been
+fixed.
 
-June 6, 1995
+A new program `vminfo' prints the virtual memory map of task.
 
-The Hurd has switched to using the ELF object file format instead of a.out.
-You will need a very recent snapshot of GCC and binutils (we are using the
-950606 versions); the `i386-gnu' configuration now uses ELF, we are dumping
-a.out entirely.
-
-The exec server now understands the ELF format directly (not through BFD),
-because BFD has some deficiencies in its treatment of ELF.  The direct
-support for a.out has been ripped out completely.  The exec server can
-still support BFD as an optional addition, if compiled with -DBFD; this is
-now the only way to run a.out executables.  But if you only want to run new
-ELF binaries, then you can omit -DBFD and needn't bother building the BFD
-library to build the Hurd.  The support for gzip'd executables is now
-conditional on -DGZIP; it adds a pretty small amount of code.  Our
-makefiles use both -DGZIP and -DBFD by default; edit exec/Makefile if you
-wnat to omit BFD or gzip support.  (Probably soon we will omit -DBFD by
-default because it will make the exec server much smaller, but we just
-switched and still have run a.out binaries lying around we'd like to
-continue being able to run.)
-
-Because everything is now in ELF, the procedure to create an executable of
-the `boot' program that can run on UX is rather hairy.  Do `make boot.a' in
-the boot directory and run `boot/boot.a', which is an a.out executable.
-`boot/boot' is a weirdo ELF executable that UX cannot understand.
-
-The startup sequence has changed; the exec server image is no longer
-embedded in the filesystem image.  The `boot' program loads both the
-filesystem and the exec server into separate tasks and runs the filesystem,
-passing it the task port of the exec server, which it starts running when
-it's ready for it.  This closey approximates the eventual plan for booting
-the system, wherein the boot loader will load the multiple program files as
-well as the kernel, and the kernel will set up the two tasks.  However,
-changes are needed in the Mach bootstrap process to read ELF binaries and
-to start multiple servers, so for the moment native booting is broken.
-
-April 12, 1995
+All disk filesystems (ufs and ext2fs) now do directory name caching of
+`..' which was not previously done.  In addition, you can now set the
+cache size to be large, and then do experiments and see what the cache
+hit rate would have been for various smaller sizes.  This should help
+in optimizing the size of the cache.
 
-Many bugfixes and changes.  Now includes a fancy ps, settrans, and
-showtrans; separate translators for all the programs in /dev (and a
-MAKEDEV script).  Also the provisional source for network servers and
-some other snippets of code are now being distributed.  The trivfs
-library is now multithreaded.
-
-The old dev.trim is still being distributed, but you shouldn't use it.
-
-A serious bug that broke the filesystem's state after enough exec
-failures (of the bad format sort) happen.  A deadlock or two was also
-found and fixed.
-
-December 13, 1994
+A port leak in the pager library has been fixed; previously ufs leaked
+two ports per file used until the kernel's limit (about 30,000) was
+reached. 
 
-The exec server now recognizes gzip'd binaries and uncompresses them into
-memory to execute them.  (This has allowed a useful number of binaries to
-fit on a 1.44MB floppy.)
 
-November 24, 1994:
-
-Program changes:
-
-term could hang in delivery of terminal signals; fixed.
-
-pipes now handles io_select.
-
-These fixes allow GNU Emacs to work under the Hurd, with subprocesses.
-
-November 11, 1994:
-
-Structural changes:
-
-Our sources are now under RCS.  That shouldn't affect you at all,
-except that the file in the distribution will now be mostly mode 0444
-by default.
-
-
-Interface changes:
-
-`dealloc' flags have been added to many MiG interfaces broadly to fix
-a class of bugs.
-
-
-Library changes:
-
-Synchronous locks were hanging in some cases; to avoid it for now,
-they are never done at all.  (Of course, this is really a bug that
-needs fixed; the current change is purely for the sake of running the
-system.)
-
-Some bugs in translator startup in libfshelp have been fixed.
-
-Bootstrapping in libdiskfs is cleared up.  A bug in io_read that cause
-a crash if you gave an offset past the file size has been fixed.
-Non-root filesystems can now contact the execserver.
-
-
-Program changes:
-
-The `boot' hack can now start the first task in one of three ways: the
-way it was before, which is pretty Hurd-ish; just like the kernel
-starts the first task; and just like CMU's `boostrap' user program
-starts the CMU multiserver.  Also, `boot' always passes a -f flag so
-that other programs can no we aren't really running native.
-
-The execserver now registers itself properly on /servers/exec and can
-thus be used by non-bootstrap filesystems.
-
-Init uses symbolic names for /bin/sh and /dev/console rather than
-hardcoded strings.  The STANDALONE macro is gone; the behavior is the
-same but depends on the presence or absence of -f in the boot flags.
-
-Some minor bugs in proc have been fixed.
-
-The terminal driver now sends SIGWINCH properly.  Changing to and from
-ICANON now moves the terminal input queues around properly.
-
-The filesystem now uses one pager to map the disk and little pagers to
-map files.  Some hair is new to keep data from showing up in both
-pagers; generally the code is much simpler and cleaner now.  (Faster,
-too.)  The DT_* type information is currently unused due to an
-implementation difficulty.  Some workarounds have been installed to
-avoid some kernel bugs.
-
-Large writes to the pipes server used to crash it; they don't any
-longer.
-
-The /dev server now has hardcoded into it more disks and it's easier
-to add more yourself.  Also work around a kernel bug.
-
-New utilities: clri, sync, halt, reboot.  The output of ps has been
-cleaned up a little.
-
-Fsck has been rewritten; there are still bugs in creating directories.
-(That code is only used if /lost+found is absent, so it's still
-useful.)  The old version is renamed to bsdfsck.
-
-
-
-
-September 8, 1994:
-
-Structural changes:
-
-No significant structural changes have been made.
-
-
-Interface changes:
-
-term.defs has a new RPC `termctty_open_terminal', necessary for
-implementing /dev/tty.
-
-The filesystem lookup retry mechanism has been altered slightly.
-FS_RETRY_NONE is gone.  If the retry pathname is empty, then no retry
-is necessary, and the returned port should be used, after
-reauthenticating it if FS_RETRY_REAUTH was set.  Uniformly Hurd
-servers attach no special meaning to leading / in filenames, the
-result is that leading / (to Hurd servers) is a NOP.  
-
-The authentication protocol now passes a second port for rendezvous
-rather than an int; this cleans up a slight security hole.  The I/O
-and proc protocols have been changed accordingly.
-
-The args to file_set_translator have been cleaned up.
-
-All routines that used to say `path' no longer do; in GNU we always
-call these filenames.
-
-
-Library changes:
-
-libdiskfs and libfshelp now do passive translator startup properly.
-
-Setuid execution is now done by libdiskfs.
-
-A little work has been done in libpager towards implementing a default
-pager, bit it's not complete yet. 
-
-
-Program changes:
-
-A braino in the auth server was fixed, and it uses the new auth
-protocol.
-
-The boot program no longer spins; it uses multiple threads.  It also
-takes nice command line args.  ufs and init only pause for debugger
-attach if you give boot the -d flag.  Init now expects passive
-translators to be set for /dev and it looks prettier.
-
-The kludgy dev server now also works for (1) disk.
-
-Some exec server bugs in EXEC_NEWTASK were fixed.
-
-There is now a port of fsck, and two new programs: settrans and
-opendisk.
-
-The proc server now has a better prime number generator, and some
-small bugs have been fixed.
-
-The terminal driver now does job control and other signals correctly.
-
-Some minor improvements have been made in ufs.
-
-
-
-
-August 8, 1994:
-
-Structural changes:
-
-Makefiles have been vastly improved and are simpler.  The programs
-`su', `ps', and `sh' have been moved from separate dirs into `utils';
-the programs `symlink' and `ifsock' have been moved into `trans'.
-
-Several changes were made to GCC use.  You should definitely get GCC
-version 2.6.0 now.  Version 2.6.1 will have distributed the proper
-`specs' file for the i386-gnu target, but it isn't quite ready yet, so
-you still have to copy hurd/gcc-specs into
-gcc-lib/i386-gnu/2.6.0/specs.
-
-
-Interface changes:
-
-The tioctl.defs suite is complete now.
-
-INTR RPC's have been changed; individual RPC's are no longer marked
-INTR.  Rather, entire interfaces are marked `INTR_INTERFACE' if they
-conform to the library's signalling/interruption expectations.
-
-There is a new magical retry type (for dir_pathtrans and fsys_getroot)
-called `machtype' and a new one `/'; the former is for @sys tweaks and
-the latter cleans up the retry of root-based symlinks a bit.
-
-There is a new interface `login.defs'.
-
-The "dotdot node" is no longer passed at fsys_startup time; instead,
-it is passed by fsys_getroot.
-
-
-Library changes:
-
-The ports library now does death-timeouts for multi-threaded servers;
-it doesn't actually work right yet, however.  Also the ports library
-has new features (soft vs. hard ports; no outstanding ports
-notifications) that enable server-death to be done cleanly.  (I hope;
-libdiskfs and ufs haven't yet been changed to use it, so libports
-might not actually have the right facilities yet.)
-
-The translator startup routines in libfshelp have been vastly improved
-(so that they can actually be used).
-
-Numerous bugfixes in libdiskfs, particularly relating to translator
-usage.  Use new magical retry type `/' when appropriate.  Use new
-dotdot node protocol.  O_FSYNC and O_NOATIME are now honored properly.
-Alternative methods of storing symlinks are now supported through new
-hooks.  
-
-The new dotdot protocol is now used by libtrivfs.  Also, users of the
-library are now able to set the atime and mtime when necessary.
-
-The special threads version of malloc has been placed back in
-libthreads now that the C library uses a Mach-safe version on its own.
-
-
-Program changes:
-
-The `boot' program no longer implements the tioctl interface now that
-the terminal driver works.
-
-A bug was fixed in the handling of pgrps in `proc'.
-
-Many bugfixes in term.  The tioctl interface is now implemented.  EOF
-processing is fixed; break characters now work right.  Signals and
-interruption are now done correctly.  VDISCARD works.  
-
-Ufs has Some bigs fixed in dir.c.  Filesystem upgraded to BSD 4.4.
-There are now some compatibility flags.  
-
-New program dev.trim does a very minimal /dev (but doesn't work yet).
-New program dev is an initial (but poor) attempt at a real /dev.
-
-
-
-
-
-July 5, 1994:
-
-The Hurd now runs all the programs in the GNU fileutils, textutils,
-and shellutils distributions, with the exception of who.  Most
-importantly it runs GNU Hello.  Also, emacs works (with the kludgy
-`boot' terminal driver) and bash works.
-
-The simple pipes server works; it will be replaced eventually by the
-pflocal server (which isn't done yet).  The terminal driver is limping
-but working.  It doesn't support terminal ioctls yet.  A minor bug in
-auth has been fixed.  boot interprets more Hurd protocols; this was
-done to get emacs functioning.  Some more-or-less serious bugs in exec
-were fixed; they were found by running emacs (a quite large executable
-indeed).  At bootstrap time, init starts pipes and term itself;
-eventually these will be passive translators, but we don't want to
-write the new disk format until we're self-hosting or fsck and UX will
-get confused.  The file proc/primes.c has been documented; thanks go
-to Jim Blandy.  Some bugs in proc dealing with pgrp and wait were
-fixed; a nasty hash table bug was also fixed.  The simple shell can do
-pipes.  Several serious bugs in ufs were fixed dealing with extension
-of large files and writes of data not aligned on block boundaries.
-The ufs pager was over-serialized; that's been fixed.  Directory
-lookups and modifications now use mapped I/O directly; this is an
-important speed-up.  The structure of the pager lockes has been
-changed significantly.  UFS now supports Mach copying mode
-MEMORY_OBJECT_COPY_DELAY; this significantly improves process startup
-time.  
-
-Some minor changes have been made to several interfaces.  The
-interface for fs.defs:dir_readdir has been totally changed.  There are
-some new fs.defs interfaces: file_check_access, file_notice_changes,
-dir_notice_changes.  The fsys.defs:fsys_getroot interface was changed
-to work correctly.  process.defs:proc_setprocargs is renamed, and a
-fetch function proc_get_arg_locations is added.  The ifsock.defs
-interface was simplified.  
-
-Several bugs were fixed in libdiskfs.  The new dir_readdir interface
-requires new support from format-specific code.  Some race conditions
-have been fixed.  dir-pathtrans.c now deals correctly with multiple
-slashes in a row.  A new concept called "light references" allows
-pagers to remain active without preventing truncate-on-nolinks from
-working right.  New interfaces in fs.defs are implemented (except
-file_notice_changes).  Active translator usage has been fixed to work
-correctly, but passive translators are still untested.  libdiskfs now
-thinks it supports S_IFSOCK nodes, but that's untested (of course)
-because pflocal isn't done yet.
-
-The passive translator startup interface in libfshelp has been
-radically simplified.  The pager library now lets other code set and
-changee the attributes on objects, synchronously if desired.  An
-init/terminate race condition was fixed.   The ports library now
-allows single-threaded users to work right (they didn't before).  The
-trivfs library works; see the ifsock server for a simple example of
-its use.  See term or pipes for more complex examples.  
-
-There is a task list in the file `tasks'; let me know if you are
-interested in working on one of these.
-
-
-May 17, 1994:
-
-The Hurd now runs all the programs in the GNU fileutils and textutils
-distributions.  All the programs in shellutils run normally except
-who, false, groups, nohup, true, and nice.  We can't tell if tty is
-working right because the necessary support isn't set up (so it just
-prints `not a tty'.  Some minor filesystem bugs have been fixed,
-including several brainos in disk allocation and total lossage in
-symlink interpretation.  No bugs are now known.
-
-The library now supports signals; the program `timertest' is one test
-program we've used.  
-
-All the core servers register their version with proc and register
-themselves as essential tasks with init.  This enables proc to compute
-proper uname version strings and enables init to crash the system if
-one of the core servers dies.
-
-Boot is set up with a special hack to detect the RPC's that emacs uses
-to go into and out of raw mode; this will hopefully enable us to run
-emacs soon.
-
-There is a kludgy server called `pipes' (not yet completed) which
-implements just those parts of the local-domain socket server that the
-library uses in implementing the `pipe' function.  This will enable us
-to have a real shell somewhat before needing the local domain socket
-server.  
-
-More work on trivfs has happened; this will be needed by pipes.
-
-Cthreads is now in the Hurd distribution; this will make it much
-easier to install.  The GNU C library depends on some changes we have
-made to this version of C threads and will not work with other
-versions you might have.  (Several files in other versions of CMU
-Cthreads are not in this distibution [notably spin locks]; those are
-now in the GNU C library.)
-
-The installation hints in README have changed considerably; read them
-again.
-
-I'm now keeping ChangeLogs; you can examine them for more detailed
-information.
-  
-
-
-April 5, 1994:
-
-The Hurd now bootstraps.  Auth and proc start successfully; init
-prints "Init has completed" where it would run the shell.
-
-There are the beginnings of some documentation in the new doc
-directory.
-
-
-
-March 25, 1994:
-
-The Makefiles now are set up for cross-compilation; see README and the
-comments in Makeconf and Maketools for more information.
-
-The new diskfs library is complete.  The filesystem using it runs as
-well as the previous version.  Interested folk: please examine the
-diskfs interface, and see if it can be used for your favorite
-filesystem; I'd like it to be as general as possible.
-
-The proc server and auth servers link completely but have not been
-tested.  The init.trim directory holds a lightweight version of init
-suitable for use before the C library support for file descriptors,
-exec, and so forth works; this version of init compiles and links.
-The primary effort right now is booting init, proc, and auth.
-
-Work has been suspended on tmpfs for the time being, it not being
-necessary for a running system.  Some new FS calls have been added,
-notably dir_mkfile.  
-
-
-Feb 1, 1994:
-
-Much filesystem code has been split out into new libraries, most
-notably, libpager, which now contains the implementation of the
-complex multi-threaded pager previously in the filesystem.
-
-libdiskfs will continue this process, with everything related to
-filesystems based on disks (or other real substrates), but format
-independent.  libfshelp will have routines for starting translators,
-keeping track of flock, and so forth; it will be useful for any
-implementor of the fs protocol.  ufs currently does not use either of
-these, but will when they are done.
-
-tmpfs and init.trim are in progress.  tmpfs will be memory-only for
-things like /tmp, and is currently waiting for the fshelp library to
-be finished.  init.trim will be a scaled down init, useful for testing
-bootstrapping before there is enough library support to run the real
-init.  Currently this is waiting on fixing some crucial ld bugs.
-(When those are fixed, work will begin in earnest on bootstrapping
-auth, proc, and init.)
-
-
+6 August 1996
+Version 0.0
+Initial release
diff -ru hurd-0.0/README hurd-0.1/README
--- hurd-0.0/README	Mon Aug  5 11:53:48 1996
+++ hurd-0.1/README	Fri Sep  6 17:03:24 1996
@@ -1,5 +1,5 @@
 -*- Text -*-
-GNU Hurd version 0.0.
+GNU Hurd version 0.1.
 
 
 This is the Hurd.  Welcome.
@@ -10,11 +10,14 @@
 It is possible to cross-build the Hurd; the file INSTALL-cross
 contains some past instructions for doing so, but it's too much
 trouble to maintain these instructions and keep them up to date.  Your
-best bet is to start with a running Hurd system already.
+best bet is to start with a running Hurd system already.  If you do
+decide to cross compile, you will need to examine the instructions in
+INSTALL for building Mach, libc, and the Hurd together, and follow
+them. 
 
 Please note that this directory also contains a fair amount of
-not-yet-working code.  The makefiles build only the working code by
-default.
+not-yet-working code.  By default, the makefiles build only the
+working code.
 
 Bug reports for the GNU Hurd should be sent to the mailing list
 `bug-hurd@prep.ai.mit.edu'.  Please do not send requests for
@@ -23,9 +26,6 @@
 `help-hurd@prep.ai.mit.edu'.  You can join these lists by sending a
 request to `bug-hurd-request@prep.ai.mit.edu' or
 `help-hurd-request@prep.ai.mit.edu' respectively.
-
-If any of these address should fail, send your message to
-`tower@gnu.ai.mit.edu' and ask him to forward it properly.
 
 The GNU Hurd is free software.  All of it, including the libraries in
 this distribution, is covered by the GNU General Public License, found
diff -ru hurd-0.0/auth/ChangeLog hurd-0.1/auth/ChangeLog
--- hurd-0.0/auth/ChangeLog	Fri Jul 19 00:36:10 1996
+++ hurd-0.1/auth/ChangeLog	Thu Sep  5 11:28:49 1996
@@ -1,3 +1,9 @@
+Thu Sep  5 11:05:37 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* auth.c (AUTH_VERSION): Delete macro.
+	(argp_program_version): Use STANDARD_HURD_VERSION.
+	(main): Pass empty string as release; HURD_VERSION as version.
+
 Fri Jul 19 00:35:46 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* auth.c (S_auth_makeauth): Deallocate initial reference to
diff -ru hurd-0.0/auth/auth.c hurd-0.1/auth/auth.c
--- hurd-0.0/auth/auth.c	Fri Jul 19 00:35:38 1996
+++ hurd-0.1/auth/auth.c	Thu Sep  5 11:39:33 1996
@@ -29,12 +29,12 @@
 #include <idvec.h>
 #include <assert.h>
 #include <argp.h>
+#include <version.h>
 #include "auth_S.h"
 #include "auth_reply_U.h"
 
-#define AUTH_VERSION "0.0"
+char *argp_program_version = STANDARD_HURD_VERSION(auth);
 
-char *argp_program_version = "auth " AUTH_VERSION " (GNU " HURD_RELEASE ")";
 
 /* Auth handles are server ports with sets of ids.  */
 struct authhandle
@@ -466,7 +466,7 @@
 
   /* Register ourselves with the proc server and then start signals.  */
   proc_getprivports (proc, &hostpriv, &masterdev);
-  proc_register_version (proc, hostpriv, "auth", HURD_RELEASE, AUTH_VERSION);
+  proc_register_version (proc, hostpriv, "auth", "", HURD_VERSION);
   mach_port_deallocate (mach_task_self (), masterdev);
   _hurd_port_set (&_hurd_ports[INIT_PORT_PROC], proc);
   _hurd_proc_init (argv);
diff -ru hurd-0.0/boot/ChangeLog hurd-0.1/boot/ChangeLog
--- hurd-0.0/boot/ChangeLog	Thu Aug  1 14:39:33 1996
+++ hurd-0.1/boot/ChangeLog	Wed Aug 14 14:04:29 1996
@@ -1,3 +1,20 @@
+Tue Aug 13 16:57:22 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makefile (device.defs): Rule removed.
+	(ourdevice.defs): Fix rule to work with Makeconf-generated device.defs.
+
+Tue Aug 13 15:09:45 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makefile (ourdevice.defs): Depend on local device.defs.
+	(device.defs): New rule.
+
+Mon Aug 12 11:11:08 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makefile (ourdevice.defs): Find device.defs under
+	install_includedir now.
+	
+	* Makefile (all): No longer build uxboot by default.
+
 Thu Aug  1 14:38:38 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* boot_script.h (safe_gets): Declare second parm as type `int'.
diff -ru hurd-0.0/boot/Makefile hurd-0.1/boot/Makefile
--- hurd-0.0/boot/Makefile	Mon Apr 15 13:10:21 1996
+++ hurd-0.1/boot/Makefile	Wed Aug 14 14:04:30 1996
@@ -36,10 +36,10 @@
 #/usr/local/bin/uxboot: uxboot
 #	cp $< $@
 
-all: boot uxboot
+all: boot # uxboot
 
-ourdevice.defs: $(includedir)/device/device.defs
-	sed -e '/out	device		: device_t/s/device_t/mach_port_send_t/' $< > $@
+ourdevice.defs: device.defs
+	$(CPP) $(CPPFLAGS) -x c $< | sed -e '/out	device		: device_t/s/device_t/mach_port_send_t/' > $@
 
 boot: ../libthreads/libthreads.so
 
diff -ru hurd-0.0/config.make.in hurd-0.1/config.make.in
--- hurd-0.0/config.make.in	Thu Jun 27 10:05:47 1996
+++ hurd-0.1/config.make.in	Wed Sep  4 08:56:45 1996
@@ -2,6 +2,7 @@
 
 # Machine architecture.
 machine = @host_cpu@
+asm_syntax = @asm_syntax@
 
 # Prefix prepended to names of machine-independent installed files.
 prefix = @prefix@
diff -ru hurd-0.0/configure hurd-0.1/configure
--- hurd-0.0/configure	Thu Jul 18 12:56:18 1996
+++ hurd-0.1/configure	Wed Sep  4 09:05:08 1996
@@ -1,6 +1,6 @@
 #! /bin/sh
 
-# From configure.in Id: configure.in,v 1.5 1996/05/01 02:19:03 roland Exp 
+# From configure.in Id: configure.in,v 1.7 1996/08/13 18:10:06 thomas Exp 
 			# Guess values for system-dependent variables and create Makefiles.
 # Generated automatically using autoconf version 2.10 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
@@ -565,6 +565,14 @@
 *) { echo "configure: error: sorry, this is the gnu os, not $host_os" 1>&2; exit 1; } ;;
 esac
 
+case "$host_cpu" in
+i[3456]86)
+	asm_syntax=i386
+	;;
+*) { echo "configure: error: unspported CPU type" 1>&2; exit 1; } ;;
+esac
+
+
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
@@ -766,7 +774,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:770: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -1107,6 +1115,7 @@
 s%@host_cpu@%$host_cpu%g
 s%@host_vendor@%$host_vendor%g
 s%@host_os@%$host_os%g
+s%@asm_syntax@%$asm_syntax%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
 s%@INSTALL_DATA@%$INSTALL_DATA%g
 s%@build@%$build%g
diff -ru hurd-0.0/configure.in hurd-0.1/configure.in
--- hurd-0.0/configure.in	Tue Apr 30 22:19:03 1996
+++ hurd-0.1/configure.in	Thu Sep  5 12:15:13 1996
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_REVISION([$Id: configure.in,v 1.5 1996/05/01 02:19:03 roland Exp $])
+AC_REVISION([$Id: configure.in,v 1.8 1996/09/05 14:14:01 thomas Exp $])
 AC_PREREQ(2.4)			dnl Minimum Autoconf version required.
 AC_INIT(hurd/hurd_types.h)	dnl A distinctive file to look for in srcdir.
 
@@ -10,6 +10,14 @@
 gnu*) ;;
 *) AC_MSG_ERROR([sorry, this is the gnu os, not $host_os]) ;;
 esac
+
+case "$host_cpu" in
+i[[3456]]86)
+	asm_syntax=i386
+	;;
+*) AC_MSG_ERROR([unspported CPU type]) ;;
+esac
+AC_SUBST(asm_syntax)
 
 AC_PROG_INSTALL
 
diff -ru hurd-0.0/daemons/ChangeLog hurd-0.1/daemons/ChangeLog
--- hurd-0.0/daemons/ChangeLog	Sat Jul 20 11:04:19 1996
+++ hurd-0.1/daemons/ChangeLog	Wed Aug 14 14:04:35 1996
@@ -1,3 +1,13 @@
+Wed Aug 14 10:22:39 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makefile (getty-LDLIBS): New variable.
+	(getty): Dependency on -lutil removed.
+	(libutil-libsubst): Variable removed.
+
+Tue Aug 13 08:13:04 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* rc.sh: When deleting files from /tmp, use -f flag to rm.
+
 Sat Jul 20 01:06:07 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* getty.c (main): Get the tty name from the right element in ARGV.
diff -ru hurd-0.0/daemons/Makefile hurd-0.1/daemons/Makefile
--- hurd-0.0/daemons/Makefile	Sat Jul  6 00:19:03 1996
+++ hurd-0.1/daemons/Makefile	Wed Aug 14 14:04:35 1996
@@ -26,14 +26,13 @@
 installationdir = $(libexecdir)
 
 OBJS = $(SRCS:.c=.o)
-
-libutil-libsubst = -lutil
+getty-LDLIBS = -lutil
 
 include ../Makeconf
 
-%: %.sh
-	cp $< $@ && chmod +w $@
-
-getty: ../libshouldbeinlibc/libshouldbeinlibc.a -lutil
+getty: ../libshouldbeinlibc/libshouldbeinlibc.a
 
 $(filter-out $(special-targets), $(targets)): %: %.o
+
+%: %.sh
+	cp $< $@ && chmod +w $@
diff -ru hurd-0.0/daemons/rc.sh hurd-0.1/daemons/rc.sh
--- hurd-0.0/daemons/rc.sh	Mon Jul 15 17:27:17 1996
+++ hurd-0.1/daemons/rc.sh	Tue Aug 13 08:11:51 1996
@@ -46,7 +46,7 @@
 rm -f /etc/nologin
 rm -f /var/lock/LCK.*
 if test -d /tmp; then
-  (cd /tmp; find . ! -name . ! -name lost+found ! -name quotas -exec rm -r {} \; )
+  (cd /tmp; find . ! -name . ! -name lost+found ! -name quotas -exec rm -rf {} \; )
 fi
 if test -d /var/run; then
   (cd /var/run && { rm -rf -- *; cp /dev/null utmp; chmod 644 utmp; })
diff -ru hurd-0.0/exec/ChangeLog hurd-0.1/exec/ChangeLog
--- hurd-0.0/exec/ChangeLog	Wed Jul 17 18:54:46 1996
+++ hurd-0.1/exec/ChangeLog	Thu Sep  5 11:12:05 1996
@@ -1,3 +1,23 @@
+Thu Sep  5 11:11:19 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* main.c: Include <version.h>.
+	(exec_version): Delete variable.
+ 	(S_exec_init): Pass empty string as release; HURD_VERSION
+	as version.
+
+Thu Aug 29 13:00:38 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* priv.h: Only include <bfd.h> if BFD.  Only declare
+	host_bfd_arc_info, and bfd_host_bfd if BFD.  If not BFD, give
+	typedef for asection. 
+	* main.c: Only define host_bfd_arch_info, host_bfd, and
+	bfd_mach_host_arch_mach if BFD.  
+	(main): Only call bfd_mach_most_arch_mach if BFD.
+	Call mach_host_elf_machine.
+	* hostarch.c (bfd_mach_host_arch_mach): Only define if BFD.
+	Delete arg E_MACHINE.  All callers changed.
+	(mach_host_elf_machine): New function.
+
 Sun Jul  7 21:13:22 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* exec.c (S_exec_exec): Don't use unsafe MOVE_SEND in call to
diff -ru hurd-0.0/exec/hostarch.c hurd-0.1/exec/hostarch.c
--- hurd-0.0/exec/hostarch.c	Thu Jul  6 22:12:51 1995
+++ hurd-0.1/exec/hostarch.c	Thu Aug 29 13:33:13 1996
@@ -1,6 +1,6 @@
 /* Determine the BFD and ELF architecture and machine flavor
    from a Mach host port.  Used by the exec and core servers.
-   Copyright (C) 1992, 1993, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1995, 1996 Free Software Foundation, Inc.
    Written by Roland McGrath.
 
 This file is part of the GNU Hurd.
@@ -19,17 +19,68 @@
 along with the GNU Hurd; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
+
 #include <mach.h>
 #include <hurd/hurd_types.h>
 #include <errno.h>
-#include <bfd.h>
 #include <elf.h>
 
 error_t
+mach_host_elf_machine (host_t host,
+		       Elf32_Half *e_machine)
+{
+  error_t err;
+  struct host_basic_info hostinfo;
+  mach_msg_type_number_t hostinfocnt = HOST_BASIC_INFO_COUNT;
+
+  err = host_info (host, HOST_BASIC_INFO, 
+		   (natural_t *) &hostinfo, &hostinfocnt);
+  if (err)
+    return err;
+
+  switch (hostinfo.cpu_type)
+    {
+    default:
+      *e_machine = EM_NONE;
+      break;
+
+    case CPU_TYPE_MC68020:
+    case CPU_TYPE_MC68030:
+    case CPU_TYPE_MC68040:
+      *e_machine = EM_68K;
+      break;
+
+    case CPU_TYPE_I860:
+      *e_machine = EM_860;
+      break;
+
+    case CPU_TYPE_MIPS:
+      *e_machine = EM_MIPS;
+      break;
+
+    case CPU_TYPE_MC88000:
+      *e_machine = EM_88K;
+      break;
+
+    case CPU_TYPE_SPARC:
+      *e_machine = EM_SPARC;
+      break;
+
+    case CPU_TYPE_I386:
+      *e_machine = EM_386;
+      break;
+    }
+
+  return 0;
+}
+
+#ifdef BFD
+#include <bfd.h>
+
+error_t
 bfd_mach_host_arch_mach (host_t host,
 			 enum bfd_architecture *arch,
-			 long int *machine,
-			 Elf32_Half *e_machine)
+			 long int *machine)
 {
   error_t err;
   struct host_basic_info hostinfo;
@@ -117,3 +168,5 @@
 
   return 0;
 }
+
+#endif /* BFD */
diff -ru hurd-0.0/exec/main.c hurd-0.1/exec/main.c
--- hurd-0.0/exec/main.c	Mon May  6 14:26:35 1996
+++ hurd-0.1/exec/main.c	Thu Sep  5 11:12:09 1996
@@ -1,5 +1,5 @@
 /* GNU Hurd standard exec server, main program and server mechanics.
-   Copyright (C) 1992, 1993, 19941996 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 19941996, 1996 Free Software Foundation, Inc.
    Written by Roland McGrath.
 
 This file is part of the GNU Hurd.
@@ -22,17 +22,18 @@
 #include <error.h>
 #include <hurd/paths.h>
 #include <hurd/startup.h>
+#include <version.h>
 
-
+#ifdef BFD
 bfd_arch_info_type host_bfd_arch_info;
 bfd host_bfd = { arch_info: &host_bfd_arch_info };
-Elf32_Half elf_machine;	/* ELF e_machine for the host.  */
-
 extern error_t bfd_mach_host_arch_mach (host_t host,
 					enum bfd_architecture *bfd_arch,
 					long int *bfd_machine,
 					Elf32_Half *elf_machine);
+#endif
 
+Elf32_Half elf_machine;	/* ELF e_machine for the host.  */
 
 /* Trivfs hooks.  */
 int trivfs_fstype = FSTYPE_MISC;
@@ -49,7 +50,6 @@
 
 struct trivfs_control *fsys;
 
-char *exec_version = "0.0";
 char **save_argv;
 
 
@@ -116,12 +116,15 @@
 
   save_argv = argv;
 
+#ifdef BFD
   /* Put the Mach kernel's idea of what flavor of machine this is into the
      fake BFD against which architecture compatibility checks are made.  */
   err = bfd_mach_host_arch_mach (mach_host_self (),
 				 &host_bfd.arch_info->arch,
-				 &host_bfd.arch_info->mach,
-				 &elf_machine);
+				 &host_bfd.arch_info->mach);
+#endif
+  err = mach_host_elf_machine (mach_host_self (), &elf_machine);
+  
   if (err)
     error (1, err, "Getting host architecture from Mach");
 
@@ -249,8 +252,7 @@
   err = get_privileged_ports (&host_priv, &dev_master);
   if (!err)
     {
-      proc_register_version (procserver, host_priv, "exec", HURD_RELEASE,
-			     exec_version);
+      proc_register_version (procserver, host_priv, "exec", "", HURD_VERSION);
       mach_port_deallocate (mach_task_self (), dev_master);
       err = proc_getmsgport (procserver, 1, &startup);
       if (err)
diff -ru hurd-0.0/exec/priv.h hurd-0.1/exec/priv.h
--- hurd-0.0/exec/priv.h	Tue Oct 24 19:21:09 1995
+++ hurd-0.1/exec/priv.h	Thu Aug 29 13:28:12 1996
@@ -1,5 +1,5 @@
 /* GNU Hurd standard exec server, private declarations.
-   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
    Written by Roland McGrath.
 
 This file is part of the GNU Hurd.
@@ -26,7 +26,11 @@
 #include <hurd/ports.h>
 #include <hurd/lookup.h>
 #include <rwlock.h>
+
+#ifdef BFD
 #include <bfd.h>
+#endif
+
 #include <elf.h>
 #include <fcntl.h>
 #include "exec_S.h"
@@ -35,11 +39,13 @@
 #ifndef exec_priv_h
 #define exec_priv_h
 
+#ifdef BFD
 /* A BFD whose architecture and machine type are those of the host system.  */
 extern bfd_arch_info_type host_bfd_arch_info;
 extern bfd host_bfd;
-extern Elf32_Half elf_machine;	/* ELF e_machine for the host.  */
+#endif
 
+extern Elf32_Half elf_machine;	/* ELF e_machine for the host.  */
 
 /* Information kept around to be given to a new task
    in response to a message on the task's bootstrap port.  */
@@ -67,6 +73,9 @@
 
 extern mach_port_t procserver;	/* Our proc port.  */
 
+#ifndef BFD
+typedef void asection;
+#endif
 
 /* Data shared between check, check_section,
    load, load_section, and finish.  */
diff -ru hurd-0.0/ext2fs/ChangeLog hurd-0.1/ext2fs/ChangeLog
--- hurd-0.0/ext2fs/ChangeLog	Fri Aug  2 16:23:20 1996
+++ hurd-0.1/ext2fs/ChangeLog	Fri Sep  6 16:05:28 1996
@@ -1,3 +1,79 @@
+Fri Sep  6 16:03:11 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* ext2fs.c: Include <version.h>.
+	(diskfs_major_version, diskfs_minor_version, diskfs_edit_version):
+	Deleted variables.
+	(diskfs_server_version): New variable.
+
+Thu Aug 29 16:59:51 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	Changes from ufs/dir.c:
+	* dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set
+ 	ds->idx by looking at the size of the file.  After successful
+ 	dirscanblock, record index where we finished in DP->dn->dir_idx.
+  	Start searches at that index.
+	(dirscanblock): Size dirents correctly when mallocing it.
+	(diskfs_direnter_hard): Be more careful when sizing or resizing
+	dirents.  Correctly set to -1 all the new entries we create after
+	realloc call.   
+	* ext2fs.h (struct disknode): New member `dir_idx'.
+	* inode.c (diskfs_cached_lookup): Initialize DN->dir_idx.
+
+	* dir.c (diskfs_direnter_hard): Initialize OLDSIZE to quiet gcc.
+
+Sun Aug 18 01:45:42 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* pager.c (file_pager_read_page): Use get_page_buf to get a free page.
+	(file_pager_read_page): Use free_page_buf to deallocate pages.
+	* ext2fs.c (get_page_buf): Return 0 if we can't allocate.
+
+Thu Aug 15 14:55:01 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* ext2fs.c (diskfs_edit_version): Change to `1'.
+	(diskfs_version_extra): New variable.
+	* inode.c (read_disknode): Change assertion to allow non-zero
+	st_size for anything, but assert that st_blocks == 0 for any case
+	where we set allocsize to 0.
+	* truncate.c (diskfs_truncate): Allow any sort of node to have a
+	size without any blocks (as linux apparently does this sometimes
+	with devices).
+
+Wed Aug 14 14:03:33 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* ext2fs.c (diskfs_minor_version): Change to `2'.
+
+Tue Aug 13 15:11:42 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* ext2_fs.h: Update to version from linux-2.0.12.
+	* ialloc.c (ext2_alloc_inode, diskfs_free_node): Pass SBLOCK as a
+	parameter to EXT2_FIRST_INO (v2.x change).
+	* hyper.c (get_hypermetadata): Use EXT2_INODE_SIZE instead of
+	sizeof (struct ext2_inode).
+	Deal with various version 2.x features.
+	* ext2fs.h (dino): Dont recalculate INODES_PER_BLOCK here.
+	(ext2_debug): redefine macro after including ext2_fs.h.
+	
+Mon Aug 12 13:48:17 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* ext2fs.c (diskfs_minor_version): Changed to `1'.
+
+	* inode.c (read_disknode): Don't set allocsize for in-inode symlinks.
+	(MAX_INODE_SYMLINK): New macro.
+	(write_symlink, read_symlink): New functions.
+	(diskfs_create_symlink_hook, diskfs_read_symlink_hook): New variables.
+	* truncate.c (diskfs_truncate): For in-inode symlinks, just frob
+	the size.
+
+	* ext2fs.h (__u32, __u16, __u8, __s32, __s16, __s8): New types.
+	* ext2_fs.h (u32, u16, u8, s32, s16, s8): All uses of these types
+	changed to have a leading `__', and the definitions removed.
+	* ext2_fs_i.h (u32, u16, u8, s32, s16, s8): All uses of these types
+	changed to have a leading `__'.
+
+Mon Aug 12 11:18:37 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* hyper.c (diskfs_set_hypermetadata): Return an error code now.
+
 Fri Aug  2 12:10:40 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* inode.c (diskfs_write_disknode): If WAIT is false, still record
diff -ru hurd-0.0/ext2fs/dir.c hurd-0.1/ext2fs/dir.c
--- hurd-0.0/ext2fs/dir.c	Tue Jun 25 17:31:35 1996
+++ hurd-0.1/ext2fs/dir.c	Tue Sep  3 10:20:41 1996
@@ -119,7 +119,8 @@
   vm_address_t buf = 0;
   vm_size_t buflen = 0;
   int blockaddr;
-  int idx;
+  int idx, lastidx;
+  int looped;
   
   if ((type == REMOVE) || (type == RENAME))
     assert (npp);
@@ -164,18 +165,39 @@
   if (!diskfs_check_readonly ())
     dp->dn_set_atime = 1;
   
-  for (blockaddr = buf, idx = 0;
-       blockaddr - buf < dp->dn_stat.st_size;
-       blockaddr += DIRBLKSIZ, idx++)
+  /* Start the lookup at DP->dn->dir_idx.  */
+  idx = dp->dn->dir_idx;
+  if (idx * DIRBLKSIZ > dp->dn_stat.st_size)
+    idx = 0;			/* just in case */
+  blockaddr = buf + idx * DIRBLKSIZ;
+  looped = (idx == 0);
+  lastidx = idx;
+  if (lastidx == 0)
+    lastidx = dp->dn_stat.st_size / DIRBLKSIZ;
+
+  while (!looped || idx < lastidx)
     {
       err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum);
       if (!err)
-	break;
+	{
+	  dp->dn->dir_idx = idx;
+	  break;
+	}
       if (err != ENOENT)
 	{
 	  vm_deallocate (mach_task_self (), buf, buflen);
 	  return err;
 	}
+
+      blockaddr += DIRBLKSIZ;
+      idx++;
+      if (blockaddr - buf >= dp->dn_stat.st_size && !looped)
+	{
+	  /* We've gotten to the end; start back at the beginning */
+	  looped = 1;
+	  blockaddr = buf;
+	  idx = 0;
+	}
     }
 
   if (!diskfs_check_readonly ())
@@ -266,7 +288,7 @@
       /* We didn't find any room, so mark ds to extend the dir */
       ds->type = CREATE;
       ds->stat = EXTEND;
-      ds->idx = idx;
+      ds->idx = dp->dn_stat.st_size / DIRBLKSIZ;
     }
 
   /* Return to the user; if we can't, release the reference
@@ -428,8 +450,8 @@
 	 down how many entries there were. */
       if (!dp->dn->dirents)
 	{
-	  dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) 
-				* sizeof (int));
+	  dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) 
+				    * sizeof (int));
 	  for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) 
 	    dp->dn->dirents[i] = -1;
 	}
@@ -475,7 +497,7 @@
   vm_address_t fromoff, tooff;
   int totfreed;  
   error_t err;
-  off_t oldsize;
+  off_t oldsize = 0;
 
   assert (ds->type == CREATE);
   
@@ -590,19 +612,26 @@
     }
   else
     {
+      int i;
       /* It's cheap, so start a count here even if we aren't counting
 	 anything at all. */
       if (dp->dn->dirents)
 	{
 	  dp->dn->dirents = realloc (dp->dn->dirents, 
-				     (ds->idx + 1) * sizeof (int));
+				     (dp->dn_stat.st_size / DIRBLKSIZ
+				      * sizeof (int)));
+	  for (i = oldsize / DIRBLKSIZ; 
+	       i < dp->dn_stat.st_size / DIRBLKSIZ;
+	       i++)
+	    dp->dn->dirents[i] = -1;
+
 	  dp->dn->dirents[ds->idx] = 1;
 	}
       else
 	{
-	  int i;
-	  dp->dn->dirents = malloc ((ds->idx + 1) * sizeof (int));
-	  for (i = 0; i < ds->idx; i++)
+	  dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ 
+				    * sizeof (int));
+	  for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++)
 	    dp->dn->dirents[i] = -1;
 	  dp->dn->dirents[ds->idx] = 1;
 	}
diff -ru hurd-0.0/ext2fs/ext2_fs.h hurd-0.1/ext2fs/ext2_fs.h
--- hurd-0.0/ext2fs/ext2_fs.h	Fri Aug  2 16:23:21 1996
+++ hurd-0.1/ext2fs/ext2_fs.h	Thu Aug 15 16:57:09 1996
@@ -16,13 +16,6 @@
 #ifndef _LINUX_EXT2_FS_H
 #define _LINUX_EXT2_FS_H
 
-typedef unsigned long u32;
-typedef long s32;
-typedef unsigned short u16;
-typedef short s16;
-typedef unsigned char u8;
-typedef signed char s8;
-
 /*
  * The second extended filesystem constants/structures
  */
@@ -33,21 +26,6 @@
 #undef EXT2FS_DEBUG
 
 /*
- * Define EXT2FS_DEBUG_CACHE to produce cache debug messages
- */
-#undef EXT2FS_DEBUG_CACHE
-
-/*
- * Define EXT2FS_CHECK_CACHE to add some checks to the name cache code
- */
-#undef EXT2FS_CHECK_CACHE
-
-/*
- * Define EXT2FS_PRE_02B_COMPAT to convert ext 2 fs prior to 0.2b
- */
-#undef EXT2FS_PRE_02B_COMPAT
-
-/*
  * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
  */
 #define EXT2_PREALLOCATE
@@ -55,18 +33,20 @@
 /*
  * The second extended file system version
  */
-#define EXT2FS_DATE		"95/03/19"
-#define EXT2FS_VERSION		"0.5a"
+#define EXT2FS_DATE		"95/08/09"
+#define EXT2FS_VERSION		"0.5b"
 
 /*
  * Debug code
  */
 #ifdef EXT2FS_DEBUG
-extern int ext2_debug_flag;
-#define ext2_debug(f, a...) \
- do { if (ext2_debug_flag) printf ("ext2fs: (debug) %s: " f "\n", __FUNCTION__ , ## a); } while (0)
+#	define ext2_debug(f, a...)	{ \
+					printk ("EXT2-fs DEBUG (%s, %d): %s:", \
+						__FILE__, __LINE__, __FUNCTION__); \
+				  	printk (f, ## a); \
+					}
 #else
-#define ext2_debug(f, a...)	(void)0
+#	define ext2_debug(f, a...)	/**/
 #endif
 
 /*
@@ -78,12 +58,13 @@
 #define EXT2_ACL_DATA_INO	 4	/* ACL inode */
 #define EXT2_BOOT_LOADER_INO	 5	/* Boot loader inode */
 #define EXT2_UNDEL_DIR_INO	 6	/* Undelete directory inode */
-#define EXT2_FIRST_INO		11	/* First non reserved inode */
+
+/* First non-reserved inode for old ext2 filesystems */
+#define EXT2_GOOD_OLD_FIRST_INO	11
 
 /*
  * The second extended file system magic number
  */
-#define EXT2_PRE_02B_MAGIC	0xEF51
 #define EXT2_SUPER_MAGIC	0xEF53
 
 /*
@@ -103,13 +84,24 @@
 # define EXT2_BLOCK_SIZE(s)		(EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
 #endif
 #define EXT2_ACLE_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
-#define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (u32))
+#define	EXT2_ADDR_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (__u32))
 #ifdef __KERNEL__
-# define EXT2_BLOCK_SIZE_BITS(s)	((s)->u.ext2_sb.s_es->s_log_block_size + 10)
+# define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_blocksize_bits)
 #else
 # define EXT2_BLOCK_SIZE_BITS(s)	((s)->s_log_block_size + 10)
 #endif
-#define	EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_inode))
+#ifdef __KERNEL__
+#define	EXT2_ADDR_PER_BLOCK_BITS(s)	((s)->u.ext2_sb.s_addr_per_block_bits)
+#define EXT2_INODE_SIZE(s)		((s)->u.ext2_sb.s_inode_size)
+#define EXT2_FIRST_INO(s)		((s)->u.ext2_sb.s_first_ino)
+#else
+#define EXT2_INODE_SIZE(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_INODE_SIZE : \
+				 (s)->s_inode_size)
+#define EXT2_FIRST_INO(s)	(((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
+				 EXT2_GOOD_OLD_FIRST_INO : \
+				 (s)->s_first_ino)
+#endif
 
 /*
  * Macro-instructions used to manage fragments
@@ -130,45 +122,36 @@
  */
 struct ext2_acl_header	/* Header of Access Control Lists */
 {
-	u32	aclh_size;
-	u32	aclh_file_count;
-	u32	aclh_acle_count;
-	u32	aclh_first_acle;
+	__u32	aclh_size;
+	__u32	aclh_file_count;
+	__u32	aclh_acle_count;
+	__u32	aclh_first_acle;
 };
 
 struct ext2_acl_entry	/* Access Control List Entry */
 {
-	u32	acle_size;
-	u16	acle_perms;	/* Access permissions */
-	u16	acle_type;	/* Type of entry */
-	u16	acle_tag;	/* User or group identity */
-	u16	acle_pad1;
-	u32	acle_next;	/* Pointer on next entry for the */
+	__u32	acle_size;
+	__u16	acle_perms;	/* Access permissions */
+	__u16	acle_type;	/* Type of entry */
+	__u16	acle_tag;	/* User or group identity */
+	__u16	acle_pad1;
+	__u32	acle_next;	/* Pointer on next entry for the */
 					/* same inode or on next free entry */
 };
 
 /*
  * Structure of a blocks group descriptor
  */
-struct ext2_old_group_desc
-{
-	u32	bg_block_bitmap;		/* Blocks bitmap block */
-	u32	bg_inode_bitmap;		/* Inodes bitmap block */
-	u32	bg_inode_table;		/* Inodes table block */
-	u16	bg_free_blocks_count;	/* Free blocks count */
-	u16	bg_free_inodes_count;	/* Free inodes count */
-};
-
 struct ext2_group_desc
 {
-	u32	bg_block_bitmap;		/* Blocks bitmap block */
-	u32	bg_inode_bitmap;		/* Inodes bitmap block */
-	u32	bg_inode_table;		/* Inodes table block */
-	u16	bg_free_blocks_count;	/* Free blocks count */
-	u16	bg_free_inodes_count;	/* Free inodes count */
-	u16	bg_used_dirs_count;	/* Directories count */
-	u16	bg_pad;
-	u32	bg_reserved[3];
+	__u32	bg_block_bitmap;		/* Blocks bitmap block */
+	__u32	bg_inode_bitmap;		/* Inodes bitmap block */
+	__u32	bg_inode_table;		/* Inodes table block */
+	__u16	bg_free_blocks_count;	/* Free blocks count */
+	__u16	bg_free_inodes_count;	/* Free inodes count */
+	__u16	bg_used_dirs_count;	/* Directories count */
+	__u16	bg_pad;
+	__u32	bg_reserved[3];
 };
 
 /*
@@ -178,6 +161,7 @@
 # define EXT2_BLOCKS_PER_GROUP(s)	((s)->u.ext2_sb.s_blocks_per_group)
 # define EXT2_DESC_PER_BLOCK(s)		((s)->u.ext2_sb.s_desc_per_block)
 # define EXT2_INODES_PER_GROUP(s)	((s)->u.ext2_sb.s_inodes_per_group)
+# define EXT2_DESC_PER_BLOCK_BITS(s)	((s)->u.ext2_sb.s_desc_per_block_bits)
 #else
 # define EXT2_BLOCKS_PER_GROUP(s)	((s)->s_blocks_per_group)
 # define EXT2_DESC_PER_BLOCK(s)		(EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
@@ -203,7 +187,8 @@
 #define EXT2_IMMUTABLE_FL		0x00000010 /* Immutable file */
 #define EXT2_APPEND_FL			0x00000020 /* writes to file may only append */
 #define EXT2_NODUMP_FL			0x00000040 /* do not dump file */
-
+#define EXT2_RESERVED_FL		0x80000000 /* reserved for ext2 lib */
+	
 /*
  * ioctl commands
  */
@@ -216,53 +201,53 @@
  * Structure of an inode on the disk
  */
 struct ext2_inode {
-	u16 i_mode;		/* File mode */
-	u16 i_uid;		/* Owner Uid */
-	u32  i_size;		/* Size in bytes */
-	u32  i_atime;		/* Access time */
-	u32  i_ctime;		/* Creation time */
-	u32  i_mtime;		/* Modification time */
-	u32  i_dtime;		/* Deletion Time */
-	u16 i_gid;		/* Group Id */
-	u16 i_links_count;	/* Links count */
-	u32  i_blocks;	/* Blocks count */
-	u32  i_flags;		/* File flags */
+	__u16	i_mode;		/* File mode */
+	__u16	i_uid;		/* Owner Uid */
+	__u32	i_size;		/* Size in bytes */
+	__u32	i_atime;	/* Access time */
+	__u32	i_ctime;	/* Creation time */
+	__u32	i_mtime;	/* Modification time */
+	__u32	i_dtime;	/* Deletion Time */
+	__u16	i_gid;		/* Group Id */
+	__u16	i_links_count;	/* Links count */
+	__u32	i_blocks;	/* Blocks count */
+	__u32	i_flags;	/* File flags */
 	union {
 		struct {
-			u32  l_i_reserved1;
+			__u32  l_i_reserved1;
 		} linux1;
 		struct {
-			u32  h_i_translator;
+			__u32  h_i_translator;
 		} hurd1;
 		struct {
-			u32  m_i_reserved1;
+			__u32  m_i_reserved1;
 		} masix1;
 	} osd1;				/* OS dependent 1 */
-	u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
-	u32	i_version;	/* File version (for NFS) */
-	u32	i_file_acl;	/* File ACL */
-	u32	i_dir_acl;	/* Directory ACL */
-	u32	i_faddr;		/* Fragment address */
+	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
+	__u32	i_version;	/* File version (for NFS) */
+	__u32	i_file_acl;	/* File ACL */
+	__u32	i_dir_acl;	/* Directory ACL */
+	__u32	i_faddr;	/* Fragment address */
 	union {
 		struct {
-			u8	l_i_frag;	/* Fragment number */
-			u8	l_i_fsize;	/* Fragment size */
-			u16	i_pad1;
-			u32	l_i_reserved2[2];
+			__u8	l_i_frag;	/* Fragment number */
+			__u8	l_i_fsize;	/* Fragment size */
+			__u16	i_pad1;
+			__u32	l_i_reserved2[2];
 		} linux2;
 		struct {
-			u8	h_i_frag;	/* Fragment number */
-			u8	h_i_fsize;	/* Fragment size */
-			u16	h_i_mode_high;
-			u16	h_i_uid_high;
-			u16	h_i_gid_high;
-			u32	h_i_author;
+			__u8	h_i_frag;	/* Fragment number */
+			__u8	h_i_fsize;	/* Fragment size */
+			__u16	h_i_mode_high;
+			__u16	h_i_uid_high;
+			__u16	h_i_gid_high;
+			__u32	h_i_author;
 		} hurd2;
 		struct {
-			u8	m_i_frag;	/* Fragment number */
-			u8	m_i_fsize;	/* Fragment size */
-			u16	m_pad1;
-			u32	m_i_reserved2[2];
+			__u8	m_i_frag;	/* Fragment number */
+			__u8	m_i_fsize;	/* Fragment size */
+			__u16	m_pad1;
+			__u32	m_i_reserved2[2];
 		} masix2;
 	} osd2;				/* OS dependent 2 */
 };
@@ -333,40 +318,76 @@
  * Structure of the super block
  */
 struct ext2_super_block {
-	u32	s_inodes_count;		/* Inodes count */
-	u32	s_blocks_count;		/* Blocks count */
-	u32	s_r_blocks_count;	/* Reserved blocks count */
-	u32	s_free_blocks_count;	/* Free blocks count */
-	u32	s_free_inodes_count;	/* Free inodes count */
-	u32	s_first_data_block;	/* First Data Block */
-	u32	s_log_block_size;	/* Block size */
-	s32	s_log_frag_size;	/* Fragment size */
-	u32	s_blocks_per_group;	/* # Blocks per group */
-	u32	s_frags_per_group;	/* # Fragments per group */
-	u32	s_inodes_per_group;	/* # Inodes per group */
-	u32	s_mtime;		/* Mount time */
-	u32	s_wtime;		/* Write time */
-	u16	s_mnt_count;		/* Mount count */
-	s16	s_max_mnt_count;	/* Maximal mount count */
-	u16	s_magic;		/* Magic signature */
-	u16	s_state;		/* File system state */
-	u16	s_errors;		/* Behaviour when detecting errors */
-	u16	s_pad;
-	u32	s_lastcheck;		/* time of last check */
-	u32	s_checkinterval;	/* max. time between checks */
-	u32	s_creator_os;		/* OS */
-	u32	s_rev_level;		/* Revision level */
-	u16	s_def_resuid;		/* Default uid for reserved blocks */
-	u16	s_def_resgid;		/* Default gid for reserved blocks */
-	u32	s_reserved[235];	/* Padding to the end of the block */
+	__u32	s_inodes_count;		/* Inodes count */
+	__u32	s_blocks_count;		/* Blocks count */
+	__u32	s_r_blocks_count;	/* Reserved blocks count */
+	__u32	s_free_blocks_count;	/* Free blocks count */
+	__u32	s_free_inodes_count;	/* Free inodes count */
+	__u32	s_first_data_block;	/* First Data Block */
+	__u32	s_log_block_size;	/* Block size */
+	__s32	s_log_frag_size;	/* Fragment size */
+	__u32	s_blocks_per_group;	/* # Blocks per group */
+	__u32	s_frags_per_group;	/* # Fragments per group */
+	__u32	s_inodes_per_group;	/* # Inodes per group */
+	__u32	s_mtime;		/* Mount time */
+	__u32	s_wtime;		/* Write time */
+	__u16	s_mnt_count;		/* Mount count */
+	__s16	s_max_mnt_count;	/* Maximal mount count */
+	__u16	s_magic;		/* Magic signature */
+	__u16	s_state;		/* File system state */
+	__u16	s_errors;		/* Behaviour when detecting errors */
+	__u16	s_minor_rev_level; 	/* minor revision level */
+	__u32	s_lastcheck;		/* time of last check */
+	__u32	s_checkinterval;	/* max. time between checks */
+	__u32	s_creator_os;		/* OS */
+	__u32	s_rev_level;		/* Revision level */
+	__u16	s_def_resuid;		/* Default uid for reserved blocks */
+	__u16	s_def_resgid;		/* Default gid for reserved blocks */
+	/*
+	 * These fields are for EXT2_DYNAMIC_REV superblocks only.
+	 *
+	 * Note: the difference between the compatible feature set and
+	 * the incompatible feature set is that if there is a bit set
+	 * in the incompatible feature set that the kernel doesn't
+	 * know about, it should refuse to mount the filesystem.
+	 * 
+	 * e2fsck's requirements are more strict; if it doesn't know
+	 * about a feature in either the compatible or incompatible
+	 * feature set, it must abort and not try to meddle with
+	 * things it doesn't understand...
+	 */
+	__u32	s_first_ino; 		/* First non-reserved inode */
+	__u16   s_inode_size; 		/* size of inode structure */
+	__u16	s_block_group_nr; 	/* block group # of this superblock */
+	__u32	s_feature_compat; 	/* compatible feature set */
+	__u32	s_feature_incompat; 	/* incompatible feature set */
+	__u32	s_feature_ro_compat; 	/* readonly-compatible feature set */
+	__u32	s_reserved[230];	/* Padding to the end of the block */
 };
 
+/*
+ * Codes for operating systems
+ */
 #define EXT2_OS_LINUX		0
 #define EXT2_OS_HURD		1
 #define EXT2_OS_MASIX		2
+#define EXT2_OS_FREEBSD		3
+#define EXT2_OS_LITES		4
 
-#define EXT2_CURRENT_REV	0
+/*
+ * Revision levels
+ */
+#define EXT2_GOOD_OLD_REV	0	/* The good old (original) format */
+#define EXT2_DYNAMIC_REV	1 	/* V2 format w/ dynamic inode sizes */
+
+#define EXT2_CURRENT_REV	EXT2_GOOD_OLD_REV
+#define EXT2_MAX_SUPP_REV	EXT2_DYNAMIC_REV
 
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+
+/*
+ * Default values for user and/or group using reserved blocks
+ */
 #define	EXT2_DEF_RESUID		0
 #define	EXT2_DEF_RESGID		0
 
@@ -376,9 +397,9 @@
 #define EXT2_NAME_LEN 255
 
 struct ext2_dir_entry {
-	u32	inode;			/* Inode number */
-	u16	rec_len;		/* Directory entry length */
-	u16	name_len;		/* Name length */
+	__u32	inode;			/* Inode number */
+	__u16	rec_len;		/* Directory entry length */
+	__u16	name_len;		/* Name length */
 	char	name[EXT2_NAME_LEN];	/* File name */
 };
 
@@ -391,5 +412,121 @@
 #define EXT2_DIR_ROUND 			(EXT2_DIR_PAD - 1)
 #define EXT2_DIR_REC_LEN(name_len)	(((name_len) + 8 + EXT2_DIR_ROUND) & \
 					 ~EXT2_DIR_ROUND)
+
+/*
+ * Feature set definitions --- none are defined as of now
+ */
+#define EXT2_FEATURE_COMPAT_SUPP	0
+#define EXT2_FEATURE_INCOMPAT_SUPP	0
+#define EXT2_FEATURE_RO_COMPAT_SUPP	0
+
+#ifdef __KERNEL__
+/*
+ * Function prototypes
+ */
+
+/*
+ * Ok, these declarations are also in <linux/kernel.h> but none of the
+ * ext2 source programs needs to include it so they are duplicated here.
+ */
+# define NORET_TYPE    /**/
+# define ATTRIB_NORET  __attribute__((noreturn))
+# define NORET_AND     noreturn,
+
+/* acl.c */
+extern int ext2_permission (struct inode *, int);
+
+/* balloc.c */
+extern int ext2_new_block (const struct inode *, unsigned long,
+			   __u32 *, __u32 *, int *);
+extern void ext2_free_blocks (const struct inode *, unsigned long,
+			      unsigned long);
+extern unsigned long ext2_count_free_blocks (struct super_block *);
+extern void ext2_check_blocks_bitmap (struct super_block *);
+
+/* bitmap.c */
+extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
+
+/* dir.c */
+extern int ext2_check_dir_entry (const char *, struct inode *,
+				 struct ext2_dir_entry *, struct buffer_head *,
+				 unsigned long);
+
+/* file.c */
+extern int ext2_read (struct inode *, struct file *, char *, int);
+extern int ext2_write (struct inode *, struct file *, char *, int);
+
+/* fsync.c */
+extern int ext2_sync_file (struct inode *, struct file *);
+
+/* ialloc.c */
+extern struct inode * ext2_new_inode (const struct inode *, int, int *);
+extern void ext2_free_inode (struct inode *);
+extern unsigned long ext2_count_free_inodes (struct super_block *);
+extern void ext2_check_inodes_bitmap (struct super_block *);
+
+/* inode.c */
+extern int ext2_bmap (struct inode *, int);
+
+extern struct buffer_head * ext2_getblk (struct inode *, long, int, int *);
+extern struct buffer_head * ext2_bread (struct inode *, int, int, int *);
+
+extern int ext2_getcluster (struct inode * inode, long block);
+extern void ext2_read_inode (struct inode *);
+extern void ext2_write_inode (struct inode *);
+extern void ext2_put_inode (struct inode *);
+extern int ext2_sync_inode (struct inode *);
+extern void ext2_discard_prealloc (struct inode *);
+
+/* ioctl.c */
+extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
+		       unsigned long);
+
+/* namei.c */
+extern void ext2_release (struct inode *, struct file *);
+extern int ext2_lookup (struct inode *,const char *, int, struct inode **);
+extern int ext2_create (struct inode *,const char *, int, int,
+			struct inode **);
+extern int ext2_mkdir (struct inode *, const char *, int, int);
+extern int ext2_rmdir (struct inode *, const char *, int);
+extern int ext2_unlink (struct inode *, const char *, int);
+extern int ext2_symlink (struct inode *, const char *, int, const char *);
+extern int ext2_link (struct inode *, struct inode *, const char *, int);
+extern int ext2_mknod (struct inode *, const char *, int, int, int);
+extern int ext2_rename (struct inode *, const char *, int,
+			struct inode *, const char *, int, int);
+
+/* super.c */
+extern void ext2_error (struct super_block *, const char *, const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
+extern NORET_TYPE void ext2_panic (struct super_block *, const char *,
+				   const char *, ...)
+	__attribute__ ((NORET_AND format (printf, 3, 4)));
+extern void ext2_warning (struct super_block *, const char *, const char *, ...)
+	__attribute__ ((format (printf, 3, 4)));
+extern void ext2_put_super (struct super_block *);
+extern void ext2_write_super (struct super_block *);
+extern int ext2_remount (struct super_block *, int *, char *);
+extern struct super_block * ext2_read_super (struct super_block *,void *,int);
+extern int init_ext2_fs(void);
+extern void ext2_statfs (struct super_block *, struct statfs *, int);
+
+/* truncate.c */
+extern void ext2_truncate (struct inode *);
+
+/*
+ * Inodes and files operations
+ */
+
+/* dir.c */
+extern struct inode_operations ext2_dir_inode_operations;
+
+/* file.c */
+extern struct inode_operations ext2_file_inode_operations;
+
+/* symlink.c */
+extern struct inode_operations ext2_symlink_inode_operations;
+
+#endif	/* __KERNEL__ */
 
 #endif	/* _LINUX_EXT2_FS_H */
diff -ru hurd-0.0/ext2fs/ext2_fs_i.h hurd-0.1/ext2fs/ext2_fs_i.h
--- hurd-0.0/ext2fs/ext2_fs_i.h	Fri Apr 14 18:56:16 1995
+++ hurd-0.1/ext2fs/ext2_fs_i.h	Tue Aug 13 11:53:17 1996
@@ -20,21 +20,21 @@
  * second extended file system inode data in memory
  */
 struct ext2_inode_info {
-	u32	i_data[15];
-	u32	i_flags;
-	u32	i_faddr;
-	u8	i_frag_no;
-	u8	i_frag_size;
-	u16	i_osync;
-	u32	i_file_acl;
-	u32	i_dir_acl;
-	u32	i_dtime;
-	u32	i_version;
-	u32	i_block_group;
-	u32	i_next_alloc_block;
-	u32	i_next_alloc_goal;
-	u32	i_prealloc_block;
-	u32	i_prealloc_count;
+	__u32	i_data[15];
+	__u32	i_flags;
+	__u32	i_faddr;
+	__u8	i_frag_no;
+	__u8	i_frag_size;
+	__u16	i_osync;
+	__u32	i_file_acl;
+	__u32	i_dir_acl;
+	__u32	i_dtime;
+	__u32	i_version;
+	__u32	i_block_group;
+	__u32	i_next_alloc_block;
+	__u32	i_next_alloc_goal;
+	__u32	i_prealloc_block;
+	__u32	i_prealloc_count;
 };
 
 #endif	/* _LINUX_EXT2_FS_I */
diff -ru hurd-0.0/ext2fs/ext2fs.c hurd-0.1/ext2fs/ext2fs.c
--- hurd-0.0/ext2fs/ext2fs.c	Fri Aug  2 16:23:21 1996
+++ hurd-0.1/ext2fs/ext2fs.c	Fri Sep  6 16:05:22 1996
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <error.h>
 #include <argz.h>
+#include <version.h>
 #include "ext2fs.h"
 
 /* ---------------------------------------------------------------- */
@@ -40,9 +41,8 @@
 int diskfs_shortcut_ifsock = 1;
 
 char *diskfs_server_name = "ext2fs";
-int diskfs_major_version = 0;
-int diskfs_minor_version = 0;
-int diskfs_edit_version = 0;
+char *diskfs_server_version = HURD_VERSION;
+char *diskfs_extra_version = "ext2 " EXT2FS_VERSION;
 
 int diskfs_synchronous = 0;
 int diskfs_readonly = 0;
@@ -214,8 +214,11 @@
   buf = free_page_bufs;
   if (buf == 0)
     {
+      error_t err;
       spin_unlock (&free_page_bufs_lock);
-      vm_allocate (mach_task_self (), &buf, vm_page_size, 1);
+      err = vm_allocate (mach_task_self (), &buf, vm_page_size, 1);
+      if (err)
+	buf = 0;
     }
   else
     {
diff -ru hurd-0.0/ext2fs/ext2fs.h hurd-0.1/ext2fs/ext2fs.h
--- hurd-0.0/ext2fs/ext2fs.h	Sat Jul 20 11:04:34 1996
+++ hurd-0.1/ext2fs/ext2fs.h	Tue Sep  3 10:20:42 1996
@@ -29,8 +29,29 @@
 #include <rwlock.h>
 
 #define __hurd__		/* Enable some hurd-specific fields.  */
+
+/* Types used by the ext2 header files.  */
+typedef u_int32_t __u32;
+typedef int32_t   __s32;
+typedef u_int16_t __u16;
+typedef int16_t   __s16;
+typedef u_int8_t  __u8;
+typedef int8_t    __s8;
+
 #include "ext2_fs.h"
 #include "ext2_fs_i.h"
+
+/* If ext2_fs.h defined a debug routine, undef it and use our own.  */
+#undef ext2_debug
+
+#ifdef EXT2FS_DEBUG
+extern int ext2_debug_flag;
+#define ext2_debug(f, a...) \
+ do { if (ext2_debug_flag) printf ("ext2fs: (debug) %s: " f "\n", __FUNCTION__ , ## a); } while (0)
+#else
+#define ext2_debug(f, a...)	(void)0
+#endif
+
 #undef __hurd__
 
 /* Define this if memory objects should not be cached by the kernel.
@@ -42,7 +63,7 @@
 int printf (const char *fmt, ...);
 
 /* A block number.  */
-typedef u32 block_t;
+typedef __u32 block_t;
 
 /* ---------------------------------------------------------------- */
 
@@ -163,6 +184,9 @@
   /* True if the last page of the file has been made writable, but is only
      partially allocated.  */
   int last_page_partially_writable;
+
+  /* Index to start a directory lookup at.  */
+  int dir_idx;
 };
 
 struct user_pager_info
@@ -299,7 +323,6 @@
   unsigned long bg_num = (inum - 1) / inodes_per_group;
   unsigned long group_inum = (inum - 1) % inodes_per_group;
   struct ext2_group_desc *bg = group_desc(bg_num);
-  unsigned long inodes_per_block = EXT2_INODES_PER_BLOCK(sblock);
   block_t block = bg->bg_inode_table + (group_inum / inodes_per_block);
   return ((struct ext2_inode *)bptr(block)) + group_inum % inodes_per_block;
 }
diff -ru hurd-0.0/ext2fs/hyper.c hurd-0.1/ext2fs/hyper.c
--- hurd-0.0/ext2fs/hyper.c	Tue Jun 25 17:29:07 1996
+++ hurd-0.1/ext2fs/hyper.c	Thu Aug 15 16:57:10 1996
@@ -107,7 +107,7 @@
 		sblock->s_blocks_count << log2_dev_blocks_per_fs_block);
 
   /* Set these handy variables.  */
-  inodes_per_block = block_size / sizeof (struct ext2_inode);
+  inodes_per_block = block_size / EXT2_INODE_SIZE (sblock);
 
   frag_size = EXT2_MIN_FRAG_SIZE << sblock->s_log_frag_size;
   if (frag_size)
@@ -115,6 +115,23 @@
   else
     ext2_panic ("frag size is zero!");
 
+  if (sblock->s_rev_level > EXT2_GOOD_OLD_REV)
+    {
+      if (sblock->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP)
+	ext2_panic ("could not mount because of unsupported optional features"
+		    " (0x%x)",
+		    sblock->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP);
+      if (sblock->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)
+	{
+	  ext2_warning ("mounted readonly because of"
+			" unsupported optional features (0x%x)",
+			sblock->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP);
+	  diskfs_readonly = 1;
+	}
+      if (sblock->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE)
+	ext2_panic ("inode size %d isn't supported", sblock->s_inode_size);
+    }
+
   groups_count =
     ((sblock->s_blocks_count - sblock->s_first_data_block +
       sblock->s_blocks_per_group - 1)
@@ -144,7 +161,7 @@
   vm_allocate (mach_task_self (), &zeroblock, block_size, 1);
 }
 
-void
+error_t
 diskfs_set_hypermetadata (int wait, int clean)
 {
   if (clean && ext2fs_clean && !(sblock->s_state & EXT2_VALID_FS))
@@ -168,6 +185,9 @@
    }
 
   sync_global (wait);
+
+  /* Should check writability here and return EROFS if necessary. XXX */
+  return 0;
 }
 
 void
diff -ru hurd-0.0/ext2fs/ialloc.c hurd-0.1/ext2fs/ialloc.c
--- hurd-0.0/ext2fs/ialloc.c	Thu Apr 11 13:31:02 1996
+++ hurd-0.1/ext2fs/ialloc.c	Thu Aug 15 16:57:11 1996
@@ -63,7 +63,7 @@
 
   spin_lock (&global_lock);
 
-  if (inum < EXT2_FIRST_INO || inum > sblock->s_inodes_count)
+  if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count)
     {
       ext2_error ("reserved inode or nonexistent inode: %u", inum);
       spin_unlock (&global_lock);
@@ -236,7 +236,7 @@
     }
 
   inum += i * sblock->s_inodes_per_group + 1;
-  if (inum < EXT2_FIRST_INO || inum > sblock->s_inodes_count)
+  if (inum < EXT2_FIRST_INO (sblock) || inum > sblock->s_inodes_count)
     {
       ext2_error ("reserved inode or inode > inodes count - "
 		  "block_group = %d,inode=%d", i, inum);
diff -ru hurd-0.0/ext2fs/inode.c hurd-0.1/ext2fs/inode.c
--- hurd-0.0/ext2fs/inode.c	Fri Aug  2 16:23:21 1996
+++ hurd-0.1/ext2fs/inode.c	Tue Sep  3 10:20:43 1996
@@ -73,6 +73,7 @@
       return ENOMEM;
     }
   dn->dirents = 0;
+  dn->dir_idx = 0;
   dn->pager = 0;
   rwlock_init (&dn->alloc_lock);
   pokel_init (&dn->indir_pokel, disk_pager, disk_image);
@@ -182,7 +183,6 @@
 read_disknode (struct node *np)
 {
   error_t err;
-  unsigned offset;
   static int fsid, fsidset;
   struct stat *st = &np->dn_stat;
   struct disknode *dn = np->dn;
@@ -255,6 +255,9 @@
   info->i_next_alloc_goal = 0;
   info->i_prealloc_count = 0;
 
+  /* Set to a conservative value.  */
+  dn->last_page_partially_writable = 0;
+
   if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
     st->st_rdev = di->i_block[0];
   else
@@ -266,14 +269,29 @@
     }
 
   diskfs_end_catch_exception ();
-
-  /* Set these to conservative values.  */
-  dn->last_page_partially_writable = 0;
   
-  np->allocsize = np->dn_stat.st_size;
-  offset = np->allocsize & ((1 << log2_block_size) - 1);
-  if (offset > 0)
-    np->allocsize += block_size - offset;
+  if (S_ISREG (st->st_mode) || S_ISDIR (st->st_mode)
+      || (S_ISLNK (st->st_mode) && st->st_blocks))
+    {
+      unsigned offset;
+
+      np->allocsize = np->dn_stat.st_size;
+
+      /* Round up to a block multiple.  */
+      offset = np->allocsize & ((1 << log2_block_size) - 1);
+      if (offset > 0)
+	np->allocsize += block_size - offset;
+    }
+  else
+    /* Allocsize should be zero for anything except directories, files, and
+       long symlinks.  These are the only things allowed to have any blocks
+       allocated as well, although st_size may be zero for any type (cases
+       where st_blocks=0 and st_size>0 include fast symlinks, and, under
+       linux, some devices).  */
+    {
+      np->allocsize = 0;
+      assert (st->st_blocks == 0);
+    }
 
   return 0;
 }
@@ -540,7 +558,7 @@
   st->f_namelen = 0;
   return 0;
 }
-
+
 /* Implement the diskfs_set_translator callback from the diskfs
    library; see <hurd/diskfs.h> for the interface description. */
 error_t
@@ -646,7 +664,57 @@
   *namelen = datalen;
   return 0;
 }
+
+/* The maximum size of a symlink store in the inode (including '\0').  */
+#define MAX_INODE_SYMLINK \
+  (EXT2_N_BLOCKS * sizeof (((struct ext2_inode *)0)->i_block[0]))
 
+/* Write an in-inode symlink, or return EINVAL if we can't.  */
+static error_t
+write_symlink (struct node *node, char *target)
+{
+  size_t len = strlen (target) + 1;
+
+  if (len > MAX_INODE_SYMLINK)
+    return EINVAL;
+
+  assert (node->dn_stat.st_blocks == 0);
+
+  bcopy (target, node->dn->info.i_data, len);
+  node->dn_stat.st_size = len - 1;
+  node->dn_set_ctime = 1;
+  node->dn_set_mtime = 1;
+
+  return 0;
+}
+
+/* Read an in-inode symlink, or return EINVAL if we can't.  */
+static error_t
+read_symlink (struct node *node, char *target)
+{
+  if (node->dn_stat.st_blocks)
+    return EINVAL;
+
+  assert (node->dn_stat.st_size < MAX_INODE_SYMLINK);
+
+  bcopy (node->dn->info.i_data, target, node->dn_stat.st_size);
+  return 0;
+}
+
+/* If this function is nonzero (and diskfs_shortcut_symlink is set) it
+   is called to set a symlink.  If it returns EINVAL or isn't set,
+   then the normal method (writing the contents into the file data) is
+   used.  If it returns any other error, it is returned to the user.  */
+error_t (*diskfs_create_symlink_hook)(struct node *np, char *target) =
+  write_symlink;
+
+/* If this function is nonzero (and diskfs_shortcut_symlink is set) it
+   is called to read the contents of a symlink.  If it returns EINVAL or
+   isn't set, then the normal method (reading from the file data) is
+   used.  If it returns any other error, it is returned to the user. */
+error_t (*diskfs_read_symlink_hook)(struct node *np, char *target) =
+  read_symlink;
+
 /* Called when all hard ports have gone away. */
 void
 diskfs_shutdown_soft_ports ()
diff -ru hurd-0.0/ext2fs/pager.c hurd-0.1/ext2fs/pager.c
--- hurd-0.0/ext2fs/pager.c	Fri Aug  2 16:23:22 1996
+++ hurd-0.1/ext2fs/pager.c	Tue Sep  3 10:20:44 1996
@@ -32,8 +32,38 @@
 #define MAY_CACHE 1
 #endif
 
-/* ---------------------------------------------------------------- */
+#define STATS
+
+#ifdef STATS
+struct ext2fs_pager_stats
+{
+  spin_lock_t lock;
+
+  unsigned long disk_pageins;
+  unsigned long disk_pageouts;
+
+  unsigned long file_pageins;
+  unsigned long file_pagein_reads; /* Device reads done by file pagein */
+  unsigned long file_pagein_freed_bufs;	/* Discarded pages */
+  unsigned long file_pagein_alloced_bufs; /* Allocated pages */
+
+  unsigned long file_pageouts;
+
+  unsigned long file_page_unlocks;
+  unsigned long file_grows;
+};
+
+static struct ext2fs_pager_stats ext2s_pager_stats;
 
+#define STAT_INC(field)							\
+do { spin_lock (&ext2s_pager_stats.lock);					\
+     ext2s_pager_stats.field++;							\
+     spin_unlock (&ext2s_pager_stats.lock); } while (0)
+
+#else /* !STATS */
+#define STAT_INC(field) /* nop */0
+#endif /* STATS */
+
 /* Find the location on disk of page OFFSET in NODE.  Return the disk block
    in BLOCK (if unallocated, then return 0).  If *LOCK is 0, then it a reader
    lock is aquired on NODE's ALLOC_LOCK before doing anything, and left
@@ -94,6 +124,8 @@
 	  int length = num_pending_blocks << log2_block_size;
 	  vm_address_t new_buf;
 
+	  STAT_INC (file_pagein_reads);
+
 	  err = diskfs_device_read_sync (dev_block, &new_buf, length);
 	  if (err)
 	    return err;
@@ -105,7 +137,8 @@
 	    {
 	      /* We've already got some buffer, so copy into it.  */
 	      bcopy ((char *)new_buf, (char *)*buf + offs, length);
-	      vm_deallocate (mach_task_self (), new_buf, length);
+	      free_page_buf (new_buf);
+	      STAT_INC (file_pagein_freed_bufs);
 	    }
 
 	  offs += length;
@@ -115,6 +148,8 @@
       return 0;
     }
 
+  STAT_INC (file_pageins);
+
   *writelock = 0;
 
   if (page >= node->allocsize)
@@ -151,9 +186,10 @@
 	  if (offs == 0)
 	    /* No page allocated to read into yet.  */
 	    {
-	      err = vm_allocate (mach_task_self (), buf, vm_page_size, 1);
-	      if (err)
+	      *buf = get_page_buf ();
+	      if (! *buf)
 		break;
+	      STAT_INC (file_pagein_alloced_bufs);
 	    }
 	  bzero ((char *)*buf + offs, block_size);
 	  offs += block_size;
@@ -284,6 +320,8 @@
 
   ext2_debug ("writing inode %d page %d[%d]", node->cache_id, offset, left);
 
+  STAT_INC (file_pageouts);
+
   while (left > 0)
     {
       err = find_block (node, offset, &block, &lock);
@@ -338,6 +376,8 @@
 
   ext2_debug ("writing disk page %d[%d]", page, length);
 
+  STAT_INC (disk_pageouts);
+
   if (modified_global_blocks)
     /* Be picky about which blocks in a page that we write.  */
     {
@@ -465,6 +505,8 @@
 		    page, vm_page_size, node->cache_id);
 #endif
 
+      STAT_INC (file_page_unlocks);
+
       rwlock_writer_unlock (&dn->alloc_lock);
 
       if (err == ENOSPC)
@@ -553,6 +595,8 @@
 		  (old_page_end_block > end_block);
 	    }
 	}
+
+      STAT_INC (file_grows);
 
       ext2_debug ("new size: %ld%s.", new_size,
 		  dn->last_page_partially_writable
diff -ru hurd-0.0/ext2fs/truncate.c hurd-0.1/ext2fs/truncate.c
--- hurd-0.0/ext2fs/truncate.c	Fri Aug  2 16:23:22 1996
+++ hurd-0.1/ext2fs/truncate.c	Tue Sep  3 10:20:44 1996
@@ -277,6 +277,18 @@
   if (length >= node->dn_stat.st_size)
     return 0;
 
+  if (! node->dn_stat.st_blocks)
+    /* There aren't really any blocks allocated, so just frob the size.  This
+       is true for fast symlinks, and also apparently for some device nodes
+       in linux.  */
+    {
+      node->dn_stat.st_size = length;
+      node->dn_set_mtime = 1;
+      node->dn_set_ctime = 1;
+      diskfs_node_update (node, 1);
+      return 0;
+    }
+
   /*
    * If the file is not being truncated to a block boundary, the
    * contents of the partial block following the end of the file must be
Only in hurd-0.0: fsck
diff -ru hurd-0.0/hurd/ChangeLog hurd-0.1/hurd/ChangeLog
--- hurd-0.0/hurd/ChangeLog	Wed Jul 17 18:54:47 1996
+++ hurd-0.1/hurd/ChangeLog	Thu Sep  5 10:39:48 1996
@@ -1,3 +1,7 @@
+Thu Sep  5 10:39:40 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* version.h: File removed.
+
 Wed Jul 17 14:30:36 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* Makefile: gs/install-hdrs/install-headers/g.
diff -ru hurd-0.0/hurd/diskfs.h hurd-0.1/hurd/diskfs.h
--- hurd-0.0/hurd/diskfs.h	Mon Jul 15 22:35:45 1996
+++ hurd-0.1/hurd/diskfs.h	Thu Sep  5 11:16:56 1996
@@ -203,11 +203,13 @@
    filesystem server. */
 extern char *diskfs_server_name;
 
-/* The user must define these variables.  Set these to be the major, minor,
-   and edit version numbers.  */
-extern int diskfs_major_version;
-extern int diskfs_minor_version;
-extern int diskfs_edit_version;
+/* The user must define this variables.  Set this to be the server
+   version number.  */
+extern char *diskfs_server_version;
+
+/* The user may define this variable.  Set this to be any additional
+   version specification that should be printed for --version. */
+extern char *diskfs_extra_version;
 
 /* The user may define this variable.  This should be nonzero iff the
    filesystem format supports shortcutting symlink translation.
@@ -364,7 +366,7 @@
    metadata.  If CLEAN is nonzero, then after this is written the
    filesystem will be absolutely clean, and the non-paged metadata can
    so indicate.  */
-void diskfs_set_hypermetadata (int wait, int clean);
+error_t diskfs_set_hypermetadata (int wait, int clean);
 
 /* The user must define this function.  Allocate a new node to be of
    mode MODE in locked directory DP (don't actually set the mode or
diff -ru hurd-0.0/hurd/ports.h hurd-0.1/hurd/ports.h
--- hurd-0.0/hurd/ports.h	Mon May  6 16:34:34 1996
+++ hurd-0.1/hurd/ports.h	Wed Aug  7 15:28:35 1996
@@ -162,6 +162,18 @@
 			   struct port_bucket *bucket,
 			   size_t size,
 			   void *result);
+
+/* Just like ports_create_port, except don't actually put the port
+   into the portset underlying BUCKET.  This is intended to be used
+   for cases where the port right must be given out before the port is
+   fully initialized; with this call you are guaranteed that no RPC
+   service will occur on the port until you have finished initializing
+   it and installed it into the portset yourself. */
+error_t
+ports_create_port_noinstall (struct port_class *class,
+			     struct port_bucket *bucket,
+			     size_t size,
+			     void *result);
    
 /* For an existing RECEIVE right, create and return in RESULT a new port
    structure; BUCKET, SIZE, and CLASS args are as for ports_create_port. */
@@ -376,5 +388,7 @@
 #define _PORTS_BLOCKED		PORTS_BLOCKED
 #define _PORTS_INHIBIT_WAIT	PORTS_INHIBIT_WAIT
 void _ports_complete_deallocate (struct port_info *);
+error_t _ports_create_port_internal (struct port_class *, struct port_bucket *,
+				     size_t, void *, int);
 
 #endif
diff -ru hurd-0.0/hurd/store.h hurd-0.1/hurd/store.h
--- hurd-0.0/hurd/store.h	Tue May 21 19:58:28 1996
+++ hurd-0.1/hurd/store.h	Thu Sep  5 10:12:37 1996
@@ -68,9 +68,9 @@
   size_t size;
 
   /* Log_2 (BLOCK_SIZE) or 0 if not a power of 2. */
-  int log2_block_size;
+  unsigned log2_block_size;
   /* Log_2 (VM_PAGE_SIZE / BLOCK_SIZE); only valid if LOG2_BLOCK_SIZE is.  */
-  int log2_blocks_per_page;
+  unsigned log2_blocks_per_page;
 
   /* Random flags.  */
   int flags;
@@ -91,15 +91,18 @@
    <hurd/hurd_types.h>.  XXX synchronize these values.  */
 
 /* Flags that reflect something immutable about the object.  */
-#define STORE_IMMUTABLE_FLAGS	0xFF
+#define STORE_IMMUTABLE_FLAGS	0x00FF
 
 /* Flags implemented by generic store code.  */
-#define STORE_READONLY		0x100	/* No writing allowed. */
-#define STORE_GENERIC_FLAGS	STORE_READONLY
+#define STORE_READONLY		0x0100	/* No writing allowed. */
+#define STORE_NO_FILEIO		0x0200	/* If store_create can't fetch store
+					   information, don't create a store
+					   using file io instead.  */
+#define STORE_GENERIC_FLAGS	(STORE_READONLY | STORE_NO_FILEIO)
 
 /* Flags implemented by each backend.  */
-#define STORE_HARD_READONLY	0x200	/* Can't be made writable.  */
-#define STORE_ENFORCED		0x400	/* Range is enforced by device.  */
+#define STORE_HARD_READONLY	0x0400	/* Can't be made writable.  */
+#define STORE_ENFORCED		0x0800	/* Range is enforced by device.  */
 #define STORE_BACKEND_SPEC_BASE	0x1000 /* Here up are backend-specific */
 #define STORE_BACKEND_FLAGS	(STORE_HARD_READONLY | STORE_ENFORCED \
 				 | ~(STORE_BACKEND_SPEC_BASE - 1))
@@ -169,6 +172,14 @@
 
 void store_free (struct store *store);
 
+/* Open the file NAME, and return a new store in STORE, which refers to the
+   storage underlying it.  CLASSES is used to select classes specified by the
+   provider; if it is 0, STORE_STD_CLASSES is used.  FLAGS is set with
+   store_set_flags.  A reference to the open file is created (but may be
+   destroyed with store_close_source).  */
+error_t store_open (char *name, int flags, struct store_class *classes,
+		    struct store **store);
+
 /* Allocate a new store structure with class CLASS, and the various other
    fields initialized to the given parameters.  */
 struct store *
@@ -392,22 +403,24 @@
 
 /* An argument parser that may be used for parsing a simple command line
    specification for stores.  The accompanying input parameter must be a
-   pointer to a structure of type struct store_argp_param.  */
+   pointer to a location in which to store the resulting pointer to a struct
+   store_parsed.  */
 extern struct argp store_argp;
 
-/* Structure used to pass in arguments and return the result from
-   STORE_ARGP.  */
-struct store_argp_params
-{
-  /* An initial set of flags desired to be set.  */
-  int flags;
-
-  /* If true, don't attempt use store_file_create to create a store on files
-     upon which store_create has failed.  */
-  int no_file_io : 1;
-
-  /* Parsed store returned here.  */
-  struct store *result;
-};
+/* The result of parsing a store, which should be enough information to open
+   it, or return the arguments.  */
+struct store_parsed;
+
+/* Free all resources used by PARSED.  */
+void store_parsed_free (struct store_parsed *parsed);
+
+/* Open PARSED, and return the corresponding store in STORE.  */
+error_t store_parsed_open (const struct store_parsed *parsed, int flags,
+			   struct store_class *classes,
+			   struct store **store);
+
+/* Add the arguments  PARSED, and return the corresponding store in STORE.  */
+error_t store_parsed_append_args (const struct store_parsed *parsed,
+				  char **args, size_t *args_len);
 
 #endif /* __STORE_H__ */
Only in hurd-0.0/hurd: version.h
diff -ru hurd-0.0/include/argp.h hurd-0.1/include/argp.h
--- hurd-0.0/include/argp.h	Sat Jul  6 17:12:56 1996
+++ hurd-0.1/include/argp.h	Tue Sep  3 10:21:04 1996
@@ -258,6 +258,8 @@
 error_t argp_parse (const struct argp *argp,
 		    int argc, char **argv, unsigned flags,
 		    int *arg_index, void *input);
+
+/* Global variables.  */
 
 /* If defined or set by the user program to a non-zero value, then a default
    option --version is added (unless the ARGP_NO_HELP flag is used), which
@@ -272,16 +274,27 @@
    used).  This variable takes precedent over ARGP_PROGRAM_VERSION.  */
 extern void (*argp_program_version_hook) (FILE *stream,
 					  struct argp_state *state);
+
+/* If defined or set by the user program, it should point to string that is
+   the bug-reporting address for the program.  It will be printed by
+   argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
+   standard help messages), embedded in a sentence that says something like
+   `Report bugs to ADDR.'.  */
+extern char *argp_program_bug_address;
 
 /* Flags for argp_help.  */
-#define ARGP_HELP_USAGE		0x01 /* Print a Usage: message. */
+#define ARGP_HELP_USAGE		0x01 /* a Usage: message. */
 #define ARGP_HELP_SHORT_USAGE	0x02 /*  " but don't actually print options. */
-#define ARGP_HELP_SEE		0x04 /* Print a `for more help...' message. */
-#define ARGP_HELP_LONG		0x08 /* Print a long help message. */
+#define ARGP_HELP_SEE		0x04 /* a `Try ... for more help' message. */
+#define ARGP_HELP_LONG		0x08 /* a long help message. */
+#define ARGP_HELP_PRE_DOC	0x10 /* doc string preceding long help.  */
+#define ARGP_HELP_POST_DOC	0x20 /* doc string following long help.  */
+#define ARGP_HELP_DOC		(ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
+#define ARGP_HELP_BUG_ADDR	0x40 /* bug report address */
 
 /* These ARGP_HELP flags are only understood by argp_state_help.  */
-#define ARGP_HELP_EXIT_ERR	0x10 /* Call exit(1) instead of returning.  */
-#define ARGP_HELP_EXIT_OK	0x20 /* Call exit(0) instead of returning.  */
+#define ARGP_HELP_EXIT_ERR	0x100 /* Call exit(1) instead of returning.  */
+#define ARGP_HELP_EXIT_OK	0x200 /* Call exit(0) instead of returning.  */
 
 /* The standard thing to do after a program command line parsing error, if an
    error message has already been printed.  */
@@ -293,7 +306,8 @@
   (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
 /* The standard thing to do in response to a --help option.  */
 #define ARGP_HELP_STD_HELP \
-  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK)
+  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
+   | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
 
 /* Output a usage message for ARGP to STREAM.  FLAGS are from the set
    ARGP_HELP_*.  */
diff -ru hurd-0.0/init/ChangeLog hurd-0.1/init/ChangeLog
--- hurd-0.0/init/ChangeLog	Wed Jul 17 18:54:50 1996
+++ hurd-0.1/init/ChangeLog	Thu Sep  5 11:13:22 1996
@@ -1,3 +1,37 @@
+Thu Sep  5 11:12:32 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* init.c: Include <version.h>.
+	(init_version): Delete variable.
+	(launch_core_servers): Pass empty string as release; HURD_VERSION
+	as version.
+
+Tue Aug 13 17:51:38 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makefile (init): Remove -lutil.
+	(libutil-libsubst): Variable removed.
+	(LDLIBS): New variable.
+
+Mon Aug 12 11:12:22 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* init.c (setup_terminal): Declare LINE.
+	(add_terminal): Don't declare LINE.
+
+Thu Aug  8 16:34:06 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* init.c (setup_terminal): New function.
+	(add_terminal): Use setup_terminal.
+	(reread_ttys): When turning an existent terminal spec on, call
+	setup_terminal before startup_terminal.
+
+	* init.c (struct terminal): New member `read'.
+	(shutdown_terminal): New function.
+	(reread_ttys): Use shutdown_terminal instead of doing it by hand.
+	Keep track of which ttys we used to know about are no longer in
+	/etc/ttys, and treat them as now `off'.
+	
+	* init.c (kill_everyone): `continue' in the essential task case
+	didn't go back to the main loop; fix it up correctly.
+
 Tue Jul 16 11:55:09 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* init.c (process_signal): Set WUNTRACED in call to waitpid.
diff -ru hurd-0.0/init/Makefile hurd-0.1/init/Makefile
--- hurd-0.0/init/Makefile	Wed Jul  3 15:06:30 1996
+++ hurd-0.1/init/Makefile	Wed Aug 14 14:04:48 1996
@@ -22,9 +22,10 @@
 OBJS = init.o startupServer.o notifyServer.o startup_replyUser.o msgServer.o \
 	startup_notifyUser.o
 target = init
-libutil-libsubst = -lutil
 
-init: $(OBJS) ../libports/libports.a ../libfshelp/libfshelp.a ../libshouldbeinlibc/libshouldbeinlibc.a -lutil
+LDLIBS=-lutil
+
+init: $(OBJS) ../libports/libports.a ../libfshelp/libfshelp.a ../libshouldbeinlibc/libshouldbeinlibc.a
 
 mung_msg_S.h: msg_S.h
 	sed 's/msg_server/mung_msg_server/' < $< > $@
diff -ru hurd-0.0/init/init.c hurd-0.1/init/init.c
--- hurd-0.0/init/init.c	Tue Jul 16 11:54:58 1996
+++ hurd-0.1/init/init.c	Thu Sep  5 11:13:25 1996
@@ -49,6 +49,7 @@
 #include <argz.h>
 #include <utmp.h>
 #include <maptime.h>
+#include <version.h>
 
 #include "startup_notify_U.h"
 #include "startup_reply_U.h"
@@ -113,6 +114,7 @@
   
   int on;
   int pid;
+  int read;
   
   char *name;
 };
@@ -154,8 +156,6 @@
 /* The tasks of auth and proc and the bootstrap filesystem. */
 task_t authtask, proctask, fstask;
 
-char *init_version = "0.0";
-
 mach_port_t default_ports[INIT_PORT_MAX];
 mach_port_t default_dtable[3];
 int default_ints[INIT_INT_MAX];
@@ -474,13 +474,38 @@
 
 /** /etc/ttys support **/
 
+/* Set up the getty and window fields of terminal spec T corresponding
+   to line TT. */
+void
+setup_terminal (struct terminal *t, struct ttyent *tt)
+{
+  char *line;
+
+  if (t->getty_argz)
+    free (t->getty_argz);
+  if (t->window_argz)
+    free (t->window_argz);
+
+  if ((tt->ty_status & TTY_ON) && tt->ty_getty)
+    {
+      asprintf (&line, "%s %s", tt->ty_getty, tt->ty_name);
+      argz_create_sep (line, ' ', &t->getty_argz, &t->getty_argz_len);
+      if (tt->ty_window)
+	argz_create_sep (tt->ty_window, ' ', 
+			 &t->window_argz, &t->window_argz_len);
+      else
+	t->window_argz = 0;
+    }
+  else
+      t->getty_argz = t->window_argz = 0;
+}  
+
 
 /* Add a new terminal spec for TT and return it. */
 struct terminal *
 add_terminal (struct ttyent *tt)
 {
   struct terminal *t;
-  char *line;
   
   if (nttys >= ttyslen)
     {
@@ -495,30 +520,12 @@
   t->name = malloc (strlen (tt->ty_name) + 1);
   strcpy (t->name, tt->ty_name);
 
+  setup_terminal (t, tt);
   if (t->getty_argz)
-    free (t->getty_argz);
-  if (t->window_argz)
-    free (t->window_argz);
+    t->on = 1;
 
-  if ((tt->ty_status & TTY_ON) && tt->ty_getty)
-    {
-      asprintf (&line, "%s %s", tt->ty_getty, tt->ty_name);
-      argz_create_sep (line, ' ', &t->getty_argz, &t->getty_argz_len);
-      if (tt->ty_window)
-	argz_create_sep (tt->ty_window, ' ', 
-			 &t->window_argz, &t->window_argz_len);
-      else
-	t->window_argz = 0;
-      t->on = 1;
-    }
-  else
-    {
-      t->getty_argz = t->window_argz = 0;
-      t->on = 0;
-    }
   return t;
 }
-  
 
 /* Read /etc/ttys and initialize ttys array.  Return non-zero if we fail. */
 int
@@ -649,22 +656,34 @@
       }
 }  
 
+/* Shutdown the things running on terminal spec T. */
+void
+shutdown_terminal (struct terminal *t)
+{
+  kill (t->pid, SIGHUP);
+  /* revoke?? */;
+}
+
 /* Re-read /etc/ttys.  If a line has turned off, kill what's there.
-   If a line has turned on, start it.  If an on line has changed,
-   kill it, and then restart it. */
+   If a line has turned on, start it.  */
 void
 reread_ttys (void)
 {
   struct ttyent *tt;
   struct terminal *t;
   int on;
-
+  int i;
+  
   if (!setttyent ())
     {
       error (0, errno, "%s", _PATH_TTYS);
       return;
     }
   
+  /* Mark all the lines not yet read */
+  for (i = 0; i < nttys; i++)
+    ttys[i].read = 0;
+
   while ((tt = getttyent ()))
     {
       if (!tt->ty_name)
@@ -678,11 +697,12 @@
 	  if (t->on && !on)
 	    {
 	      t->on = 0;
-	      kill (t->pid, SIGHUP);
+	      shutdown_terminal (t);
 	    }
 	  else if (!t->on && on)
 	    {
 	      t->on = 1;
+	      setup_terminal (t, tt);
 	      startup_terminal (t);
 	    }
 	}
@@ -692,8 +712,18 @@
 	  if (on)
 	    startup_terminal (t);
 	}
+
+      t->read = 1;
     }
   endttyent ();
+
+  /* Scan tty entries; any that were not found and were on, turn off. */
+  for (i = 0; i < nttys; i++)
+    if (!ttys[i].read && ttys[i].on)
+      {
+	ttys[i].on = 0;
+	shutdown_terminal (&ttys[i]);
+      }
 }
 
 
@@ -848,8 +878,7 @@
 
   default_ports[INIT_PORT_AUTH] = authserver;
 
-  proc_register_version (procserver, host_priv, "init", HURD_RELEASE,
-			 init_version);
+  proc_register_version (procserver, host_priv, "init", "", HURD_VERSION);
 
   /* Get the bootstrap filesystem's proc server port.
      We must do this before calling proc_setmsgport below.  */
@@ -1213,8 +1242,10 @@
 		  {
 		    /* Skip this one */
 		    mach_port_deallocate (mach_task_self (), tk);
-		    continue;
+		    break;
 		  }
+	      if (es)
+		continue;
 	      
 	      /* Kill it */
 	      if (signo == SIGKILL)
diff -ru hurd-0.0/libdiskfs/ChangeLog hurd-0.1/libdiskfs/ChangeLog
--- hurd-0.0/libdiskfs/ChangeLog	Thu Aug  1 17:25:40 1996
+++ hurd-0.1/libdiskfs/ChangeLog	Thu Sep  5 18:39:27 1996
@@ -1,3 +1,109 @@
+Thu Sep  5 11:13:54 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* io-version.c (diskfs_S_io_server_version): Only fill in
+	SERVER_NAME; ignore the rest.
+
+	* diskfs.h (diskfs_major_version, diskfs_minor_version,
+	diskfs_edit_version): Delete variables.
+	(diskfs_server_version, diskfs_extra_version): New variables.
+	* boot-start.c (diskfs_S_fsys_init): Register version from
+	diskfs_server_version; pass empty string as release.
+	* extra-version.c: New file.
+	* Makefile (OTHERSRCS): Add extra-version.c.
+	* opts-version.c: Include <version.h>.
+ 	(diskfs_extra_version): Delete special declaration. 
+	(_print_version): Use the user's provided version number, and also
+	give it our (libdiskfs) version number.
+
+Tue Sep  3 10:48:05 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* name-cache.c (diskfs_enter_lookup_cache): Cache `.' and `..'
+	just like other nodes.
+	(diskfs_check_lookup_cache): If we get a cache hit on `..', then
+	do the inverse locking semantic, and only return success if things
+	are stable around the call.
+
+Fri Aug 30 21:57:18 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* lookup.c (cache_misses): New variable, to find out what sort of
+	thing all the cache misses are.
+	(cm_lock): New variable.
+	(diskfs_lookup): Keep track of cache misses in cache_misses.
+
+	* name-cache.c (MAXCACHE): 200 now.  After experimentation, this
+	appears to be a pretty good value.  Very little benefit after
+	this. 
+
+Fri Aug 30 20:41:27 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* name-cache.c (struct lookup_cache): Delete member `hits'.
+	New member `stati'.
+	(diskfs_enter_lookup_cache): Don't initialize C->hits.
+	(find_cache): Set C->stati before returning.
+	(build_partial): Delete function.
+	(diskfs_check_lookup_cache): Delete calls to build_partial.
+	Register all statistics through register_neg_hit,
+	register_pos_hit, and register_miss.
+	(MAXCACHE): 2000 now.
+
+Wed Aug 28 12:20:53 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* name-cache.c (MAXCACHE): 500 for now.
+
+Mon Aug 26 15:10:55 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* name-cache.c (MAXCACHE): Increase to 50000.
+	(struct lookup_cache): New member `hits'.
+	(statistics): Name struct type `struct stats'.
+	(diskfs_enter_lookup_cache): Initialize C->hits.
+	(PARTIAL_THRESH, NPARTIALS): New macros.
+	(partial_stats): New variable.
+	(build_partial): New function.
+	(diskfs_check_lookup_cache): Call build_partial after statistics
+	frobbing. 
+
+	* name-cache.c (diskfs_check_lookup_cache): Increment members of
+	statistics while still holding CACHE_LOCK.
+
+Fri Aug 16 18:23:25 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* name-cache.c (diskfs_check_lookup_cache): Keep track of negative
+	hits properly.
+	* lookup.c (diskfs_lookup): On LOOKUPs that fail to find the node,
+	enter a negative cache entry.
+
+Thu Aug 15 16:07:23 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* opts-version.c (diskfs_extra_version): New (weak) reference.
+	(_print_version): Use DISKFS_EXTRA_VERSION.  Tweak edit version.
+	Fix type of EV.
+
+Thu Aug 15 16:38:41 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* io-identity.c (diskfs_S_io_identity): Don't hold lock around
+	call to fshelp_get_identity.
+
+Mon Aug 12 15:54:27 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* opts-version.c (_print_version): Print the edit version too if
+	it's non-zero.
+
+Thu Aug  8 18:18:09 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* readonly.c: Include <error.h>.
+
+Wed Aug  7 13:53:56 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* readonly.c (diskfs_check_readonly): If we get an error from
+	diskfs_hypermetadata, then switch to readonly.
+	* diskfs.h (diskfs_set_hypermetadata): Require an error code return.
+	* dev-io.c (diskfs_device_write_sync): If we get D_READ_ONLY, then
+	return EROFS to the caller instead of EIO.
+
+	* node-create.c (diskfs_create_node): New files always copy GID
+	from their parent; that's NetBSD's behavior, and it's good enough
+	for me. 
+
 Thu Aug  1 17:24:08 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* file-get-transcntl.c (diskfs_S_file_get_translator_cntl): Don't
diff -ru hurd-0.0/libdiskfs/Makefile hurd-0.1/libdiskfs/Makefile
--- hurd-0.0/libdiskfs/Makefile	Sat Jul  6 17:14:14 1996
+++ hurd-0.1/libdiskfs/Makefile	Thu Sep  5 11:18:20 1996
@@ -48,7 +48,7 @@
 	dev-open.c dev-io.c dev-globals.c console.c disk-pager.c \
 	name-cache.c direnter.c dirrewrite.c dirremove.c lookup.c dead-name.c \
 	validate-mode.c validate-group.c validate-author.c validate-flags.c \
-	validate-rdev.c validate-owner.c
+	validate-rdev.c validate-owner.c extra-version.c
 SRCS = $(OTHERSRCS) $(FSSRCS) $(IOSRCS) $(FSYSSRCS) $(IFSOCKSRCS)
 LCLHDRS = diskfs.h priv.h lithp.h fsmutations.h diskfs-pager.h
 installhdrs = diskfs.h diskfs-pager.h
diff -ru hurd-0.0/libdiskfs/boot-start.c hurd-0.1/libdiskfs/boot-start.c
--- hurd-0.0/libdiskfs/boot-start.c	Sun Jul  7 21:21:04 1996
+++ hurd-0.1/libdiskfs/boot-start.c	Thu Sep  5 12:53:07 1996
@@ -366,7 +366,6 @@
   struct port_infe *pt;
   static int initdone = 0;
   process_t execprocess;
-  string_t version;
   mach_port_t host, startup;
   error_t err;
   mach_port_t root_pt;
@@ -463,9 +462,8 @@
   if (err)
     return err;
 
-  sprintf (version, "%d.%d", diskfs_major_version, diskfs_minor_version);
-  proc_register_version (procserver, host,
-			 diskfs_server_name, HURD_RELEASE, version);
+  proc_register_version (procserver, host, diskfs_server_name, "", 
+			 diskfs_server_version);
 
   err = proc_getmsgport (procserver, 1, &startup);
   if (!err)
diff -ru hurd-0.0/libdiskfs/dev-io.c hurd-0.1/libdiskfs/dev-io.c
--- hurd-0.0/libdiskfs/dev-io.c	Fri Oct 13 19:14:47 1995
+++ hurd-0.1/libdiskfs/dev-io.c	Wed Aug  7 15:12:28 1996
@@ -1,5 +1,5 @@
 /* Device input and output
-   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
 
 This file is part of the GNU Hurd.
 
@@ -29,10 +29,15 @@
 diskfs_device_write_sync (off_t addr, vm_address_t data, size_t len)
 {
   int written;
+  error_t err;
+  
   assert (!diskfs_readonly);
-  if (device_write (diskfs_device, 0, diskfs_device_start + addr,
-		    (io_buf_ptr_t) data, len, &written)
-      || written != len)
+  err = device_write (diskfs_device, 0, diskfs_device_start + addr,
+		      (io_buf_ptr_t) data, len, &written);
+  
+  if (err == D_READ_ONLY)
+    return EROFS;
+  else if (err || written != len)
     return EIO;
   return 0;
 }
diff -ru hurd-0.0/libdiskfs/diskfs.h hurd-0.1/libdiskfs/diskfs.h
--- hurd-0.0/libdiskfs/diskfs.h	Mon Jul 15 22:35:45 1996
+++ hurd-0.1/libdiskfs/diskfs.h	Thu Sep  5 11:16:56 1996
@@ -203,11 +203,13 @@
    filesystem server. */
 extern char *diskfs_server_name;
 
-/* The user must define these variables.  Set these to be the major, minor,
-   and edit version numbers.  */
-extern int diskfs_major_version;
-extern int diskfs_minor_version;
-extern int diskfs_edit_version;
+/* The user must define this variables.  Set this to be the server
+   version number.  */
+extern char *diskfs_server_version;
+
+/* The user may define this variable.  Set this to be any additional
+   version specification that should be printed for --version. */
+extern char *diskfs_extra_version;
 
 /* The user may define this variable.  This should be nonzero iff the
    filesystem format supports shortcutting symlink translation.
@@ -364,7 +366,7 @@
    metadata.  If CLEAN is nonzero, then after this is written the
    filesystem will be absolutely clean, and the non-paged metadata can
    so indicate.  */
-void diskfs_set_hypermetadata (int wait, int clean);
+error_t diskfs_set_hypermetadata (int wait, int clean);
 
 /* The user must define this function.  Allocate a new node to be of
    mode MODE in locked directory DP (don't actually set the mode or
Only in hurd-0.1/libdiskfs: extra-version.c
diff -ru hurd-0.0/libdiskfs/io-identity.c hurd-0.1/libdiskfs/io-identity.c
--- hurd-0.0/libdiskfs/io-identity.c	Wed Jul  3 11:37:25 1996
+++ hurd-0.1/libdiskfs/io-identity.c	Thu Aug 15 16:38:03 1996
@@ -32,14 +32,17 @@
 {
   struct node *np;
   error_t err;
+  ino_t inum;
 
   if (!cred)
     return EOPNOTSUPP;
   
   np = cred->po->np;
   mutex_lock (&np->lock);
-  
-  err = fshelp_get_identity (diskfs_port_bucket, np->dn_stat.st_ino, id);
+  inum = np->dn_stat.st_ino;
+  mutex_unlock (&np->lock);
+
+  err = fshelp_get_identity (diskfs_port_bucket, inum, id);
   if (!err)
     {
       *idtype = MACH_MSG_TYPE_MAKE_SEND;
diff -ru hurd-0.0/libdiskfs/io-version.c hurd-0.1/libdiskfs/io-version.c
--- hurd-0.0/libdiskfs/io-version.c	Thu May  5 09:13:53 1994
+++ hurd-0.1/libdiskfs/io-version.c	Thu Sep  5 12:00:43 1996
@@ -1,5 +1,5 @@
 /*
-   Copyright (C) 1994 Free Software Foundation
+   Copyright (C) 1994, 1996 Free Software Foundation
 
 This file is part of the GNU Hurd.
 
@@ -31,10 +31,8 @@
 {
   if (cred)
     {
-      strcpy (server_name, diskfs_server_name);
-      *major = diskfs_major_version;
-      *minor = diskfs_minor_version;
-      *edit = diskfs_edit_version;
+      sprintf (server_name, "%s %s", 
+	       diskfs_server_name, diskfs_server_version);
       return 0;
     }
   else
diff -ru hurd-0.0/libdiskfs/lookup.c hurd-0.1/libdiskfs/lookup.c
--- hurd-0.0/libdiskfs/lookup.c	Mon Jul 29 12:33:26 1996
+++ hurd-0.1/libdiskfs/lookup.c	Fri Aug 30 23:24:14 1996
@@ -20,6 +20,17 @@
 
 #include "priv.h"
 
+static struct
+{
+  int present;
+  int absent;
+  int errors;
+  int dot;
+  int dotdot;
+} cache_misses;
+static spin_lock_t cm_lock = SPIN_LOCK_INITIALIZER;
+
+
 /* Lookup in directory DP (which is locked) the name NAME.  TYPE will
    either be LOOKUP, CREATE, RENAME, or REMOVE.  CRED identifies the
    user making the call.
@@ -71,7 +82,7 @@
 	       struct protid *cred)
 {
   error_t err;
-  
+
   if (type == REMOVE || type == RENAME)
     assert (np);
 
@@ -119,6 +130,26 @@
     }
   
   err = diskfs_lookup_hard (dp, name, type, np, ds, cred);
+
+  spin_lock (&cm_lock);
+  if (type == LOOKUP)
+    {
+      if (err == ENOENT)
+	cache_misses.absent++;
+      else if (err)
+	cache_misses.errors++;
+      else 
+	cache_misses.present++;
+      if (name[0] == '.')
+	{
+	  if (name[1] == '\0')
+	    cache_misses.dot++;
+	  else if (name[1] == '.' && name[2] == '\0')
+	    cache_misses.dotdot++;
+	}
+    }
+  spin_unlock (&cm_lock);
+
   if (err && err != ENOENT)
     return err;
   
@@ -137,6 +168,8 @@
 
   if ((type == LOOKUP || type == CREATE) && !err && np)
     diskfs_enter_lookup_cache (dp, *np, name);
+  else if (type == LOOKUP && err == ENOENT)
+    diskfs_enter_lookup_cache (dp, 0, name);
     
   return err;
 }
diff -ru hurd-0.0/libdiskfs/name-cache.c hurd-0.1/libdiskfs/name-cache.c
--- hurd-0.0/libdiskfs/name-cache.c	Mon Apr 29 16:11:08 1996
+++ hurd-0.1/libdiskfs/name-cache.c	Tue Sep  3 11:36:42 1996
@@ -24,7 +24,7 @@
 #include <cacheq.h>
 
 /* Maximum number of names to cache at once */
-#define MAXCACHE 256
+#define MAXCACHE 200
 
 /* Maximum length of file name we bother caching */
 #define CACHE_NAME_LEN 100
@@ -44,7 +44,10 @@
   char name[CACHE_NAME_LEN];
 
   /* Strlen of NAME.  If this is zero, it's an unused entry. */
-  size_t name_len;		
+  size_t name_len;
+
+  /* XXX */
+  int stati;
 };
 
 /* The contents of the cache in no particular order */
@@ -53,13 +56,18 @@
 static spin_lock_t cache_lock = SPIN_LOCK_INITIALIZER;
 
 /* Buffer to hold statistics */
-static struct
+static struct stats
 {
   long pos_hits;
   long neg_hits;
   long miss;
   long fetch_errors;
 } statistics;
+
+#define PARTIAL_THRESH 100
+#define NPARTIALS MAXCACHE / PARTIAL_THRESH
+struct stats partial_stats [NPARTIALS];
+
 
 /* If there's an entry for NAME, of length NAME_LEN, in directory DIR in the
    cache, return it's entry, otherwise 0.  CACHE_LOCK must be held.  */
@@ -67,15 +75,21 @@
 find_cache (struct node *dir, const char *name, size_t name_len)
 {
   struct lookup_cache *c;
+  int i;
 
   /* Search the list.  All unused entries are contiguous at the end of the
      list, so we can stop searching when we see the first one.  */
-  for (c = lookup_cache.mru; c && c->name_len; c = c->hdr.next)
+  for (i = 0, c = lookup_cache.mru; 
+       c && c->name_len; 
+       c = c->hdr.next, i++)
     if (c->name_len == name_len
 	&& c->dir_cache_id == dir->cache_id
 	&& c->name[0] == name[0] && strcmp (c->name, name) == 0)
-      return c;
-
+      {
+	c->stati = i / 100;
+	return c;
+      }
+  
   return 0;
 }
 
@@ -90,13 +104,6 @@
   if (name_len > CACHE_NAME_LEN - 1)
     return;
 
-  /* Never cache . or ..; it's too much trouble to get the locking
-     order right.  */
-  if (name[0] == '.' 
-      && (name[1] == '\0'
-	  || (name[1] == '.' && name[2] == '\0')))
-    return;
-
   spin_lock (&cache_lock);
 
   if (lookup_cache.length == 0)
@@ -145,6 +152,47 @@
   spin_unlock (&cache_lock);
 }
 
+/* Register a negative hit for an entry in the Nth stat class */
+void
+register_neg_hit (int n)
+{
+  int i;
+
+  statistics.neg_hits++;
+
+  for (i = 0; i < n; i++)
+    partial_stats[i].miss++;
+  for (; i < NPARTIALS; i++)
+    partial_stats[i].neg_hits++;
+}
+
+/* Register a positive hit for an entry in the Nth stat class */
+void
+register_pos_hit (int n)
+{
+  int i;
+
+  statistics.pos_hits++;
+
+  for (i = 0; i < n; i++)
+    partial_stats[i].miss++;
+  for (; i < NPARTIALS; i++)
+    partial_stats[i].pos_hits++;
+}
+  
+/* Register a miss */
+void
+register_miss ()
+{
+  int i;
+  
+  statistics.miss++;
+  for (i = 0; i < NPARTIALS; i++)
+    partial_stats[i].miss++;
+}
+
+
+
 /* Scan the cache looking for NAME inside DIR.  If we don't know
    anything entry at all, then return 0.  If the entry is confirmed to
    not exist, then return -1.  Otherwise, return NP for the entry, with
@@ -163,15 +211,18 @@
 
       cacheq_make_mru (&lookup_cache, c); /* Record C as recently used.  */
 
-      statistics.pos_hits++;
-      spin_unlock (&cache_lock);
-
       if (id == 0)
 	/* A negative cache entry.  */
-	return (struct node *)-1;
+	{
+	  register_neg_hit (c->stati);
+	  spin_unlock (&cache_lock);
+	  return (struct node *)-1;
+	}
       else if (id == dir->cache_id)
 	/* The cached node is the same as DIR.  */
 	{
+	  register_pos_hit (c->stati);
+	  spin_unlock (&cache_lock);
 	  diskfs_nref (dir);
 	  return dir;
 	}
@@ -179,12 +230,35 @@
 	/* Just a normal entry in DIR; get the actual node.  */
 	{
 	  struct node *np;
-	  error_t err = diskfs_cached_lookup (id, &np);
+	  error_t err;
+	  
+	  register_pos_hit (c->stati);
+	  spin_unlock (&cache_lock);
+	  
+	  if (name[0] == '.' && name[1] == '.' && name[2] == '\0')
+	    {
+	      mutex_unlock (&dir->lock);
+	      err = diskfs_cached_lookup (id, &np);
+	      mutex_lock (&dir->lock);
+
+	      /* In the window where DP was unlocked, we might
+		 have lost.  So check the cache again, and see
+		 if it's still there; if so, then we win. */
+	      c = find_cache (dir, "..", 2);
+	      if (!c || c->node_cache_id != id)
+		{
+		  /* Lose */
+		  mutex_unlock (&np->lock);
+		  return 0;
+		}
+	    }
+	  else
+	    err = diskfs_cached_lookup (id, &np);
 	  return err ? 0 : np;
 	}
     }
   
-  statistics.miss++;
+  register_miss ();
   spin_unlock (&cache_lock);
 
   return 0;
diff -ru hurd-0.0/libdiskfs/node-create.c hurd-0.1/libdiskfs/node-create.c
--- hurd-0.0/libdiskfs/node-create.c	Mon Jun 24 16:45:19 1996
+++ hurd-0.1/libdiskfs/node-create.c	Wed Aug  7 13:53:43 1996
@@ -64,15 +64,9 @@
     goto change_err;
   np->dn_stat.st_uid = newuid;
 
-  if (diskfs_groupmember (dir->dn_stat.st_gid, cred))
-    newgid = dir->dn_stat.st_gid;
-  else if (cred->ngids)
-    newgid = cred->gids[0];
-  else
-    {
-      newgid = dir->dn_stat.st_gid;
-      mode &= ~S_ISGID;
-    }
+  newgid = dir->dn_stat.st_gid;
+  if (!diskfs_groupmember (newgid, cred))
+    mode &= ~S_ISGID;
   err = diskfs_validate_group_change (np, newgid);
   if (err)
     goto change_err;
diff -ru hurd-0.0/libdiskfs/opts-version.c hurd-0.1/libdiskfs/opts-version.c
--- hurd-0.0/libdiskfs/opts-version.c	Mon Jul 29 12:33:28 1996
+++ hurd-0.1/libdiskfs/opts-version.c	Thu Sep  5 18:39:09 1996
@@ -21,6 +21,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include <version.h>
 
 static void
 _print_version (FILE *stream, struct argp_state *state)
@@ -28,12 +29,17 @@
   if (argp_program_version)
     /* If this is non-zero, then the program's probably defined it, so let
        that take precedence over the default.  */
-    fprintf (stream, "%s\n", argp_program_version);
+    fputs (argp_program_version, stream);
   else
-    /* Construct a version using the standard diskfs variables.  */
-    fprintf (stream, "%s %d.%d (GNU %s)\n",
-	     diskfs_server_name, diskfs_major_version, diskfs_minor_version,
-	     HURD_RELEASE);
+    {
+      fprintf (stream, "%s %s ", diskfs_server_name, diskfs_server_version);
+      if (diskfs_extra_version[0])
+	fprintf (stream, "(%s) ", diskfs_extra_version);
+    }
+  /* And because diskfs is big and huge, put our information out too. */
+  fputs (STANDARD_HURD_VERSION (libdiskfs), stream);
+  
+  putc ('\n', stream);
 }
 
 void (*argp_program_version_hook) (FILE *stream, struct argp_state *state)
diff -ru hurd-0.0/libdiskfs/readonly.c hurd-0.1/libdiskfs/readonly.c
--- hurd-0.0/libdiskfs/readonly.c	Mon Jun 24 17:04:31 1996
+++ hurd-0.1/libdiskfs/readonly.c	Thu Aug  8 18:17:55 1996
@@ -21,6 +21,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include <fcntl.h>
+#include <error.h>
 
 #include "priv.h"
 
@@ -29,13 +30,23 @@
 int
 diskfs_check_readonly ()
 {
+  error_t err;
+  
   if (diskfs_readonly)
     return 1;
   else
     {
       if (!_diskfs_diskdirty)
 	{
-	  diskfs_set_hypermetadata (1, 0);
+	  err = diskfs_set_hypermetadata (1, 0);
+	  if (err)
+	    {
+	      error (0, 0, 
+		     "%s: MEDIA NOT WRITABLE; switching to READ-ONLY",
+		     diskfs_device_arg);
+	      diskfs_readonly = 1;
+	      return 1;
+	    }
 	  _diskfs_diskdirty = 1;
 	}
       return 0;
Only in hurd-0.1: libhurdbugaddr
diff -ru hurd-0.0/libnetfs/ChangeLog hurd-0.1/libnetfs/ChangeLog
--- hurd-0.0/libnetfs/ChangeLog	Mon Jul 29 12:33:54 1996
+++ hurd-0.1/libnetfs/ChangeLog	Fri Aug 16 19:20:36 1996
@@ -1,3 +1,8 @@
+Fri Aug 16 19:20:22 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* priv.h (end_using_protid_port): Only call ports_port_deref if
+	CRED is set.
+
 Fri Jul 26 14:34:11 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* file-exec.c (netfs_S_file_exec): Unlock NP before we attempt to
diff -ru hurd-0.0/libnetfs/priv.h hurd-0.1/libnetfs/priv.h
--- hurd-0.0/libnetfs/priv.h	Mon Mar  4 13:54:23 1996
+++ hurd-0.1/libnetfs/priv.h	Fri Aug 16 19:20:10 1996
@@ -31,5 +31,6 @@
 extern inline void
 end_using_protid_port (struct protid *cred)
 {
-  ports_port_deref (cred);
+  if (cred)
+    ports_port_deref (cred);
 }
diff -ru hurd-0.0/libpager/ChangeLog hurd-0.1/libpager/ChangeLog
--- hurd-0.0/libpager/ChangeLog	Wed Jul 17 18:54:52 1996
+++ hurd-0.1/libpager/ChangeLog	Tue Aug 13 10:51:54 1996
@@ -1,3 +1,11 @@
+Tue Aug 13 10:47:47 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* object-terminate.c (_pager_free_structure): Don't bother calling
+	mach_port_deallocate if the cells are already null; set the cells
+	to null after the deallocation is done.
+	(_pager_seqnos_memory_object_terminate): Destroy the rights passed
+	in for control and name.
+
 Thu May  9 11:10:11 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* pager-create.c: Get rid of link warning.
diff -ru hurd-0.0/libpager/object-terminate.c hurd-0.1/libpager/object-terminate.c
--- hurd-0.0/libpager/object-terminate.c	Tue Mar 26 16:17:04 1996
+++ hurd-0.1/libpager/object-terminate.c	Tue Aug 13 10:49:47 1996
@@ -53,6 +53,12 @@
       condition_wait (&p->wakeup, &p->interlock);
     }
 
+  /* Destry the ports we received; mark that in P so that it doesn't bother
+     doing it again. */
+  mach_port_destroy (mach_task_self (), control);
+  mach_port_destroy (mach_task_self (), name);
+  p->memobjcntl = p->memobjname = MACH_PORT_NULL;
+
   _pager_free_structure (p);
 
 #ifdef KERNEL_INIT_RACE
@@ -104,8 +110,16 @@
   if (wakeup)
     condition_broadcast (&p->wakeup);
 
-  mach_port_deallocate (mach_task_self (), p->memobjcntl);
-  mach_port_deallocate (mach_task_self (), p->memobjname);
+  if (p->memobjcntl != MACH_PORT_NULL)
+    {
+      mach_port_deallocate (mach_task_self (), p->memobjcntl);
+      p->memobjcntl = MACH_PORT_NULL;
+    }
+  if (p->memobjname != MACH_PORT_NULL)
+    {
+      mach_port_deallocate (mach_task_self (), p->memobjname);
+      p->memobjname = MACH_PORT_NULL;
+    }
 
   /* Free the pagemap */
   if (p->pagemapsize)
diff -ru hurd-0.0/libports/ChangeLog hurd-0.1/libports/ChangeLog
--- hurd-0.0/libports/ChangeLog	Thu Jul 18 23:42:25 1996
+++ hurd-0.1/libports/ChangeLog	Wed Aug  7 15:29:09 1996
@@ -1,3 +1,8 @@
+Wed Aug  7 15:28:48 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* ports.h (_ports_create_port_internal,
+	ports_create_port_noinstall): New declarations.
+
 Thu Jul 18 22:59:14 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* Makefile (SRCS): Add create-port-noinstall.c and create-internal.c.
diff -ru hurd-0.0/libports/ports.h hurd-0.1/libports/ports.h
--- hurd-0.0/libports/ports.h	Mon May  6 16:34:34 1996
+++ hurd-0.1/libports/ports.h	Wed Aug  7 15:28:35 1996
@@ -162,6 +162,18 @@
 			   struct port_bucket *bucket,
 			   size_t size,
 			   void *result);
+
+/* Just like ports_create_port, except don't actually put the port
+   into the portset underlying BUCKET.  This is intended to be used
+   for cases where the port right must be given out before the port is
+   fully initialized; with this call you are guaranteed that no RPC
+   service will occur on the port until you have finished initializing
+   it and installed it into the portset yourself. */
+error_t
+ports_create_port_noinstall (struct port_class *class,
+			     struct port_bucket *bucket,
+			     size_t size,
+			     void *result);
    
 /* For an existing RECEIVE right, create and return in RESULT a new port
    structure; BUCKET, SIZE, and CLASS args are as for ports_create_port. */
@@ -376,5 +388,7 @@
 #define _PORTS_BLOCKED		PORTS_BLOCKED
 #define _PORTS_INHIBIT_WAIT	PORTS_INHIBIT_WAIT
 void _ports_complete_deallocate (struct port_info *);
+error_t _ports_create_port_internal (struct port_class *, struct port_bucket *,
+				     size_t, void *, int);
 
 #endif
diff -ru hurd-0.0/libshouldbeinlibc/ChangeLog hurd-0.1/libshouldbeinlibc/ChangeLog
--- hurd-0.0/libshouldbeinlibc/ChangeLog	Wed Jul 31 15:24:32 1996
+++ hurd-0.1/libshouldbeinlibc/ChangeLog	Tue Sep  3 10:21:03 1996
@@ -1,3 +1,28 @@
+Fri Aug 30 20:44:44 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp-help.c (argp_help): Print documentation only according to
+	the ARGP_HELP_*_DOC bits in FLAGS.
+	Possibly print bug report address if ARGP_HELP_BUG_ADDR is set.
+	Replace FIRST by ANYTHING (sense inverted).
+	* argp.h (ARGP_HELP_PRE_DOC, ARGP_HELP_POST_DOC, ARGP_HELP_DOC,
+	ARGP_HELP_BUG_ADDR): New macros.
+	(ARGP_HELP_STD_HELP): Include ARGP_HELP_DOC & ARGP_HELP_BUG_ADDR.
+	(argp_program_bug_address): New declaration.
+	(ARGP_HELP_EXIT_ERR, ARGP_HELP_EXIT_OK): Values changed.
+	* Makefile (SRCS): Add argp-ba.c.
+
+Tue Aug 20 17:12:42 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp-help.c (argp_doc): Add FIRST_ONLY argument.
+	Don't output a blank line for empty post-docs.
+	(argp_help): Use it.  Move first call to argp_doc after newline.
+
+Mon Aug 19 14:45:30 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp-help.c (argp_help): Add note about --usage to `Try...' msg.
+	Supply new args to argp_doc, and additional call before arg help.
+	(argp_doc): Add the POST and PRE_BLANK arguments, & return val.
+
 Wed Jul 31 15:24:09 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* wire.c (_start): No longer declared as weak, now that everything
diff -ru hurd-0.0/libshouldbeinlibc/Makefile hurd-0.1/libshouldbeinlibc/Makefile
--- hurd-0.0/libshouldbeinlibc/Makefile	Wed Jun 19 14:21:46 1996
+++ hurd-0.1/libshouldbeinlibc/Makefile	Tue Sep  3 10:21:03 1996
@@ -20,7 +20,7 @@
 makemode := library
 
 libname = libshouldbeinlibc
-SRCS = argp-parse.c argp-help.c argp-pv.c argp-pvh.c  \
+SRCS = argp-parse.c argp-help.c argp-pv.c argp-pvh.c argp-ba.c \
 	termsize.c idvec.c idvec-auth.c timefmt.c exec-reauth.c \
 	canon-host.c maptime.c shared-dom.c localhost.c wire.c portinfo.c \
 	xportinfo.c portxlate.c lcm.c cacheq.c fsysops.c
Only in hurd-0.1/libshouldbeinlibc: argp-ba.c
diff -ru hurd-0.0/libshouldbeinlibc/argp-help.c hurd-0.1/libshouldbeinlibc/argp-help.c
--- hurd-0.0/libshouldbeinlibc/argp-help.c	Mon Jul 29 12:34:28 1996
+++ hurd-0.1/libshouldbeinlibc/argp-help.c	Tue Sep  3 10:21:04 1996
@@ -709,23 +709,48 @@
       argp_args_usage (*children++, stream);
 }
 
-/* Print the documentation for ARGP to STREAM.  Each separate bit of
-   documentation is preceded by a blank line.  */
-static void
-argp_doc (const struct argp *argp, FILE *stream)
+/* Print the documentation for ARGP to STREAM; if POST is false, then
+   everything preceeding a `\v' character in the documentation strings (or
+   the whole string, for those with none) is printed, otherwise, everything
+   following the `\v' character (nothing for strings without).  Each separate
+   bit of documentation is separated a blank line, and if PRE_BLANK is true,
+   then the first is as well.  If FIRST_ONLY is true, only the first
+   occurance is output.  Returns true if anything was output.  */
+static int
+argp_doc (const struct argp *argp, int post, int pre_blank, int first_only,
+	  FILE *stream)
 {
   const struct argp **children = argp->children;
   const char *doc = argp->doc;
+  int anything = 0;
+
   if (doc)
     {
-      putc ('\n', stream);
-      fputs (doc, stream);
+      char *vt = index (doc, '\v');
+
+      if (pre_blank && (vt || !post))
+	putc ('\n', stream);
+
+      if (vt)
+	if (post)
+	  fputs (vt + 1, stream);
+	else
+	  fwrite (doc, 1, vt - doc, stream);
+      else
+	if (! post)
+	  fputs (doc, stream);
       if (line_wrap_point (stream) > line_wrap_lmargin (stream))
 	putc ('\n', stream);
+
+      anything = 1;
     }
   if (children)
-    while (*children)
-      argp_doc (*children++, stream);
+    while (*children && !(first_only && anything))
+      anything |=
+	argp_doc (*children++, post, anything || pre_blank, first_only,
+		  stream);
+
+  return anything;
 }
 
 /* Output a usage message for ARGP to STREAM.  FLAGS are from the set
@@ -733,7 +758,7 @@
 void argp_help (const struct argp *argp, FILE *stream,
 		unsigned flags, char *name)
 {
-  int first = 1;
+  int anything = 0;		/* Whether we've output anything.  */
   struct hol *hol = 0;
 
   if (! stream)
@@ -780,13 +805,18 @@
       line_wrap_set_lmargin (stream, old_lm);
 
       putc ('\n', stream);
-      first = 0;
+      anything = 1;
     }
 
+  if (flags & ARGP_HELP_PRE_DOC)
+    anything |= argp_doc (argp, 0, 0, 1, stream);
+
   if (flags & ARGP_HELP_SEE)
     {
-      fprintf (stream, "Try `%s --help' for more information.\n", name);
-      first = 0;
+      fprintf (stream,
+	       "Try `%s --help' or `%s --usage' for more information.\n",
+	       name, name);
+      anything = 1;
     }
 
   if (flags & ARGP_HELP_LONG)
@@ -795,14 +825,23 @@
       /* Print info about all the options.  */
       if (hol->num_entries > 0)
 	{
-	  if (! first)
+	  if (anything)
 	    putc ('\n', stream);
 	  hol_help (hol, stream);
-	  first = 0;
+	  anything = 1;
 	}
+    }
 
-      /* Finally, print any documentation strings at the end.  */
-      argp_doc (argp, stream);
+  if (flags & ARGP_HELP_POST_DOC)
+    /* Print any documentation strings at the end.  */
+    anything |= argp_doc (argp, 1, anything, 0, stream);
+
+  if ((flags & ARGP_HELP_BUG_ADDR) && argp_program_bug_address)
+    {
+      if (anything)
+	putc ('\n', stream);
+      fprintf (stream, "Report bugs to %s.\n", argp_program_bug_address);
+      anything = 1;
     }
 
   if (hol)
diff -ru hurd-0.0/libshouldbeinlibc/argp.h hurd-0.1/libshouldbeinlibc/argp.h
--- hurd-0.0/libshouldbeinlibc/argp.h	Sat Jul  6 17:12:56 1996
+++ hurd-0.1/libshouldbeinlibc/argp.h	Tue Sep  3 10:21:04 1996
@@ -258,6 +258,8 @@
 error_t argp_parse (const struct argp *argp,
 		    int argc, char **argv, unsigned flags,
 		    int *arg_index, void *input);
+
+/* Global variables.  */
 
 /* If defined or set by the user program to a non-zero value, then a default
    option --version is added (unless the ARGP_NO_HELP flag is used), which
@@ -272,16 +274,27 @@
    used).  This variable takes precedent over ARGP_PROGRAM_VERSION.  */
 extern void (*argp_program_version_hook) (FILE *stream,
 					  struct argp_state *state);
+
+/* If defined or set by the user program, it should point to string that is
+   the bug-reporting address for the program.  It will be printed by
+   argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
+   standard help messages), embedded in a sentence that says something like
+   `Report bugs to ADDR.'.  */
+extern char *argp_program_bug_address;
 
 /* Flags for argp_help.  */
-#define ARGP_HELP_USAGE		0x01 /* Print a Usage: message. */
+#define ARGP_HELP_USAGE		0x01 /* a Usage: message. */
 #define ARGP_HELP_SHORT_USAGE	0x02 /*  " but don't actually print options. */
-#define ARGP_HELP_SEE		0x04 /* Print a `for more help...' message. */
-#define ARGP_HELP_LONG		0x08 /* Print a long help message. */
+#define ARGP_HELP_SEE		0x04 /* a `Try ... for more help' message. */
+#define ARGP_HELP_LONG		0x08 /* a long help message. */
+#define ARGP_HELP_PRE_DOC	0x10 /* doc string preceding long help.  */
+#define ARGP_HELP_POST_DOC	0x20 /* doc string following long help.  */
+#define ARGP_HELP_DOC		(ARGP_HELP_PRE_DOC | ARGP_HELP_POST_DOC)
+#define ARGP_HELP_BUG_ADDR	0x40 /* bug report address */
 
 /* These ARGP_HELP flags are only understood by argp_state_help.  */
-#define ARGP_HELP_EXIT_ERR	0x10 /* Call exit(1) instead of returning.  */
-#define ARGP_HELP_EXIT_OK	0x20 /* Call exit(0) instead of returning.  */
+#define ARGP_HELP_EXIT_ERR	0x100 /* Call exit(1) instead of returning.  */
+#define ARGP_HELP_EXIT_OK	0x200 /* Call exit(0) instead of returning.  */
 
 /* The standard thing to do after a program command line parsing error, if an
    error message has already been printed.  */
@@ -293,7 +306,8 @@
   (ARGP_HELP_SHORT_USAGE | ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR)
 /* The standard thing to do in response to a --help option.  */
 #define ARGP_HELP_STD_HELP \
-  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK)
+  (ARGP_HELP_SHORT_USAGE | ARGP_HELP_LONG | ARGP_HELP_EXIT_OK \
+   | ARGP_HELP_DOC | ARGP_HELP_BUG_ADDR)
 
 /* Output a usage message for ARGP to STREAM.  FLAGS are from the set
    ARGP_HELP_*.  */
diff -ru hurd-0.0/libstore/ChangeLog hurd-0.1/libstore/ChangeLog
--- hurd-0.0/libstore/ChangeLog	Mon Jul 29 12:34:35 1996
+++ hurd-0.1/libstore/ChangeLog	Thu Sep  5 10:12:36 1996
@@ -1,3 +1,56 @@
+Wed Sep  4 13:01:19 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp.c (parse_opt): --layer isn't implemented, so say so.
+
+	* storeread.c (main): Add new args to store_*_create calls.
+	* storecat.c (main): Use new interface to store_argp.
+
+Wed Sep  3 11:00:00 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp.c (struct store_parsed): New type.
+	(store_parsed_free, store_parsed_append_args, store_parsed_open):
+	New functions.
+	(parse_opt): Use new store_parsed structure instead of the old
+	store_pars_hook, and just fill in the names rather than doing the
+	open here.  Don't take a struct store_argp_params as input any
+	more; instead just take the address of a location in which to
+	return a store_parsed structure.
+	(struct store_parse_hook): Type removed.
+	(free_hook, open_file): Functions removed.
+	<assert.h>: New include.
+	<stdlib.h>, <fcntl.h>: Includes removed.
+	(options): --machdev/-m renamed to --device/-D.
+	* store.h (struct store): Make log2_* fields unsigned.
+	(STORE_NO_FILEIO): New macro.
+	(STORE_HARD_READONLY, STORE_ENFORCED): Values changed.
+	(STORE_GENERIC_FLAGS): Add STORE_NO_FILEIO.
+	(struct store_argp_params): Type removed.
+	(store_parsed_Free, store_parsed_open, store_parsed_append_args):
+	New declarations.
+	(struct store_parsed): New incomplete type.
+	
+Mon Sep  2 18:56:26 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* store.h (store_open): New declaration.
+	* open.c: New file.
+	* Makefile (SRCS): Add open.c.
+
+Wed Aug 21 14:40:15 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* device.c (store_device_open): Don't call store_device_create if
+	device_open fails.
+
+Tue Aug 20 14:37:33 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* argp.c (free_hook): Free H->params->args if necessary.
+	(parse_opt): Initialize and fill in H->params->args when appropriate.
+	<argz.h>: New include.
+
+Mon Aug 19 14:31:33 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* store.h (struct store_argp_params): Add return_args, args, &
+	args_len fields.
+
 Fri Jul 19 16:16:46 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* decode.c (store_std_leaf_decode): Decode name too.
diff -ru hurd-0.0/libstore/Makefile hurd-0.1/libstore/Makefile
--- hurd-0.0/libstore/Makefile	Tue May 21 20:18:16 1996
+++ hurd-0.1/libstore/Makefile	Thu Sep  5 10:12:36 1996
@@ -25,7 +25,7 @@
 libname = libstore
 SRCS = create.c derive.c make.c rdwr.c set.c device.c file.c stripe.c \
 	storeread.c storecat.c enc.c encode.c decode.c clone.c argp.c \
-	std.c kids.c null.c flags.c
+	std.c kids.c null.c flags.c open.c
 LCLHDRS=store.h
 installhdrs=store.h
 
@@ -36,3 +36,4 @@
 
 storeread: libstore.so ../libshouldbeinlibc/libshouldbeinlibc.so
 storecat: libstore.so ../libshouldbeinlibc/libshouldbeinlibc.so
+storeargs: libstore.so ../libshouldbeinlibc/libshouldbeinlibc.so
diff -ru hurd-0.0/libstore/argp.c hurd-0.1/libstore/argp.c
--- hurd-0.0/libstore/argp.c	Sun Jun 16 22:50:06 1996
+++ hurd-0.1/libstore/argp.c	Thu Sep  5 10:12:37 1996
@@ -20,86 +20,127 @@
    with this program; if not, write to the Free Software Foundation, Inc.,
    675 Mass Ave, Cambridge, MA 02139, USA. */
 
-#include <stdlib.h>
 #include <string.h>
-#include <fcntl.h>
+#include <assert.h>
 #include <hurd.h>
 #include <argp.h>
-#include <error.h>
+#include <argz.h>
 
 #include "store.h"
 
 static const struct argp_option options[] = {
-  {"machdev", 'm', 0, 0, "DEVICE is a mach device, not a file"},
-  {"interleave", 'i', "BLOCKS", 0, "Interleave in runs of length BLOCKS"},
-  {"layer",   'l', 0, 0, "Layer multiple devices for redundancy"},
+  {"device",	'D', 0,        0, "DEVICE is a mach device, not a file"},
+  {"interleave",'i', "BLOCKS", 0, "Interleave in runs of length BLOCKS"},
+  {"layer",   	'l', 0,        0, "Layer multiple devices for redundancy"},
   {0}
 };
 
 static const char args_doc[] = "DEVICE...";
-static const char doc[] = "If multiple DEVICEs are specified, they are"
+static const char doc[] = "\vIf multiple DEVICEs are specified, they are"
 " concatenated unless either --interleave or --layer is specified (mutually"
 " exlusive).";
 
-/* Used to hold data during argument parsing.  */
-struct store_parse_hook
+struct store_parsed
 {
-  /* A malloced vector of stores specified on the command line, NUM_STORES
-     long.  */
-  struct store **stores;
-  size_t num_stores;
-
-  /* Pointer to params struct passed in by user.  */
-  struct store_argp_params *params;
-
+  char *names;
+  size_t names_len;
   off_t interleave;		/* --interleave value */
   int machdev : 1;		/* --machdev specified */
   int layer : 1;		/* --layer specified */
 };
 
-/* Free the parse hook H.  If FREE_STORES is true, also free the stores in
-   H's store vector, otherwise just free the vector itself.  */
-static void
-free_hook (struct store_parse_hook *h, int free_stores)
+void
+store_parsed_free (struct store_parsed *parsed)
 {
-  int i;
-  if (free_stores)
-    for (i = 0; i < h->num_stores; i++)
-      store_free (h->stores[i]);
-  if (h->stores)
-    free (h->stores);
-  free (h);
+  free (parsed->names);
+  free (parsed);
 }
-
-static error_t
-open_file (char *name, struct store_parse_hook *h, struct store **s)
+
+/* Add the arguments  PARSED, and return the corresponding store in STORE.  */
+error_t
+store_parsed_append_args (const struct store_parsed *parsed,
+			  char **args, size_t *args_len)
 {
-  error_t err;
-  int flags = h->params->flags;
-  int open_flags = (flags & STORE_HARD_READONLY) ? O_RDONLY : O_RDWR;
-  file_t node = file_name_lookup (name, open_flags, 0);
+  error_t err = 0;
+  size_t num_names = argz_count (parsed->names, parsed->names_len);
 
-  if (node == MACH_PORT_NULL)
-    return errno;
+  if (parsed->machdev)
+    err = argz_add (args, args_len, "--machdev");
 
-  err = store_create (node, flags, 0, s);
-  if (err)
+  if (!err && num_names > 1 && (parsed->interleave || parsed->layer))
     {
-      if (! h->params->no_file_io)
-	/* Try making a store that does file io to NODE.  */
-	err = store_file_create (node, flags, s);
-      if (err)
-	mach_port_deallocate (mach_task_self (), node);
+      char buf[40];
+      if (parsed->interleave)
+	snprintf (buf, sizeof buf, "--interleave=%ld", parsed->interleave);
+      else
+	snprintf (buf, sizeof buf, "--layer=%ld", parsed->layer);
+      err = argz_add (args, args_len, buf);
     }
 
+  if (! err)
+    err = argz_append (args, args_len, parsed->names, parsed->names_len);
+
   return err;
 }
 
+/* Open PARSED, and return the corresponding store in STORE.  */
+error_t
+store_parsed_open (const struct store_parsed *parsed, int flags,
+		   struct store_class *classes,
+		   struct store **store)
+{
+  size_t num = argz_count (parsed->names, parsed->names_len);
+  error_t open (char *name, struct store **store)
+    {
+      if (parsed->machdev)
+	return store_device_open (name, flags, store);
+      else
+	return store_open (name, flags, classes, store);
+    }
+
+  if (num == 1)
+    return open (parsed->names, store);
+  else
+    {
+      int i;
+      char *name;
+      error_t err = 0;
+      struct store **stores = malloc (sizeof (struct store *) * num);
+
+      if (! stores)
+	return ENOMEM;
+
+      for (i = 0, name = parsed->names;
+	   !err && i < num;
+	   i++, name = argz_next (parsed->names, parsed->names_len, name))
+	err = open (name, &stores[i]);
+
+      if (! err)
+	if (parsed->interleave)
+	  err =
+	    store_ileave_create (stores, num, parsed->interleave,
+				 flags, store);
+	else if (parsed->layer)
+	  assert (! parsed->layer);
+	else
+	  err = store_concat_create (stores, num, flags, store);
+
+      if (err)
+	{
+	  while (i > 0)
+	    store_free (stores[i--]);
+	  free (stores);
+	}
+
+      return err;
+    }
+}
+
 static error_t
 parse_opt (int opt, char *arg, struct argp_state *state)
 {
-  error_t err = 0;
-  struct store_parse_hook *h = state->hook;
+  error_t err;
+  struct store_parsed *parsed = state->hook;
 
   /* Print a parsing error message and (if exiting is turned off) return the
      error code ERR.  */
@@ -108,100 +149,63 @@
 
   switch (opt)
     {
-      struct store *s;
-
     case 'm':
-      h->machdev = 1; break;
+      parsed->machdev = 1; break;
 
     case 'i':
-      if (h->layer)
+      if (parsed->layer)
 	PERR (EINVAL, "--layer and --interleave are exclusive");
-      if (h->interleave)
+      if (parsed->interleave)
 	/* Actually no reason why we couldn't support this.... */
 	PERR (EINVAL, "--interleave specified multiple times");
 
-      h->interleave = atoi (arg);
-      if (! h->interleave)
+      parsed->interleave = atoi (arg);
+      if (! parsed->interleave)
 	PERR (EINVAL, "%s: Bad value for --interleave", arg);
       break;
 
     case 'l':
-      if (h->interleave)
+#if 1
+      argp_failure (state, 5, 0, "--layer not implemented");
+      return EINVAL;
+#else
+      if (parsed->interleave)
 	PERR (EINVAL, "--layer and --interleave are exclusive");
-      h->layer = 1;
+      parsed->layer = 1;
+#endif
       break;
 
     case ARGP_KEY_ARG:
       /* A store device to use!  */
-      if (h->machdev)
-	err = store_device_open (arg, h->params->flags, &s);
-      else
-	err = open_file (arg, h, &s);
+      err = argz_add (&parsed->names, &parsed->names_len, arg);
       if (err)
-	{
-	  argp_failure (state, 1, err, "%s", arg);
-	  return err;
-	}
-      else
-	{
-	  struct store **stores = realloc (h->stores, h->num_stores + 1);
-	  if (stores)
-	    {
-	      stores[h->num_stores++] = s;
-	      h->stores = stores;
-	    }
-	  else
-	    return ENOMEM;	/* Just fucking lovely */
-	}
+	argp_failure (state, 1, err, "%s", arg);
+      return err;
       break;
 
     case ARGP_KEY_INIT:
       /* Initialize our parsing state.  */
       if (! state->input)
 	return EINVAL;		/* Need at least a way to return a result.  */
-      h = malloc (sizeof (struct store_parse_hook));
-      if (! h)
+      state->hook = malloc (sizeof (struct store_parsed));
+      if (! state->hook)
 	return ENOMEM;
-      bzero (h, sizeof (struct store_parse_hook));
-      h->params = state->input;
-      state->hook = h;
+      bzero (state->hook, sizeof (struct store_parsed));
       break;
 
     case ARGP_KEY_ERROR:
       /* Parsing error occured, free everything. */
-      free_hook (h, 1); break;
+      store_parsed_free (parsed); break;
 
     case ARGP_KEY_SUCCESS:
       /* Successfully finished parsing, return a result.  */
-
-      if (h->num_stores == 0)
+      if (parsed->names == 0)
 	{
-	  free_hook (h, 1);
+	  store_parsed_free (parsed);
 	  PERR (EINVAL, "No store specified");
 	}
-
-      if (state->input == 0)
-	/* No way to return a value!  */
-	err = EINVAL;
-      else if (h->num_stores == 1)
-	s = h->stores[0];	/* Just a single store.  */
-      else if (h->interleave)
-	err =
-	  store_ileave_create (h->stores, h->num_stores, h->interleave,
-			       h->params->flags, &s);
-      else if (h->layer)
-	{
-	  free_hook (h, 1);
-	  PERR (EINVAL, "--layer not implemented");
-	}
       else
-	err =
-	  store_concat_create (h->stores, h->num_stores, h->params->flags, &s);
-
-      free_hook (h, err);
-      if (! err)
-	h->params->result = s;
-
+	*(struct store_parsed **)state->input = parsed;
       break;
 
     default:
diff -ru hurd-0.0/libstore/device.c hurd-0.1/libstore/device.c
--- hurd-0.0/libstore/device.c	Tue May 21 20:12:38 1996
+++ hurd-0.1/libstore/device.c	Tue Sep  3 10:21:06 1996
@@ -117,12 +117,13 @@
     return err;
 
   err = device_open (dev_master, open_flags, (char *)name, &device);
-
   mach_port_deallocate (mach_task_self (), dev_master);
-
-  err = store_device_create (device, flags, store);
-  if (err)
-    mach_port_deallocate (mach_task_self (), device);
+  if (! err)
+    {
+      err = store_device_create (device, flags, store);
+      if (err)
+	mach_port_deallocate (mach_task_self (), device);
+    }
 
   return err;
 }
Only in hurd-0.1/libstore: open.c
diff -ru hurd-0.0/libstore/store.h hurd-0.1/libstore/store.h
--- hurd-0.0/libstore/store.h	Tue May 21 19:58:28 1996
+++ hurd-0.1/libstore/store.h	Thu Sep  5 10:12:37 1996
@@ -68,9 +68,9 @@
   size_t size;
 
   /* Log_2 (BLOCK_SIZE) or 0 if not a power of 2. */
-  int log2_block_size;
+  unsigned log2_block_size;
   /* Log_2 (VM_PAGE_SIZE / BLOCK_SIZE); only valid if LOG2_BLOCK_SIZE is.  */
-  int log2_blocks_per_page;
+  unsigned log2_blocks_per_page;
 
   /* Random flags.  */
   int flags;
@@ -91,15 +91,18 @@
    <hurd/hurd_types.h>.  XXX synchronize these values.  */
 
 /* Flags that reflect something immutable about the object.  */
-#define STORE_IMMUTABLE_FLAGS	0xFF
+#define STORE_IMMUTABLE_FLAGS	0x00FF
 
 /* Flags implemented by generic store code.  */
-#define STORE_READONLY		0x100	/* No writing allowed. */
-#define STORE_GENERIC_FLAGS	STORE_READONLY
+#define STORE_READONLY		0x0100	/* No writing allowed. */
+#define STORE_NO_FILEIO		0x0200	/* If store_create can't fetch store
+					   information, don't create a store
+					   using file io instead.  */
+#define STORE_GENERIC_FLAGS	(STORE_READONLY | STORE_NO_FILEIO)
 
 /* Flags implemented by each backend.  */
-#define STORE_HARD_READONLY	0x200	/* Can't be made writable.  */
-#define STORE_ENFORCED		0x400	/* Range is enforced by device.  */
+#define STORE_HARD_READONLY	0x0400	/* Can't be made writable.  */
+#define STORE_ENFORCED		0x0800	/* Range is enforced by device.  */
 #define STORE_BACKEND_SPEC_BASE	0x1000 /* Here up are backend-specific */
 #define STORE_BACKEND_FLAGS	(STORE_HARD_READONLY | STORE_ENFORCED \
 				 | ~(STORE_BACKEND_SPEC_BASE - 1))
@@ -169,6 +172,14 @@
 
 void store_free (struct store *store);
 
+/* Open the file NAME, and return a new store in STORE, which refers to the
+   storage underlying it.  CLASSES is used to select classes specified by the
+   provider; if it is 0, STORE_STD_CLASSES is used.  FLAGS is set with
+   store_set_flags.  A reference to the open file is created (but may be
+   destroyed with store_close_source).  */
+error_t store_open (char *name, int flags, struct store_class *classes,
+		    struct store **store);
+
 /* Allocate a new store structure with class CLASS, and the various other
    fields initialized to the given parameters.  */
 struct store *
@@ -392,22 +403,24 @@
 
 /* An argument parser that may be used for parsing a simple command line
    specification for stores.  The accompanying input parameter must be a
-   pointer to a structure of type struct store_argp_param.  */
+   pointer to a location in which to store the resulting pointer to a struct
+   store_parsed.  */
 extern struct argp store_argp;
 
-/* Structure used to pass in arguments and return the result from
-   STORE_ARGP.  */
-struct store_argp_params
-{
-  /* An initial set of flags desired to be set.  */
-  int flags;
-
-  /* If true, don't attempt use store_file_create to create a store on files
-     upon which store_create has failed.  */
-  int no_file_io : 1;
-
-  /* Parsed store returned here.  */
-  struct store *result;
-};
+/* The result of parsing a store, which should be enough information to open
+   it, or return the arguments.  */
+struct store_parsed;
+
+/* Free all resources used by PARSED.  */
+void store_parsed_free (struct store_parsed *parsed);
+
+/* Open PARSED, and return the corresponding store in STORE.  */
+error_t store_parsed_open (const struct store_parsed *parsed, int flags,
+			   struct store_class *classes,
+			   struct store **store);
+
+/* Add the arguments  PARSED, and return the corresponding store in STORE.  */
+error_t store_parsed_append_args (const struct store_parsed *parsed,
+				  char **args, size_t *args_len);
 
 #endif /* __STORE_H__ */
diff -ru hurd-0.0/libstore/storecat.c hurd-0.1/libstore/storecat.c
--- hurd-0.0/libstore/storecat.c	Tue May 21 20:49:26 1996
+++ hurd-0.1/libstore/storecat.c	Thu Sep  5 10:12:38 1996
@@ -13,10 +13,12 @@
   struct store *s;
   char buf[4096], *data = buf;
   size_t data_len = sizeof (buf);
-  struct store_argp_params params = { 0, 0, 0 };
+  struct store_parsed *parsed;
 
-  argp_parse (&store_argp, argc, argv, 0, 0, &params);
-  s = params.result;
+  argp_parse (&store_argp, argc, argv, 0, 0, &parsed);
+  err = store_parsed_open (parsed, STORE_READONLY, 0, &s);
+  if (err)
+    error (4, err, "store_parsed_open");
 
   err = store_read (s, 0, s->size, &data, &data_len);
   if (err)
diff -ru hurd-0.0/libstore/storeread.c hurd-0.1/libstore/storeread.c
--- hurd-0.0/libstore/storeread.c	Sat May 11 01:23:23 1996
+++ hurd-0.1/libstore/storeread.c	Thu Sep  5 10:12:38 1996
@@ -60,14 +60,14 @@
 		    if (! err)
 		      {
 			struct store_run run = {0, stat.st_size / block_size};
-			err = _store_file_create (source, block_size, &run, 1,
+			err = _store_file_create (source, 0, block_size, &run, 1,
 						  &store);
 		      }
 		  }
 		else
-		  err = store_file_create (source, &store);
+		  err = store_file_create (source, 0, &store);
 	      else
-		err = store_create (source, &store);
+		err = store_create (source, 0, 0, &store);
 	      if (err)
 		error (err, 3, "%s", arg);
 	    }
diff -ru hurd-0.0/libthreads/ChangeLog hurd-0.1/libthreads/ChangeLog
--- hurd-0.0/libthreads/ChangeLog	Sat Jul 20 15:47:42 1996
+++ hurd-0.1/libthreads/ChangeLog	Wed Sep  4 09:06:39 1996
@@ -1,3 +1,14 @@
+Wed Sep  4 09:06:09 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makefile (VPATH): Look in $(asm_syntax) instead of old
+	$(machine); Hurd configure now folds equivalent CPU types into
+	asm_syntax. 
+
+Thu Aug 29 12:50:37 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* i386/csw.S: Include <mach/i386/asm.h> instead of <i386/asm.h>.
+	Define ELF before inclusion.
+
 Sat Jul 20 15:47:24 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* Makefile (lndist-i386-files): Look for I386SRCS and I386HDRS in
diff -ru hurd-0.0/libthreads/Makefile hurd-0.1/libthreads/Makefile
--- hurd-0.0/libthreads/Makefile	Sat Jul 20 15:49:44 1996
+++ hurd-0.1/libthreads/Makefile	Wed Sep  4 09:07:16 1996
@@ -15,8 +15,6 @@
 #   along with this program; if not, write to the Free Software
 #   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-# This is currently i386 specific. XXX
-
 dir := libthreads
 makemode := library
 
@@ -37,7 +35,7 @@
 installhdrs = cthreads.h rwlock.h
 installhdrsubdir = .
 
-VPATH += $(srcdir)/$(machine)
+VPATH += $(srcdir)/$(asm_syntax)
 
 include ../Makeconf
 
diff -ru hurd-0.0/libthreads/i386/csw.S hurd-0.1/libthreads/i386/csw.S
--- hurd-0.0/libthreads/i386/csw.S	Wed Oct  4 16:55:28 1995
+++ hurd-0.1/libthreads/i386/csw.S	Thu Aug 29 13:44:42 1996
@@ -26,6 +26,9 @@
 /*
  * HISTORY
  * $Log: csw.S,v $
+ * Revision 1.6  1996/08/29 17:44:42  thomas
+ * *** empty log message ***
+ *
  * Revision 1.5  1995/10/04 20:55:28  roland
  * (JUMPTARGET): New macro, versions for [PIC] and not.
  * Use it in place of EXT.
@@ -63,7 +66,8 @@
  * 	[90/02/05            dbg]
  * 
  */
-#include <i386/asm.h>
+#define ELF
+#include <mach/i386/asm.h>
 
 #ifdef	PIC
 #define	JUMPTARGET(name)	EXT(name##@PLT)
diff -ru hurd-0.0/libtrivfs/ChangeLog hurd-0.1/libtrivfs/ChangeLog
--- hurd-0.0/libtrivfs/ChangeLog	Thu Jul 18 23:35:28 1996
+++ hurd-0.1/libtrivfs/ChangeLog	Fri Aug 16 19:25:05 1996
@@ -1,3 +1,14 @@
+Fri Aug 16 19:24:45 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* migsupport.c (trivfs_end_using_protid): Only call
+	ports_port_deref if CRED is set.
+	(trivfs_end_using_control): Likewise.
+
+Thu Aug 15 16:14:33 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* io-pathconf.c (trivfs_S_io_pathconf): Implement by calling
+	underlying node.
+
 Thu Jul 18 23:14:44 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* io-reauthenticate.c (trivfs_S_io_reauthenticate): Use noinstall
diff -ru hurd-0.0/libtrivfs/io-pathconf.c hurd-0.1/libtrivfs/io-pathconf.c
--- hurd-0.0/libtrivfs/io-pathconf.c	Mon Sep 18 14:38:22 1995
+++ hurd-0.1/libtrivfs/io-pathconf.c	Thu Aug 15 16:14:21 1996
@@ -1,5 +1,5 @@
 /* 
-   Copyright (C) 1994 Free Software Foundation
+   Copyright (C) 1994, 1996 Free Software Foundation
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -24,10 +24,7 @@
 		      int name, int *val)
 {
   if (cred)
-    {
-      *val = 0;
-      return 0;
-    }
+    return io_pathconf (cred->realnode, name, val);
   else
     return EOPNOTSUPP;
 }
diff -ru hurd-0.0/libtrivfs/migsupport.c hurd-0.1/libtrivfs/migsupport.c
--- hurd-0.0/libtrivfs/migsupport.c	Fri Oct  6 17:43:55 1995
+++ hurd-0.1/libtrivfs/migsupport.c	Fri Aug 16 19:24:29 1996
@@ -1,5 +1,5 @@
 /* 
-   Copyright (C) 1994, 1995 Free Software Foundation
+   Copyright (C) 1994, 1995, 1996 Free Software Foundation
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -37,7 +37,8 @@
 void 
 trivfs_end_using_protid (struct trivfs_protid *cred)
 {
-  ports_port_deref (cred);
+  if (cred)
+    ports_port_deref (cred);
 }
 
 struct trivfs_control *
@@ -60,5 +61,6 @@
 void 
 trivfs_end_using_control (struct trivfs_control *cred)
 {
-  ports_port_deref (cred);
+  if (cred)
+    ports_port_deref (cred);
 }
diff -ru hurd-0.0/nfs/ChangeLog hurd-0.1/nfs/ChangeLog
--- hurd-0.0/nfs/ChangeLog	Wed Jul 31 13:25:17 1996
+++ hurd-0.1/nfs/ChangeLog	Tue Sep  3 14:15:35 1996
@@ -1,3 +1,193 @@
+Tue Sep  3 14:00:25 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* nfs-spec.h: Renamed from rpcsvc/nfs_prot.h.
+	* mount.c: Include "mount.h" instead of <rpcsvc/mount.h>.
+	* nfs.h: Include "nfs-spec.h" instead of <rpcsvc/nfs_prot.h>.
+	* rpcsvc/mount.h: Deleted file.
+	* rpcsvc: Deleted directory.
+	* mount.h (MOUNTPROG): Renamed from MOUNT_RPC_PROGRAM.
+	(MOUNTVERS): Renamed from MOUNT_RPC_VERSION.
+	* Makefile (RPCSVC_FILES): Deleted var.
+	(lndist, lndist-rpcsvc-files,
+	$(top_srcdir)/hurd-snap/$(dir)/rpcsvc): Deleted targets.
+	(LCLHDRS): Added mount.h and nfs-spec.h.
+
+Thu Aug 29 10:41:27 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* rpcsvc/nfs_prot.h (createmode): Spell EXCLUSIVE correctly.
+	* nfs.c (hurd_mode_to_nfs_type): New function.
+	* nfs.h (hurd_mode_to_nfs_type): New decl.
+	* ops.c (netfs_attempt_rmdir): process_wcc_stat for NP, not DIR.
+	(netfs_attempt_link): Spell netfs_validate_stat correctly. 
+	(minor, major): New macros.
+	(netfs_report_access): Don't try and return an error.
+
+	* rpc.c (conduct_rpc): Tolerate and return errors from write.
+
+	* Makefile (RPCSVC_FILES): New variable.
+	(lndist): Depend on lndist-rpcsvc-files.
+	(lndist-rpcsvc-files, $(top_srcdir)/hurd-snap/$(dir)/rpcsvc): New
+	targets. 
+
+Fri Aug 16 11:56:53 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* ops.c (process_wcc_stat): New function.
+	(netfs_attempt_chown): Use process_wcc_stat instead of
+	register_fresh_stat.  Pack and unpack v3 SETATTR structure if
+	appropriate.
+	(netfs_attempt_chmod): Likewise.
+	(netfs_attempt_utimes): Likewise.
+	(netfs_attempt_set_size): Likewise.
+	(netfs_attempt_lookup): Use process_returned_stat instead of
+	register_fresh state.  Unpack v3 LOOKUP structure if appropriate.
+	(netfs_attempt_link): Likewise.
+	(verify_nonexistent): Assert that we are v2.
+	(netfs_report_access): Use NFS3PROC_ACCESS if we are v3.
+	(netfs_check_open_permissions): Use netfs_report_access.
+	(netfs_attempt_readlink): Unpack v3 READLINK structure if
+	appropriate.
+	(netfs_attempt_read): Pack and unpack v3 READ structure in
+	appropriate.  Use process_returned_stat instead of
+	register_fresh_stat. 
+	(netfs_attempt_write): Pack and unpack v3 WRITE structure in
+	appropriate.  Use process_wcc_stat instead of
+	register_fresh_stat. 
+	(netfs_attempt_create_file): Pack and unpack v3 CREATE structure
+	if appropriate.  Use process_returned_stat instead of
+	register_fresh_stat.
+	(netfs_attempt_link) [CHRDEV, BLKDEV, FIFO, SOCK]: If v3, use new
+	MKNOD call instead of CREATE with overloaded mode.
+	(netfs_attempt_link) [SYMLINK]: If pack and unpack v3 SYMLINK
+	structure if appropriate.
+	(netfs_attempt_unlink): Unpack v3 REMOVE structure if appropriate.
+	(netfs_attempt_rmdir): Unpack v3 RMDIR structure if appropriate.
+	(netfs_attempt_rename): Unpack v3 RENAME structure if appropriate.
+
+	* rpcsvc/nfs_prot.h (ACCESS3_READ, ACCESS3_LOOKUP, ACCESS3_MODIFY,
+	ACCESS3_EXTEND, ACCESS3_DELETE, ACCESS3_EXECUTE): New macros.
+
+	* ops.c (netfs_attempt_chown): Bother to read NFS error/success
+	value. 
+
+Thu Aug 15 15:24:29 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* ops.c (verify_nonexistent): Don't need to lock DIR; it's already
+	locked.
+	(netfs_attempt_link): Lock DIR *before* calling verify_nonexistent.
+
+	* nfs.c (xdr_encode_fhandle) [protocol_version == 2]: Copy
+	fhandle->data, not fhandle itself.
+
+Wed Aug 14 12:33:37 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+  	* nfs.c (xdr_encode_fhandle): Second arg now a `struct fhandle *'.
+	Encode v3 fhandle if appropriate.
+	* cache.c: Include <netinet/in.h>.
+	(hash): New arg `length'.
+	(lookup_fhandle): Changed to be more like xdr_decode_* functions.
+	All callers changed.  Do the right thing for v3.
+	(recache_handle): Likewise.
+	* nfs.h (struct fhandle): New type.  
+	(struct netnode): Member `handle' is now a `struct fhandle'.  
+	(xdr_encode_fhandle): Second arg now a `struct fhandle *'.
+	(lookup_fhandle, recache_handle): Changed to be more like
+	xdr_decode_* functions. 
+
+	* rpcsvc/nfs_prot.h (enum sattr_time_how): New type.
+	* nfs.c (xdr_encode_64bit): New function.
+	(xdr_encode_sattr_mode, xdr_encode_sattr_ids,
+	xdr_encode_sattr_size, xdr_encode_sattr_times,
+	xdr_encode_create_state, xdr_encode_sattr_stat): Encode v3 sattr
+	if appropriate. 
+	(xdr_decode_fattr): Decode v3 fattr if appropriate.
+
+	* rpcsvc/nfs_prot.h (NFS_FHSIZE): Deleted macro.
+	(NFS2_FHSIZE, NFS3_FHSIZE, NFS3_COOKIEVERFSIZE, NFS3_CREATEVERFSIZE,
+	NFS3_WRITEVERFSIZE): New macros.
+	(enum ftype): Deleted NFFIFO.  Added NF2FIFO, NF3FIFO, and an
+	alias NF2BAD for NF3FIFO.
+	(NFSPROC_NULL, NFSPROC_GETATTR, NFSPROC_SETATTR,
+	NFSPROC_LOOKUP, NFSPROC_READLINK, NFSPROC_READ,
+	NFSPROC_WRITE, NFSPROC_CREATE, NFSPROC_REMOVE,
+	NFSPROC_RENAME, NFSPROC_LINK, NFSPROC_SYMLINK, NFSPROC_MKDIR,
+	NFSPROC_RMDIR, NFSPROC_READDIR): Replace with new
+	macros that take a version arg.  All users changed to use new
+	version arg. 
+	(NFS_PROTOCOL_FUNC): New macro.
+	(NFS2PROC_NULL, NFS2PROC_GETATTR, NFS2PROC_SETATTR, NFS2PROC_ROOT,
+	NFS2PROC_LOOKUP, NFS2PROC_READLINK, NFS2PROC_READ,
+	NFS2PROC_WRITECACHE, NFS2PROC_WRIT, NFS2PROC_CREATE,
+	NFS2PROC_REMOVE, NFS2PROC_RENAME, NFS2PROC_LINK, NFS2PROC_SYMLINK,
+	NFS2PROC_MKDIR, NFS2PROC_RMDIR, NFS2PROC_READDIR, NFS2PROC_STATFS,
+	NFS3PROC_NULL, NFS3PROC_GETATTR, NFS3PROC_SETATTR,
+	NFS3PROC_LOOKUP, NFS3PROC_ACCESS, NFS3PROC_READLINK,
+	NFS3PROC_READ, NFS3PROC_WRITE, NFS3PROC_CREATE, NFS3PROC_MKDIR,
+	NFS3PROC_SYMLINK, NFS3PROC_MKNOD, NFS3PROC_REMOVE, NFS3PROC_RMDIR,
+	NFS3PROC_RENAME, NFS3PROC_LINK, NFS3PROC_READDIR,
+	NFS3PROC_READDIRPLUS, NFS3PROC_FSSTAT, NFS3PROC_FSINFO,
+	NFS3PROC_PATHCONF, NFS3PROC_COMMIT): New macros.  All callers
+	appropriately changed.
+	
+	* nfs.c (nfs_error_trans): NFS_SERVERFAULT maps to EIO;
+	NFSERR_BADTYPE maps to EOPNOTSUPP.
+
+	* rpcsvc/nfs_prot.h (nfsstat, ftype, struct nfs_fh, nfs_fh, struct
+	nfstime, nfstime, struct fattr, fattr, struct sattr, sattr,
+	filename, nfspath, struct attrstat, attrstat, struct sattrargs,
+	sattrargs, struct diropargs, diropargs, struct diropokres,
+	diropokres, struct diropres, diropres, struct readlinkres,
+	readlinkres, struct readargs, readargs, struct readokres,
+	readokres, struct readres, readres, struct writeargs, writeargs,
+	struct createargs, createargs, struct renameargs, renameargs,
+	struct linkargs, linkargs, struct symlinkargs, symlinkargs,
+	nfscookie, struct readdirargs, readdirargs, struct entry, entry,
+	struct dirlist, dirlist, struct readdirres, readdirres, struct
+	statfsokres, statfsokres, struct statfsres, statfsres): Delete
+	unused types.
+	(xdr_nfsstat, xdr_ftype, xdr_nfs_fh, xdr_nfstime, xdr_fattr,
+	xdr_sattr, xdr_filename, xdr_nfspath, xdr_attrstat, xdr_sattrargs,
+	xdr_diropargs, xdr_diropokres, xdr_diropres, xdr_readlinkres,
+	xdr_readargs, xdr_readokres, xdr_readres, xdr_writeargs,
+	xdr_createargs, xdr_renameargs, xdr_linkargs, xdr_symlinkargs,
+	xdr_nfscookie, xdr_readdirargs, xdr_entry, xdr_dirlist,
+	xdr_readdirres, xdr_statfsokres, xdr_statfsres, nfsproc_null_2,
+	nfsproc_getattr_2, nfsproc_setattr_2, nfsproc_root_2,
+	nfsproc_lookup_2, nfsproc_readlink_2, rfsproc_read_2,
+	nfsproc_writecache_2, nfsproc_write_2, nfsproc_create_2,
+	nfsproc_remove_2, nfsproc_rename_2, nfsproc_link_2,
+	nfsproc_symlink_2, nfsproc_mkdir_2, nfsproc_rmdir_2,
+	nfsproc_readdir_2, nfsproc_statfs_2): Delete unused function
+	declarations. 
+
+Tue Aug 13 14:57:03 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* ops.c (netfs_attempt_create_file): Sun's NFS client does not
+ 	expect NFSPROC_CREATE to be exclusive.  Accordingly, on most
+ 	servers (including ours) it isn't exclusive.  (Which, of course,
+ 	contradicts Sun's own RGC 1094, section 2.2.10.)  Which means we
+ 	have to insert our own test here to make sure the file doesn't
+	exist before attempting NFSPROC_CREATE.
+	(netfs_attempt_link): Likewise.
+	(verify_nonexistent): New function.
+
+Mon Aug 12 11:13:58 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* nfs.c (nfs_error_trans): Repair syntax.
+
+Thu Aug  8 18:48:22 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* nfs.h (protocol_version): New variable.
+	* mount.c (protocol_version): Define and initialize to `2'.
+
+	* rpcsvc/nfs_prot.h (enum nfsstat): Added new nfsv3 error codes:
+	NFSERR_XDEV, NFSERR_INVAL, NFSERR_MLINK, NFSERR_REMOTE,
+	NFSERR_BADHANDLE, NFSERR_NOT_SYNC, NFSERR_BAD_COOKIE,
+	NFSERR_NOTSUPP, NFSERR_TOOSMALL, NFSERR_SERVERFAULT,
+	NFSERR_BADTYPE, NFSERR_JUKEBOX.
+	(NFSERR_TRYLATER): New macro.
+	* nfs.c (nfs_error_trans): Understand v3 error codes if we are
+	runnnig v3.
+
 Wed Jul 31 13:25:00 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* ops.c (netfs_attempt_statfs): Use NFSPROC_STATFS, not SETATTR to
diff -ru hurd-0.0/nfs/Makefile hurd-0.1/nfs/Makefile
--- hurd-0.0/nfs/Makefile	Thu Jun 13 09:38:58 1996
+++ hurd-0.1/nfs/Makefile	Tue Sep  3 14:15:16 1996
@@ -22,10 +22,12 @@
 makemode := server
 
 target = nfs
-LCLHDRS = nfs.h 
+LCLHDRS = nfs.h mount.h nfs-spec.h
 SRCS = ops.c rpc.c mount.c cred.c nfs.c cache.c consts.c main.c 
 OBJS = $(subst .c,.o,$(SRCS))
 
 nfs: $(OBJS) ../libports/libports.a ../libnetfs/libnetfs.a ../libfshelp/libfshelp.a ../libthreads/libthreads.a
 
 include ../Makeconf
+
+
diff -ru hurd-0.0/nfs/cache.c hurd-0.1/nfs/cache.c
--- hurd-0.0/nfs/cache.c	Tue Mar 19 12:56:54 1996
+++ hurd-0.1/nfs/cache.c	Wed Aug 14 15:33:08 1996
@@ -21,49 +21,62 @@
 #include "nfs.h"
 
 #include <string.h>
+#include <netinet/in.h>
 
 /* Hash table containing all the nodes currently active. */
 #define CACHESIZE 512
 static struct node *nodehash [CACHESIZE];
 
-/* Compute and return a hash key for NFS file handle FHANDLE. */
+/* Compute and return a hash key for NFS file handle DATA of LEN bytes. */
 static inline int
-hash (void *fhandle)
+hash (int *data, size_t len)
 {
   unsigned int h = 0;
+  char *cp = (char *)data;
   int i;
   
-  for (i = 0; i < NFS_FHSIZE; i++)
-    h += ((char *)fhandle)[i];
+  for (i = 0; i < len; i++)
+    h += cp[i];
   
   return h % CACHESIZE;
 }
 
-/* Lookup the specified file handle FHANDLE in the hash table.  If it
+/* Lookup the file handle in RPC result at P in the hash table.  If it
    is not present, initialize a new node structure and insert it into
    the hash table.  Whichever course, a new reference is generated and
-   the node is returned. */
-struct node *
-lookup_fhandle (void *fhandle)
+   the node is returned in *NPP.  Return the address in the RPC result
+   after the file handle.  */
+int *
+lookup_fhandle (int *p, struct node **npp)
 {
   struct node *np;
   struct netnode *nn;
-  int h = hash (fhandle);
+  size_t len;
+  int h;
+
+  if (protocol_version == 2)
+    len = NFS2_FHSIZE;
+  else
+    len = ntohl (*p++);
+  h = hash (p, len);
 
   spin_lock (&netfs_node_refcnt_lock);
   for (np = nodehash[h]; np; np = np->nn->hnext)
     {
-      if (bcmp (np->nn->handle, fhandle, NFS_FHSIZE) != 0)
+      if (np->nn->handle.size != len
+	  || bcmp (np->nn->handle.data, p, len) != 0)
 	continue;
       
       np->references++;
       spin_unlock (&netfs_node_refcnt_lock);
       mutex_lock (&np->lock);
-      return np;
+      *npp = np;
+      return p + len / sizeof (int);
     }
   
   nn = malloc (sizeof (struct netnode));
-  bcopy (fhandle, nn->handle, NFS_FHSIZE);
+  nn->handle.size = len;
+  bcopy (p, nn->handle.data, len);
   nn->stat_updated = 0;
   nn->dtrans = NOT_POSSIBLE;
   nn->dead_dir = 0;
@@ -79,7 +92,8 @@
 
   spin_unlock (&netfs_node_refcnt_lock);
   
-  return np;
+  *npp = np;
+  return p + len / sizeof (int);
 }
 
 /* Called by libnetfs when node NP has no more references.  (See
@@ -123,27 +137,36 @@
     }
 }
 
-/* Change the file handle used for node NP to be HANDLE.  Make sure the
-   hash table stays up to date. */
-void
-recache_handle (struct node *np, void *handle)
+/* Change the file handle used for node NP to be the handle at P.
+   Make sure the hash table stays up to date.  Return the address
+   after the hnadle. */
+int *
+recache_handle (int *p, struct node *np)
 {
   int h;
+  size_t len;
+
+  if (protocol_version == 2)
+    len = NFS2_FHSIZE;
+  else
+    len = ntohl (*p++);
   
   spin_lock (&netfs_node_refcnt_lock);
   *np->nn->hprevp = np->nn->hnext;
   if (np->nn->hnext)
     np->nn->hnext->nn->hprevp = np->nn->hprevp;
+
+  np->nn->handle.size = len;
+  bcopy (p, np->nn->handle.data, len);
   
-  bcopy (handle, np->nn->handle, NFS_FHSIZE);
-  
-  h = hash (handle);
+  h = hash (p, len);
   np->nn->hnext = nodehash[h];
   if (np->nn->hnext)
     np->nn->hnext->nn->hprevp = &np->nn->hnext;
   np->nn->hprevp = &nodehash[h];
   
   spin_unlock (&netfs_node_refcnt_lock);
+  return p + len / sizeof (int);
 }
 
 
diff -ru hurd-0.0/nfs/mount.c hurd-0.1/nfs/mount.c
--- hurd-0.0/nfs/mount.c	Tue Mar 19 13:12:43 1996
+++ hurd-0.1/nfs/mount.c	Tue Sep  3 14:03:55 1996
@@ -20,7 +20,6 @@
 
 #include "nfs.h"
 
-#include <rpcsvc/mount.h>
 #include <rpc/pmap_prot.h>
 #include <errno.h>
 #include <sys/socket.h>
@@ -29,6 +28,8 @@
 #include <netinet/in.h>
 #include <stdio.h>
 
+#include "mount.h"
+
 /* Service name for portmapper */
 char *pmap_service_name = "sunrpc";
 
@@ -59,6 +60,8 @@
 /* True iff NFS_PORT should be used even if portmapper present. */
 int nfs_port_override = 0;
 
+int protocol_version = 2;
+
 /* Set up an RPC for procedure PROCNUM for talking to the portmapper.
    Allocate storage with malloc and point *BUF at it; caller must free
    this when done.  Return the address where the args for the
@@ -174,8 +177,7 @@
     }
   
   /* Create the node for root */
-  np = lookup_fhandle (p);
-  p += NFS_FHSIZE / sizeof (int);
+  lookup_fhandle (p, &np);
   free (rpcbuf);
   mutex_unlock (&np->lock);
 
Only in hurd-0.1/nfs: mount.h
Only in hurd-0.1/nfs: nfs-spec.h
diff -ru hurd-0.0/nfs/nfs.c hurd-0.1/nfs/nfs.c
--- hurd-0.0/nfs/nfs.c	Mon Jul 29 12:35:00 1996
+++ hurd-0.1/nfs/nfs.c	Thu Aug 29 18:36:01 1996
@@ -45,9 +45,6 @@
       break;
 
     case NFREG:
-    case NFNON:
-    case NFBAD:
-    default:
       hurdmode = S_IFREG;
       break;
       
@@ -59,8 +56,31 @@
       hurdmode = S_IFSOCK;
       break;
 
-    case NFFIFO:
-      hurdmode = S_IFIFO;
+    default:
+      if (protocol_version == 2)
+	switch (type)
+	  {
+	  case NF2NON:
+	  case NF2BAD:
+	  default:
+	    hurdmode = S_IFREG;
+	    break;
+	    
+	  case NF2FIFO:
+	    hurdmode = S_IFIFO;
+	    break;
+	  }
+      else
+	switch (type)
+	  {
+	  case NF3FIFO:
+	    hurdmode = S_IFIFO;
+	    break;
+	    
+	  default:
+	    hurdmode = S_IFREG;
+	    break;
+	  }
       break;
     }
   
@@ -77,6 +97,37 @@
   return mode & 07777;
 }
 
+/* Convert a Hurd mode to an NFS type */
+int 
+hurd_mode_to_nfs_type (mode_t mode)
+{
+  switch (mode & S_IFMT)
+    {
+    case S_IFDIR:
+      return NFDIR;
+      
+    case S_IFCHR:
+    default:
+      return NFCHR;
+
+    case S_IFBLK:
+      return NFBLK;
+      
+    case S_IFREG:
+      return NFREG;
+
+    case S_IFLNK:
+      return NFLNK;
+      
+    case S_IFSOCK:
+      return NFSOCK;
+      
+    case S_IFIFO:
+      return protocol_version == 2 ? NF2FIFO : NF3FIFO;
+    }
+}
+
+
 
 /* Each of the functions on this page copies its second arg to *P,
    converting it to XDR representation along the way.  They then
@@ -84,10 +135,15 @@
 
 /* Encode an NFS file handle. */
 int *
-xdr_encode_fhandle (int *p, void *fhandle)
+xdr_encode_fhandle (int *p, struct fhandle *fhandle)
 {
-  bcopy (fhandle, p, NFS_FHSIZE);
-  return p + INTSIZE (NFS_FHSIZE);
+  if (protocol_version == 2)
+    {
+      bcopy (fhandle->data, p, NFS2_FHSIZE);
+      return p + INTSIZE (NFS2_FHSIZE);
+    }
+  else
+    return xdr_encode_data (p, fhandle->data, fhandle->size);
 }
 
 /* Encode uninterpreted bytes. */
@@ -102,6 +158,15 @@
   return p + nints;
 }
 
+/* Encode a 64 bit integer */
+int *
+xdr_encode_64bit (int *p, long long n)
+{
+  *p++ = htonl (n & 0xffffffff00000000LL >> 32);
+  *p++ = htonl (n & 0xffffffff);
+  return p;
+}
+
 /* Encode a C string. */
 int *
 xdr_encode_string (int *p, char *string)
@@ -113,14 +178,27 @@
 int *
 xdr_encode_sattr_mode (int *p, mode_t mode)
 {
-  *p++ = htonl (hurd_mode_to_nfs_mode (mode));
-  *p++ = -1;			/* uid */
-  *p++ = -1;			/* gid */
-  *p++ = -1;			/* size */
-  *p++ = -1;			/* atime secs */
-  *p++ = -1;			/* atime usecs */
-  *p++ = -1;			/* mtime secs */
-  *p++ = -1;			/* mtime usecs */
+  if (protocol_version == 2)
+    {
+      *p++ = htonl (hurd_mode_to_nfs_mode (mode));
+      *p++ = -1;			/* uid */
+      *p++ = -1;			/* gid */
+      *p++ = -1;			/* size */
+      *p++ = -1;			/* atime secs */
+      *p++ = -1;			/* atime usecs */
+      *p++ = -1;			/* mtime secs */
+      *p++ = -1;			/* mtime usecs */
+    }
+  else
+    {
+      *p++ = htonl (1);		/* set mode */
+      *p++ = htonl (hurd_mode_to_nfs_mode (mode));
+      *p++ = 0;			/* no uid */
+      *p++ = 0;			/* no gid */
+      *p++ = 0;			/* no size */
+      *p++ = DONT_CHANGE;	/* no atime */
+      *p++ = DONT_CHANGE;	/* no mtime */
+    }
   return p;
 }
 
@@ -128,14 +206,28 @@
 int *
 xdr_encode_sattr_ids (int *p, u_int uid, u_int gid)
 {
-  *p++ = -1;			/* mode */
-  *p++ = htonl (uid);
-  *p++ = htonl (gid);
-  *p++ = -1;			/* size */
-  *p++ = -1;			/* atime secs */
-  *p++ = -1;			/* atime usecs */
-  *p++ = -1;			/* mtime secs */
-  *p++ = -1;			/* mtime usecs */
+  if (protocol_version == 2)
+    {
+      *p++ = -1;			/* mode */
+      *p++ = htonl (uid);
+      *p++ = htonl (gid);
+      *p++ = -1;			/* size */
+      *p++ = -1;			/* atime secs */
+      *p++ = -1;			/* atime usecs */
+      *p++ = -1;			/* mtime secs */
+      *p++ = -1;			/* mtime usecs */
+    }
+  else
+    {
+      *p++ = 0;			/* no mode */
+      *p++ = htonl (1);		/* set uid */
+      *p++ = htonl (uid);
+      *p++ = htonl (1);		/* set gid */
+      *p++ = htonl (gid);
+      *p++ = 0;			/* no size */
+      *p++ = DONT_CHANGE;	/* no atime */
+      *p++ = DONT_CHANGE;	/* no mtime */
+    }
   return p;
 }
 
@@ -143,14 +235,27 @@
 int *
 xdr_encode_sattr_size (int *p, off_t size)
 {
-  *p++ = -1;			/* mode */
-  *p++ = -1;			/* uid */
-  *p++ = -1;			/* gid */
-  *p++ = htonl (size);
-  *p++ = -1;			/* atime secs */
-  *p++ = -1;			/* atime usecs */
-  *p++ = -1;			/* mtime secs */
-  *p++ = -1;			/* mtime secs */
+  if (protocol_version == 2)
+    {
+      *p++ = -1;			/* mode */
+      *p++ = -1;			/* uid */
+      *p++ = -1;			/* gid */
+      *p++ = htonl (size);
+      *p++ = -1;			/* atime secs */
+      *p++ = -1;			/* atime usecs */
+      *p++ = -1;			/* mtime secs */
+      *p++ = -1;			/* mtime secs */
+    }
+  else
+    {
+      *p++ = 0;			/* no mode */
+      *p++ = 0;			/* no uid */
+      *p++ = 0;			/* no gid */
+      *p++ = htonl (1);		/* size */
+      p = xdr_encode_64bit (p, size);
+      *p++ = DONT_CHANGE;	/* no atime */
+      *p++ = DONT_CHANGE;	/* no mtime */
+    }
   return p;
 }
 
@@ -158,14 +263,30 @@
 int *
 xdr_encode_sattr_times (int *p, struct timespec *atime, struct timespec *mtime)
 {
-  *p++ = -1;			/* mode */
-  *p++ = -1;			/* uid */
-  *p++ = -1;			/* gid */
-  *p++ = -1;			/* size */
-  *p++ = htonl (atime->tv_sec);
-  *p++ = htonl (atime->tv_nsec * 1000);
-  *p++ = htonl (mtime->tv_sec);
-  *p++ = htonl (mtime->tv_nsec * 1000);
+  if (protocol_version == 2)
+    {
+      *p++ = -1;			/* mode */
+      *p++ = -1;			/* uid */
+      *p++ = -1;			/* gid */
+      *p++ = -1;			/* size */
+      *p++ = htonl (atime->tv_sec);
+      *p++ = htonl (atime->tv_nsec * 1000);
+      *p++ = htonl (mtime->tv_sec);
+      *p++ = htonl (mtime->tv_nsec * 1000);
+    }
+  else
+    {
+      *p++ = 0;			/* no mode */
+      *p++ = 0;			/* no uid */
+      *p++ = 0;			/* no gid */
+      *p++ = 0;			/* no size */
+      *p++ = htonl (SET_TO_CLIENT_TIME); /* atime */
+      *p++ = htonl (atime->tv_sec);
+      *p++ = htonl (atime->tv_nsec);
+      *p++ = htonl (SET_TO_CLIENT_TIME); /* mtime */
+      *p++ = htonl (mtime->tv_sec);
+      *p++ = htonl (mtime->tv_nsec);
+    }
   return p;
 }
 
@@ -174,14 +295,28 @@
 xdr_encode_create_state (int *p, 
 			 mode_t mode)
 {
-  *p++ = htonl (hurd_mode_to_nfs_mode (mode));
-  *p++ = -1;			/* uid */
-  *p++ = -1;			/* gid */
-  *p++ = 0;			/* size */
-  *p++ = -1;			/* atime sec */
-  *p++ = -1;			/* atime usec */
-  *p++ = -1;			/* mtime sec */
-  *p++ = -1;			/* mtime usec */
+  if (protocol_version == 2)
+    {
+      *p++ = htonl (hurd_mode_to_nfs_mode (mode));
+      *p++ = -1;		/* uid */
+      *p++ = -1;		/* gid */
+      *p++ = 0;			/* size */
+      *p++ = -1;		/* atime sec */
+      *p++ = -1;		/* atime usec */
+      *p++ = -1;		/* mtime sec */
+      *p++ = -1;		/* mtime usec */
+    }
+  else
+    {
+      *p++ = htonl (1);		/* mode */
+      *p++ = htonl (hurd_mode_to_nfs_mode (mode));
+      *p++ = 0;			/* no uid */
+      *p++ = 0;			/* no gid */
+      *p++ = htonl (1);		/* set size */
+      p = xdr_encode_64bit (p, 0);
+      *p++ = htonl (SET_TO_SERVER_TIME); /* atime */
+      *p++ = htonl (SET_TO_SERVER_TIME); /* mtime */
+    }
   return p;
 }
 
@@ -190,18 +325,49 @@
 xdr_encode_sattr_stat (int *p,
 		       struct stat *st)
 {
-  *p++ = htonl (st->st_mode);
-  *p++ = htonl (st->st_uid);
-  *p++ = htonl (st->st_gid);
-  *p++ = htonl (st->st_size);
-  *p++ = htonl (st->st_atime);
-  *p++ = htonl (st->st_atime_usec);
-  *p++ = htonl (st->st_mtime);
-  *p++ = htonl (st->st_mtime_usec);
+  if (protocol_version == 2)
+    {
+      *p++ = htonl (hurd_mode_to_nfs_mode (st->st_mode));
+      *p++ = htonl (st->st_uid);
+      *p++ = htonl (st->st_gid);
+      *p++ = htonl (st->st_size);
+      *p++ = htonl (st->st_atime);
+      *p++ = htonl (st->st_atime_usec);
+      *p++ = htonl (st->st_mtime);
+      *p++ = htonl (st->st_mtime_usec);
+    }
+  else
+    {
+      *p++ = htonl (1);		/* set mode */
+      *p++ = htonl (hurd_mode_to_nfs_mode (st->st_mode));
+      *p++ = htonl (1);		/* set uid */
+      *p++ = htonl (st->st_uid);
+      *p++ = htonl (1);		/* set gid */
+      *p++ = htonl (st->st_gid);
+      *p++ = htonl (1);		/* set size */
+      p = xdr_encode_64bit (p, st->st_size);
+      *p++ = htonl (SET_TO_CLIENT_TIME); /* set atime */
+      *p++ = htonl (st->st_atime);
+      *p++ = htonl (st->st_atime_usec * 1000);
+      *p++ = htonl (SET_TO_CLIENT_TIME); /* set mtime */
+      *p++ = htonl (st->st_mtime);
+      *p++ = htonl (st->st_mtime_usec * 1000);
+    }
   return p;
 }
 
 
+/* Decode *P into a long long; return the address of the following data. */
+int *
+xdr_decode_64bit (int *p, long long *n)
+{
+  long long high, low;
+  high = ntohl (*p++);
+  low = ntohl (*p++);
+  *n = ((high & 0xffffffff) << 32) | (low & 0xffffffff);
+  return p;
+}
+
 /* Decode *P into a stat structure; return the address of the
    following data. */
 int *
@@ -215,10 +381,28 @@
   st->st_nlink = ntohl (*p++);
   st->st_uid = ntohl (*p++);
   st->st_gid = ntohl (*p++);
-  st->st_size = ntohl (*p++);
-  st->st_blksize = ntohl (*p++);
-  st->st_rdev = ntohl (*p++);
-  st->st_blocks = ntohl (*p++);
+  if (protocol_version == 2)
+    {
+      st->st_size = ntohl (*p++);
+      st->st_blksize = ntohl (*p++);
+      st->st_rdev = ntohl (*p++);
+      st->st_blocks = ntohl (*p++);
+    }
+  else
+    {
+      long long size;
+      int major, minor;
+      p = xdr_decode_64bit (p, &size);
+      st->st_size = size;
+      p = xdr_decode_64bit (p, &size);
+      st->st_blocks = size / 512;
+      st->st_blksize = read_size < write_size ? read_size : write_size;
+      major = ntohl (*p++);
+      minor = ntohl (*p++);
+/* XXX - Temporary */
+#define makedev(maj,min) ((((maj)&0xFF)<<8)+((min)&0xFF))
+      st->st_rdev = makedev (major, minor);
+    }
   st->st_fsid = ntohl (*p++);
   st->st_ino = ntohl (*p++);
   st->st_atime = ntohl (*p++);
@@ -228,6 +412,13 @@
   st->st_ctime = ntohl (*p++);
   st->st_ctime_usec = ntohl (*p++);
 
+  if (protocol_version == 3)
+    {
+      st->st_atime_usec /= 1000;
+      st->st_mtime_usec /= 1000;
+      st->st_ctime_usec /= 1000;
+    }
+
   return p;
 
 }
@@ -401,8 +592,41 @@
       return ESTALE;
 		  
     case NFSERR_WFLUSH:
-    default:
+      /* Not known in v3, but we just give EINVAL for unknown errors
+	 so it's the same. */
       return EINVAL;
+
+    default:
+      if (protocol_version == 2)
+	return EINVAL;
+      else
+	switch (error)
+	  {
+	  case NFSERR_XDEV:
+	    return EXDEV;
+	    
+	  case NFSERR_INVAL:
+	  case NFSERR_REMOTE:	/* not sure about this one */
+	  default:
+	    return EINVAL;
+	    
+	  case NFSERR_MLINK:
+	    return EMLINK;
+	    
+	  case NFSERR_NOTSUPP:
+	  case NFSERR_BADTYPE:
+	    return EOPNOTSUPP;
+
+	  case NFSERR_SERVERFAULT:
+	    return EIO;
+
+	  case NFSERR_BADHANDLE:
+	  case NFSERR_NOT_SYNC:
+	  case NFSERR_BAD_COOKIE:
+	  case NFSERR_TOOSMALL:
+	  case NFSERR_JUKEBOX:	/* ??? */
+	    /* These indicate bugs in the client, so EGRATUITOUS is right. */
+	    return EGRATUITOUS;
+	  }
     }
 }
-
diff -ru hurd-0.0/nfs/nfs.h hurd-0.1/nfs/nfs.h
--- hurd-0.0/nfs/nfs.h	Thu Jun 13 09:26:31 1996
+++ hurd-0.1/nfs/nfs.h	Tue Sep  3 14:10:04 1996
@@ -21,14 +21,23 @@
 
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <rpcsvc/nfs_prot.h>
+#include "nfs-spec.h"
 #include <hurd/netfs.h>
 
+/* A file handle */
+struct fhandle
+{
+  size_t size;
+
+  /* Leave enough room for the biggest possible fhandle. */
+  char data[NFS3_FHSIZE];
+};
+
 /* One of these exists for private data needed by the client for each
    node. */
 struct netnode 
 {
-  char handle[NFS_FHSIZE];
+  struct fhandle handle;
   time_t stat_updated;
   struct node *hnext, **hprevp;
 
@@ -142,6 +151,9 @@
    portmapper. */
 extern int nfs_port_override;
 
+/* Which NFS protocol version we are using */
+extern int protocol_version;
+
 
 /* Count how many four-byte chunks it takss to hold LEN bytes. */
 #define INTSIZE(len) (((len)+3)>>2)
@@ -152,7 +164,8 @@
 int cred_has_gid (struct netcred *, gid_t);
 
 /* nfs.c */
-int *xdr_encode_fhandle (int *, void *);
+int hurd_mode_to_nfs_type (mode_t);
+int *xdr_encode_fhandle (int *, struct fhandle *);
 int *xdr_encode_data (int *, char *, size_t);
 int *xdr_encode_string (int *, char *);
 int *xdr_encode_sattr_mode (int *, mode_t);
@@ -180,5 +193,5 @@
 void rpc_receive_thread (void);
 
 /* cache.c */
-struct node *lookup_fhandle (void *);
-void recache_handle (struct node *, void *);
+int *lookup_fhandle (int *, struct node **);
+int *recache_handle (int *, struct node *);
diff -ru hurd-0.0/nfs/ops.c hurd-0.1/nfs/ops.c
--- hurd-0.0/nfs/ops.c	Wed Jul 31 13:24:43 1996
+++ hurd-0.1/nfs/ops.c	Thu Aug 29 18:31:59 1996
@@ -74,6 +74,61 @@
   return ret;
 }
 
+/* Handle returned wcc information for various calls.  In protocol
+   version 2, this is just register_fresh_stat.  In version 3, it
+   checks to see if stat information is present too.  If this follows
+   an operation that we expect has modified the attributes, MOD should
+   be set.  (This unpacks the post_op_attr XDR type.)  */
+int *
+process_returned_stat (struct node *np, int *p, int mod)
+{
+  int attrs_exist;
+
+  if (protocol_version == 2)
+    return register_fresh_stat (np, p);
+  else
+    {
+      attrs_exist = ntohl (*p++);
+      if (attrs_exist)
+	p = register_fresh_stat (np, p);
+      else if (mod)
+	/* We know that our values are now wrong */
+	np->nn->stat_updated = 0;
+      return p;
+    }
+}
+
+
+/* Handle returned wcc information for various calls.  In protocol
+   version 2, this is just register_fresh_stat.  In version 3, it does
+   the wcc_data interpretation too.  If this follows an operation that
+   we expect has modified the attributes, MOD should be set. 
+   (This unpacks the wcc_data XDR type.) */
+int *
+process_wcc_stat (struct node *np, int *p, int mod)
+{
+  if (protocol_version == 2)
+    return register_fresh_stat (np, p);
+  else
+    {
+      int attrs_exist;
+
+      /* First the pre_op_attr */
+      attrs_exist = ntohl (*p++);
+      if (attrs_exist)
+	{
+	  /* Just skip them for now */
+	  p += 2 * sizeof (int); /* size */
+	  p += 2 * sizeof (int); /* mtime */
+	  p += 2 * sizeof (int); /* atime */
+	}
+      
+      /* Now the post_op_attr */
+      return process_returned_stat (np, p, mod);
+    }
+}
+
+
 /* Implement the netfs_validate_stat callback as described in
    <hurd/netfs.h>. */
 error_t
@@ -86,8 +141,8 @@
   if (mapped_time->seconds - np->nn->stat_updated < stat_timeout)
     return 0;
 
-  p = nfs_initialize_rpc (NFSPROC_GETATTR, (struct netcred *) -1,
-			  0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_GETATTR (protocol_version),
+			  (struct netcred *) -1, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   
   err = conduct_rpc (&rpcbuf, &p);
@@ -112,14 +167,20 @@
   void *rpcbuf;
   error_t err;
     
-  p = nfs_initialize_rpc (NFSPROC_SETATTR, cred, 0, &rpcbuf, np, gid);
+  p = nfs_initialize_rpc (NFSPROC_SETATTR (protocol_version),
+			  cred, 0, &rpcbuf, np, gid);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_sattr_ids (p, uid, gid);
+  if (protocol_version == 3)
+    *p++ = 0;			/* guard_check == 0 */
   
   err = conduct_rpc (&rpcbuf, &p);
-
   if (!err)
-    register_fresh_stat (np, p);
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (!err || protocol_version == 3)
+	p = process_wcc_stat (np, p, !err);
+    }
 
   free (rpcbuf);
   
@@ -180,17 +241,21 @@
 	}
     }
 
-  p = nfs_initialize_rpc (NFSPROC_SETATTR, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_SETATTR (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_sattr_mode (p, mode);
+  if (protocol_version == 3)
+    *p++ = 0;			/* guard check == 0 */
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (!err || protocol_version == 3)
+	p = process_wcc_stat (np, p, !err);
+    }
   
-  if (!err)
-    register_fresh_stat (np, p);
-
   free (rpcbuf);
   return err;
 }
@@ -214,16 +279,20 @@
   void *rpcbuf;
   error_t err;
     
-  p = nfs_initialize_rpc (NFSPROC_SETATTR, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_SETATTR (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_sattr_times (p, atime, mtime);
+  if (protocol_version == 3)
+    *p++ = 0;			/* guard check == 0 */
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
-  
-  if (!err)
-    register_fresh_stat (np, p);
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (!err || protocol_version == 3)
+	p = process_wcc_stat (np, p, !err);
+    }
 
   free (rpcbuf);
   return err;
@@ -239,17 +308,21 @@
   void *rpcbuf;
   error_t err;
   
-  p = nfs_initialize_rpc (NFSPROC_SETATTR, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_SETATTR (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_sattr_size (p, size);
+  if (protocol_version == 3)
+    *p++ = 0;			/* guard_check == 0 */
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (!err || protocol_version == 3)
+	p = process_wcc_stat (np, p, !err);
+    }
   
-  if (!err)
-    register_fresh_stat (np, p);
-
   free (rpcbuf);
   return err;
 }
@@ -264,7 +337,7 @@
   void *rpcbuf;
   error_t err;
     
-  p = nfs_initialize_rpc (NFSPROC_STATFS, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFS2PROC_STATFS, cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   
   err = conduct_rpc (&rpcbuf, &p);
@@ -320,6 +393,7 @@
   size_t trans_len;
   error_t err;
   size_t amt, thisamt;
+  int eof;
   
   for (amt = *len; amt;)
     {
@@ -327,40 +401,49 @@
       if (thisamt > read_size)
 	thisamt = read_size;
 
-      p = nfs_initialize_rpc (NFSPROC_READ, cred, 0, &rpcbuf, np, -1);
+      p = nfs_initialize_rpc (NFSPROC_READ (protocol_version),
+			      cred, 0, &rpcbuf, np, -1);
       p = xdr_encode_fhandle (p, &np->nn->handle);
       *p++ = htonl (offset);
       *p++ = htonl (thisamt);
-      *p++ = 0;
+      if (protocol_version == 2)
+	*p++ = 0;
   
       err = conduct_rpc (&rpcbuf, &p);
       if (!err)
-	err = nfs_error_trans (ntohl (*p++));
-  
-      if (err)
 	{
-	  free (rpcbuf);
-	  return err;
-	}
-      
-      p = register_fresh_stat (np, p);
-      
-      trans_len = ntohl (*p++);
-      if (trans_len > thisamt)
-	trans_len = thisamt;	/* ??? */
+	  err = nfs_error_trans (ntohl (*p++));
+
+	  if (!err || protocol_version == 3)
+	    p = process_returned_stat (np, p, !err);
+
+	  if (err)
+	    {
+	      free (rpcbuf);
+	      return err;
+	    }
       
-      bcopy (p, data, trans_len);
-      free (rpcbuf);
+	  trans_len = ntohl (*p++);
+	  if (trans_len > thisamt)
+	    trans_len = thisamt;	/* ??? */
 
-      data += trans_len;
-      offset += trans_len;
-      amt -= trans_len;
+	  if (protocol_version == 3)
+	    eof = ntohl (*p++);
+	  else
+	    eof = (trans_len < thisamt);
+	  
+	  bcopy (p, data, trans_len);
+	  free (rpcbuf);
+
+	  data += trans_len;
+	  offset += trans_len;
+	  amt -= trans_len;
       
-      /* If we got a short count, that means we're all done */
-      if (trans_len < thisamt)
-	{
-	  *len -= amt;
-	  return 0;
+	  if (eof)
+	    {
+	      *len -= amt;
+	      return 0;
+	    }
 	}
     }
   return 0;
@@ -376,6 +459,7 @@
   void *rpcbuf;
   error_t err;
   size_t amt, thisamt;
+  size_t count;
   
   for (amt = *len; amt;)
     {
@@ -383,32 +467,80 @@
       if (thisamt > write_size)
 	thisamt = write_size;
       
-      p = nfs_initialize_rpc (NFSPROC_WRITE, cred, thisamt, &rpcbuf, np, -1);
+      p = nfs_initialize_rpc (NFSPROC_WRITE (protocol_version),
+			      cred, thisamt, &rpcbuf, np, -1);
       p = xdr_encode_fhandle (p, &np->nn->handle);
-      *p++ = 0;
+      if (protocol_version == 2)
+	*p++ = 0;
       *p++ = htonl (offset);
-      *p++ = 0;
+      if (protocol_version == 2)
+	*p++ = 0;
+      if (protocol_version == 3)
+	*p++ = htonl (FILE_SYNC);
       p = xdr_encode_data (p, data, thisamt);
   
       err = conduct_rpc (&rpcbuf, &p);
       if (!err)
-	err = nfs_error_trans (ntohl (*p++));
-  
+	{
+	  err = nfs_error_trans (ntohl (*p++));
+	  if (!err || protocol_version == 3)
+	    p = process_wcc_stat (np, p, !err);
+	  if (!err)
+	    {
+	      if (protocol_version == 3)
+		{
+		  count = ntohl (*p++);
+		  p++;		/* ignore COMMITTED */
+		  /* ignore verf for now */
+		  p += NFS3_WRITEVERFSIZE / sizeof (int);		  
+		}
+	      else
+		/* assume it wrote the whole thing */
+		count = thisamt;
+	      
+	      free (rpcbuf);
+	      amt -= count;
+	      data += count;
+	      offset += count;
+	    }
+	}
+      
       if (err)
 	{
 	  *len = 0;
 	  free (rpcbuf);
 	  return err;
 	}
-      register_fresh_stat (np, p);
-      free (rpcbuf);
-      amt -= thisamt;
-      data += thisamt;
-      offset += thisamt;
     }
   return 0;
 }
 
+/* See if NAME exists in DIR for CRED.  If so, return EEXIST.  */
+error_t
+verify_nonexistent (struct netcred *cred, struct node *dir,
+		    char *name)
+{
+  int *p;
+  void *rpcbuf;
+  error_t err;
+  
+  assert (protocol_version == 2);
+
+  p = nfs_initialize_rpc (NFSPROC_LOOKUP (protocol_version),
+			  cred, 0, &rpcbuf, dir, -1);
+  p = xdr_encode_fhandle (p, &dir->nn->handle);
+  p = xdr_encode_string (p, name);
+
+  err = conduct_rpc (&rpcbuf, &p);
+  if (!err)
+    err = nfs_error_trans (ntohl (*p++));
+  
+  if (!err)
+    return EEXIST;
+  else
+    return 0;
+}
+
 /* Implement the netfs_attempt_lookup callback as described in
    <hurd/netfs.h>. */
 error_t
@@ -419,7 +551,8 @@
   void *rpcbuf;
   error_t err;
   
-  p = nfs_initialize_rpc (NFSPROC_LOOKUP, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_LOOKUP (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_string (p, name);
   
@@ -427,13 +560,25 @@
 
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
-  
-  if (!err)
     {
-      *newnp = lookup_fhandle (p);
-      p += NFS_FHSIZE / sizeof (int);
-      register_fresh_stat (*newnp, p);
+      err = nfs_error_trans (ntohl (*p++));
+      if (!err)
+	{
+	  p = lookup_fhandle (p, newnp);
+	  p = process_returned_stat (*newnp, p, 1);
+	}
+      if (err)
+	*newnp = 0;
+      if (protocol_version == 3)
+	{
+	  if (*newnp)
+	    mutex_unlock (&(*newnp)->lock);
+	  mutex_lock (&np->lock);
+	  p = process_returned_stat (np, p, 0);
+	  mutex_unlock (&np->lock);
+	  if (*newnp)
+	    mutex_lock (&(*newnp)->lock);
+	}
     }
   else
     *newnp = 0;
@@ -453,7 +598,8 @@
   void *rpcbuf;
   error_t err;
   
-  p = nfs_initialize_rpc (NFSPROC_MKDIR, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_MKDIR (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_string (p, name);
   p = xdr_encode_create_state (p, mode);
@@ -481,13 +627,18 @@
   
   /* Should we do the same sort of thing here as with attempt_unlink? */
 
-  p = nfs_initialize_rpc (NFSPROC_RMDIR, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_RMDIR (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_string (p, name);
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (protocol_version == 3)
+	p = process_wcc_stat (np, p, !err);
+    }
   
   free (rpcbuf);
   return err;
@@ -515,7 +666,8 @@
     case POSSIBLE:
     case NOT_POSSIBLE:
       mutex_lock (&dir->lock);
-      p = nfs_initialize_rpc (NFSPROC_LINK, cred, 0, &rpcbuf, dir, -1);
+      p = nfs_initialize_rpc (NFSPROC_LINK (protocol_version),
+			      cred, 0, &rpcbuf, dir, -1);
       mutex_unlock (&dir->lock);
       
       mutex_lock (&np->lock);
@@ -537,7 +689,8 @@
 
     case SYMLINK:
       mutex_lock (&dir->lock);
-      p = nfs_initialize_rpc (NFSPROC_SYMLINK, cred, 0, &rpcbuf, dir, -1);
+      p = nfs_initialize_rpc (NFSPROC_SYMLINK (protocol_version),
+			      cred, 0, &rpcbuf, dir, -1);
       p = xdr_encode_fhandle (p, &dir->nn->handle);
       mutex_unlock (&dir->lock);
       
@@ -552,78 +705,159 @@
 	  return err;
 	}
       
-      p = xdr_encode_string (p, np->nn->transarg.name);
-      p = xdr_encode_sattr_stat (p, &np->nn_stat);
+      if (protocol_version == 2)
+	{
+	  p = xdr_encode_string (p, np->nn->transarg.name);
+	  p = xdr_encode_sattr_stat (p, &np->nn_stat);
+	}
+      else
+	{
+	  p = xdr_encode_sattr_stat (p, &np->nn_stat);
+	  p = xdr_encode_string (p, np->nn->transarg.name);
+	}	  
       mutex_unlock (&np->lock);
 
       mutex_lock (&dir->lock);
       err = conduct_rpc (&rpcbuf, &p);
       if (!err)
-	err = nfs_error_trans (ntohl (*p++));
-      
-      if (!err)
 	{
-	  /* NFSPROC_SYMLINK stupidly does not pass back an
-	     fhandle, so we have to fetch one now. */
-	  p = nfs_initialize_rpc (NFSPROC_LOOKUP, cred, 0, &rpcbuf, dir, -1);
-	  p = xdr_encode_fhandle (p, &dir->nn->handle);
-	  p = xdr_encode_string (p, name);
-	  
-	  err = conduct_rpc (&rpcbuf, &p);
-	  if (!err)
-	    err = nfs_error_trans (ntohl (*p++));
-
-	  mutex_unlock (&dir->lock);
+	  err = nfs_error_trans (ntohl (*p++));
+      
+	  if (protocol_version == 2 && !err)
+	    {
+	      free (rpcbuf);
 
-	  if (err)
-	    err = EGRATUITOUS;	/* damn */
-	  else
+	      /* NFSPROC_SYMLINK stupidly does not pass back an
+		 fhandle, so we have to fetch one now. */
+	      p = nfs_initialize_rpc (NFSPROC_LOOKUP (protocol_version),
+				      cred, 0, &rpcbuf, dir, -1);
+	      p = xdr_encode_fhandle (p, &dir->nn->handle);
+	      p = xdr_encode_string (p, name);
+	  
+	      mutex_unlock (&dir->lock);
+	  
+	      err = conduct_rpc (&rpcbuf, &p);
+	      if (!err)
+		err = nfs_error_trans (ntohl (*p++));
+	      if (!err)
+		{
+		  mutex_lock (&np->lock);
+		  p = recache_handle (p, np);
+		  p = process_returned_stat (np, p, 1);
+		  mutex_unlock (&np->lock);
+		}
+	      if (err)
+		err = EGRATUITOUS; /* damn */
+	    }
+	  else if (protocol_version == 3)
 	    {
-	      mutex_lock (&np->lock);
-	      recache_handle (np, p);
-	      p += NFS_FHSIZE / sizeof (int);
-	      register_fresh_stat (np, p);
-	      mutex_unlock (&np->lock);
+	      if (!err)
+		{
+		  mutex_unlock (&dir->lock);
+		  mutex_lock (&np->lock);
+		  p = recache_handle (p, np);
+		  p = process_returned_stat (np, p, 1);
+		  mutex_unlock (&np->lock);
+		  mutex_lock (&dir->lock);
+		}
+	      p = process_wcc_stat (dir, p, !err);
+	      mutex_unlock (&dir->lock);
 	    }
+	  else
+	    mutex_unlock (&dir->lock);
 	}
       else
 	mutex_unlock (&dir->lock);
+
+      free (rpcbuf);
       break;
       
     case CHRDEV:
     case BLKDEV:
     case FIFO:
     case SOCK:
-      mutex_lock (&dir->lock);
-      p = nfs_initialize_rpc (NFSPROC_CREATE, cred, 0, &rpcbuf, dir, -1);
-      p = xdr_encode_fhandle (p, &dir->nn->handle);
-      p = xdr_encode_string (p, name);
-      mutex_unlock (&dir->lock);
 
-      mutex_lock (&np->lock);
-      err = netfs_validate_stat (np, cred);
-      if (err)
+      if (protocol_version == 2)
 	{
+	  mutex_lock (&dir->lock);
+	  err = verify_nonexistent (cred, dir, name);
+	  if (err)
+	    return err;
+
+	  p = nfs_initialize_rpc (NFSPROC_CREATE (protocol_version),
+				  cred, 0, &rpcbuf, dir, -1);
+	  p = xdr_encode_fhandle (p, &dir->nn->handle);
+	  p = xdr_encode_string (p, name);
+	  mutex_unlock (&dir->lock);
+	  
+	  mutex_lock (&np->lock);
+	  err = netfs_validate_stat (np, cred);
+	  if (err)
+	    {
+	      mutex_unlock (&np->lock);
+	      free (rpcbuf);
+	      return err;
+	    }
+	  
+	  p = xdr_encode_sattr_stat (p, &np->nn_stat);
 	  mutex_unlock (&np->lock);
-	  free (rpcbuf);
-	  return err;
-	}
-      
-      p = xdr_encode_sattr_stat (p, &np->nn_stat);
-      mutex_unlock (&np->lock);
 
-      mutex_lock (&dir->lock);
-      err = conduct_rpc (&rpcbuf, &p);
-      if (!err)
-	err = nfs_error_trans (ntohl (*p++));
-      mutex_unlock (&dir->lock);
+	  mutex_lock (&dir->lock);
+	  err = conduct_rpc (&rpcbuf, &p);
+	  if (!err)
+	    err = nfs_error_trans (ntohl (*p++));
+	  mutex_unlock (&dir->lock);
       
-      mutex_lock (&np->lock);
-      recache_handle (np, p);
-      p += NFS_FHSIZE / sizeof (int);
-      register_fresh_stat (np, p);
-      mutex_unlock (&np->lock);
-
+	  mutex_lock (&np->lock);
+	  p = recache_handle (p, np);
+	  register_fresh_stat (np, p);
+	  mutex_unlock (&np->lock);
+	  free (rpcbuf);
+	}
+      else
+	{
+	  mutex_lock (&dir->lock);
+	  p = nfs_initialize_rpc (NFS3PROC_MKNOD, cred, 0, &rpcbuf, dir, -1);
+	  p = xdr_encode_fhandle (p, &dir->nn->handle);
+	  p = xdr_encode_string (p, name);
+	  mutex_unlock (&dir->lock);
+	  
+	  mutex_lock (&np->lock);
+	  err = netfs_validate_stat (np, cred);
+	  if (err)
+	    {
+	      mutex_unlock (&np->lock);
+	      free (rpcbuf);
+	      return err;
+	    }
+	  *p++ = htonl (hurd_mode_to_nfs_type (np->nn_stat.st_mode));
+	  p = xdr_encode_sattr_stat (p, &np->nn_stat);
+	  if (np->nn->dtrans == BLKDEV || np->nn->dtrans == CHRDEV)
+	    {
+#define major(D) (((D)>>8) & 0xff)
+#define minor(D) ((D) & 0xff)
+	      *p++ = htonl (major (np->nn_stat.st_rdev));
+	      *p++ = htonl (minor (np->nn_stat.st_rdev));
+	    }
+	  mutex_unlock (&np->lock);
+	  
+	  err = conduct_rpc (&rpcbuf, &p);
+	  if (!err)
+	    {
+	      err = nfs_error_trans (ntohl (*p++));
+	      if (!err)
+		{
+		  mutex_lock (&np->lock);
+		  p = recache_handle (p, np);
+		  p = process_returned_stat (np, p, 1);
+		  mutex_unlock (&np->lock);
+		}
+	      mutex_lock (&dir->lock);
+	      p = process_wcc_stat (dir, p, !err);
+	      mutex_unlock (&dir->lock);
+	    }
+	  free (rpcbuf);
+	}
       break;
     }
 
@@ -704,22 +938,57 @@
   void *rpcbuf;
   error_t err;
 
-  p = nfs_initialize_rpc (NFSPROC_CREATE, cred, 0, &rpcbuf, np, -1);
+  /* RFC 1094 says that create is always exclusive.  But Sun doesn't
+     actually *implement* the spec.  No, of course not.  So we have to do
+     it for them.  */
+  if (protocol_version == 2)
+    {
+      err = verify_nonexistent (cred, np, name);
+      if (err)
+	return err;
+    }
+
+  p = nfs_initialize_rpc (NFSPROC_CREATE (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   p = xdr_encode_string (p, name);
-  p = xdr_encode_create_state (p, mode);
+  if (protocol_version == 3)
+    {
+      /* We happen to know this is where the XID is. */
+      int verf = *(int *)rpcbuf;
+      
+      *p++ = ntohl (EXCLUSIVE);
+      /* 8 byte verf */
+      *p++ = ntohl (verf);
+      p++;
+    }
+  else
+    p = xdr_encode_create_state (p, mode);
   
   err = conduct_rpc (&rpcbuf, &p);
-  if (!err)
-    err = nfs_error_trans (ntohl (*p++));
 
   mutex_unlock (&np->lock);
 
   if (!err)
     {
-      *newnp = lookup_fhandle (p);
-      p += NFS_FHSIZE / sizeof (int);
-      register_fresh_stat (*newnp, p);
+      err = nfs_error_trans (ntohl (*p++));
+      if (!err)
+	{
+	  p = lookup_fhandle (p, newnp);
+	  p = process_returned_stat (*newnp, p, 1);
+	}
+      if (err)
+	*newnp = 0;
+      if (protocol_version == 3)
+	{
+	  if (*newnp)
+	    mutex_unlock (&(*newnp)->lock);
+	  mutex_lock (&np->lock);
+	  p = process_wcc_stat (np, p, 1);
+	  mutex_unlock (&np->lock);
+	  if (*newnp)
+	    mutex_lock (&(*newnp)->lock);
+	}
     }
   else
     *newnp = 0;
@@ -789,13 +1058,18 @@
   netfs_nput (np);
 
   mutex_lock (&dir->lock);
-  p = nfs_initialize_rpc (NFSPROC_REMOVE, cred, 0, &rpcbuf, dir, -1);
+  p = nfs_initialize_rpc (NFSPROC_REMOVE (protocol_version),
+			  cred, 0, &rpcbuf, dir, -1);
   p = xdr_encode_fhandle (p, &dir->nn->handle);
   p = xdr_encode_string (p, name);
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (protocol_version == 3)
+	p = process_wcc_stat (dir, p, !err);
+    }
   
   free (rpcbuf);
 
@@ -817,7 +1091,8 @@
     return EOPNOTSUPP;		/* XXX */
 
   mutex_lock (&fromdir->lock);
-  p = nfs_initialize_rpc (NFSPROC_RENAME, cred, 0, &rpcbuf, fromdir, -1);
+  p = nfs_initialize_rpc (NFSPROC_RENAME (protocol_version),
+			  cred, 0, &rpcbuf, fromdir, -1);
   p = xdr_encode_fhandle (p, &fromdir->nn->handle);
   p = xdr_encode_string (p, fromname);
   mutex_unlock (&fromdir->lock);
@@ -829,7 +1104,15 @@
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (protocol_version == 3)
+	{
+	  mutex_lock (&fromdir->lock);
+	  p = process_wcc_stat (fromdir, p, !err);
+	  p = process_wcc_stat (todir, p, !err);
+	}
+    }
   
   free (rpcbuf);
   return err;
@@ -851,15 +1134,19 @@
       return 0;
     }
   
-  p = nfs_initialize_rpc (NFSPROC_READLINK, cred, 0, &rpcbuf, np, -1);
+  p = nfs_initialize_rpc (NFSPROC_READLINK (protocol_version),
+			  cred, 0, &rpcbuf, np, -1);
   p = xdr_encode_fhandle (p, &np->nn->handle);
   
   err = conduct_rpc (&rpcbuf, &p);
   if (!err)
-    err = nfs_error_trans (ntohl (*p++));
-  
-  if (!err)
-    p = xdr_decode_string (p, buf);
+    {
+      err = nfs_error_trans (ntohl (*p++));
+      if (protocol_version == 3)
+	p = process_returned_stat (np, p, 0);
+      if (!err)
+	p = xdr_decode_string (p, buf);
+    }
 
   free (rpcbuf);
   return err;
@@ -915,11 +1202,13 @@
 netfs_check_open_permissions (struct netcred *cred, struct node *np,
 			      int flags, int newnode)
 {
+  int modes;
+  
   if ((flags & (O_READ|O_WRITE|O_EXEC)) == 0)
     return 0;
   
-  if ((flags & (O_READ|O_WRITE|O_EXEC))
-      == (flags & guess_mode_use (np, cred)))
+  netfs_report_access (cred, np, &modes);
+  if ((flags & (O_READ|O_WRITE|O_EXEC)) == (flags & modes))
     return 0;
   else
     return EACCES;
@@ -932,9 +1221,53 @@
 		     struct node *np,
 		     int *types)
 {
-  *types = guess_mode_use (np, cred);
-}
+  if (protocol_version == 2)
+    *types = guess_mode_use (np, cred);
+  else
+    {
+      int *p;
+      void *rpcbuf;
+      error_t err;
+      int ret;
+      int write_check, execute_check;
 
+      err = netfs_validate_stat (np, cred);
+      if (err)
+	goto fallback;
+      if (S_ISDIR (np->nn_stat.st_mode))
+	{
+	  write_check = ACCESS3_MODIFY | ACCESS3_DELETE | ACCESS3_EXTEND;
+	  execute_check = ACCESS3_LOOKUP;
+	}
+      else
+	{
+	  write_check = ACCESS3_MODIFY;
+	  execute_check = ACCESS3_EXECUTE;
+	}
+
+      p = nfs_initialize_rpc (NFS3PROC_ACCESS, cred, 0, &rpcbuf, np, -1);
+      p = xdr_encode_fhandle (p, &np->nn->handle);
+      *p++ = htonl (ACCESS3_READ | write_check | execute_check);
+      
+      err = conduct_rpc (&rpcbuf, &p);
+      if (!err)
+	{
+	  err = nfs_error_trans (ntohl (*p++));
+	  p = process_returned_stat (np, p, 0);
+	  if (!err)
+	    {
+	      ret = ntohl (*p++);
+	      *types = ((ret & ACCESS3_READ ? O_READ : 0)
+			| (ret & write_check ? O_WRITE : 0)
+			| (ret & execute_check ? O_EXEC : 0));
+	    }
+	  else
+	    /* fall back, sigh. */
+          fallback:
+	    *types = guess_mode_use (np, cred);
+	}
+    }
+}
 
 /* These definitions have unfortunate side effects, don't use them,
    clever though they are. */
@@ -1106,7 +1439,8 @@
   while (!eof)
     {
       /* Fetch new directory entries */
-      p = nfs_initialize_rpc (NFSPROC_READDIR, cred, 0, &rpcbuf, dir, -1);
+      p = nfs_initialize_rpc (NFSPROC_READDIR (protocol_version),
+			      cred, 0, &rpcbuf, dir, -1);
       p = xdr_encode_fhandle (p, &dir->nn->handle);
       *p++ = cookie;
       *p++ = ntohl (read_size);
diff -ru hurd-0.0/nfs/rpc.c hurd-0.1/nfs/rpc.c
--- hurd-0.0/nfs/rpc.c	Fri Mar 29 17:26:52 1996
+++ hurd-0.1/nfs/rpc.c	Thu Aug 29 16:49:25 1996
@@ -193,7 +193,10 @@
       nc = (void *) *pp - *rpcbuf - sizeof (struct rpc_list);
       cc = write (main_udp_socket, *rpcbuf + sizeof (struct rpc_list), nc);
       if (cc == -1)
-	assert_perror (errno);
+	{
+	  unlink_rpc (hdr);
+	  return errno;
+	}
       else 
 	assert (cc == nc);
       
Only in hurd-0.1: nfsd
diff -ru hurd-0.0/pfinet/ChangeLog hurd-0.1/pfinet/ChangeLog
--- hurd-0.0/pfinet/ChangeLog	Sat Jul 20 15:48:52 1996
+++ hurd-0.1/pfinet/ChangeLog	Fri Sep  6 16:48:27 1996
@@ -1,3 +1,8 @@
+Fri Sep  6 16:46:43 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* socket-ops.c (S_socket_recv): Bother to pass
+	USER->sock->userflags through to the recvfrom routine.
+
 Sat Jul 20 15:48:29 1996  Michael I. Bushnell, p/BSG  <mib@gnu.ai.mit.edu>
 
 	* Makefile (lndist-asm-files): Look for files in $(srcdir).
diff -ru hurd-0.0/pfinet/socket-ops.c hurd-0.1/pfinet/socket-ops.c
--- hurd-0.0/pfinet/socket-ops.c	Thu Jul 18 23:21:02 1996
+++ hurd-0.1/pfinet/socket-ops.c	Fri Sep  6 16:48:12 1996
@@ -482,7 +482,8 @@
   mutex_lock (&global_lock);
   become_task (user);
 
-  recvd =  (*user->sock->ops->recvfrom) (user->sock, *data, amount, 0, flags,
+  recvd =  (*user->sock->ops->recvfrom) (user->sock, *data, amount, 
+					 user->sock->userflags, flags,
 					 (struct sockaddr *)addr, &addrlen);
   
   mutex_unlock (&global_lock);
diff -ru hurd-0.0/proc/ChangeLog hurd-0.1/proc/ChangeLog
--- hurd-0.0/proc/ChangeLog	Mon Jul 29 12:39:57 1996
+++ hurd-0.1/proc/ChangeLog	Thu Sep  5 11:00:14 1996
@@ -1,3 +1,13 @@
+Thu Sep  5 10:43:39 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* host.c (struct server_version): Delete member `release'.
+	(kernel_name, kernel_version): New variables.
+	(rebuild_uname): Do the voting on versions, not releases.
+	(initialize_version_info): Store kernel information in kernel_name
+	and kernel_version, not as an entry in the server_versions array. 
+	Don't fill in a release for ourselves.
+	(S_proc_register_version): Ignore RELEASE arg.
+
 Sun Jul 28 22:57:03 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* info.c (get_string_array): Correctly adjust NEWSIZE when
diff -ru hurd-0.0/proc/host.c hurd-0.1/proc/host.c
--- hurd-0.0/proc/host.c	Thu Apr 25 15:35:48 1996
+++ hurd-0.1/proc/host.c	Thu Sep  5 11:03:35 1996
@@ -47,7 +47,6 @@
 {
   char *name;
   char *version;
-  char *release;
 } *server_versions;
 int nserver_versions, server_versions_nalloc;
 
@@ -271,14 +270,17 @@
 
 /* Version information handling.
 
-   A server registers its name, release, and version with
-   startup_register_version.  The uname version string is composed of all
-   the server names and versions.  The uname release is composed of the
-   differing server releases in order of decreasing popularity (just one if
-   they all agree).
+   A server registers its name and version with
+   startup_register_version.
+
+   The uname release is the most popular version number.
+
+   The uname version string is composed of all the server names and
+   versions, omitting special mention of those which match the uname
+   release, plus the kernel version string. */
+   
+char *kernel_name, *kernel_version;
 
-   The Hurd release comes from <hurd/hurd_types.h> and
-   is compiled into proc as well as the other servers. */
 
 /* Rebuild the uname version string.  */
 static void
@@ -314,73 +316,59 @@
 	*p++ = '/';
     }
 
-  /* Collect all the differing release strings and count how many
+  /* Collect all the differing version strings and count how many
      servers use each.  */
-  struct release
+  struct version
     {
-      const char *release;
+      const char *version;
       unsigned int count;
-    } releases[nserver_versions];
-  int compare_releases (const void *a, const void *b)
+    } versions[nserver_versions];
+  int compare_versions (const void *a, const void *b)
     {
-      return (((const struct release *) b)->count -
-	      ((const struct release *) a)->count);
+      return (((const struct version *) b)->count -
+	      ((const struct version *) a)->count);
     }
-  unsigned int nreleases = 0;
+  unsigned int nversions = 0;
 
   for (i = 0; i < nserver_versions; ++i)
     {
-      for (j = 0; j < nreleases; ++j)
-	if (! strcmp (releases[j].release, server_versions[i].release))
+      for (j = 0; j < nversions; ++j)
+	if (! strcmp (versions[j].version, server_versions[i].version))
 	  {
-	    ++releases[j].count;
+	    ++versions[j].count;
 	    break;
 	  }
-      if (j == nreleases)
+      if (j == nversions)
 	{
-	  releases[nreleases].release = server_versions[i].release;
-	  releases[nreleases].count = 1;
-	  ++nreleases;
+	  versions[nversions].version = server_versions[i].version;
+	  versions[nversions].count = 1;
+	  ++nversions;
 	}
     }
 
-  /* Sort the releases in order of decreasing popularity.  */
-  qsort (releases, nreleases, sizeof (struct release), compare_releases);
+  /* Sort the versions in order of decreasing popularity.  */
+  qsort (versions, nversions, sizeof (struct version), compare_versions);
 
   /* Now build the uname strings.  */
 
-  initstr (uname_info.release);
-  for (i = 0; i < nreleases; ++i)
-    addstr (NULL, releases[i].release);
-
-  if (p > end)
-#ifdef notyet
-    syslog (LOG_EMERG,
-	    "_UTSNAME_LENGTH %u too short; inform bug-glibc@prep.ai.mit.edu\n",
-	    p - end)
-#endif
-      ;
-  else
-    p[-1] = '\0';
-  end[-1] = '\0';
+  /* release is the most popular version */
+  strcpy (uname_info.release, versions[0].version);
+  
+  initstr (uname_info.version);
 
-  for (i = 2; i < nserver_versions; i++)
-    if (strcmp (server_versions[i].version, server_versions[1].version))
-      break;
+  addstr (kernel_name, kernel_version);
 
-  initstr (uname_info.version);
+  if (versions[0].count > 1)
+    addstr ("Hurd", versions[0].version);
 
-  if (i == nserver_versions)
-    {
-      /* All the servers after [0] (the microkernel version)
-	 are the same, so just write one "hurd" version.  */
-      addstr (server_versions[0].name, server_versions[0].version);
-      addstr ("Hurd", server_versions[1].version);
-    }
-  else
+  /* Now, for any which differ (if there might be any), write it out
+     separately. */
+  if (versions[0].count != nserver_versions)
     for (i = 0; i < nserver_versions; i++)
-      addstr (server_versions[i].name, server_versions[i].version);
-
+      if (versions[0].count == 1
+	  || strcmp (server_versions[i].version, versions[0].version))
+	addstr (server_versions[i].name, server_versions[i].version);
+    
   if (p > end)
 #ifdef notyet
     syslog (LOG_EMERG,
@@ -393,13 +381,12 @@
   end[-1] = '\0';
 }
 
-      
 void
 initialize_version_info (void)
 {
   extern const char *const mach_cpu_types[];
   extern const char *const mach_cpu_subtypes[][32];
-  kernel_version_t kernel_version;
+  kernel_version_t kv;
   char *p;
   struct host_basic_info info;
   unsigned int n = sizeof info;
@@ -419,23 +406,21 @@
   server_versions = malloc (sizeof (struct server_version) * 10);
   server_versions_nalloc = 10;
 
-  err = host_kernel_version (mach_host_self (), kernel_version);
+  err = host_kernel_version (mach_host_self (), kv);
   assert (! err);
-  p = index (kernel_version, ':');
+  p = index (kv, ':');
   if (p)
     *p = '\0';
-  p = index (kernel_version, ' ');
+  p = index (kv, ' ');
   if (p)
     *p = '\0';
-  server_versions[0].name = strdup (p ? kernel_version : "mach");
-  server_versions[0].release = strdup (HURD_RELEASE);
-  server_versions[0].version = strdup (p ? p + 1 : kernel_version);
+  kernel_name = strdup (p ? kv : "mach");
+  kernel_version = strdup (p ? p + 1 : kv);
 
   server_versions[1].name = strdup (OUR_SERVER_NAME);
-  server_versions[1].release = strdup (HURD_RELEASE);
   server_versions[1].version = strdup (OUR_VERSION);
 
-  nserver_versions = 2;
+  nserver_versions = 1;
 
   rebuild_uname ();
   
@@ -471,11 +456,8 @@
       {
 	/* Change this entry.  */
 	free (server_versions[i].version);
-	free (server_versions[i].release);
 	server_versions[i].version = malloc (strlen (version) + 1);
-	server_versions[i].release = malloc (strlen (version) + 1);
 	strcpy (server_versions[i].version, version);
-	strcpy (server_versions[i].release, release);
 	break;
       }
   if (i == nserver_versions)
@@ -491,11 +473,8 @@
       server_versions[nserver_versions].name = malloc (strlen (name) + 1);
       server_versions[nserver_versions].version = malloc (strlen (version) 
 							  + 1);
-      server_versions[nserver_versions].release = malloc (strlen (release)
-							  + 1);
       strcpy (server_versions[nserver_versions].name, name);
       strcpy (server_versions[nserver_versions].version, version);
-      strcpy (server_versions[nserver_versions].release, release);
       nserver_versions++;
     }
   
diff -ru hurd-0.0/release/ChangeLog hurd-0.1/release/ChangeLog
--- hurd-0.0/release/ChangeLog	Mon Aug  5 20:30:22 1996
+++ hurd-0.1/release/ChangeLog	Fri Aug 16 10:50:10 1996
@@ -1,3 +1,13 @@
+Fri Aug 16 10:50:01 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* SETUP: Set `PATH'.
+
+Wed Aug 14 16:23:11 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* tool-Makefile (INSTALL, IMAGE): New variables.
+	Change all rules &c to use these variables instead of
+	`../hurdinst' and `hurd-image'.
+
 Mon Aug  5 11:44:30 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* SETUP: Put `r' before BOOT_DEV in call to INSTALL-GRUB-MBR.
diff -ru hurd-0.0/release/SETUP hurd-0.1/release/SETUP
--- hurd-0.0/release/SETUP	Mon Aug  5 20:29:49 1996
+++ hurd-0.1/release/SETUP	Fri Aug 16 10:49:50 1996
@@ -1,6 +1,8 @@
 #!/bin/bash
 # Setup critical hurd translators
 
+PATH=/bin:/sbin
+
 BOOT_DEV="$1"
 if [ ! "$BOOT_DEV" ]; then
   echo "No device to install a boot loader was specified."
diff -ru hurd-0.0/release/SOURCES.0.0 hurd-0.1/release/SOURCES.0.0
--- hurd-0.0/release/SOURCES.0.0	Mon Aug  5 13:37:09 1996
+++ hurd-0.1/release/SOURCES.0.0	Thu Aug  8 17:55:05 1996
@@ -2,7 +2,7 @@
 
 
 The following packages were built from the sources of the indicated
-version in ftp://prep.gnu.ai.edu/pub.gnu according to the provided
+version in ftp://prep.gnu.ai.edu/pub/gnu according to the provided
 instructions without modification:
 
 autoconf (2.10)
diff -ru hurd-0.0/release/tool-Makefile hurd-0.1/release/tool-Makefile
--- hurd-0.0/release/tool-Makefile	Mon Jul  8 16:21:02 1996
+++ hurd-0.1/release/tool-Makefile	Thu Aug 15 16:58:29 1996
@@ -3,6 +3,9 @@
 export GNUTARGET=elf32-i386
 export OBJCOPY=i386-gnu-objcopy
 
+INSTALL=install
+IMAGE=image
+
 BF=bfloppy-image
 RF=rfloppy-image
 
@@ -11,14 +14,14 @@
 bfloppy-bootfs = ufs
 bfloppy-bootprogs = kernel bootstrap
 
-$(BF)/boot/servers.boot: hurd-image/boot/floppy.boot
+$(BF)/boot/servers.boot: $(IMAGE)/boot/floppy.boot
 	-rm -f $@
 	@test -d $(@D) || mkdir -p $(@D)
 	cp $< $@
 
-$(BF)/%/: hurd-image/%/
+$(BF)/%/: $(IMAGE)/%/
 	test -d $@ || mkdir -p $@
-$(BF)/%: hurd-image/%
+$(BF)/%: $(IMAGE)/%
 	-rm -f $@
 	@test -d $(@D) || mkdir -p $(@D)
 	ln $< $@ || cp $< $@
@@ -46,27 +49,27 @@
 libc-USERS =
 libc-DEPS =
 
-$(RF)/lib/libc.so: hurd-image/lib/libc.so hurd-image/lib/libhurduser.so hurd-image/lib/libmachuser.so $(libc-satisfies:%=hurd-image/%)
+$(RF)/lib/libc.so: $(IMAGE)/lib/libc.so $(IMAGE)/lib/libhurduser.so $(IMAGE)/lib/libmachuser.so $(libc-satisfies:%=$(IMAGE)/%)
 	mksmallso $(smallso-LDFLAGS) \
-	  $@ $(libc-obj-dir)/libc_pic.a '-Lhurd-image/lib -lhurduser -lmachuser' \
+	  $@ $(libc-obj-dir)/libc_pic.a '-L$(IMAGE)/lib -lhurduser -lmachuser' \
 	  $(filter-out $(firstword $^),$^)
 
-$(RF)/lib/libhurduser.so: $(RF)/lib/libc.so $(libc-satisfies:%=hurd-image/%)
-	mksmallso $(smallso-LDFLAGS) $@ $(libc-obj-dir)/libhurduser_pic.a -Lhurd-image/lib -lmachuser $(filter-out $(firstword $^),$^)
+$(RF)/lib/libhurduser.so: $(RF)/lib/libc.so $(libc-satisfies:%=$(IMAGE)/%)
+	mksmallso $(smallso-LDFLAGS) $@ $(libc-obj-dir)/libhurduser_pic.a -L$(IMAGE)/lib -lmachuser $(filter-out $(firstword $^),$^)
 
-$(RF)/lib/libmachuser.so: $(RF)/lib/libc.so $(RF)/lib/libhurduser.so $(libc-satisfies:%=hurd-image/%)
+$(RF)/lib/libmachuser.so: $(RF)/lib/libc.so $(RF)/lib/libhurduser.so $(libc-satisfies:%=$(IMAGE)/%)
 	mksmallso $(smallso-LDFLAGS) $@ $(libc-obj-dir)/libmachuser_pic.a '' $(filter-out $(firstword $^),$^)
 
 $(addprefix $(RF)/,$(rfloppy-hurd:%=hurd/%) $(rfloppy-progs:%=bin/%)): \
-  $(RF)/%: hurd-image/%
+  $(RF)/%: $(IMAGE)/%
 	@test -d $(@D) || mkdir -p $(@D)
 	gzip -9v -c $< > $@.new
 	chmod 555 $@.new
 	mv -f $@.new $@
 
-$(RF)/%/: hurd-image/%/
+$(RF)/%/: $(IMAGE)/%/
 	test -d $@ || mkdir -p $@
-$(RF)/%: hurd-image/%
+$(RF)/%: $(IMAGE)/%
 	-rm -f $@
 	@test -d $(@D) || mkdir -p $(@D)
 	ln $< $@ || cp $< $@
@@ -96,7 +99,7 @@
 	vnconfig -u ${VND_DEV} $@.new
 	mv -f $@.new $@
 
-hurd-image.tar: hurd-image hurd-image.stamp
+$(IMAGE).tar: $(IMAGE) $(IMAGE).stamp
 	tar cof $@ $<
 
 %.gz: %
@@ -108,17 +111,14 @@
 	mv -f $@.new $@
 
 
-instdirs := $(patsubst ../hurdinst/%,%,\
-		       $(filter-out ../hurdinst,\
-				    $(shell find ../hurdinst -type d -print \
+instdirs := $(patsubst $(INSTALL)/%,%,\
+		       $(filter-out $(INSTALL),\
+				    $(shell find $(INSTALL) -type d -print \
 					    | sort -r)))
 
-hurd-image/%/.stamp: ../hurdinst/%
+$(IMAGE)/%/.stamp: $(INSTALL)/%
 	@./install-stripped -N $@ $< $(@D)
 	@echo $< `date` > $@
 	@echo updated $(@D)/
-hurd-image.stamp: $(instdirs:%=hurd-image/%/.stamp); touch $@
-hurd-image: hurd-image.stamp
-
-
-	
\ No newline at end of file
+$(IMAGE).stamp: $(instdirs:%=$(IMAGE)/%/.stamp); touch $@
+$(IMAGE): $(IMAGE).stamp
Only in hurd-0.1: sh-version.sed
diff -ru hurd-0.0/sutils/ChangeLog hurd-0.1/sutils/ChangeLog
--- hurd-0.0/sutils/ChangeLog	Thu Aug  1 16:29:54 1996
+++ hurd-0.1/sutils/ChangeLog	Thu Sep  5 12:21:12 1996
@@ -1,3 +1,38 @@
+Thu Sep  5 11:40:00 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makefile: Use $(top_srcdir)/sh-version.sed to make executables
+	from .sh files.
+
+	* fsck.c: Include <version.h>.
+ 	(argp_program_version): Define with STANDARD_HURD_VERSION. 
+	* halt.c: Likewise.
+	* reboot.c: Likewise.
+
+Tue Aug 27 12:06:55 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* reboot.c, halt.c (main): Add argument parsing.
+	(argp_program_version): New variable.
+	<argp.h>, <hurd.h>: New includes.
+	* Makefile (fsck): Remove dependency on libshouldbeinlibc.a.
+	(reboot halt fsck): Add dependency on libshouldbeinlibc.a.
+
+Mon Aug 19 15:17:38 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* fsck.c (doc): Supply a useful value.
+
+Wed Aug 14 13:32:12 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* e2os.sh: Add `;' before last commands inside { } pairs.
+	(OS_FREEBSD, OS_LITES): New variables.
+	Add symbolic names for freebsd & lites.
+
+Mon Aug 12 10:51:24 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* e2os.sh: New file.
+	* Makefile (targets): Add e2os.
+	(SRCS): Add $(SCRIPTS).
+	(special-targets, SCRIPTS, LCLHDRS): New variables.
+
 Thu Aug  1 16:29:31 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
 
 	* clookup.c (file_name_lookup_carefully/lookup): When appending
diff -ru hurd-0.0/sutils/Makefile hurd-0.1/sutils/Makefile
--- hurd-0.0/sutils/Makefile	Wed Jun 19 16:14:20 1996
+++ hurd-0.1/sutils/Makefile	Thu Sep  5 12:21:40 1996
@@ -20,17 +20,21 @@
 dir := sutils
 makemode := utilities
 
-targets = reboot halt fsck
-SRCS = reboot.c halt.c fsck.c fstab.c clookup.c
+targets = reboot halt fsck e2os
+special-targets = e2os
 installationdir = $(sbindir)
+SCRIPTS = e2os.sh
+SRCS = reboot.c halt.c fsck.c fstab.c clookup.c $(SCRIPTS)
+LCLHDRS = fstab.h
 
-OBJS = $(SRCS:.c=.o)
+OBJS = $(filter-out $(SCRIPTS),$(SRCS:.c=.o))
 
 include ../Makeconf
 
-fsck: fstab.o clookup.o ../libshouldbeinlibc/libshouldbeinlibc.a
+fsck: fstab.o clookup.o
+reboot halt fsck: ../libshouldbeinlibc/libshouldbeinlibc.a
 
-%: %.sh
-	cp $< $@
+%: %.sh $(top_srcdir)/sh-version.sed
+	sed -f $(top_srcdir)/sh-version.sed < $< > $@
 
 $(filter-out $(special-targets), $(targets)): %: %.o
Only in hurd-0.1/sutils: e2os.sh
diff -ru hurd-0.0/sutils/fsck.c hurd-0.1/sutils/fsck.c
--- hurd-0.0/sutils/fsck.c	Sat Jul  6 19:55:19 1996
+++ hurd-0.1/sutils/fsck.c	Thu Sep  5 11:43:46 1996
@@ -51,10 +51,12 @@
 #include <argp.h>
 #include <argz.h>
 #include <assert.h>
+#include <version.h>
 
 #include "fstab.h"
 
-char *argp_program_version = "fsck 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (fsck);
+
 
 /* for debugging  */
 static int _debug = 0;
@@ -454,7 +456,7 @@
   {0, 0}
 };
 static const char *args_doc = "[ DEVICE|FSYS... ]";
-static const char *doc = 0;
+static const char *doc = "Filesystem consistency check and repair";
 
 int
 main (int argc, char **argv)
Only in hurd-0.1/sutils: fstab.h
diff -ru hurd-0.0/sutils/halt.c hurd-0.1/sutils/halt.c
--- hurd-0.0/sutils/halt.c	Wed Nov 16 20:29:18 1994
+++ hurd-0.1/sutils/halt.c	Thu Sep  5 11:51:45 1996
@@ -1,5 +1,5 @@
 /* Halt the system
-   Copyright (C) 1994 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1996 Free Software Foundation, Inc.
    Written by Michael I. Bushnell.
 
    This file is part of the GNU Hurd.
@@ -22,10 +22,17 @@
 #include <sys/reboot.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <argp.h>
+#include <hurd.h>
+#include <version.h>
+
+char *argp_program_version = STANDARD_HURD_VERSION (halt);
 
 int
-main (void)
+main (int argc, char *argv[])
 {
+  struct argp argp = {0, 0, 0, "Halt the system"};
+  argp_parse (&argp, argc, argv, 0, 0, 0);
   reboot (RB_HALT);
   perror ("reboot");
   return 1;
diff -ru hurd-0.0/sutils/reboot.c hurd-0.1/sutils/reboot.c
--- hurd-0.0/sutils/reboot.c	Wed Nov 16 20:28:36 1994
+++ hurd-0.1/sutils/reboot.c	Thu Sep  5 11:43:28 1996
@@ -1,5 +1,5 @@
 /* Reboot the system
-   Copyright (C) 1994 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1996 Free Software Foundation, Inc.
    Written by Michael I. Bushnell.
 
    This file is part of the GNU Hurd.
@@ -22,15 +22,18 @@
 #include <sys/reboot.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <argp.h>
+#include <hurd.h>
+#include <version.h>
+
+char *argp_program_version = STANDARD_HURD_VERSION (reboot);
 
 int
-main (void)
+main (int argc, char *argv[])
 {
+  struct argp argp = {0, 0, 0, "Reboot the system"};
+  argp_parse (&argp, argc, argv, 0, 0, 0);
   reboot (0);
   perror ("reboot");
   return 1;
 }
-
-  
-  
-  
diff -ru hurd-0.0/tasks hurd-0.1/tasks
--- hurd-0.0/tasks	Sat Jul 13 16:00:33 1996
+++ hurd-0.1/tasks	Tue Sep  3 15:02:16 1996
@@ -1,7 +1,7 @@
-GNU Hurd Task List Version 1.15.  Last updated 13 July 1996.
+GNU Hurd Task List Version 1.17.  Last updated 3 September 1996.
 
 If you would like to work on one of these, please contact
-mib@gnu.ai.mit.edu.  It's important that you let me know what's being
+thomas@gnu.ai.mit.edu.  It's important that you let me know what's being
 worked on, because someone else might also be interested, and you
 should coordinate work.
 
@@ -48,10 +48,6 @@
   in functionality to the Unix ITIMER_PROF and ITIMER_VIRTUAL timers.
 
 !!!
-  * Mach 3.0 needs to provide a way for users to do statistical PC
-  profiling similar to the Unix profil system call.
-
-!!!
   * Mach 3.0 needs to make switches from MEMORY_OBJECT_COPY_DELAY to
   MEMORY_OBJECT_COPY_NONE have the effect of immediately completing any
   delayed copies.
@@ -120,6 +116,8 @@
   * Add a timestamp for task and thread creation to the relevant info
   structures (and make sure it works for the kernel task and threads).
 
+  * Add an anonymous swap allocation statistic to the task info structure.
+
 
 Hurd work (these are brief descriptions; mib can give more information):
 
@@ -152,7 +150,6 @@
   * Filesystem implementations (using libdiskfs) for other popular
   formats.  Importantly, MSDOS FAT format.
   
-
   * Transparent FTP translator.
 
   * A fancy terminal driver that uses readline and supports detach/attach.
diff -ru hurd-0.0/term/ChangeLog hurd-0.1/term/ChangeLog
--- hurd-0.0/term/ChangeLog	Mon Jul 29 12:40:07 1996
+++ hurd-0.1/term/ChangeLog	Thu Aug 29 17:32:37 1996
@@ -1,3 +1,37 @@
+Thu Aug 29 17:26:37 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* devio.c (device_open_reply): After error from ports_create_port,
+	unlock global_lock before returning.
+	* users.c (trivfs_S_io_readable): Likewise before returning
+	EBADF. 
+
+Thu Aug 15 16:07:07 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* users.c (trivfs_S_io_pathconf): Implement function.
+
+	* term.h (QUEUE_HIWAT, QUEUE_LOWAT): New macros.
+	* main.c (main): Use these new macros to create inputq, rawq, and
+	outputq.
+
+Thu Aug 15 15:32:47 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* users.c (trivfs_S_file_check_access): Renamed from
+	`trivfs_S_file_access'.
+
+Mon Aug 12 11:04:28 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* term.h (CTRL_BIT): Correct value is 0x40, not 0x20.
+
+	* munge.c (poutput): Compute tab width using the same loop
+	strategy as output_character and output_width.
+
+Thu Aug  8 17:16:06 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* munge.c (echo_char): Compute non-ctrl version of control
+	character correctly.
+	* term.h (CHAR_SOH): Delete macro.
+	(CTRL_BIT): New macro.
+
 Mon Jul 29 02:46:12 1996  Roland McGrath  <roland@baalperazim.frob.com>
 
 	* munge.c (input_character): In LAST_LNEXT case, jump to `alldone'
diff -ru hurd-0.0/term/devio.c hurd-0.1/term/devio.c
--- hurd-0.0/term/devio.c	Thu Jun 20 16:45:53 1996
+++ hurd-0.1/term/devio.c	Thu Aug 29 17:44:03 1996
@@ -468,7 +468,10 @@
 			     sizeof (struct port_info),
 			     &phys_reply_writes_pi);
   if (errno)
-    return errno;
+    {
+      mutex_unlock (&global_lock);
+      return errno;
+    }
   phys_reply_writes = ports_get_right (phys_reply_writes_pi);
   mach_port_insert_right (mach_task_self (), phys_reply_writes,
 			  phys_reply_writes, MACH_MSG_TYPE_MAKE_SEND);
diff -ru hurd-0.0/term/main.c hurd-0.1/term/main.c
--- hurd-0.0/term/main.c	Tue Jul 16 20:56:38 1996
+++ hurd-0.1/term/main.c	Thu Aug 15 16:07:37 1996
@@ -180,9 +180,9 @@
   term_owner = term_group = 0;
   term_mode = (bottom == &ptyio_bottom ? 0666 : 0600) | S_IFCHR;
 
-  inputq = create_queue (256, 100, 300);
-  rawq = create_queue (256, 100, 300);
-  outputq = create_queue (256, 100, 300);
+  inputq = create_queue (256, QUEUE_LOWAT, QUEUE_HIWAT);
+  rawq = create_queue (256, QUEUE_LOWAT, QUEUE_HIWAT);
+  outputq = create_queue (256, QUEUE_LOWAT, QUEUE_HIWAT);
   
   if (bottom == &ptyio_bottom)
     ptyio_init ();
diff -ru hurd-0.0/term/munge.c hurd-0.1/term/munge.c
--- hurd-0.0/term/munge.c	Mon Jul 29 12:40:08 1996
+++ hurd-0.1/term/munge.c	Mon Aug 12 11:06:48 1996
@@ -49,7 +49,11 @@
   else if (c == '\r')
     output_psize = 0;
   else if (c == '\t')
-    output_psize += (output_psize + 8) % 8;
+    {
+      output_psize++;
+      while (output_psize % 8)
+	output_psize++;
+    }
   else if (c == '\b')
     output_psize--;
 
@@ -131,7 +135,7 @@
       int n = loc + 1;
       while (n % 8)
 	n++;
-      return n;
+      return n; 
     }
   if ((c >= ' ') && (c < '\177'))
     return 1;
@@ -229,7 +233,7 @@
       if (echo_double (c, quoted))
 	{
 	  output_character ('^');
-	  output_character (c + ('A' - CHAR_SOH));
+	  output_character (c ^ CTRL_BIT);
 	}
       else
 	output_character (c);
diff -ru hurd-0.0/term/term.h hurd-0.1/term/term.h
--- hurd-0.0/term/term.h	Tue Jul 16 20:49:22 1996
+++ hurd-0.1/term/term.h	Thu Aug 15 16:06:41 1996
@@ -33,13 +33,15 @@
 #undef NOFLSH
 #include <termios.h>
 
-#define CHAR_SOH '\001'		/* C-a */
 #define CHAR_EOT '\004'		/* C-d */
 #define CHAR_DC1 '\021'		/* C-q */
 #define CHAR_DC2 '\022'		/* C-r */
 #define CHAR_DC3 '\023'		/* C-s */
 #define CHAR_USER_QUOTE '\377'	/* break quoting, etc. */
 
+/* This bit specifies control */
+#define CTRL_BIT 0x40
+
 /* XXX These belong in <termios.h> */
 #define ILCASE (1 << 14)
 #define OLCASE (1 << 9)
@@ -67,6 +69,9 @@
 #define EXCL_USE          0x00000100 /* user accessible exclusive use */
 #define NO_OWNER          0x00000200 /* there is no foreground_id */
 #define ICKY_ASYNC	  0x00000400 /* some user has set O_ASYNC */
+
+#define QUEUE_LOWAT 100
+#define QUEUE_HIWAT 300
 
 /* Global lock */
 struct mutex global_lock;
diff -ru hurd-0.0/term/users.c hurd-0.1/term/users.c
--- hurd-0.0/term/users.c	Fri Jul 19 23:46:26 1996
+++ hurd-0.1/term/users.c	Thu Aug 29 17:32:22 1996
@@ -515,10 +515,9 @@
 
 
 error_t
-trivfs_S_file_access (struct trivfs_protid *cred,
-		      mach_port_t reply,
-		      mach_msg_type_name_t reply_type,
-		      int *allowed)
+trivfs_S_file_check_access (struct trivfs_protid *cred,
+			    mach_port_t reply, mach_msg_type_name_t reply_type,
+			    int *allowed)
 {
   if (!cred)
     return EOPNOTSUPP;
@@ -743,6 +742,46 @@
 }
 
 error_t
+trivfs_S_io_pathconf (struct trivfs_protid *cred,
+		      mach_port_t reply,
+		      mach_msg_type_name_t reply_type,
+		      int name,
+		      int *val)
+{
+  if (!cred)
+    return EOPNOTSUPP;
+  
+  switch (name)
+    {
+    case _PC_LINK_MAX:
+    case _PC_NAME_MAX:
+    case _PC_PATH_MAX:
+    case _PC_PIPE_BUF:
+    case _PC_NO_TRUNC:
+    default:
+      return io_pathconf (cred->realnode, name, val);
+      
+    case _PC_MAX_CANON:
+      *val = rawq->hiwat;
+      return 0;
+      
+    case _PC_MAX_INPUT:
+      *val = inputq->hiwat;
+      return 0;
+      
+    case _PC_CHOWN_RESTRICTED:
+      /* We implement this locally, remember... */
+      *val = 1;
+      return 0;
+      
+    case _PC_VDISABLE:
+      *val = _POSIX_VDISABLE;
+      return 0;
+    }
+}    
+
+
+error_t
 trivfs_S_io_readable (struct trivfs_protid *cred,
 		      mach_port_t reply,
 		      mach_msg_type_name_t replytype,
@@ -756,7 +795,10 @@
 
   mutex_lock (&global_lock);
   if ((cred->po->openmodes & O_READ) == 0)
-    return EBADF;
+    {
+      mutex_unlock (&global_lock);
+      return EBADF;
+    }
   *amt = qsize (inputq);
   if (remote_input_mode && *amt)
     --*amt;
diff -ru hurd-0.0/ufs/ChangeLog hurd-0.1/ufs/ChangeLog
--- hurd-0.0/ufs/ChangeLog	Mon Jul 29 12:40:15 1996
+++ hurd-0.1/ufs/ChangeLog	Fri Sep  6 16:02:50 1996
@@ -1,3 +1,55 @@
+Fri Sep  6 16:00:42 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* consts.c: Include <version.h>.
+ 	(diskfs_major_version, diskfs_minor_version, diskfs_edit_version):
+	Deleted variables. 
+	(diskfs_server_version): New variable.
+
+Thu Aug 29 16:07:07 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* dir.c (diskfs_lookup_hard): When setting ds->stat to EXTEND, set
+	ds->idx by looking at the size of the file.  (IDX itself is no
+	longer at the end because of the change on Aug 16 1996.) 
+
+Wed Aug 28 12:15:15 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* dir.c (dirscanblock): Size dirents correctly when mallocing it.
+	(diskfs_direnter_hard): Be more careful when sizing or resizing
+	dirents.  Correctly set to -1 all the new entries we create after
+	realloc call.   
+
+Fri Aug 16 18:51:31 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* ufs.h (struct disknode): New member `dir_idx'.
+	* inode.c (diskfs_cached_lookup): Initialize DN->dir_idx.
+	* dir.c (diskfs_lookup_hard): 	After successful dirscanblock,
+	record index where we finished in DP->dn->dir_idx.  Start searches
+	at that index.
+
+Mon Aug 12 13:43:46 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* hyper.c (diskfs_set_hypermetadata): Bother to return 0 at end of
+	function.
+
+Wed Aug  7 13:00:30 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* inode.c (diskfs_set_statfs): Compute st->f_blocks correctly; set
+	bsize to be fs_fsize, not fs_bsize.
+
+	* hyper.c (diskfs_set_hypermetadata): Return an error as
+	appropriate. 
+	
+	* inode.c (struct ufs_fhandle): Layout filehandle more like Unixy
+	NFSD. 
+ 	(diskfs_S_file_getfh): Bother to clear unused parts of a
+	file handle so that they always compare equal.
+
+Tue Aug  6 12:19:38 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* inode.c: Include <fcntl.h>.
+	(struct ufs_fhandle): New type.
+	(diskfs_S_fsys_getfile, diskfs_S_file_getfh): New functions.
+
 Tue Jul 23 15:58:28 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* inode.c (write_node, read_disknode): `struct timespec' now uses
diff -ru hurd-0.0/ufs/consts.c hurd-0.1/ufs/consts.c
--- hurd-0.0/ufs/consts.c	Mon Mar 20 13:58:39 1995
+++ hurd-0.1/ufs/consts.c	Fri Sep  6 16:04:15 1996
@@ -1,5 +1,5 @@
 /* Various constants wanted by the diskfs library
-   Copyright (C) 1994, 1995 Free Software Foundation
+   Copyright (C) 1994, 1995, 1996 Free Software Foundation
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "ufs.h"
+#include <version.h>
 
 int diskfs_link_max = LINK_MAX;
 int diskfs_maxsymlinks = 8;
@@ -25,7 +26,5 @@
 int diskfs_shortcut_fifo = 1;
 int diskfs_shortcut_ifsock = 1;
 char *diskfs_server_name = "ufs";
-int diskfs_major_version = 0;
-int diskfs_minor_version = 0;
-int diskfs_edit_version = 0;
+char *diskfs_server_version = HURD_VERSION;
 int diskfs_synchronous = 0;
diff -ru hurd-0.0/ufs/dir.c hurd-0.1/ufs/dir.c
--- hurd-0.0/ufs/dir.c	Mon Jun 24 17:25:22 1996
+++ hurd-0.1/ufs/dir.c	Thu Aug 29 16:07:31 1996
@@ -111,7 +111,8 @@
   vm_address_t buf = 0;
   vm_size_t buflen = 0;
   int blockaddr;
-  int idx;
+  int idx, lastidx;
+  int looped;
   
   if ((type == REMOVE) || (type == RENAME))
     assert (npp);
@@ -156,18 +157,39 @@
   if (!diskfs_check_readonly ())
     dp->dn_set_atime = 1;
   
-  for (blockaddr = buf, idx = 0;
-       blockaddr - buf < dp->dn_stat.st_size;
-       blockaddr += DIRBLKSIZ, idx++)
+  /* Start the lookup at DP->dn->dir_idx.  */
+  idx = dp->dn->dir_idx;
+  if (idx * DIRBLKSIZ > dp->dn_stat.st_size)
+    idx = 0;			/* just in case */
+  blockaddr = buf + idx * DIRBLKSIZ;
+  looped = (idx == 0);
+  lastidx = idx;
+  if (lastidx == 0)
+    lastidx = dp->dn_stat.st_size / DIRBLKSIZ;
+
+  while (!looped || idx < lastidx)
     {
       err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum);
       if (!err)
-	break;
+	{
+	  dp->dn->dir_idx = idx;
+	  break;
+	}
       if (err != ENOENT)
 	{
 	  vm_deallocate (mach_task_self (), buf, buflen);
 	  return err;
 	}
+
+      blockaddr += DIRBLKSIZ;
+      idx++;
+      if (blockaddr - buf >= dp->dn_stat.st_size && !looped)
+	{
+	  /* We've gotten to the end; start back at the beginning */
+	  looped = 1;
+	  blockaddr = buf;
+	  idx = 0;
+	}
     }
 
   if (!diskfs_check_readonly ())
@@ -258,7 +280,7 @@
       /* We didn't find any room, so mark ds to extend the dir */
       ds->type = CREATE;
       ds->stat = EXTEND;
-      ds->idx = idx;
+      ds->idx = dp->dn_stat.st_size / DIRBLKSIZ;
     }
 
   /* Return to the user; if we can't, release the reference
@@ -422,8 +444,8 @@
 	 down how many entries there were. */
       if (!dp->dn->dirents)
 	{
-	  dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ + 1) 
-				* sizeof (int));
+	  dp->dn->dirents = malloc ((dp->dn_stat.st_size / DIRBLKSIZ) 
+				    * sizeof (int));
 	  for (i = 0; i < dp->dn_stat.st_size/DIRBLKSIZ; i++) 
 	    dp->dn->dirents[i] = -1;
 	}
@@ -595,19 +617,26 @@
     }
   else
     {
+      int i;
       /* It's cheap, so start a count here even if we aren't counting
 	 anything at all. */
       if (dp->dn->dirents)
 	{
 	  dp->dn->dirents = realloc (dp->dn->dirents, 
-				     (ds->idx + 1) * sizeof (int));
+				     (dp->dn_stat.st_size / DIRBLKSIZ
+				      * sizeof (int)));
+	  for (i = oldsize / DIRBLKSIZ; 
+	       i < dp->dn_stat.st_size / DIRBLKSIZ;
+	       i++)
+	    dp->dn->dirents[i] = -1;
+
 	  dp->dn->dirents[ds->idx] = 1;
 	}
       else
 	{
-	  int i;
-	  dp->dn->dirents = malloc ((ds->idx + 1) * sizeof (int));
-	  for (i = 0; i < ds->idx; i++)
+	  dp->dn->dirents = malloc (dp->dn_stat.st_size / DIRBLKSIZ 
+				    * sizeof (int));
+	  for (i = 0; i < dp->dn_stat.st_size / DIRBLKSIZ; i++)
 	    dp->dn->dirents[i] = -1;
 	  dp->dn->dirents[ds->idx] = 1;
 	}
diff -ru hurd-0.0/ufs/hyper.c hurd-0.1/ufs/hyper.c
--- hurd-0.0/ufs/hyper.c	Mon Jun 24 17:23:42 1996
+++ hurd-0.1/ufs/hyper.c	Mon Aug 12 13:43:10 1996
@@ -276,7 +276,7 @@
    taken from ordinary data blocks and might not be an even number
    of pages; in that case writing it through the pager would nuke whatever
    pages came after it on the disk and were backed by file pagers. */
-void
+error_t
 diskfs_set_hypermetadata (int wait, int clean)
 {
   vm_address_t buf;
@@ -294,16 +294,22 @@
 
       err = diskfs_device_read_sync (fsbtodb (sblock, sblock->fs_csaddr),
 				     &buf, bufsize);
-      if (!err)
+      if (err)
+	return err;
+      
+      bcopy (csum, (void *) buf, sblock->fs_cssize);
+      if (swab_disk)
+	swab_csums ((struct csum *)buf);
+      err = diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr),
+				      buf, bufsize);
+      vm_deallocate (mach_task_self (), buf, bufsize);
+      
+      if (err)
 	{
-	  bcopy (csum, (void *) buf, sblock->fs_cssize);
-	  if (swab_disk)
-	    swab_csums ((struct csum *)buf);
-	  diskfs_device_write_sync (fsbtodb (sblock, sblock->fs_csaddr),
-				    buf, bufsize);
-	  csum_dirty = 0;
-	  vm_deallocate (mach_task_self (), buf, bufsize);
+	  spin_unlock (&alloclock);
+	  return err;
 	}
+      csum_dirty = 0;
     }
 
   if (clean && ufs_clean && !sblock->fs_clean)
@@ -326,6 +332,7 @@
   copy_sblock ();
 
   sync_disk (wait);
+  return 0;
 }
 
 /* Copy the sblock into the disk */
diff -ru hurd-0.0/ufs/inode.c hurd-0.1/ufs/inode.c
--- hurd-0.0/ufs/inode.c	Mon Jul 29 12:40:17 1996
+++ hurd-0.1/ufs/inode.c	Fri Aug 16 18:52:19 1996
@@ -20,6 +20,7 @@
 #include <unistd.h>
 #include <stdio.h>
 #include <netinet/in.h>
+#include <fcntl.h>
 
 #define	INOHSZ	512
 #if	((INOHSZ&(INOHSZ-1)) == 0)
@@ -68,6 +69,7 @@
 
   dn->number = inum;
   dn->dirents = 0;
+  dn->dir_idx = 0;
 
   rwlock_init (&dn->allocptrlock);
   dn->dirty = 0;
@@ -497,8 +499,8 @@
 diskfs_set_statfs (struct statfs *st)
 {
   st->f_type = FSTYPE_UFS;
-  st->f_bsize = sblock->fs_bsize;
-  st->f_blocks = sblock->fs_dsize * sblock->fs_frag;
+  st->f_bsize = sblock->fs_fsize;
+  st->f_blocks = sblock->fs_dsize;
   st->f_bfree = (sblock->fs_cstotal.cs_nbfree * sblock->fs_frag
 		 + sblock->fs_cstotal.cs_nffree);
   st->f_bavail = ((sblock->fs_dsize * (100 - sblock->fs_minfree) / 100)
@@ -721,6 +723,127 @@
   mutex_unlock (&np->lock);
   
   return 0;
+}
+
+/* Must be exactly 28 bytes long */
+struct ufs_fhandle
+{
+  int filler1;
+  ino_t inum;
+  long gen;
+  int filler2[4];
+};
+
+/* Return an NFS file handle */
+
+error_t
+diskfs_S_file_getfh (struct protid *cred,
+		     char **fh,
+		     u_int *fh_len)
+{
+  struct node *np;
+  error_t err;
+  struct ufs_fhandle *f;
+
+  if (!cred)
+    return EOPNOTSUPP;
+
+  if (!diskfs_isuid (0, cred))
+    return EPERM;
+  
+  np = cred->po->np;
+
+  mutex_lock (&np->lock);
+
+  if (*fh_len < sizeof (struct ufs_fhandle))
+    vm_allocate (mach_task_self (), (vm_address_t *) fh, 
+		 sizeof (struct ufs_fhandle), 1);
+  *fh_len = sizeof (struct ufs_fhandle);
+  
+  f = (struct ufs_fhandle *) *fh;
+  f->inum = np->dn->number;
+  f->gen = np->dn_stat.st_gen;
+  f->filler1 = 0;
+  f->filler2[0] = f->filler2[1] = f->filler2[2] = f->filler2[3] = 0;
+  mutex_unlock (&np->lock);
+  return 0;
+}
+
+/* Lookup an NFS file handle */
+error_t
+diskfs_S_fsys_getfile (mach_port_t fsys,
+		       mach_port_t reply,
+		       mach_msg_type_name_t replytype,
+		       uid_t *uids,
+		       u_int nuids,
+		       uid_t *gids,
+		       u_int ngids,
+		       char *handle,
+		       u_int handlelen,
+		       mach_port_t *file,
+		       mach_msg_type_name_t *filetype)
+{
+  struct port_info *pt = ports_lookup_port (diskfs_port_bucket, fsys,
+					    diskfs_control_class);
+  struct node *np;
+  struct ufs_fhandle *f;
+  error_t err;
+  int flags;
+  struct protid fakecred, *newpi;
+  
+  if (!pt)
+    return EOPNOTSUPP;
+
+  if (handlelen != sizeof (struct ufs_fhandle))
+    {
+      ports_port_deref (pt);
+      return EINVAL;
+    }
+
+  f = (struct ufs_fhandle *) handle;
+
+  err = diskfs_cached_lookup (f->inum, &np);
+  if (err)
+    {
+      ports_port_deref (pt);
+      return err;
+    }
+
+  if (np->dn_stat.st_gen != f->gen)
+    {
+      diskfs_nput (np);
+      ports_port_deref (pt);
+      return ESTALE;
+    }
+  
+  /* This call should have a flags arg, but until then... */
+  fakecred.uids = uids;
+  fakecred.gids = gids;
+  fakecred.nuids = nuids;
+  fakecred.ngids = ngids;
+
+  flags = 0;
+  if (!diskfs_access (np, S_IREAD, &fakecred))
+    flags |= O_READ;
+  if (!diskfs_access (np, S_IEXEC, &fakecred))
+    flags |= O_EXEC;
+  if (!diskfs_access (np, S_IWRITE, &fakecred)
+      && !S_ISDIR (np->dn_stat.st_mode)
+      && !diskfs_check_readonly ())
+    flags |= O_WRITE;
+  
+  err = diskfs_create_protid (diskfs_make_peropen (np, flags, MACH_PORT_NULL),
+			      uids, nuids, gids, ngids, &newpi);
+  
+  diskfs_nput (np);
+  ports_port_deref (pt);
+  
+  if (!err)
+    {
+      *file = ports_get_right (newpi);
+      *filetype = MACH_MSG_TYPE_MAKE_SEND;
+    }
+  return err;
 }
 
   
diff -ru hurd-0.0/ufs/ufs.h hurd-0.1/ufs/ufs.h
--- hurd-0.0/ufs/ufs.h	Thu May  9 11:54:08 1996
+++ hurd-0.1/ufs/ufs.h	Fri Aug 16 18:51:18 1996
@@ -36,6 +36,8 @@
 {
   ino_t number;
 
+  int dir_idx;
+
   /* For a directory, this array holds the number of directory entries in
      each DIRBLKSIZE piece of the directory. */
   int *dirents;
Only in hurd-0.1: ufs-fsck
diff -ru hurd-0.0/ufs-utils/ChangeLog hurd-0.1/ufs-utils/ChangeLog
--- hurd-0.0/ufs-utils/ChangeLog	Mon Jul 29 12:40:25 1996
+++ hurd-0.1/ufs-utils/ChangeLog	Thu Sep  5 11:44:53 1996
@@ -1,3 +1,12 @@
+Thu Sep  5 11:44:38 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* mkfs.c: Include <version.h>.
+	(argp_program_version): Define with STANDARD_HURD_VERSION.
+
+Mon Aug 19 15:18:30 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* mkfs.c (doc): Supply a useful value.
+
 Tue Jul 23 19:34:58 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* mkfs.c (fsinit): `struct timespec' now uses a field prefix of `tv_'.
diff -ru hurd-0.0/ufs-utils/mkfs.c hurd-0.1/ufs-utils/mkfs.c
--- hurd-0.0/ufs-utils/mkfs.c	Mon Jul 29 12:40:27 1996
+++ hurd-0.1/ufs-utils/mkfs.c	Thu Sep  5 12:59:14 1996
@@ -33,7 +33,7 @@
 
 #ifndef lint
 /*static char sccsid[] = "from: @(#)mkfs.c	8.3 (Berkeley) 2/3/94";*/
-static char *rcsid = "$Id: mkfs.c,v 1.13 1996/07/23 23:37:21 miles Exp $";
+static char *rcsid = "$Id: mkfs.c,v 1.15 1996/09/05 16:59:14 thomas Exp $";
 #endif /* not lint */
 
 #include <unistd.h>
@@ -54,6 +54,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <dirent.h>
+#include <version.h>
 
 #include <device/device_types.h>
 #include <device/disk_status.h>
@@ -163,7 +164,7 @@
 int	fsi, fso;
 daddr_t	alloc();
 
-char *argp_program_version = "mkfs.ufs 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (mkfs.ufs);
 
 #define _STRINGIFY(arg) #arg
 #define STRINGIFY(arg) _STRINGIFY (arg)
@@ -219,7 +220,7 @@
   {0, 0}
 };
 static char *args_doc = "DEVICE";
-static char *doc = 0;
+static char *doc = "Write a ufs filesystem image onto DEVICE.";
 
 struct amark { void *addr; struct amark *next; };
 
diff -ru hurd-0.0/utils/ChangeLog hurd-0.1/utils/ChangeLog
--- hurd-0.0/utils/ChangeLog	Thu Aug  1 12:03:41 1996
+++ hurd-0.1/utils/ChangeLog	Thu Sep  5 12:20:26 1996
@@ -1,3 +1,54 @@
+Thu Sep  5 11:45:58 1996  Thomas Bushnell, n/BSG  <thomas@gnu.ai.mit.edu>
+
+	* Makefile: Use $(top_srcdir)/sh-version.h to make executables
+ 	from .sh files.
+
+	* fsysopts.c: Include <version.h>.
+	(argp_program_version): Define with STANDARD_HURD_VERSION.
+	* w.c: Likewise.
+	* vmstat.c: Likewise.
+	* vminfo.c: Likewise.
+	* sync.c: Likewise.
+	* storeinfo.c: Likewise.
+	* showtrans.c: Likewise.
+	* settrans.c: Likewise.
+	* ps.c: Likewise.
+	* portinfo.c: Likewise.
+	* login.c: Likewise.
+	* hurdids.c: Likewise.
+
+Sun Sep  1 14:15:46 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* sync.c (argp_program_version): New variable.
+	(main): Call argp_parse with just a doc string.
+	<argp.h>: New include.
+	* Makefile (sync): Depend on libshouldbeinlibc.a.
+
+Fri Aug 30 16:54:57 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* vminfo.c: New file.
+	* Makefile (targets): Add vminfo.
+	(SRCS): Add vminfo.c.
+	(INSTALL-vminfo-ops): New variable.
+
+Mon Aug 19 15:19:20 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* devprobe.c, fsysopts.c, hurdids.c, login.c, portinfo.c, ps.c,
+ 	settrans.c, showtrans.c, storeinfo.c, vmstat.c, w.c, x.c (doc):
+ 	Add program description.
+
+Wed Aug 14 10:18:41 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* Makefile (login-LDLIBS): New variable.
+	(login): Dependency on -lutil removed.
+	(libutil-libsubst): Variable removed.
+
+Sat Aug 10 10:03:57 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* ps.c (options): Whoops, short option for --sort is -s.
+
+	* Makefile (LCLHDRS): New variable.
+
 Wed Jul 31 14:23:31 1996  Miles Bader  <miles@gnu.ai.mit.edu>
 
 	* login.c (main/verify_passwd): Use #pragma weak instead of
diff -ru hurd-0.0/utils/Makefile hurd-0.1/utils/Makefile
--- hurd-0.0/utils/Makefile	Mon Jul 29 12:40:50 1996
+++ hurd-0.1/utils/Makefile	Thu Sep  5 12:22:16 1996
@@ -20,34 +20,33 @@
 
 targets = shd ps settrans showtrans sync su mount fsysopts \
 	storeinfo login w uptime hurdids loginpr sush vmstat portinfo \
-	devprobe 
+	devprobe vminfo
 special-targets = mount loginpr sush uptime
 SRCS = shd.c ps.c su.c settrans.c sync.c showtrans.c \
 	mount.sh fsysopts.c storeinfo.c login.c loginpr.sh sush.sh w.c \
-	uptime.sh psout.c hurdids.c vmstat.c portinfo.c devprobe.c
+	uptime.sh psout.c hurdids.c vmstat.c portinfo.c devprobe.c vminfo.c
+LCLHDRS = psout.h
 
 OBJS = $(filter-out loginpr.sh mount.sh sush.sh uptime.sh,$(SRCS:.c=.o))
-
-# This hack to get around ickiness in Makeconf
-libutil-libsubst = -lutil
+login-LDLIBS = -lutil
 
 INSTALL-login-ops = -o root -m 4755
 INSTALL-ps-ops = -o root -m 4755
 INSTALL-w-ops = -o root -m 4755
 INSTALL-vmstat-ops = -o root -m 4755
+INSTALL-vminfo-ops = -o root -m 4755
 
 include ../Makeconf
 
-login: -lutil     # /gd4/hurdinst/lib/libutil.a	# ick ick ick ick
 ps w: psout.o ../libps/libps.a ../libihash/libihash.a
 storeinfo: ../libstore/libstore.a
 # We must include libthreads because of a bug in the way shared libraries
 # work: all libraries that *any* routine in libfshelp uses must be defined.
 settrans: ../libfshelp/libfshelp.a ../libports/libports.a ../libthreads/libthreads.a
-ps w hurdids settrans showtrans fsysopts storeinfo login vmstat portinfo \
-  devprobe: ../libshouldbeinlibc/libshouldbeinlibc.a
+ps w hurdids settrans sync showtrans fsysopts storeinfo login vmstat portinfo \
+  devprobe vminfo: ../libshouldbeinlibc/libshouldbeinlibc.a
 
 %: %.sh
-	cp $< $@
+	sed -f $(top_srcdir)/sh-version.sed < $< > $@
 
 $(filter-out $(special-targets), $(targets)): %: %.o
diff -ru hurd-0.0/utils/devprobe.c hurd-0.1/utils/devprobe.c
--- hurd-0.0/utils/devprobe.c	Sat May 11 01:03:23 1996
+++ hurd-0.1/utils/devprobe.c	Tue Sep  3 10:21:24 1996
@@ -33,7 +33,8 @@
   {0}
 };
 static const char *args_doc = "DEVNAME...";
-static const char *doc = "The exit status is 0 if any devices were found.";
+static const char *doc = "Test for the existance of mach device DEVNAME..."
+  "\vThe exit status is 0 if any devices were found.";
 
 int
 main (int argc, char **argv)
diff -ru hurd-0.0/utils/fsysopts.c hurd-0.1/utils/fsysopts.c
--- hurd-0.0/utils/fsysopts.c	Mon Jul 29 12:40:52 1996
+++ hurd-0.1/utils/fsysopts.c	Thu Sep  5 11:45:56 1996
@@ -28,10 +28,11 @@
 
 #include <error.h>
 #include <argz.h>
+#include <version.h>
 
 #include <hurd/fsys.h>
 
-char *argp_program_version = "fsysopts 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (fsysopts);
 
 static struct argp_option options[] =
 {
@@ -40,7 +41,8 @@
   {0, 0, 0, 0}
 };
 static char *args_doc = "FILESYS [FS_OPTION...]";
-static char *doc = "The legal values for FS_OPTION depends on FILESYS, but\
+static char *doc = "Get or set command line options for running translator FILESYS."
+"\vThe legal values for FS_OPTION depends on FILESYS, but\
  some common ones are: --readonly, --writable, --remount, --sync[=INTERVAL],\
  and --nosync.\n\nIf no options are supplied, FILESYS's existing options\
  are printed";
diff -ru hurd-0.0/utils/hurdids.c hurd-0.1/utils/hurdids.c
--- hurd-0.0/utils/hurdids.c	Sat Jul  6 19:07:11 1996
+++ hurd-0.1/utils/hurdids.c	Thu Sep  5 11:46:38 1996
@@ -26,11 +26,12 @@
 #include <unistd.h>
 #include <pwd.h>
 #include <grp.h>
+#include <version.h>
 
 #include <error.h>
 #include <hurd/id.h>
 
-char *argp_program_version = "hurdids 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (hurdids);
 
 static struct argp_option options[] =
 {
@@ -43,7 +44,7 @@
   {0}
 };
 static char *args_doc = 0;
-static char *doc = 0;
+static char *doc = "Show hurd uids/gids.";
 
 /* ---------------------------------------------------------------- */
 
diff -ru hurd-0.0/utils/login.c hurd-0.1/utils/login.c
--- hurd-0.0/utils/login.c	Thu Aug  1 12:03:42 1996
+++ hurd-0.1/utils/login.c	Thu Sep  5 11:47:12 1996
@@ -31,6 +31,7 @@
 #include <netdb.h>
 #include <time.h>
 #include <assert.h>
+#include <version.h>
 
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -50,7 +51,8 @@
 	     mach_port_t *ports, unsigned num_ports,
 	     mach_port_t *fds, unsigned num_fds);
 
-char *argp_program_version = "login 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (login);
+     
 
 /* Defaults for various login parameters.  */
 char *default_args[] = {
@@ -108,6 +110,7 @@
 };
 static char *args_doc = "[USER [ARG...]]";
 static char *doc =
+"Exec a program with uids and/or the environment changed appropriately.\v"
 "To give args to the shell without specifying a user, use - for USER.\n"
 "Current login parameters include HOME, SHELL, USER, NAME, and ROOT.";
 
diff -ru hurd-0.0/utils/portinfo.c hurd-0.1/utils/portinfo.c
--- hurd-0.0/utils/portinfo.c	Mon Jul 29 12:40:52 1996
+++ hurd-0.1/utils/portinfo.c	Thu Sep  5 11:47:35 1996
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <version.h>
 
 #include <mach.h>
 
@@ -34,7 +35,7 @@
 #include <portinfo.h>
 #include <portxlate.h>
 
-char *argp_program_version = "portinfo 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (portinfo);
 
 static const struct argp_option options[] = {
   {0,0,0,0,0, 1},
@@ -72,7 +73,8 @@
 };
 static const char *args_doc = "PID [NAME...]";
 static const char *doc =
-"If no port NAMEs are given, all ports in process PID are reported (if"
+"Show information about mach ports NAME... (default all ports) in process PID."
+"\vIf no port NAMEs are given, all ports in process PID are reported (if"
 " translation is used, then only those common to both processes).  NAMEs"
 " may be specified in hexadecimal or octal by using a 0x or 0 prefix.";
 
diff -ru hurd-0.0/utils/ps.c hurd-0.1/utils/ps.c
--- hurd-0.0/utils/ps.c	Thu Aug  1 12:03:42 1996
+++ hurd-0.1/utils/ps.c	Thu Sep  5 11:47:58 1996
@@ -30,9 +30,11 @@
 #include <idvec.h>
 #include <ps.h>
 #include <error.h>
+#include <version.h>
+
 #include "psout.h"
 
-char *argp_program_version = "ps 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (ps);
 
 #define OA OPTION_ARG_OPTIONAL
 
@@ -75,7 +77,7 @@
                                       " (which defaults to the sid of the"
                                       " current process)"},
   {"sid",        0,       0,      OPTION_ALIAS | OPTION_HIDDEN},
-  {"sort",       'S',	  "FIELD",0, "Sort the output with respect to FIELD,"
+  {"sort",       's',	  "FIELD",0, "Sort the output with respect to FIELD,"
                                      " backwards if FIELD is prefixed by `-'"},
   {"threads",    'T',     0,      0,  "Show the threads for each process"},
   {"tty",        't',     "TTY",  OA, "Only show processes with controlling"
@@ -90,10 +92,10 @@
 };
 
 char *args_doc = "[PID...]";
-
-char *doc = "The USER, LID, PID, PGRP, and SID arguments may also be comma \
-separated lists.  The System V options -u and -g may be accessed with -O and \
---pgrp.";
+char *doc =
+"Show information about processes PID... (default all `interesting' processes)"
+"\vThe USER, LID, PID, PGRP, and SID arguments may also be comma separated"
+" lists.  The System V options -u and -g may be accessed with -O and -G."; 
 
 int 
 parse_enum(char *arg, char **choices, char *kind, int allow_mismatches)
Only in hurd-0.1/utils: psout.h
diff -ru hurd-0.0/utils/settrans.c hurd-0.1/utils/settrans.c
--- hurd-0.0/utils/settrans.c	Sat Jul 20 11:07:15 1996
+++ hurd-0.1/utils/settrans.c	Thu Sep  5 11:48:20 1996
@@ -29,8 +29,9 @@
 #include <error.h>
 #include <argz.h>
 #include <hurd/fshelp.h>
+#include <version.h>
 
-char *argp_program_version = "settrans 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (settrans);
 
 #define DEFAULT_TIMEOUT 60
 
@@ -61,7 +62,8 @@
   {0, 0}
 };
 static char *args_doc = "NODE [TRANSLATOR ARG...]";
-static char *doc = "By default the passive translator is set.";
+static char *doc = "Set the passive/active translator on NODE."
+"\vBy default the passive translator is set.";
 
 /* ---------------------------------------------------------------- */
 
diff -ru hurd-0.0/utils/showtrans.c hurd-0.1/utils/showtrans.c
--- hurd-0.0/utils/showtrans.c	Sat Jul  6 19:07:18 1996
+++ hurd-0.1/utils/showtrans.c	Thu Sep  5 11:48:42 1996
@@ -25,11 +25,12 @@
 #include <argp.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <version.h>
 
 #include <error.h>
 #include <argz.h>
 
-char *argp_program_version = "showtrans 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (showtrans);
 
 static struct argp_option options[] =
 {
@@ -42,9 +43,9 @@
 };
 
 static char *args_doc = "FILE...";
-
-static char *doc = "A FILE argument of `-' prints the translator on the node \
-attached to standard input.";
+static char *doc = "Show the passive translator of FILE..."
+"\vA FILE argument of `-' prints the translator on the node"
+" attached to standard input.";
 
 /* ---------------------------------------------------------------- */
 
diff -ru hurd-0.0/utils/storeinfo.c hurd-0.1/utils/storeinfo.c
--- hurd-0.0/utils/storeinfo.c	Sat Jul  6 19:07:32 1996
+++ hurd-0.1/utils/storeinfo.c	Thu Sep  5 11:49:06 1996
@@ -25,13 +25,14 @@
 #include <argp.h>
 #include <unistd.h>
 #include <sys/fcntl.h>
+#include <version.h>
 
 #include <error.h>
 
 #include <hurd/fs.h>
 #include <hurd/store.h>
 
-char *argp_program_version = "storeinfo 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (storeinfo);
 
 static struct argp_option options[] =
 {
@@ -48,7 +49,8 @@
   {0, 0}
 };
 static char *args_doc = "FILE...";
-static char *doc = "With no FILE arguments, the file attached to standard \
+static char *doc = "Show information about storage used by FILE..."
+"\vWith no FILE arguments, the file attached to standard \
 input is used.  The fields to be printed are separated by colons, in this \
 order: PREFIX: KIND: NAME: BLOCK-SIZE: BLOCKS: SIZE: RUNS.  If the store is a \
 composite one and --children is specified, children are printed on lines \
diff -ru hurd-0.0/utils/sync.c hurd-0.1/utils/sync.c
--- hurd-0.0/utils/sync.c	Thu Jul  6 22:58:50 1995
+++ hurd-0.1/utils/sync.c	Thu Sep  5 11:49:32 1996
@@ -1,5 +1,5 @@
 /* Call sync synchronously.
-   Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
    Written by Michael I. Bushnell.
 
    This file is part of the GNU Hurd.
@@ -19,10 +19,17 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include <hurd.h>
+#include <argp.h>
+#include <version.h>
+
+char *argp_program_version = STANDARD_HURD_VERSION (sync);
 
 int
-main ()
+main (int argc, char *argv[])
 {
+  struct argp argp =
+    {0, 0, 0, "Force all pending disk writes to be done immediately"};
+  argp_parse (&argp, argc, argv, 0, 0, 0);
   __USEPORT (CRDIR, __file_syncfs (port, 1, 1));
   return 0;
 }
Only in hurd-0.1/utils: vminfo.c
diff -ru hurd-0.0/utils/vmstat.c hurd-0.1/utils/vmstat.c
--- hurd-0.0/utils/vmstat.c	Mon Jul 29 12:40:54 1996
+++ hurd-0.1/utils/vmstat.c	Thu Sep  5 11:50:33 1996
@@ -25,13 +25,14 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <version.h>
 
 #include <mach.h>
 #include <mach/vm_statistics.h>
 #include <mach/default_pager.h>
 #include <hurd.h>
 
-char *argp_program_version = "vmstat 1.1 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (vmstat);
 
 static const struct argp_option options[] = {
   {"terse",	't', 0, 0, "Use short one-line output format", 1 },
@@ -48,7 +49,8 @@
   {0}
 };
 static const char *args_doc = "[PERIOD [COUNT [HEADER_INTERVAL]]]";
-static const char *doc = "If PERIOD is supplied, then terse mode is"
+static const char *doc = "Show system virtual memory statistics"
+"\vIf PERIOD is supplied, then terse mode is"
 " selected, and the output repeated every PERIOD seconds, with cumulative"
 " fields given the difference from the last output.  If COUNT is given"
 " and non-zero, only that many lines are output.  HEADER_INTERVAL"
diff -ru hurd-0.0/utils/w.c hurd-0.1/utils/w.c
--- hurd-0.0/utils/w.c	Thu Aug  1 12:03:42 1996
+++ hurd-0.1/utils/w.c	Thu Sep  5 11:50:57 1996
@@ -29,6 +29,7 @@
 #include <pwd.h>
 #include <grp.h>
 #include <netdb.h>
+#include <version.h>
 
 #include <sys/fcntl.h>
 
@@ -48,7 +49,7 @@
 extern char *shared_domain (char *host1, char *host2);
 extern char *localhost ();
 
-char *argp_program_version = "w 1.0 (GNU " HURD_RELEASE ")";
+char *argp_program_version = STANDARD_HURD_VERSION (w);
 
 #define OA OPTION_ARG_OPTIONAL
 
@@ -71,7 +72,7 @@
   {0, 0}
 };
 static char *args_doc = "[USER...]";
-static char *doc = 0;
+static char *doc = "Show logged in users and what they are doing";
 
 /* The current time of day.  */
 static struct timeval now;
Only in hurd-0.1: version.h
