Many files:
  Checked in e2fsprogs 1.05

diff --git a/.head-Changelog b/.head-Changelog
new file mode 100644
index 0000000..d62d0a2
--- /dev/null
+++ b/.head-Changelog
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+for i in `find . -name ChangeLog -print`
+do
+	echo "=========================================="
+	echo $i
+	sed -n '1,/Release/p'  $i
+done
+
diff --git a/ChangeLog b/ChangeLog
index bc4c349..4694ae3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+Sat Aug 31 10:55:45 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* configure.in (AC_CHECK_FUNCS): Add fchown to list of functions
+	 	that we check.
+
+Wed Aug 28 14:42:12 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* configure.in (usr_prefix): To be slightly more conformant with
+		the coding standards, always default to ${prefix}
+		unless on a linux system with prefix = ''.  Allow
+		--with-usr-prefix option.
+
+Tue Aug 27 16:53:29 1996  Miles Bader  <miles@gnu.ai.mit.edu>
+
+	* configure.in (AC_CHECK_HEADERS): Add net/if.h & netinet/in.h.
+		Add `--enable-fsck' switch, to allow configuration of
+		fsck wrapper building (default yes except on the hurd).
+		Make '' prefix default and LDFLAG_STATIC hacks work on
+		the hurd as well as linux.
+
+Tue Aug 27 16:23:56 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* configure.in: Check to see if sys/types.h defines ino_t.  Add
+		support for checking/sizing "long long".
+
+Wed Aug 21 00:44:22 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* configure.in: Added configure flag --enable-old-bitops, which
+ 		forces the bitops to use the standard bitmask operations.
+
+Fri Aug  9 08:29:00 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* configure.in: Check for existence of sys/utsname.h and
+	 	strcasecmp().  Remove check for EXT2 fragment in system
+	 	header file.  E2fsprogs now deals with the fragment fields
+	 	by dispatching off of the OS field.
+
+Tue Aug  6 14:34:19 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* configure.in (AC_OUPUT): Create substitutions for the uuid
+	 	library.
+
+	* MCONFIG.in (all): Add new variables for the uuid library.
+
+Thu May 23 12:39:07 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* configure.in: Make the default prefix be '' for Linux.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.04
diff --git a/MCONFIG.in b/MCONFIG.in
index 0874305..1776cf8 100644
--- a/MCONFIG.in
+++ b/MCONFIG.in
@@ -24,7 +24,6 @@
 INSTALL_DATA = @INSTALL_DATA@
 CC = @CC@
 DEFS = @DEFS@
-LIBS = @LIBS@
 CFLAGS = @CFLAGS@
 ALL_CFLAGS = $(CPPFLAGS) $(DEFS) $(WFLAGS) $(CFLAGS) $(XTRA_CFLAGS) \
 	-I$(top_builddir)/lib -I$(top_srcdir)/lib $(LINUX_INCLUDE) 
@@ -32,6 +31,7 @@
 ALL_LDFLAGS = $(LDFLAGS)
 RM = @RM@
 LN = @LN@
+LN_S = @LN_S@
 MV = @MV@
 CP = @CP@
 CHMOD = @CHMOD@
@@ -51,16 +51,19 @@
 LIBCOM_ERR = $(LIB)/libcom_err@LIB_EXT@
 LIBE2P = $(LIB)/libe2p@LIB_EXT@
 LIBEXT2FS = $(LIB)/libext2fs@LIB_EXT@
+LIBUUID = $(LIB)/libuuid@LIB_EXT@ @SOCKET_LIB@ 
 
 STATIC_LIBSS = $(LIB)/libss@STATIC_LIB_EXT@
 STATIC_LIBCOM_ERR = $(LIB)/libcom_err@STATIC_LIB_EXT@
 STATIC_LIBE2P = $(LIB)/libe2p@STATIC_LIB_EXT@
 STATIC_LIBEXT2FS = $(LIB)/libext2fs@STATIC_LIB_EXT@
+STATIC_LIBUUID = $(LIB)/libuuid@STATIC_LIB_EXT@ @SOCKET_LIB@ 
 
 PROFILED_LIBSS = $(LIB)/libss@PROFILED_LIB_EXT@
 PROFILED_LIBCOM_ERR = $(LIB)/libcom_err@PROFILED_LIB_EXT@
 PROFILED_LIBE2P = $(LIB)/libe2p@PROFILED_LIB_EXT@
 PROFILED_LIBEXT2FS = $(LIB)/libext2fs@PROFILED_LIB_EXT@
+PROFILED_LIBUUID = $(LIB)/libuuid@PROFILED_LIB_EXT@ @SOCKET_LIB@ 
 
 #
 # Use these definitions is you use tools 2.x, x < 16
@@ -91,7 +94,7 @@
 #
 @W@WFLAGS=		-ansi -D_POSIX_SOURCE -pedantic \
 @W@			-Wall -Wwrite-strings -Wpointer-arith \
-@W@			-Wcast-qual -Wenum-clash -Wcast-align -Wtraditional \
+@W@			-Wcast-qual -Wcast-align -Wtraditional \
 @W@			-Wstrict-prototypes -Wmissing-prototypes \
 @W@			-Wnested-externs -Winline -DNO_INLINE_FUNCS -Wshadow 
 
@@ -114,18 +117,39 @@
 all::
 
 #
+# Autoconf magic...
+#
+
+$(top_builddir)/config.status: $(top_srcdir)/configure
+	(cd $(top_builddir); ./config.status --recheck)
+
+$(top_builddir)/MCONFIG: $(top_srcdir)/MCONFIG.in $(top_builddir)/config.status
+	(cd $(top_builddir); CONFIG_FILES=MCONFIG ./config.status)
+
+$(top_builddir)/lib/substitute_sh: $(top_srcdir)/lib/substitute_sh.in \
+		$(top_builddir)/config.status
+	(cd $(top_builddir); CONFIG_FILES=lib/substitute_sh ./config.status)
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/MCONFIG \
+		$(top_builddir)/config.status
+	(cd $(top_builddir); CONFIG_FILES=$(my_dir)/Makefile ./config.status)
+
+$(top_srcdir)/configure: $(top_srcdir)/configure.in
+	cd $(top_srcdir) && autoconf
+
+#
 # Make depend magic...
 #
 
 .depend: Makefile $(SRCS) $(top_srcdir)/depfix.sed
 	if test -n "$(SRCS)" ; then \
 		$(CC) -M $(ALL_CFLAGS) $(SRCS) | \
-			sed -f $(top_srcdir)/depfix.sed | \
-			sed -e 's; $(srcdir)/; $$(srcdir)/;g' | \
-			sed -e 's; $(top_srcdir)/; $$(top_srcdir)/;g' | \
-			sed -e 's; $(top_builddir)/; $$(top_builddir)/;g' | \
-			sed -e 's; \./; ;g' | \
-		grep -v "  \\\\$$" > .depend; \
+			sed -f $(top_srcdir)/depfix.sed \
+			    -e 's; $(srcdir)/; $$(srcdir)/;g' \
+			    -e 's; $(top_srcdir)/; $$(top_srcdir)/;g' \
+			    -e 's; $(top_builddir)/; $$(top_builddir)/;g' \
+			    -e 's; \./; ;g' \
+			    -e '/^ *\\$$/d' > .depend; \
 	else :; fi
 
 depend:: .depend
diff --git a/Makefile.in b/Makefile.in
index bcdae22..1d78c63 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -2,11 +2,12 @@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = .
+my_dir = .
 INSTALL = @INSTALL@
 
 @MCONFIG@
 
-LIB_SUBDIRS=lib/et lib/ss lib/ext2fs lib/e2p
+LIB_SUBDIRS=lib/et lib/ss lib/ext2fs lib/e2p lib/uuid
 PROG_SUBDIRS=e2fsck debugfs misc
 SUBDIRS=$(LIB_SUBDIRS) $(PROG_SUBDIRS) tests
 
@@ -57,7 +58,7 @@
 include/linux/types.h: $(SUBSTITUTE) $(srcdir)/include/linux/types.h.in
 	-chmod +x $(SUBSTITUTE)
 	$(SUBSTITUTE) $(srcdir)/include/linux/types.h.in \
-		include/linux/types.h.in
+		include/linux/types.h
 
 mostlyclean-local:
 	$(RM) -f \#* *~ core MAKELOG 
@@ -80,11 +81,20 @@
 	(cd /tmp/dest; tar cf - . ) | gzip -9 \
 		> e2fsprogs-@E2FSPROGS_VERSION@-@BINARY_TYPE@.tar.gz
 
+SRCROOT = `echo e2fsprogs-@E2FSPROGS_VERSION@ | sed -e 's/-WIP//'`
 
-Makefile: config.status $(srcdir)/Makefile.in
-	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+$(srcdir)/.exclude-file:
+	(cd $(srcdir)/.. ; find $(SRCROOT) \( -name \*~ -o -name \*.orig \
+		-o -name \*.rej \) -print > $(SRCROOT)/.exclude-file)
+	echo "$(SRCROOT)/build" >> $(srcdir)/.exclude-file
+	echo "$(SRCROOT)/todo" >> $(srcdir)/.exclude-file
+	echo "$(SRCROOT)/.exclude-file" >> $(srcdir)/.exclude-file
+	echo $(SRCROOT)/e2fsprogs-@E2FSPROGS_VERSION@.tar.gz \
+		>> $(srcdir)/.exclude-file
+	
 
-config.status: $(srcdir)/configure
-	./config.status --recheck
-$(srcdir)/configure: $(srcdir)/configure.in
-	cd $(srcdir) && autoconf
+source_tar_file: $(srcdir)/.exclude-file
+	(cd $(srcdir) ; tar -C .. -c -v -f - \
+		-X .exclude-file $(SRCROOT) | \
+		gzip -9 > e2fsprogs-@E2FSPROGS_VERSION@.tar.gz)
+	rm -f $(srcdir)/.exclude-file
diff --git a/README b/README
index 3c47df1..c8e2626 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-	This is the new version (1.02) of the second extended file system
-management programs.  
+	This is the new version (1.05) of the second extended file system
+management programs, otherwise known as the Monomonac Release.
 
 	See the file INSTALL for installation instructions.  This is
 important!  Note that your /etc/fstab file may need modifying before
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 470d322..1fa079f 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,3 +1,108 @@
+E2fsprogs 1.05 (September 7, 1996)
+==================================
+
+Add support for new fields in the ext2 superblock --- volume name,
+volume UUID, and last mounted field.  Dumpe2fs displays these fields,
+tune2fs and mke2fs allows you to set them.  E2fsck will automatically
+generate a UUID for those volumes that don't have them.  
+
+Put in support for e2fsck to recognize HURD specific ext2 features ---
+most notably, the translator block.  The e2fsprogs tools will now use
+the creator_os field in the superblock to correctly handle different
+OS-specific variants of the ext2 filesystem.
+
+E2fsck now fixes inodes which have a the deletion time set, but which
+have a non-zero i_link_count field by offering to clear the deletion
+time.  Previously e2fsck assumed that the inode was deleted (per 0.3c
+ext2 kernel behavior) and offered to unlink the file.
+
+If e2fsck sets the clean bit, but nothing else, set the exit code
+FSCK_NONDESTRUCT.  After all, e2fsck did fix a filesystem error --- it
+set the filesystem valid bit when it was previously cleared.  :-) This
+was needed to make the HURD fsck driver happy.
+
+If the  user  refuses to attach an  unattached  inode, e2fsck  will no
+longer set the inode's link count.  Otherwise, the  inode would end up
+getting marked as unused, which might cause loss of data later.
+
+Make the message issued by e2fsck when the superblock is corrupt less
+confusing for users.  It now mentions that another reason for the
+"corrupt superblock" message might be that the partition might not be
+an ext2 filesystem at all (it might swap, msdos filesystem, ufs, etc.)
+
+Make the libext2 library more robuest so that e2fsck won't coredump on
+an illegal superblock where the blocksize is zero.  (f_crashdisk is
+the test case).
+
+By default, create filesystems where the default checkinterval is 6
+months (180 days).  Linux servers can be robust enough that 20 reboots
+can be a long, long time.
+
+Added configure flag --enable-old-bitops, which forces the bitops to
+use the old (native) bitmask operations.  By default on the sparc
+platform, the standard ext2 bit ordering is now used.
+
+Added a new feature to e2fsck to byte-swap filesystems; this can be
+used to convert old m68k filesystems to use the standard byte-order
+storage for the superblock, inodes, and directory blocks.  This
+function is invoked by using the '-s' option to e2fsck.
+
+Debugfs's "dump" command has been enhanced so that it writes out the
+exact size of the file so that the nulls at the end of the file are
+eliminated.  The command also accept a new "-p" option which will
+attempt preserve to preserve the ownernship, permissions, and
+file modification/access times.
+
+Debugfs has two new options, -f and -R.  The -R option allows the user
+to execute a single debugfs command from the command line.  The -f
+option allows the user to specify a "command file" containing debugfs
+commands which will get executed.
+
+Dumpe2fs now pretty prints the check interval, instead of just
+printing the check interval as a number of seconds.
+
+Fix bugs in debugfs: the params command when no filesystem is opened
+no longer causes a core dump.  It is now possible to unlink a file
+when a pathame containing a '/' is specified.
+
+Tune2fs has a new -C option which sets the number of times the
+filesystem has been mounted.
+
+Fix the chattr '-v' option so that it actually works.  Chattr was
+being buggy about the -v option parsing.
+
+Programmers' notes:
+-------------------
+
+The directory lib/uuid contains a set of library routines to generate
+DCE compatible UUIDs.  
+
+Extended ext2fs_namei() to handle symbolic links.  Added new function
+ext2fs_nami_follow() which will follow last symbolic link in the case
+where the pathname points to a sym link.
+
+The ext2fs_block_iterate function will now return the HURD translator
+block, if present.  The new flag BLOCK_FLAG_DATA_ONLY will cause the
+iterator to return data blocks only.  The ext2fs.h file now defines
+constants BLOCK_COUNT_IND, BLOCK_COUNT_DIND, BLOCK_COUNT_TIND, and
+BLOCK_COUNT_TRANSLATOR, which are the magic values passed in the block
+count field of the iterator callback function.
+
+The test script driver now takes an optional second argument, which is
+the test case to be run.  This allows you to run a test case without
+needing to run the entire test suite.
+
+On Linux ELF systems, install the .so files in the correct places
+(/usr/lib).  The .so files must be stored in the same directory as the
+.a files.
+
+Fixed miscellaneous HURD compilation issues with header file being
+included in the right order.
+
+Fixed debugfs so that it resets optind to zero, not one, since setting
+optind to zero is more correct.
+
+
 E2fsprogs 1.04 (May 16, 1996)
 =============================
 
@@ -79,6 +184,8 @@
 with other filesytems.  This is not the safest thing in the world to
 do, but some system administrators really wanted it.
 
+Fixed -Wall flames in lib/ss.
+
 
 E2fsprogs 1.02 (January 16, 1996)
 =================================
diff --git a/configure b/configure
index 279bb44..6c5fc70 100644
--- a/configure
+++ b/configure
@@ -20,6 +20,8 @@
 ac_help="$ac_help
   --with-ldopts=LDOPTS    select linker command line options"
 ac_help="$ac_help
+  --with-usr-prefx=PREFIX specify a prefix corresponding to /usr (default ${prefix})"
+ac_help="$ac_help
   --enable-dll-shlibs	  select DLL libraries"
 ac_help="$ac_help
   --enable-elf-shlibs	  select ELF shared libraries"
@@ -33,6 +35,10 @@
   --enable-gcc-wall	  enable GCC anal warnings"
 ac_help="$ac_help
   --enable-dynamic-e2fsck build e2fsck dynamically"
+ac_help="$ac_help
+  --enable-fsck           build fsck wrapper program"
+ac_help="$ac_help
+  --enable-old-bitops	  Use old (non-standard but native) bitmask operations"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -458,6 +464,52 @@
 
 
 
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Make sure we can run config.sub.
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`$ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`$ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
 # Check whether --with-cc or --without-cc was given.
 withval="$with_cc"
 if test -n "$withval"; then
@@ -502,6 +554,13 @@
   LDFLAGS=
 fi
 
+# Check whether --with-usr-prefix or --without-usr-prefix was given.
+withval="$with_usr_prefix"
+if test -n "$withval"; then
+  usr_prefix=$withval
+else
+  usr_prefix=NONE
+fi
 # Check whether --enable-dll-shlibs or --disable-dll-shlibs was given.
 enableval="$enable_dll_shlibs"
 if test -n "$enableval"; then
@@ -664,8 +723,55 @@
 fi
 
 
+# Check whether --enable-fsck or --disable-fsck was given.
+enableval="$enable_fsck"
+if test -n "$enableval"; then
+  if test "$enableval" = "no"
+then
+	FSCK_PROG='' FSCK_MAN=''
+	echo "Not building fsck wrapper"
+else
+	FSCK_PROG=fsck FSCK_MAN=fsck.8
+	echo "Building fsck wrapper"
+fi
+
+else
+  case "$host_os" in
+  gnu*)
+    FSCK_PROG='' FSCK_MAN=''
+    echo "Not building fsck wrapper by default"
+    ;;
+  *)
+    FSCK_PROG=fsck FSCK_MAN=fsck.8
+    echo "Building fsck wrapper by default"
+esac
+
+fi
+
+
+
 MAKEFILE_LIBRARY=$srcdir/lib/Makefile.library
 
+# Check whether --enable-old-bitops or --disable-old-bitops was given.
+enableval="$enable_old_bitops"
+if test -n "$enableval"; then
+  if test "$enableval" = "no"
+then
+	echo "Using new (standard) bitmask operations"
+else
+	cat >> confdefs.h <<\EOF
+#define EXT2_OLD_BITOPS 1
+EOF
+
+	echo "Using old (native) bitmask operations"
+
+fi
+
+else
+  echo "Using standard bitmask operations by default"
+
+fi
+
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
 set dummy ${MAKE-make}; ac_make=$2
@@ -724,6 +830,26 @@
   echo "$ac_t""no" 1>&6
 fi
 
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
 # Extract the first word of "mv", so it can be a program name with args.
 set dummy mv; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
@@ -910,51 +1036,6 @@
   echo "$ac_t""no" 1>&6
 fi
 
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f $ac_dir/install.sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
-
-# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
-else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
-fi
-
-echo $ac_n "checking host system type""... $ac_c" 1>&6
-
-host_alias=$host
-case "$host_alias" in
-NONE)
-  case $nonopt in
-  NONE)
-    if host_alias=`$ac_config_guess`; then :
-    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
-    fi ;;
-  *) host_alias=$nonopt ;;
-  esac ;;
-esac
-
-host=`$ac_config_sub $host_alias`
-host_cpu=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\1/'`
-host_vendor=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\2/'`
-host_os=`echo $host | sed 's/^\(.*\)-\(.*\)-\(.*\)$/\3/'`
-echo "$ac_t""$host" 1>&6
-
 echo $ac_n "checking build system type""... $ac_c" 1>&6
 
 build_alias=$build
@@ -1301,7 +1382,7 @@
   ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 1305 "configure"
+#line 1386 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
@@ -1332,7 +1413,7 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1336 "configure"
+#line 1417 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1346,7 +1427,7 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1350 "configure"
+#line 1431 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -1371,7 +1452,7 @@
 fi
 echo "$ac_t""$CPP" 1>&6
 
-for ac_hdr in stdlib.h unistd.h stdarg.h errno.h mntent.h dirent.h getopt.h linux/fd.h linux/major.h sys/disklabel.h
+for ac_hdr in stdlib.h unistd.h stdarg.h errno.h mntent.h dirent.h getopt.h linux/fd.h linux/major.h sys/disklabel.h sys/sockio.h net/if.h netinet/in.h
 do
 ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@@ -1379,7 +1460,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1383 "configure"
+#line 1464 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
@@ -1412,7 +1493,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1416 "configure"
+#line 1497 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vprintf(); below.  */
@@ -1460,7 +1541,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1464 "configure"
+#line 1545 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char _doprnt(); below.  */
@@ -1509,7 +1590,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1513 "configure"
+#line 1594 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <dirent.h>
@@ -1541,6 +1622,7 @@
   ac_cv_sizeof_short=2
   ac_cv_sizeof_int=4
   ac_cv_sizeof_long=4
+  ac_cv_sizeof_long_long=0
   echo "configure: warning: Cross-compiling, so cannot check type sizes; assuming short=2, int=4, long=4" 1>&2
 fi
 echo $ac_n "checking size of short""... $ac_c" 1>&6
@@ -1551,7 +1633,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1555 "configure"
+#line 1637 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1585,7 +1667,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1589 "configure"
+#line 1671 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1619,7 +1701,7 @@
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
 cat > conftest.$ac_ext <<EOF
-#line 1623 "configure"
+#line 1705 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1645,9 +1727,45 @@
 EOF
 
 
+echo $ac_n "checking size of long long""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+cat > conftest.$ac_ext <<EOF
+#line 1739 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long long));
+  exit(0);
+}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+  ac_cv_sizeof_long_long=`cat conftestval`
+else
+  ac_cv_sizeof_long_long=0
+fi
+fi
+rm -fr conftest*
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+EOF
+
+
 SIZEOF_SHORT=$ac_cv_sizeof_short
 SIZEOF_INT=$ac_cv_sizeof_int
 SIZEOF_LONG=$ac_cv_sizeof_long
+SIZEOF_LONG_LONG=$ac_cv_sizeof_long_long
+
 
 
 
@@ -1656,7 +1774,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1660 "configure"
+#line 1778 "configure"
 #include "confdefs.h"
 #include <sys/stat.h>
 int main() { return 0; }
@@ -1682,14 +1800,14 @@
 EOF
 
 fi
-for ac_func in chflags getrusage llseek strdup getmntinfo
+for ac_func in chflags getrusage llseek strdup getmntinfo strcasecmp srandom fchown
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1693 "configure"
+#line 1811 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1733,13 +1851,44 @@
 fi
 done
 
+echo $ac_n "checking ino_t defined by sys/types.h""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'e2fsprogs_cv_ino_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1860 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+int main() { return 0; }
+int t() {
+ino_t ino; ino = 0;
+; return 0; }
+EOF
+if eval $ac_compile; then
+  rm -rf conftest*
+  e2fsprogs_cv_ino_t=yes
+else
+  rm -rf conftest*
+  e2fsprogs_cv_ino_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$e2fsprogs_cv_ino_t" 1>&6
+if test "$e2fsprogs_cv_ino_t" = yes; then
+   cat >> confdefs.h <<\EOF
+#define HAVE_INO_T 1
+EOF
+
+fi
 ac_safe=`echo "linux/fs.h" | tr './\055' '___'`
 echo $ac_n "checking for linux/fs.h""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1743 "configure"
+#line 1892 "configure"
 #include "confdefs.h"
 #include <linux/fs.h>
 EOF
@@ -1778,12 +1927,47 @@
   CPPFLAGS="$CPPFLAGS -I$srcdir/include -I./include"
 fi
 
+SOCKET_LIB=''
+echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_lib_socket'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1939 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+socket()
+; return 0; }
+EOF
+if eval $ac_link; then
+  rm -rf conftest*
+  eval "ac_cv_lib_socket=yes"
+else
+  rm -rf conftest*
+  eval "ac_cv_lib_socket=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'socket`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SOCKET_LIB=-lsocket
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
 echo $ac_n "checking for optreset""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_have_optreset'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1787 "configure"
+#line 1971 "configure"
 #include "confdefs.h"
 #include <unistd.h>
 EOF
@@ -1805,43 +1989,12 @@
 EOF
 
 fi
-echo $ac_n "checking whether struct ext2_inode has frags fields""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'e2fsprogs_cv_struct_ext2_inode_frags'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1814 "configure"
-#include "confdefs.h"
-#include <linux/ext2_fs.h>
-int main() { return 0; }
-int t() {
-struct ext2_inode i; i.i_frag = i.i_fsize = 0;
-; return 0; }
-EOF
-if eval $ac_compile; then
-  rm -rf conftest*
-  e2fsprogs_cv_struct_ext2_inode_frags=yes
-else
-  rm -rf conftest*
-  e2fsprogs_cv_struct_ext2_inode_frags=no
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$e2fsprogs_cv_struct_ext2_inode_frags" 1>&6
-if test "$e2fsprogs_cv_struct_ext2_inode_frags" = yes; then
-  cat >> confdefs.h <<\EOF
-#define HAVE_EXT2_FRAGS 1
-EOF
-
-fi
 echo $ac_n "checking whether the ext2 ioctls compile""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'e2fsprogs_cv_ioctl_ext2'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1845 "configure"
+#line 1998 "configure"
 #include "confdefs.h"
 #include <linux/ext2_fs.h>
 #include <sys/ioctl.h>
@@ -1868,30 +2021,35 @@
 EOF
 
 fi
-
 case "$host_os" in
 linux*)
 	if test "$prefix" = NONE ; then
-		prefix='/';
-		echo "On Linux systems, prefix defaults to '/'"
+		usr_prefix="\${prefix}/usr";
+		echo "On $host_os systems, usr_prefix defaults to $usr_prefix"
+	fi
+	;;
+esac
+if test "$usr_prefix" = NONE ; then
+	usr_prefix="\${prefix}"
+fi
+
+case "$host_os" in
+linux* | gnu*)
+	if test "$prefix" = NONE ; then
+		prefix='';
+		echo "On $host_os systems, prefix defaults to ''"
 	fi
 ;;
 esac
 
 LDFLAG_STATIC=
 case "$host_os" in
-linux*)
+linux* | gnu*)
 	LDFLAG_STATIC=-static
-	echo "On Linux systems, assume -static works"
+	echo "On $host_os systems, assume -static works"
 ;;
 esac
 
-if test "$prefix" = / ; then
-	usr_prefix=/usr
-else
-	usr_prefix="\${prefix}"
-fi
-
 SS_DIR=`cd ${srcdir}/lib/ss; pwd`
 ET_DIR=`cd ${srcdir}/lib/et; pwd`
 
@@ -2007,8 +2165,9 @@
 ac_given_INSTALL="$INSTALL"
 
 trap 'rm -fr `echo "MCONFIG lib/substitute_sh Makefile lib/et/Makefile 
-	lib/ss/Makefile lib/ext2fs/Makefile lib/e2p/Makefile misc/Makefile 
-	e2fsck/Makefile debugfs/Makefile tests/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+	lib/ss/Makefile lib/ext2fs/Makefile lib/e2p/Makefile lib/uuid/Makefile
+	misc/Makefile e2fsck/Makefile debugfs/Makefile tests/Makefile 
+	relocate/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 
 # Protect against being on the right side of a sed subst in config.status. 
 sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g; 
@@ -2029,6 +2188,11 @@
 s%@E2FSPROGS_YEAR@%$E2FSPROGS_YEAR%g
 s%@E2FSPROGS_MONTH@%$E2FSPROGS_MONTH%g
 s%@E2FSPROGS_VERSION@%$E2FSPROGS_VERSION%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
 s%@CC@%$CC%g
 s%@LD@%$LD%g
 s%@CCOPTS@%$CCOPTS%g
@@ -2052,22 +2216,20 @@
 s%@PROFILED_LIB_EXT@%$PROFILED_LIB_EXT%g
 s%@W@%$W%g
 s%@E2FSCK_TYPE@%$E2FSCK_TYPE%g
+s%@FSCK_PROG@%$FSCK_PROG%g
+s%@FSCK_MAN@%$FSCK_MAN%g
 /@MAKEFILE_LIBRARY@/r $MAKEFILE_LIBRARY
 s%@MAKEFILE_LIBRARY@%%g
 s%@BINARY_TYPE@%$BINARY_TYPE%g
 s%@SET_MAKE@%$SET_MAKE%g
 s%@LN@%$LN%g
+s%@LN_S@%$LN_S%g
 s%@MV@%$MV%g
 s%@CP@%$CP%g
 s%@RM@%$RM%g
 s%@CHMOD@%$CHMOD%g
 s%@AWK@%$AWK%g
 s%@SED@%$SED%g
-s%@host@%$host%g
-s%@host_alias@%$host_alias%g
-s%@host_cpu@%$host_cpu%g
-s%@host_vendor@%$host_vendor%g
-s%@host_os@%$host_os%g
 s%@build@%$build%g
 s%@build_alias@%$build_alias%g
 s%@build_cpu@%$build_cpu%g
@@ -2082,10 +2244,12 @@
 s%@SIZEOF_SHORT@%$SIZEOF_SHORT%g
 s%@SIZEOF_INT@%$SIZEOF_INT%g
 s%@SIZEOF_LONG@%$SIZEOF_LONG%g
+s%@SIZEOF_LONG_LONG@%$SIZEOF_LONG_LONG%g
 s%@EXTRA_PROGS@%$EXTRA_PROGS%g
 s%@LINUX_INCLUDE@%$LINUX_INCLUDE%g
-s%@LDFLAG_STATIC@%$LDFLAG_STATIC%g
+s%@SOCKET_LIB@%$SOCKET_LIB%g
 s%@usr_prefix@%$usr_prefix%g
+s%@LDFLAG_STATIC@%$LDFLAG_STATIC%g
 s%@SS_DIR@%$SS_DIR%g
 s%@ET_DIR@%$ET_DIR%g
 s%@DO_TEST_SUITE@%$DO_TEST_SUITE%g
@@ -2097,8 +2261,9 @@
 cat >> $CONFIG_STATUS <<EOF
 
 CONFIG_FILES=\${CONFIG_FILES-"MCONFIG lib/substitute_sh Makefile lib/et/Makefile 
-	lib/ss/Makefile lib/ext2fs/Makefile lib/e2p/Makefile misc/Makefile 
-	e2fsck/Makefile debugfs/Makefile tests/Makefile"}
+	lib/ss/Makefile lib/ext2fs/Makefile lib/e2p/Makefile lib/uuid/Makefile
+	misc/Makefile e2fsck/Makefile debugfs/Makefile tests/Makefile 
+	relocate/Makefile"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
diff --git a/configure.in b/configure.in
index 7d134b6..3a99161 100644
--- a/configure.in
+++ b/configure.in
@@ -40,6 +40,7 @@
 AC_SUBST(E2FSPROGS_YEAR)
 AC_SUBST(E2FSPROGS_MONTH)
 AC_SUBST(E2FSPROGS_VERSION)
+AC_REQUIRE([AC_CANONICAL_HOST])
 dnl
 dnl set $(CC) from --with-cc=value
 dnl
@@ -89,6 +90,13 @@
 LDFLAGS=)dnl
 AC_SUBST(LDFLAGS)
 dnl
+dnl Allow separate `usr_prefix' to be specified
+dnl
+AC_ARG_WITH([usr-prefix],
+[  --with-usr-prefx=PREFIX specify a prefix corresponding to /usr (default ${prefix})],
+usr_prefix=$withval,
+usr_prefix=NONE)dnl
+dnl
 dnl handle --enable-dll-shlibs
 dnl
 AC_ARG_ENABLE([dll-shlibs],
@@ -244,15 +252,57 @@
 )
 AC_SUBST(E2FSCK_TYPE)
 dnl
+dnl See whether to install the `fsck' wrapper program (that calls e2fsck)
+dnl
+AC_ARG_ENABLE([fsck],
+[  --enable-fsck           build fsck wrapper program],
+[if test "$enableval" = "no"
+then
+	FSCK_PROG='' FSCK_MAN=''
+	echo "Not building fsck wrapper"
+else
+	FSCK_PROG=fsck FSCK_MAN=fsck.8
+	echo "Building fsck wrapper"
+fi]
+,
+[case "$host_os" in
+  gnu*)
+    FSCK_PROG='' FSCK_MAN=''
+    echo "Not building fsck wrapper by default"
+    ;;
+  *)
+    FSCK_PROG=fsck FSCK_MAN=fsck.8
+    echo "Building fsck wrapper by default"
+esac]
+)
+AC_SUBST(FSCK_PROG)
+AC_SUBST(FSCK_MAN)
+dnl
 dnl
 MAKEFILE_LIBRARY=$srcdir/lib/Makefile.library
 AC_SUBST_FILE(MAKEFILE_LIBRARY)
 dnl
+dnl
+AC_ARG_ENABLE([old-bitops],
+[  --enable-old-bitops	  Use old (non-standard but native) bitmask operations],
+if test "$enableval" = "no"
+then
+	echo "Using new (standard) bitmask operations"
+else
+	AC_DEFINE(EXT2_OLD_BITOPS)
+	echo "Using old (native) bitmask operations"
+
+fi
+,
+echo "Using standard bitmask operations by default"
+)
+dnl
 dnl End of configuration options
 dnl
 AC_SUBST(BINARY_TYPE)
 AC_PROG_MAKE_SET
 AC_PATH_PROG(LN, ln, ln)
+AC_PROG_LN_S
 AC_PATH_PROG(MV, mv, mv)
 AC_PATH_PROG(CP, cp, cp)
 AC_PATH_PROG(RM, rm, rm)
@@ -265,7 +315,7 @@
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_C_CROSS
-AC_CHECK_HEADERS(stdlib.h unistd.h stdarg.h errno.h mntent.h dirent.h getopt.h linux/fd.h linux/major.h sys/disklabel.h)
+AC_CHECK_HEADERS(stdlib.h unistd.h stdarg.h errno.h mntent.h dirent.h getopt.h linux/fd.h linux/major.h sys/disklabel.h sys/sockio.h net/if.h netinet/in.h)
 AC_FUNC_VPRINTF
 dnl
 dnl See if struct dirent has a d_namlen field (like bsd systems), implying
@@ -292,17 +342,21 @@
   ac_cv_sizeof_short=2
   ac_cv_sizeof_int=4
   ac_cv_sizeof_long=4
+  ac_cv_sizeof_long_long=0
   AC_MSG_WARN([Cross-compiling, so cannot check type sizes; assuming short=2, int=4, long=4])
 fi
 AC_CHECK_SIZEOF(short)
 AC_CHECK_SIZEOF(int)
 AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(long long)
 SIZEOF_SHORT=$ac_cv_sizeof_short
 SIZEOF_INT=$ac_cv_sizeof_int
 SIZEOF_LONG=$ac_cv_sizeof_long
+SIZEOF_LONG_LONG=$ac_cv_sizeof_long_long
 AC_SUBST(SIZEOF_SHORT)
 AC_SUBST(SIZEOF_INT)
 AC_SUBST(SIZEOF_LONG)
+AC_SUBST(SIZEOF_LONG_LONG)
 dnl
 dnl See if struct stat has a st_flags field, in which case we can get file
 dnl flags somewhat portably.  Also check for the analogous setter, chflags().
@@ -317,7 +371,20 @@
 if test "$e2fsprogs_cv_struct_st_flags" = yes; then
   AC_DEFINE(HAVE_STAT_FLAGS)
 fi
-AC_CHECK_FUNCS(chflags getrusage llseek strdup getmntinfo)
+AC_CHECK_FUNCS(chflags getrusage llseek strdup getmntinfo strcasecmp srandom fchown)
+dnl
+dnl Check to see if ino_t is defined
+dnl
+AC_MSG_CHECKING(ino_t defined by sys/types.h)
+AC_CACHE_VAL(e2fsprogs_cv_ino_t,
+	AC_TRY_COMPILE([#include <sys/types.h>],
+	[ino_t ino; ino = 0;],
+	[e2fsprogs_cv_ino_t=yes],
+	[e2fsprogs_cv_ino_t=no]))
+AC_MSG_RESULT($e2fsprogs_cv_ino_t)
+if test "$e2fsprogs_cv_ino_t" = yes; then
+   AC_DEFINE(HAVE_INO_T)
+fi
 dnl
 dnl On systems without linux header files, we add an extra include directory
 dnl that holds enough to fake it (hopefully).  Note that the $(top_srcdir) here
@@ -337,6 +404,13 @@
 fi
 AC_SUBST(LINUX_INCLUDE)
 dnl
+dnl Check to see if -lsocket is required (solaris) to make something
+dnl that uses socket() to compile; this is needed for the UUID library
+dnl
+SOCKET_LIB=''
+AC_CHECK_LIB(socket, socket, [SOCKET_LIB=-lsocket])
+AC_SUBST(SOCKET_LIB)
+dnl
 dnl See if optreset exists
 dnl
 AC_MSG_CHECKING(for optreset)
@@ -348,19 +422,6 @@
   AC_DEFINE(HAVE_OPTRESET)
 fi
 dnl
-dnl See if our system has frags enabled (at least in the header file)
-dnl
-AC_MSG_CHECKING(whether struct ext2_inode has frags fields)
-AC_CACHE_VAL(e2fsprogs_cv_struct_ext2_inode_frags,
-	AC_TRY_COMPILE([#include <linux/ext2_fs.h>],
-		[struct ext2_inode i; i.i_frag = i.i_fsize = 0;],
-		[e2fsprogs_cv_struct_ext2_inode_frags=yes],
-		[e2fsprogs_cv_struct_ext2_inode_frags=no]))
-AC_MSG_RESULT($e2fsprogs_cv_struct_ext2_inode_frags)
-if test "$e2fsprogs_cv_struct_ext2_inode_frags" = yes; then
-  AC_DEFINE(HAVE_EXT2_FRAGS)
-fi
-dnl
 dnl See if using the EXT2 ioctls causes a compile-time barf (as on the hurd).
 dnl
 AC_MSG_CHECKING(whether the ext2 ioctls compile)
@@ -375,40 +436,45 @@
   AC_DEFINE(HAVE_EXT2_IOCTLS)
 fi
 dnl
-dnl On linux, force the prefix to be '/'
+dnl Linux uses a separate usr_prefix by default
 dnl
-AC_REQUIRE([AC_CANONICAL_HOST])
 case "$host_os" in
 linux*)
 	if test "$prefix" = NONE ; then
-		prefix='/';
-		echo "On Linux systems, prefix defaults to '/'"
+		usr_prefix="\${prefix}/usr";
+		echo "On $host_os systems, usr_prefix defaults to $usr_prefix"
+	fi
+	;;
+esac
+if test "$usr_prefix" = NONE ; then
+	usr_prefix="\${prefix}"
+fi
+AC_SUBST(usr_prefix)
+dnl
+dnl On Linux/hurd, force the prefix to be ''
+dnl
+case "$host_os" in
+linux* | gnu*)
+	if test "$prefix" = NONE ; then
+		prefix='';
+		echo "On $host_os systems, prefix defaults to ''"
 	fi
 ;;
 esac
 dnl
 dnl See if -static works.
-dnl XXX for now, assume that only Linux systems support -static
+dnl XXX for now, assume that only Linux/hurd systems support -static
 dnl
 AC_REQUIRE([AC_CANONICAL_HOST])
 LDFLAG_STATIC=
 case "$host_os" in
-linux*)
+linux* | gnu*)
 	LDFLAG_STATIC=-static
-	echo "On Linux systems, assume -static works"
+	echo "On $host_os systems, assume -static works"
 ;;
 esac
 AC_SUBST(LDFLAG_STATIC)
 dnl
-dnl Check to see if prefix is '/'
-dnl
-if test "$prefix" = / ; then
-	usr_prefix=/usr
-else
-	usr_prefix="\${prefix}"
-fi
-AC_SUBST(usr_prefix)
-dnl
 dnl Make the ss and et directories work correctly.
 dnl
 SS_DIR=`cd ${srcdir}/lib/ss; pwd`
@@ -437,5 +503,6 @@
 test -d include || mkdir include
 test -d include/linux || mkdir include/linux
 AC_OUTPUT(MCONFIG lib/substitute_sh Makefile lib/et/Makefile 
-	lib/ss/Makefile lib/ext2fs/Makefile lib/e2p/Makefile misc/Makefile 
-	e2fsck/Makefile debugfs/Makefile tests/Makefile)
+	lib/ss/Makefile lib/ext2fs/Makefile lib/e2p/Makefile lib/uuid/Makefile
+	misc/Makefile e2fsck/Makefile debugfs/Makefile tests/Makefile 
+	relocate/Makefile)
diff --git a/debugfs/ChangeLog b/debugfs/ChangeLog
index 68020df..a1b4125 100644
--- a/debugfs/ChangeLog
+++ b/debugfs/ChangeLog
@@ -1,3 +1,46 @@
+Mon Sep  9 23:05:11 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* debugfs.c (unlink_file_by_name): If unlinking a file with a
+		directory path, correctly replace the slash with a NULL.
+		(do_show_debugfs_params): Don't try to print the open mode
+		if there's no filesystem opened (since that will cause a
+		core dump).
+		(main): Fix usage string; the -w and device elements are
+		independently optional.
+
+Tu Sep  3 15:09:39 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* debugfs.c (main): Added -f option to debugfs, which takes a
+		command file of debugfs commands and executes them.
+
+Sat Aug 31 01:18:43 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* debugfs.8.in: Heavily edited and improved manual page.
+
+	* dump.c (dump_file): Improve the write function for writing out
+		the file, so that it is limited to the actual size of the
+		file, instead of outputing the nulls following the EOF.
+		Make sure dump_file does the right thing for files with holes.
+		(do_dump): Add support for the -p option to the dump
+		command, which attempts to preserve the owner and
+		permissions field.
+
+Fri Aug 30 14:56:59 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* debugfs.c (main): Add -R option to debugfs, which allows it to
+		take a single debugfs command on the command line.
+
+Fri Aug  9 09:03:31 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+	* debugfs.c (do_open_filesys): Set optind to 0 to reset getopt(),
+ 		to be complete correct.
+		(do_show_super_stats): Print OS type, volume label, last
+ 		mounted directory, and UUID.
+		(dump_inode): Print the fragment information in a
+ 		filesystem independent way.
+		(do_modify_inode): Modify the fragement information in a
+ 		filesystem independent way.
+
 Thu May 16 11:12:30 1996  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
 	* Release of E2fsprogs version 1.04
diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
index 264d042..da9af49 100644
--- a/debugfs/Makefile.in
+++ b/debugfs/Makefile.in
@@ -6,6 +6,7 @@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
 top_builddir = ..
+my_dir = debugfs
 INSTALL = @INSTALL@
 
 @MCONFIG@
@@ -21,8 +22,8 @@
 	$(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \
 	$(srcdir)/dump.c
 
-LIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR) 
-DEPLIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR) 
+LIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR)  $(LIBUUID)
+DEPLIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR)  $(LIBUUID)
 
 .c.o:
 	$(CC) -c $(ALL_CFLAGS) $< -o $@
@@ -72,13 +73,14 @@
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-debug_cmds.o: debug_cmds.c $(top_srcdir)/lib/ss/ss.h $(top_srcdir)/lib/ss/copyright.h \
- $(top_builddir)/lib/ss/ss_err.h
+debug_cmds.o: debug_cmds.c  $(top_builddir)/lib/ss/ss_err.h \
+ $(top_srcdir)/lib/ss/ss.h $(top_srcdir)/lib/ss/copyright.h
 debugfs.o: $(srcdir)/debugfs.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ss/ss.h $(top_srcdir)/lib/ss/copyright.h \
  $(top_builddir)/lib/ss/ss_err.h $(srcdir)/debugfs.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/uuid/uuid.h
 util.o: $(srcdir)/util.c $(srcdir)/debugfs.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
@@ -99,4 +101,3 @@
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/bitops.h
-
diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in
index 28c83db..dc6352a 100644
--- a/debugfs/debugfs.8.in
+++ b/debugfs/debugfs.8.in
@@ -8,13 +8,23 @@
 .SH SYNOPSIS
 .B debugfs
 [
-[
 .B \-w
 ]
+[
+.B \-f 
+cmd_file
+]
+[
+.B \-R
+request
+]
+[
 device
 ]
 .SH DESCRIPTION
-.B debugfs
+The 
+.B debugfs 
+program
 is a file system debugger. It can be used to examine and change the
 state of an ext2 file system.
 .br
@@ -26,31 +36,61 @@
 .I -w
 Specify that the file system should be open in read-write mode. Without this
 option, the file system is open in read-only mode.
+.TP
+.I -f cmd_file
+Causes 
+.B debugfs
+to read in commands from 
+.IR cmd_file , 
+and execute them.  When 
+.B debugfs
+is finsihed executing those commands, it will exit.
+.TP 
+.I -R request
+Causes 
+.B debugfs
+to execute the single command 
+.IR request ,
+and then exit.
 .SH COMMANDS
 .B debugfs
 is an interactive debugger. It understands a number of commands.
 .TP
-.I cat <file>
-Dump the contents of an inode to stdout.
+.I cat filespec
+Dump the contents of the inode 
+.I filespec
+to stdout.
 .TP
-.I cd <directory>
-Change the current working directory to specified directory
+.I cd filespec
+Change the current working directory to 
+.IR filespec .
 .TP
-.I chroot <directory>
-Change the root directory to be the specified inode.
+.I chroot filespec
+Change the root directory to be the directory 
+.IR filespec .
 .TP
 .I close
 Close the currently open file system.
 .TP
-.I clri <file>
-Clear the contents of the inode corresponding to
-.I file
+.I clri file
+Clear the contents of the inode 
+.IR file .
 .TP
-.I dump <file> <out_file>
-Dump the contents of an inode to a file.
+.I dump [-p] filspec out_file
+Dump the contents of the inode 
+.I filespec
+to the output file 
+.IR out_file .  
+If the 
+.I -p 
+option is given set the owner, group and permissions information on 
+.I out_file 
+to match 
+.IR filespec .
 .TP
-.I expand_dir <file>
-Expand a directory.
+.I expand_dir filespec
+Expand the directory
+.IR filespec .
 .TP
 .I find_free_block [goal]
 Find the first free block, starting from
@@ -58,57 +98,83 @@
 and allocates it.
 .TP
 .I find_free_inode [dir [mode]]
-Find a free inode and allocates it.
+Find a free inode and allocates it.  If present, 
+.I dir
+specifies the inode number of the directory 
+which the inode is to be located.  The second 
+optional argument
+.I mode
+specifies the permissions of the new inode.  (If the directory bit is set
+on the mode, the allocation routine will function differently.)
 .TP
-.I freeb <block>
-Mark the block as not allocated.
+.I freeb block
+Mark the block number
+.I block
+as not allocated.
 .TP
-.I freei <file>
-Free the inode corresponding to
-.I file
+.I freei filespec
+Free the inode specified by 
+.I filespec
 .TP
 .I help
 Print a list of commands understood by 
 .BR debugfs (8).
 .TP
-.I icheck <block>
-Do block->inode translation.
+.I icheck block ...
+Print a listing of the inodes which use the one or more block specified
+on the command line.
 .TP
-.I iname <inode>
-Print the file name corresponding to
-.I inode
-(currently not implemented - see ncheck).
-.TP
-.I initialize <device> <blocksize>
+.I initialize device blocksize
 Create an ext2 file system on
 .I device
+with device size
+.IR blocksize .
+Note that this does not fully initialize all of the data structures; 
+to do this, use the 
+.BR mke2fs (8)
+program.  This is just a call to the low-level library, which sets up
+the superblock and block descriptors.
 .TP
-.I kill_file <file>
-Remove a file and deallocates its blocks.
+.I kill_file filespec
+Dellocate the inode 
+.I filespec
+and its blocks.  Note that this does not remove any directory
+entries (if any) to this inode.  See the 
+.I rm
+command if you wish to unlink a file.
 .TP
-.I ln <source_file> <dest_file>
-Create a link.
+.I ln filespec dest_file
+Create a link named 
+.I dest_file
+which is a link to 
+.IR filespec .
+Note this does not adjust the inode reference counts.
 .TP
-.I ls [pathname]
-Emulate the
-.BR ls (1)
-command.
+.I ls filespec
+Print a listing of the files in the directory
+.IR filespec .
 .TP
-.I modify_inode <file>
-Modify the contents of the inode corresponding to
-.I file
+.I modify_inode filespec
+Modify the contents of the inode structure in the inode
+.IR filespec .
 .TP
-.I mkdir <file>
+.I mkdir filespec
 Make a directory.
 .TP
-.I mknod <file> [p|[[c|b] <major> <minor>]]
-Create a special device file
+.I mknod filespec [p|[[c|b] major minor]]
+Create a special device file (a named pipe, character or block device).
+If a character or block device is to be made, the 
+.I major
+and
+.I minor
+device numbers must be specified.
 .TP
-.I ncheck <inode>
-Do inode->name translation.
+.I ncheck inode_num ...
+Take the requested list of inode numbers, and print a listing of pathnams
+to those inodes.
 .TP
-.I open [-w] <device>
-Open a file system.
+.I open [-w] device
+Open a file system for editing.  
 .TP
 .I pwd
 Print the current working directory.
@@ -117,43 +183,75 @@
 Quit
 .B debugfs
 .TP
-.I rm <file>
-Remove a file.
+.I rm pathname
+Unlink 
+.IR pathname .
+If this cuases the inode pointed to by 
+.I pathname
+to have no other references, deallocate the file.  This command functions
+as the unlink() system call.
+.I 
 .TP
-.I rmdir <directory>
-Remove a directory.
+.I rmdir filespec
+Remove the directory
+.IR filespec .
+This function is currently not implemented.
 .TP
-.I setb <block>
-Mark the block as allocated.
+.I setb block
+Mark the block number
+.I block
+as allocated.
 .TP
-.I seti <file>
-Mark in use the inode corresponding to
-.I file
+.I seti filespec
+Mark inode 
+.I filespec
+as in use in the inode bitmap.
 .TP
 .I show_super_stats
 List the contents of the super block.
 .TP
-.I stat <file>
-Dump the contents of the inode corresponding to
-.I file
+.I stat filespec
+Display the contents of the inode structure of the inode
+.IR filespec .
 .TP
-.I testb <block>
-Test if the block is marked as allocated.
+.I testb block
+Test if the block number
+.I block
+is marked as allocated in the block bitmap.
 .TP
-.I testi <file>
-Test if the inode correponding to
-.I file
-is marked as allocated.
+.I testi filespec
+Test if the inode 
+.I filespec
+is marked as allocated in the inode bitmap.
 .TP
-.I unlink <file>
-Remove a link.
+.I unlink pathname
+Remove the link specified by 
+.I pathname 
+to an inode.  Note this does not adjust the inode reference counts.
 .TP
-.I write source_file <file>
+.I write source_file out_file
 Create a file in the filesystem named
-.IR file ,
+.IR out_file ,
 and copy the contents of
 .I source_file
 into the destination file.
+.SH SPECIFYING FILES
+Many
+.B debugfs
+commands take a
+.I filespec
+as an argument to specify an inode (as opposed to a pathname) 
+in the filesystem which is currently opened by debugfs. The
+.I filespec
+argument may be specified in two forms.  The first form is an inode 
+number surrounded by angle brackets, e.g., 
+.IR <2> .
+The second form is a pathname; if the pathname is prefixed by a forward slash
+('/'), then it is interpreted relative to the root of the filesystem 
+which is currently opened by debugfs.  If not, the pathname is 
+interpreted relative to the current working directory as maintained 
+by debugfs.  This may be modified by using the debugfs command
+.IR cd .
 .SH AUTHOR
 .B debugfs
 was written by Theodore Ts'o <tytso@mit.edu>.
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 71437c0..7a4fc49 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -33,28 +33,30 @@
 #include "et/com_err.h"
 #include "ss/ss.h"
 #include "debugfs.h"
+#include "uuid/uuid.h"
 
 extern ss_request_table debug_cmds;
 
-ext2_filsys fs = NULL;
+ext2_filsys current_fs = NULL;
 ino_t	root, cwd;
 
 static void open_filesystem(char *device, int open_flags)
 {
 	int	retval;
 	
-	retval = ext2fs_open(device, open_flags, 0, 0, unix_io_manager, &fs);
+	retval = ext2fs_open(device, open_flags, 0, 0,
+			     unix_io_manager, &current_fs);
 	if (retval) {
 		com_err(device, retval, "while opening filesystem");
-		fs = NULL;
+		current_fs = NULL;
 		return;
 	}
-	retval = ext2fs_read_inode_bitmap(fs);
+	retval = ext2fs_read_inode_bitmap(current_fs);
 	if (retval) {
 		com_err(device, retval, "while reading inode bitmap");
 		goto errout;
 	}
-	retval = ext2fs_read_block_bitmap(fs);
+	retval = ext2fs_read_block_bitmap(current_fs);
 	if (retval) {
 		com_err(device, retval, "while reading block bitmap");
 		goto errout;
@@ -63,10 +65,10 @@
 	return;
 
 errout:
-	retval = ext2fs_close(fs);
+	retval = ext2fs_close(current_fs);
 	if (retval)
 		com_err(device, retval, "while trying to close filesystem");
-	fs = NULL;
+	current_fs = NULL;
 }
 
 void do_open_filesys(int argc, char **argv)
@@ -75,7 +77,7 @@
 	char	c;
 	int open_flags = 0;
 	
-	optind = 1;
+	optind = 0;
 #ifdef HAVE_OPTRESET
 	optreset = 1;		/* Makes BSD getopt happy */
 #endif
@@ -102,20 +104,20 @@
 {
 	int	retval;
 	
-	if (fs->flags & EXT2_FLAG_IB_DIRTY) {
-		retval = ext2fs_write_inode_bitmap(fs);
+	if (current_fs->flags & EXT2_FLAG_IB_DIRTY) {
+		retval = ext2fs_write_inode_bitmap(current_fs);
 		if (retval)
 			com_err("ext2fs_write_inode_bitmap", retval, "");
 	}
-	if (fs->flags & EXT2_FLAG_BB_DIRTY) {
-		retval = ext2fs_write_block_bitmap(fs);
+	if (current_fs->flags & EXT2_FLAG_BB_DIRTY) {
+		retval = ext2fs_write_block_bitmap(current_fs);
 		if (retval)
 			com_err("ext2fs_write_block_bitmap", retval, "");
 	}
-	retval = ext2fs_close(fs);
+	retval = ext2fs_close(current_fs);
 	if (retval)
 		com_err("ext2fs_close", retval, "");
-	fs = NULL;
+	current_fs = NULL;
 	return;
 }
 
@@ -150,10 +152,11 @@
 		com_err(argv[0], 0, "Bad blocks count - %s", argv[2]);
 		return;
 	}
-	retval = ext2fs_initialize(argv[1], 0, &param, unix_io_manager, &fs);
+	retval = ext2fs_initialize(argv[1], 0, &param,
+				   unix_io_manager, &current_fs);
 	if (retval) {
 		com_err(argv[1], retval, "while initializing filesystem");
-		fs = NULL;
+		current_fs = NULL;
 		return;
 	}
 	root = cwd = EXT2_ROOT_INO;
@@ -164,6 +167,10 @@
 {
 	int	i;
 	FILE 	*out;
+	struct ext2fs_sb *sb;
+	struct ext2_group_desc *gdp;
+	char buf[80];
+	const char *none = "(none)";
 
 	if (argc > 1) {
 		com_err(argv[0], 0, "Usage: show_super");
@@ -172,43 +179,72 @@
 	if (check_fs_open(argv[0]))
 		return;
 	out = open_pager();
-	fprintf(out, "Filesystem is read-%s\n", fs->flags & EXT2_FLAG_RW ?
-	        "write" : "only");
-	fprintf(out, "Last mount time = %s", ctime(&fs->super->s_mtime));
-	fprintf(out, "Last write time = %s", ctime(&fs->super->s_wtime));
+	sb = (struct ext2fs_sb *) current_fs->super;
+	fprintf(out, "Filesystem is read-%s\n",
+		current_fs->flags & EXT2_FLAG_RW ? "write" : "only");
+	if (sb->s_volume_name[0]) {
+		memset(buf, 0, sizeof(buf));
+		strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name));
+	} else
+		strcpy(buf, none);
+	fprintf(out, "Volume name = %s\n", buf);
+	if (sb->s_last_mounted[0]) {
+		memset(buf, 0, sizeof(buf));
+		strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted));
+	} else
+		strcpy(buf, none);
+	fprintf(out, "Last mounted directory = %s\n", buf);
+	if (!uuid_is_null(sb->s_uuid))
+		uuid_unparse(sb->s_uuid, buf);
+	else
+		strcpy(buf, none);
+	fprintf(out, "Filesystem UUID = %s\n", buf);
+	fprintf(out, "Last mount time = %s", time_to_string(sb->s_mtime));
+	fprintf(out, "Last write time = %s", time_to_string(sb->s_wtime));
 	fprintf(out, "Mount counts = %d (maximal = %d)\n",
-		fs->super->s_mnt_count, fs->super->s_max_mnt_count);
-	fprintf(out, "Superblock size = %d\n", sizeof(struct ext2_super_block));
+		sb->s_mnt_count, sb->s_max_mnt_count);
+	fputs ("Filesystem OS type = ", out);
+	switch (sb->s_creator_os) {
+	    case EXT2_OS_LINUX: fputs ("Linux\n", out); break;
+	    case EXT2_OS_HURD:  fputs ("GNU\n", out); break;
+	    case EXT2_OS_MASIX: fputs ("Masix\n", out); break;
+	    default:		fputs ("unknown\n", out);
+	}
+	fprintf(out, "Superblock size = %d\n",
+		sizeof(struct ext2_super_block));
 	fprintf(out, "Block size = %d, fragment size = %d\n",
-		EXT2_BLOCK_SIZE(fs->super), EXT2_FRAG_SIZE(fs->super));
-	fprintf(out, "Inode size = %d\n", EXT2_INODE_SIZE(fs->super));
-	fprintf(out, "%d inodes, %d free\n", fs->super->s_inodes_count,
-	        fs->super->s_free_inodes_count);
+		EXT2_BLOCK_SIZE(sb), EXT2_FRAG_SIZE(sb));
+	fprintf(out, "Inode size = %d\n", EXT2_INODE_SIZE(sb));
+	fprintf(out, "%d inodes, %d free\n", sb->s_inodes_count,
+	        sb->s_free_inodes_count);
 	fprintf(out, "%d blocks, %d free, %d reserved, first block = %d\n",
-	        fs->super->s_blocks_count, fs->super->s_free_blocks_count,
-	        fs->super->s_r_blocks_count, fs->super->s_first_data_block);
-	fprintf(out, "%d blocks per group\n", fs->super->s_blocks_per_group);
-	fprintf(out, "%d fragments per group\n", fs->super->s_frags_per_group);
-	fprintf(out, "%d inodes per group\n", EXT2_INODES_PER_GROUP(fs->super));
+	        sb->s_blocks_count, sb->s_free_blocks_count,
+	        sb->s_r_blocks_count, sb->s_first_data_block);
+	fprintf(out, "%d blocks per group\n", sb->s_blocks_per_group);
+	fprintf(out, "%d fragments per group\n", sb->s_frags_per_group);
+	fprintf(out, "%d inodes per group\n", EXT2_INODES_PER_GROUP(sb));
 	fprintf(out, "%ld group%s (%ld descriptors block%s)\n",
-		fs->group_desc_count, (fs->group_desc_count != 1) ? "s" : "",
-		fs->desc_blocks, (fs->desc_blocks != 1) ? "s" : "");
-	for (i = 0; i < fs->group_desc_count; i++)
+		current_fs->group_desc_count,
+		(current_fs->group_desc_count != 1) ? "s" : "",
+		current_fs->desc_blocks,
+		(current_fs->desc_blocks != 1) ? "s" : "");
+	
+	gdp = &current_fs->group_desc[0];
+	for (i = 0; i < current_fs->group_desc_count; i++, gdp++)
 		fprintf(out, " Group %2d: block bitmap at %d, "
 		        "inode bitmap at %d, "
 		        "inode table at %d\n"
 		        "           %d free block%s, "
 		        "%d free inode%s, "
 		        "%d used director%s\n",
-		        i, fs->group_desc[i].bg_block_bitmap,
-		        fs->group_desc[i].bg_inode_bitmap,
-		        fs->group_desc[i].bg_inode_table,
-		        fs->group_desc[i].bg_free_blocks_count,
-		        fs->group_desc[i].bg_free_blocks_count != 1 ? "s" : "",
-		        fs->group_desc[i].bg_free_inodes_count,
-		        fs->group_desc[i].bg_free_inodes_count != 1 ? "s" : "",
-		        fs->group_desc[i].bg_used_dirs_count,
-		        fs->group_desc[i].bg_used_dirs_count != 1 ? "ies" : "y");
+		        i, gdp->bg_block_bitmap,
+		        gdp->bg_inode_bitmap, gdp->bg_inode_table,
+		        gdp->bg_free_blocks_count,
+		        gdp->bg_free_blocks_count != 1 ? "s" : "",
+		        gdp->bg_free_inodes_count,
+		        gdp->bg_free_inodes_count != 1 ? "s" : "",
+		        gdp->bg_used_dirs_count,
+		        gdp->bg_used_dirs_count != 1 ? "ies" : "y");
 	close_pager(out);
 }
 
@@ -235,7 +271,8 @@
 	fprintf(f, "BLOCKS:\n");
 	lb.total = 0;
 	lb.f = f;
-	ext2fs_block_iterate(fs,inode,0,NULL,list_blocks_proc,(void *)&lb);
+	ext2fs_block_iterate(current_fs, inode, 0, NULL,
+			     list_blocks_proc, (void *)&lb);
 	if (lb.total)
 		fprintf(f, "\nTOTAL: %d\n", lb.total);
 	fprintf(f,"\n");
@@ -246,6 +283,8 @@
 {
 	const char *i_type;
 	FILE	*out;
+	char frag, fsize;
+	int os = current_fs->super->s_creator_os;
 	
 	out = open_pager();
 	if (LINUX_S_ISDIR(inode.i_mode)) i_type = "directory";
@@ -261,7 +300,7 @@
 		inode.i_mode & 0777, inode.i_flags, inode.i_version);
 	fprintf(out, "User: %5d   Group: %5d   Size: %d\n",  
 		inode.i_uid, inode.i_gid, inode.i_size);
-	if (fs->super->s_creator_os == EXT2_OS_HURD)
+	if (current_fs->super->s_creator_os == EXT2_OS_HURD)
 		fprintf(out,
 			"File ACL: %d    Directory ACL: %d Translator: %d\n",
 			inode.i_file_acl, inode.i_dir_acl,
@@ -271,19 +310,33 @@
 			inode.i_file_acl, inode.i_dir_acl);
 	fprintf(out, "Links: %d   Blockcount: %d\n", inode.i_links_count,
 		inode.i_blocks);
-#if HAVE_EXT2_FRAGS
+	switch (os) {
+	    case EXT2_OS_LINUX:
+		frag = inode.osd2.linux2.l_i_frag;
+		fsize = inode.osd2.linux2.l_i_fsize;
+		break;
+	    case EXT2_OS_HURD:
+		frag = inode.osd2.hurd2.h_i_frag;
+		fsize = inode.osd2.hurd2.h_i_fsize;
+		break;
+	    case EXT2_OS_MASIX:
+		frag = inode.osd2.masix2.m_i_frag;
+		fsize = inode.osd2.masix2.m_i_fsize;
+		break;
+	    default:
+		frag = fsize = 0;
+	}
 	fprintf(out, "Fragment:  Address: %d    Number: %d    Size: %d\n",
-		inode.i_faddr, inode.i_frag, inode.i_fsize);
-#endif
+		inode.i_faddr, frag, fsize);
 	fprintf(out, "ctime: 0x%08x -- %s", inode.i_ctime,
-		ctime(&inode.i_ctime));
+		time_to_string(inode.i_ctime));
 	fprintf(out, "atime: 0x%08x -- %s", inode.i_atime,
-		ctime(&inode.i_atime));
+		time_to_string(inode.i_atime));
 	fprintf(out, "mtime: 0x%08x -- %s", inode.i_mtime,
-		ctime(&inode.i_mtime));
+		time_to_string(inode.i_mtime));
 	if (inode.i_dtime) 
 	  fprintf(out, "dtime: 0x%08x -- %s", inode.i_dtime,
-		  ctime(&inode.i_dtime));
+		  time_to_string(inode.i_dtime));
 	if (LINUX_S_ISLNK(inode.i_mode) && inode.i_blocks == 0)
 		fprintf(out, "Fast_link_dest: %s\n", (char *)inode.i_block);
 	else
@@ -308,7 +361,7 @@
 	if (!inode) 
 		return;
 
-	retval = ext2fs_read_inode(fs,inode,&inode_buf);
+	retval = ext2fs_read_inode(current_fs, inode, &inode_buf);
 	if (retval) 
 	  {
 	    com_err(argv[0], 0, "Reading inode");
@@ -334,7 +387,7 @@
 	if (!inode) 
 		return;
 
-	retval = ext2fs_check_directory(fs, inode);
+	retval = ext2fs_check_directory(current_fs, inode);
 	if (retval)  {
 		com_err(argv[1], retval, "");
 		return;
@@ -354,21 +407,19 @@
 	}
 	if (check_fs_open(argv[0]))
 		return;
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "Filesystem opened read/only");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 	inode = string_to_inode(argv[1]);
 	if (!inode) 
 		return;
 
-	retval = ext2fs_read_inode(fs, inode, &inode_buf);
+	retval = ext2fs_read_inode(current_fs, inode, &inode_buf);
 	if (retval) {
 		com_err(argv[0], 0, "while trying to read inode %d", inode);
 		return;
 	}
 	memset(&inode_buf, 0, sizeof(inode_buf));
-	retval = ext2fs_write_inode(fs, inode, &inode_buf);
+	retval = ext2fs_write_inode(current_fs, inode, &inode_buf);
 	if (retval) {
 		com_err(argv[0], retval, "while trying to write inode %d",
 			inode);
@@ -386,18 +437,16 @@
 	}
 	if (check_fs_open(argv[0]))
 		return;
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "Filesystem opened read/only");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 	inode = string_to_inode(argv[1]);
 	if (!inode) 
 		return;
 
-	if (!ext2fs_test_inode_bitmap(fs->inode_map,inode))
+	if (!ext2fs_test_inode_bitmap(current_fs->inode_map,inode))
 		com_err(argv[0], 0, "Warning: inode already clear");
-	ext2fs_unmark_inode_bitmap(fs->inode_map,inode);
-	ext2fs_mark_ib_dirty(fs);
+	ext2fs_unmark_inode_bitmap(current_fs->inode_map,inode);
+	ext2fs_mark_ib_dirty(current_fs);
 }
 
 void do_seti(int argc, char *argv[])
@@ -410,18 +459,16 @@
 	}
 	if (check_fs_open(argv[0]))
 		return;
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "Filesystem opened read/only");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 	inode = string_to_inode(argv[1]);
 	if (!inode) 
 		return;
 
-	if (ext2fs_test_inode_bitmap(fs->inode_map,inode))
+	if (ext2fs_test_inode_bitmap(current_fs->inode_map,inode))
 		com_err(argv[0], 0, "Warning: inode already set");
-	ext2fs_mark_inode_bitmap(fs->inode_map,inode);
-	ext2fs_mark_ib_dirty(fs);
+	ext2fs_mark_inode_bitmap(current_fs->inode_map,inode);
+	ext2fs_mark_ib_dirty(current_fs);
 }
 
 void do_testi(int argc, char *argv[])
@@ -438,7 +485,7 @@
 	if (!inode) 
 		return;
 
-	if (ext2fs_test_inode_bitmap(fs->inode_map,inode))
+	if (ext2fs_test_inode_bitmap(current_fs->inode_map,inode))
 		printf("Inode %ld is marked in use\n", inode);
 	else
 		printf("Inode %ld is not in use\n", inode);
@@ -456,19 +503,17 @@
 	}
 	if (check_fs_open(argv[0]))
 		return;
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "Filesystem opened read/only");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 	block = strtoul(argv[1], &tmp, 0);
 	if (!block || *tmp) {
 		com_err(argv[0], 0, "No block 0");
 		return;
 	} 
-	if (!ext2fs_test_block_bitmap(fs->block_map,block))
+	if (!ext2fs_test_block_bitmap(current_fs->block_map,block))
 		com_err(argv[0], 0, "Warning: block already clear");
-	ext2fs_unmark_block_bitmap(fs->block_map,block);
-	ext2fs_mark_bb_dirty(fs);
+	ext2fs_unmark_block_bitmap(current_fs->block_map,block);
+	ext2fs_mark_bb_dirty(current_fs);
 }
 
 void do_setb(int argc, char *argv[])
@@ -482,19 +527,17 @@
 	}
 	if (check_fs_open(argv[0]))
 		return;
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "Filesystem opened read/only");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 	block = strtoul(argv[1], &tmp, 0);
 	if (!block || *tmp) {
 		com_err(argv[0], 0, "No block 0");
 		return;
 	} 
-	if (ext2fs_test_block_bitmap(fs->block_map,block))
+	if (ext2fs_test_block_bitmap(current_fs->block_map,block))
 		com_err(argv[0], 0, "Warning: block already set");
-	ext2fs_mark_block_bitmap(fs->block_map,block);
-	ext2fs_mark_bb_dirty(fs);
+	ext2fs_mark_block_bitmap(current_fs->block_map,block);
+	ext2fs_mark_bb_dirty(current_fs);
 }
 
 void do_testb(int argc, char *argv[])
@@ -513,7 +556,7 @@
 		com_err(argv[0], 0, "No block 0");
 		return;
 	} 
-	if (ext2fs_test_block_bitmap(fs->block_map,block))
+	if (ext2fs_test_block_bitmap(current_fs->block_map,block))
 		printf("Block %d marked in use\n", block);
 	else printf("Block %d not in use\n", block);
 }
@@ -588,7 +631,9 @@
 	ino_t inode_num;
 	int i;
 	errcode_t	retval;
+	unsigned char *frag, *fsize;
 	char	buf[80];
+	int os = current_fs->super->s_creator_os;
 	const char *hex_format = "0x%x";
 	const char *octal_format = "0%o";
 	const char *decimal_format = "%d";
@@ -599,16 +644,14 @@
 	}
 	if (check_fs_open(argv[0]))
 		return;
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "Filesystem opened read/only");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 
 	inode_num = string_to_inode(argv[1]);
 	if (!inode_num) 
 		return;
 
-	retval = ext2fs_read_inode(fs, inode_num, &inode);
+	retval = ext2fs_read_inode(current_fs, inode_num, &inode);
 	if (retval) {
 		com_err(argv[1], retval, "while trying to read inode %d",
 			inode_num);
@@ -632,15 +675,32 @@
 	modify_u32(argv[0], "File acl", decimal_format, &inode.i_file_acl);
 	modify_u32(argv[0], "Directory acl", decimal_format, &inode.i_dir_acl);
 
-	if (fs->super->s_creator_os == EXT2_OS_HURD)
+	if (current_fs->super->s_creator_os == EXT2_OS_HURD)
 		modify_u32(argv[0], "Translator Block",
 			    decimal_format, &inode.osd1.hurd1.h_i_translator);
 	
 	modify_u32(argv[0], "Fragment address", decimal_format, &inode.i_faddr);
-#if HAVE_EXT2_FRAGS
-	modify_u8(argv[0], "Fragment number", decimal_format, &inode.i_frag);
-	modify_u8(argv[0], "Fragment size", decimal_format, &inode.i_fsize);
-#endif
+	switch (os) {
+	    case EXT2_OS_LINUX:
+		frag = &inode.osd2.linux2.l_i_frag;
+		fsize = &inode.osd2.linux2.l_i_fsize;
+		break;
+	    case EXT2_OS_HURD:
+		frag = &inode.osd2.hurd2.h_i_frag;
+		fsize = &inode.osd2.hurd2.h_i_fsize;
+		break;
+	    case EXT2_OS_MASIX:
+		frag = &inode.osd2.masix2.m_i_frag;
+		fsize = &inode.osd2.masix2.m_i_fsize;
+		break;
+	    default:
+		frag = fsize = 0;
+	}
+	if (frag)
+		modify_u8(argv[0], "Fragment number", decimal_format, frag);
+	if (fsize)
+		modify_u8(argv[0], "Fragment size", decimal_format, fsize);
+
 	for (i=0;  i < EXT2_NDIR_BLOCKS; i++) {
 		sprintf(buf, "Direct Block #%d", i);
 		modify_u32(argv[0], buf, decimal_format, &inode.i_block[i]);
@@ -651,7 +711,7 @@
 		    &inode.i_block[EXT2_DIND_BLOCK]);
 	modify_u32(argv[0], "Triple Indirect Block", decimal_format,
 		    &inode.i_block[EXT2_TIND_BLOCK]);
-	retval = ext2fs_write_inode(fs, inode_num, &inode);
+	retval = ext2fs_write_inode(current_fs, inode_num, &inode);
 	if (retval) {
 		com_err(argv[1], retval, "while trying to write inode %d",
 			inode_num);
@@ -720,7 +780,8 @@
 
 	ls.f = open_pager();
 	ls.col = 0;
-	retval = ext2fs_dir_iterate(fs, inode, DIRENT_FLAG_INCLUDE_EMPTY,
+	retval = ext2fs_dir_iterate(current_fs, inode,
+				    DIRENT_FLAG_INCLUDE_EMPTY,
 				    0, list_dir_proc, &ls);
 	fprintf(ls.f, "\n");
 	close_pager(ls.f);
@@ -746,7 +807,7 @@
 	if (!inode) 
 		return;
 
-	retval = ext2fs_check_directory(fs, inode);
+	retval = ext2fs_check_directory(current_fs, inode);
 	if (retval) {
 		com_err(argv[1], retval, "");
 		return;
@@ -767,14 +828,14 @@
 	if (check_fs_open(argv[0]))
 		return;
 
-	retval = ext2fs_get_pathname(fs, cwd, 0, &pathname);
+	retval = ext2fs_get_pathname(current_fs, cwd, 0, &pathname);
 	if (retval) {
 		com_err(argv[0], retval,
 			"while trying to get pathname of cwd");
 	}
 	printf("[pwd]   INODE: %6ld  PATH: %s\n", cwd, pathname);
 	free(pathname);
-	retval = ext2fs_get_pathname(fs, root, 0, &pathname);
+	retval = ext2fs_get_pathname(current_fs, root, 0, &pathname);
 	if (retval) {
 		com_err(argv[0], retval,
 			"while trying to get pathname of root");
@@ -806,7 +867,7 @@
 	 * Figure out the destination.  First see if it exists and is
 	 * a directory.  
 	 */
-	if (! (retval=ext2fs_namei(fs, root, cwd, destname, &dir)))
+	if (! (retval=ext2fs_namei(current_fs, root, cwd, destname, &dir)))
 		dest = basename;
 	else {
 		/*
@@ -826,7 +887,7 @@
 		}
 	}
 	
-	retval = ext2fs_link(fs, dir, dest, inode, 0);
+	retval = ext2fs_link(current_fs, dir, dest, inode, 0);
 	if (retval)
 		com_err("make_link", retval, "");
 	return;
@@ -853,7 +914,7 @@
 	
 	basename = strrchr(filename, '/');
 	if (basename) {
-		*basename++ = '0';
+		*basename++ = '\0';
 		dir = string_to_inode(filename);
 		if (!dir)
 			return;
@@ -861,7 +922,7 @@
 		dir = cwd;
 		basename = filename;
 	}
-	retval = ext2fs_unlink(fs, dir, basename, 0, 0);
+	retval = ext2fs_unlink(current_fs, dir, basename, 0, 0);
 	if (retval)
 		com_err("unlink_file_by_name", retval, "");
 	return;
@@ -900,9 +961,9 @@
 		}
 	}
 	else
-		goal = fs->super->s_first_data_block;
+		goal = current_fs->super->s_first_data_block;
 
-	retval = ext2fs_new_block(fs, goal, 0, &free_blk);
+	retval = ext2fs_new_block(current_fs, goal, 0, &free_blk);
 	if (retval)
 		com_err("ext2fs_new_block", retval, "");
 	else
@@ -942,7 +1003,7 @@
 	} else
 		mode = 010755;
 
-	retval = ext2fs_new_inode(fs, dir, mode, 0, &free_inode);
+	retval = ext2fs_new_inode(current_fs, dir, mode, 0, &free_inode);
 	if (retval)
 		com_err("ext2fs_new_inode", retval, "");
 	else
@@ -955,7 +1016,7 @@
 	errcode_t err;
 };
 
-static int copy_file_proc(ext2_filsys fs,
+static int copy_file_proc(ext2_filsys to_fs,
 			   blk_t	*blocknr,
 			   int	blockcnt,
 			   void	*private)
@@ -971,22 +1032,22 @@
 	if (*blocknr) {
 		new_blk = *blocknr;
 	} else {
-		retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
+		retval = ext2fs_new_block(to_fs, last_blk, 0, &new_blk);
 		if (retval) {
 			cs->err = retval;
 			return BLOCK_ABORT;
 		}
 	}
 	last_blk = new_blk;
-	block = malloc(fs->blocksize);
+	block = malloc(to_fs->blocksize);
 	if (!block) {
 		cs->err = ENOMEM;
 		return BLOCK_ABORT;
 	}
 	if (blockcnt >= 0) {
-		nr = read(cs->fd, block, fs->blocksize);
+		nr = read(cs->fd, block, to_fs->blocksize);
 	} else {
-		nr = fs->blocksize;
+		nr = to_fs->blocksize;
 		memset(block, 0, nr);
 	}
 	if (nr == 0) {
@@ -997,7 +1058,7 @@
 		cs->err = nr;
 		return BLOCK_ABORT;
 	}
-	retval = io_channel_write_blk(fs->io, new_blk, 1, block);
+	retval = io_channel_write_blk(to_fs->io, new_blk, 1, block);
 	if (retval) {
 		cs->err = retval;
 		return BLOCK_ABORT;
@@ -1005,20 +1066,20 @@
 	free(block);
 	if (blockcnt >= 0)
 		cs->size += nr;
-	cs->blocks += fs->blocksize / 512;
+	cs->blocks += to_fs->blocksize / 512;
 	printf("%ld(%d) ", cs->size, blockcnt);
 	fflush(stdout);
-	if (nr < fs->blocksize) {
+	if (nr < to_fs->blocksize) {
 		cs->done = 1;
 		printf("\n");
 	}
 	*blocknr = new_blk;
-	ext2fs_mark_block_bitmap(fs->block_map, new_blk);
-	ext2fs_mark_bb_dirty(fs);
-	group = ext2fs_group_of_blk(fs, new_blk);
-	fs->group_desc[group].bg_free_blocks_count--;
-	fs->super->s_free_blocks_count--;
-	ext2fs_mark_super_dirty(fs);
+	ext2fs_mark_block_bitmap(to_fs->block_map, new_blk);
+	ext2fs_mark_bb_dirty(to_fs);
+	group = ext2fs_group_of_blk(to_fs, new_blk);
+	to_fs->group_desc[group].bg_free_blocks_count--;
+	to_fs->super->s_free_blocks_count--;
+	ext2fs_mark_super_dirty(to_fs);
 	if (cs->done)
 		return (BLOCK_CHANGED | BLOCK_ABORT);
 	else
@@ -1037,7 +1098,8 @@
 	cs.size = 0;
 	cs.blocks = 0;
 	
-	retval = ext2fs_block_iterate(fs, newfile, BLOCK_FLAG_APPEND,
+	retval = ext2fs_block_iterate(current_fs, newfile,
+				      BLOCK_FLAG_APPEND,
 				      0, copy_file_proc, &cs);
 
 	if (cs.err)
@@ -1048,13 +1110,13 @@
 	/*
 	 * Update the size and block count fields in the inode.
 	 */
-	retval = ext2fs_read_inode(fs, newfile, &inode);
+	retval = ext2fs_read_inode(current_fs, newfile, &inode);
 	if (retval)
 		return retval;
 	
 	inode.i_blocks += cs.blocks;
 
-	retval = ext2fs_write_inode(fs, newfile, &inode);
+	retval = ext2fs_write_inode(current_fs, newfile, &inode);
 	if (retval)
 		return retval;
 
@@ -1075,10 +1137,8 @@
 		com_err(argv[0], 0, "Usage: write <nativefile> <newfile>");
 		return;
 	}
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "read-only filesystem");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
 	fd = open(argv[1], O_RDONLY);
 	if (fd < 0) {
 		com_err(argv[1], fd, "");
@@ -1090,32 +1150,33 @@
 		return;
 	}
 
-	retval = ext2fs_new_inode(fs, cwd, 010755, 0, &newfile);
+	retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
 	if (retval) {
 		com_err(argv[0], retval, "");
 		close(fd);
 		return;
 	}
 	printf("Allocated inode: %ld\n", newfile);
-	retval = ext2fs_link(fs, cwd, argv[2], newfile, 0);
+	retval = ext2fs_link(current_fs, cwd, argv[2], newfile, 0);
 	if (retval) {
 		com_err(argv[2], retval, "");
 		close(fd);
 		return;
 	}
-        if (ext2fs_test_inode_bitmap(fs->inode_map,newfile))
+        if (ext2fs_test_inode_bitmap(current_fs->inode_map,newfile))
 		com_err(argv[0], 0, "Warning: inode already set");
-	ext2fs_mark_inode_bitmap(fs->inode_map,newfile);
-	ext2fs_mark_ib_dirty(fs);
+	ext2fs_mark_inode_bitmap(current_fs->inode_map,newfile);
+	ext2fs_mark_ib_dirty(current_fs);
 	memset(&inode, 0, sizeof(inode));
 	inode.i_mode = statbuf.st_mode;
 	inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
 	inode.i_links_count = 1;
 	inode.i_size = statbuf.st_size;
-	ext2fs_write_inode(fs, newfile, &inode);
-	retval = ext2fs_write_inode(fs, newfile, &inode);
+	ext2fs_write_inode(current_fs, newfile, &inode);
+	retval = ext2fs_write_inode(current_fs, newfile, &inode);
 	if (retval) {
-		com_err(argv[0], retval, "while trying to write inode %d", inode);
+		com_err(argv[0], retval, "while trying to write inode %d", 
+			inode);
 		close(fd);
 		return;
 	}
@@ -1167,39 +1228,38 @@
 		com_err(argv[0], 0, "Usage: mknod <name> [p| [c|b] <major> <minor>]");
 		return;
 	}
-	if (!(fs->flags & EXT2_FLAG_RW)) {
-		com_err(argv[0], 0, "read-only filesystem");
+	if (check_fs_read_write(argv[0]))
 		return;
-	}
-	retval = ext2fs_new_inode(fs, cwd, 010755, 0, &newfile);
+	retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
 	if (retval) {
 		com_err(argv[0], retval, "");
 		return;
 	}
 	printf("Allocated inode: %ld\n", newfile);
-	retval = ext2fs_link(fs, cwd, argv[1], newfile, 0);
+	retval = ext2fs_link(current_fs, cwd, argv[1], newfile, 0);
 	if (retval) {
 		if (retval == EXT2_ET_DIR_NO_SPACE) {
-			retval = ext2fs_expand_dir(fs, cwd);
+			retval = ext2fs_expand_dir(current_fs, cwd);
 			if (!retval)
-				retval = ext2fs_link(fs, cwd, argv[1], newfile, 0);
+				retval = ext2fs_link(current_fs, cwd,
+						     argv[1], newfile, 0);
 		}
 		if (retval) {
 			com_err(argv[1], retval, "");
 			return;
 		}
 	}
-        if (ext2fs_test_inode_bitmap(fs->inode_map,newfile))
+        if (ext2fs_test_inode_bitmap(current_fs->inode_map,newfile))
 		com_err(argv[0], 0, "Warning: inode already set");
-	ext2fs_mark_inode_bitmap(fs->inode_map,newfile);
-	ext2fs_mark_ib_dirty(fs);
+	ext2fs_mark_inode_bitmap(current_fs->inode_map, newfile);
+	ext2fs_mark_ib_dirty(current_fs);
 	memset(&inode, 0, sizeof(inode));
 	inode.i_mode = mode;
 	inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
 	inode.i_block[0] = major*256+minor;
 	inode.i_links_count = 1;
-	ext2fs_write_inode(fs, newfile, &inode);
-	retval = ext2fs_write_inode(fs, newfile, &inode);
+	ext2fs_write_inode(current_fs, newfile, &inode);
+	retval = ext2fs_write_inode(current_fs, newfile, &inode);
 	if (retval) {
 		com_err(argv[0], retval, "while trying to write inode %d", inode);
 		return;
@@ -1236,7 +1296,7 @@
 	}
 
 
-	retval = ext2fs_mkdir(fs, parent, 0, name);
+	retval = ext2fs_mkdir(current_fs, parent, 0, name);
 	if (retval) {
 		com_err("ext2fs_mkdir", retval, "");
 		return;
@@ -1258,20 +1318,21 @@
 	return 0;
 }
 
-void kill_file_by_inode(ino_t inode)
+static void kill_file_by_inode(ino_t inode)
 {
 	struct ext2_inode inode_buf;
 
-	ext2fs_read_inode(fs, inode, &inode_buf);
+	ext2fs_read_inode(current_fs, inode, &inode_buf);
 	inode_buf.i_dtime = time(NULL);
-	ext2fs_write_inode(fs, inode, &inode_buf);
+	ext2fs_write_inode(current_fs, inode, &inode_buf);
 
 	printf("Kill file by inode %ld\n", inode);
-	ext2fs_block_iterate(fs,inode,0,NULL,release_blocks_proc,NULL);
-	ext2fs_unmark_inode_bitmap(fs->inode_map,inode);
+	ext2fs_block_iterate(current_fs, inode, 0, NULL,
+			     release_blocks_proc, NULL);
+	ext2fs_unmark_inode_bitmap(current_fs->inode_map, inode);
 
-	ext2fs_mark_bb_dirty(fs);
-	ext2fs_mark_ib_dirty(fs);
+	ext2fs_mark_bb_dirty(current_fs);
+	ext2fs_mark_ib_dirty(current_fs);
 }
 
 
@@ -1307,13 +1368,13 @@
 	if (check_fs_open(argv[0]))
 		return;
 
-	retval = ext2fs_namei(fs, root, cwd, argv[1], &inode_num);
+	retval = ext2fs_namei(current_fs, root, cwd, argv[1], &inode_num);
 	if (retval) {
 		com_err(argv[0], 0, "Cannot find file");
 		return;
 	}
 
-	retval = ext2fs_read_inode(fs,inode_num,&inode);
+	retval = ext2fs_read_inode(current_fs,inode_num,&inode);
 	if (retval) {
 		com_err(argv[0], retval, "while reading file's inode");
 		return;
@@ -1325,7 +1386,7 @@
 	}
 
 	--inode.i_links_count;
-	retval = ext2fs_write_inode(fs,inode_num,&inode);
+	retval = ext2fs_write_inode(current_fs,inode_num,&inode);
 	if (retval) {
 		com_err(argv[0], retval, "while writing inode");
 		return;
@@ -1340,10 +1401,11 @@
 {
 	FILE *out = stdout;
 
-	fprintf(out, "Open mode: read-%s\n",
-		fs->flags & EXT2_FLAG_RW ? "write" : "only");
+	if (current_fs)
+		fprintf(out, "Open mode: read-%s\n",
+			current_fs->flags & EXT2_FLAG_RW ? "write" : "only");
 	fprintf(out, "Filesystem in use: %s\n",
-		fs ? fs->device_name : "--none--");
+		current_fs ? current_fs->device_name : "--none--");
 }
 
 void do_expand_dir(int argc, char *argv[])
@@ -1361,24 +1423,71 @@
 	if (!inode)
 		return;
 
-	retval = ext2fs_expand_dir(fs, inode);
+	retval = ext2fs_expand_dir(current_fs, inode);
 	if (retval)
 		com_err("ext2fs_expand_dir", retval, "");
 	return;
 }
 
+static int source_file(const char *cmd_file, int sci_idx)
+{
+	FILE		*f;
+	char		buf[256];
+	char		*cp;
+	int		exit_status = 0;
+	int		retval;
+
+	if (strcmp(cmd_file, "-") == 0)
+		f = stdin;
+	else {
+		f = fopen(cmd_file, "r");
+		if (!f) {
+			perror(cmd_file);
+			exit(1);
+		}
+	}
+	setbuf(stdout, NULL);
+	setbuf(stderr, NULL);
+	while (!feof(f)) {
+		if (fgets(buf, sizeof(buf), f) == NULL)
+			break;
+		cp = strchr(buf, '\n');
+		if (cp)
+			*cp = 0;
+		cp = strchr(buf, '\r');
+		if (cp)
+			*cp = 0;
+		printf("debugfs: %s\n", buf);
+		retval = ss_execute_line(sci_idx, buf);
+		if (retval) {
+			ss_perror(sci_idx, retval, buf);
+			exit_status++;
+		}
+	}
+	return exit_status;
+}
+
 void main(int argc, char **argv)
 {
 	int		retval;
 	int		sci_idx;
-	const char	*usage = "Usage: debugfs [[-w] device]";
+	const char	*usage = "Usage: debugfs [-w] [device]";
 	char		c;
 	int		open_flags = 0;
+	char		*request = 0;
+	int		exit_status = 0;
+	char		*cmd_file = 0;
 	
 	initialize_ext2_error_table();
 
-	while ((c = getopt (argc, argv, "w")) != EOF) {
+	while ((c = getopt (argc, argv, "wR:f:")) != EOF) {
 		switch (c) {
+		case 'R':
+			request = optarg;
+			break;
+		case 'f':
+			cmd_file = optarg;
+			break;
 		case 'w':
 			open_flags = EXT2_FLAG_RW;
 			break;
@@ -1402,12 +1511,22 @@
 		ss_perror(sci_idx, retval, "adding standard requests");
 		exit (1);
 	}
+	if (request) {
+		retval = 0;
+		retval = ss_execute_line(sci_idx, request);
+		if (retval) {
+			ss_perror(sci_idx, retval, request);
+			exit_status++;
+		}
+	} else if (cmd_file) {
+		exit_status = source_file(cmd_file, sci_idx);
+	} else {
+		ss_listen(sci_idx);
+	}
 
-	ss_listen(sci_idx);
-
-	if (fs)
+	if (current_fs)
 		close_filesystem();
 	
-	exit(0);
+	exit(exit_status);
 }
 
diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h
index 7c3c214..0ac71cf 100644
--- a/debugfs/debugfs.h
+++ b/debugfs/debugfs.h
@@ -12,14 +12,16 @@
 #define const
 #endif
 
-extern ext2_filsys fs;
+extern ext2_filsys current_fs;
 extern ino_t	root, cwd;
 
 extern FILE *open_pager(void);
 extern void close_pager(FILE *stream);
 extern int check_fs_open(char *name);
 extern int check_fs_not_open(char *name);
+extern int check_fs_read_write(char *name);
 extern ino_t string_to_inode(char *str);
+extern char *time_to_string(__u32);
 
 /* ss command functions */
 
diff --git a/debugfs/dump.c b/debugfs/dump.c
index 7223bf5..3997dfd 100644
--- a/debugfs/dump.c
+++ b/debugfs/dump.c
@@ -17,19 +17,62 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <utime.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else 
+extern int optind;
+extern char *optarg;
+#endif
+#ifdef HAVE_OPTRESET
+extern int optreset;		/* defined by BSD, but not others */
+#endif
 
 #include "debugfs.h"
 
+/*
+ * The mode_xlate function translates a linux mode into a native-OS mode_t.
+ */
+static struct {
+	__u16 lmask;
+	mode_t mask;
+} mode_table[] = {
+	{ LINUX_S_IRUSR, S_IRUSR },
+	{ LINUX_S_IWUSR, S_IWUSR },
+	{ LINUX_S_IXUSR, S_IXUSR },
+	{ LINUX_S_IRGRP, S_IRGRP },
+	{ LINUX_S_IWGRP, S_IWGRP },
+	{ LINUX_S_IXGRP, S_IXGRP },
+	{ LINUX_S_IROTH, S_IROTH },
+	{ LINUX_S_IWOTH, S_IWOTH },
+	{ LINUX_S_IXOTH, S_IXOTH },
+	{ 0, 0 }
+};
+ 
+static mode_t mode_xlate(__u16 lmode)
+{
+	mode_t	mode = 0;
+	int	i;
+
+	for (i=0; mode_table[i].lmask; i++) {
+		if (lmode & mode_table[i].lmask)
+			mode |= mode_table[i].mask;
+	}
+	return mode;
+}
+
 struct dump_block_struct {
 	int		fd;
 	char		*buf;
+	int		left;
 	errcode_t	errcode;
 };
 
 static int dump_block(ext2_filsys fs, blk_t *blocknr, int blockcnt,
 		      void *private)
 {
-	ssize_t nbytes;
+	int nbytes, left;
+	off_t	ret_off;
 	
 	struct dump_block_struct *rec = (struct dump_block_struct *) private;
 	
@@ -41,41 +84,65 @@
 						   1, rec->buf);
 		if (rec->errcode)
 			return BLOCK_ABORT;
-	} else
+	} else {
+		/*
+		 * OK, the file has a hole.  Let's try to seek past
+		 * the hole in the destination file, so that the
+		 * destination file has a hole too.
+		 */
+		ret_off = lseek(rec->fd, fs->blocksize, SEEK_CUR);
+		if (ret_off >= 0)
+			return 0;
 		memset(rec->buf, 0, fs->blocksize);
+	}
 
-retry_write:
-	nbytes = write(rec->fd, rec->buf, fs->blocksize);
-	if (nbytes == -1) {
-		if (errno == EINTR)
-			goto retry_write;
-		rec->errcode = errno;
-		return BLOCK_ABORT;
+	left = (rec->left > fs->blocksize) ? fs->blocksize : rec->left;
+	rec->left -= left;
+	
+	while (left > 0) {
+		nbytes = write(rec->fd, rec->buf, left);
+		if (nbytes == -1) {
+			if (errno == EINTR)
+				continue;
+			rec->errcode = errno;
+			return BLOCK_ABORT;
+		}
+		left -= nbytes;
 	}
-	if (nbytes != fs->blocksize) {
-		/* XXX not quite right, but good enough */
-		rec->errcode = EXT2_ET_SHORT_WRITE;
+	if (rec->left <= 0)
 		return BLOCK_ABORT;
-	}
 	return 0;
 }
 
-static void dump_file(char *cmdname, ino_t inode, int fd, char *outname)
+static void dump_file(char *cmdname, ino_t ino, int fd, int preserve,
+		      char *outname)
 {
 	errcode_t retval;
 	struct dump_block_struct rec;
+	struct ext2_inode	inode;
+	struct utimbuf	ut;
+
+	retval = ext2fs_read_inode(current_fs, ino, &inode);
+	if (retval) {
+		com_err(cmdname, retval,
+			"while reading inode %u in dump_file", ino);
+		return;
+	}
 
 	rec.fd = fd;
 	rec.errcode = 0;
-	rec.buf = malloc(fs->blocksize);
+	rec.buf = malloc(current_fs->blocksize);
+	rec.left = inode.i_size;
 
 	if (rec.buf == 0) {
-		com_err(cmdname, ENOMEM, "while allocating block buffer for dump_inode");
+		com_err(cmdname, ENOMEM,
+			"while allocating block buffer for dump_inode");
 		return;
 	}
 	
-	retval = ext2fs_block_iterate(fs, inode, 0, NULL,
-				      dump_block, &rec);
+	retval = ext2fs_block_iterate(current_fs, ino,
+				      BLOCK_FLAG_HOLE|BLOCK_FLAG_DATA_ONLY,
+				      NULL, dump_block, &rec);
 	if (retval) {
 		com_err(cmdname, retval, "while iterating over blocks in %s",
 			outname);
@@ -88,6 +155,29 @@
 	}
 	
 cleanup:
+	if (preserve) {
+#ifdef HAVE_FCHOWN
+		if (fchown(fd, inode.i_uid, inode.i_gid) < 0)
+			com_err("dump_file", errno,
+				"while changing ownership of %s", outname);
+#else
+		if (chown(outname, inode.i_uid, inode.i_gid) < 0)
+			com_err("dump_file", errno,
+				"while changing ownership of %s", outname);
+			
+#endif
+		if (fchmod(fd, mode_xlate(inode.i_mode)) < 0)
+			com_err("dump_file", errno,
+				"while setting permissions of %s", outname);
+		ut.actime = inode.i_atime;
+		ut.modtime = inode.i_mtime;
+		close(fd);
+		if (utime(outname, &ut) < 0)
+			com_err("dump_file", errno,
+				"while setting times on %s", outname);
+	} else if (fd != 1)
+		close(fd);
+				    
 	free(rec.buf);
 	return;
 }
@@ -96,29 +186,49 @@
 {
 	ino_t	inode;
 	int	fd;
-
-	if (argc != 3) {
-		com_err(argv[0], 0, "Usage: dump_inode <file> <output_file>");
+	char	c;
+	int	preserve = 0;
+	const char *dump_usage = "Usage: dump_inode [-p] <file> <output_file>";
+	char	*in_fn, *out_fn;
+	
+	optind = 0;
+#ifdef HAVE_OPTRESET
+	optreset = 1;		/* Makes BSD getopt happy */
+#endif
+	while ((c = getopt (argc, argv, "p")) != EOF) {
+		switch (c) {
+		case 'p':
+			preserve++;
+			break;
+		default:
+			com_err(argv[0], 0, dump_usage);
+			return;
+		}
+	}
+	if (optind != argc-2) {
+		com_err(argv[0], 0, dump_usage);
 		return;
 	}
 
 	if (check_fs_open(argv[0]))
 		return;
 
-	inode = string_to_inode(argv[1]);
+	in_fn = argv[optind];
+	out_fn = argv[optind+1];
+
+	inode = string_to_inode(in_fn);
 	if (!inode) 
 		return;
 
-	fd = open(argv[2], O_CREAT | O_WRONLY | O_TRUNC, 0666);
+	fd = open(out_fn, O_CREAT | O_WRONLY | O_TRUNC, 0666);
 	if (fd < 0) {
 		com_err(argv[0], errno, "while opening %s for dump_inode",
-			argv[2]);
+			out_fn);
 		return;
 	}
 
-	dump_file(argv[0], inode, fd, argv[2]);
+	dump_file(argv[0], inode, fd, preserve, out_fn);
 
-	close(fd);
 	return;
 }
 
@@ -138,7 +248,9 @@
 	if (!inode) 
 		return;
 
-	dump_file(argv[0], inode, 0, argv[2]);
+	fflush(stdout);
+	fflush(stderr);
+	dump_file(argv[0], inode, 1, 0, argv[2]); 
 
 	return;
 }
diff --git a/debugfs/icheck.c b/debugfs/icheck.c
index ef053f5..9e40611 100644
--- a/debugfs/icheck.c
+++ b/debugfs/icheck.c
@@ -77,7 +77,7 @@
 	}
 	memset(bw.barray, 0, sizeof(struct block_info) * argc);
 
-	block_buf = malloc(fs->blocksize * 3);
+	block_buf = malloc(current_fs->blocksize * 3);
 	if (!block_buf) {
 		com_err("icheck", ENOMEM, "while allocating block buffer");
 		goto error_out;
@@ -93,7 +93,7 @@
 
 	bw.num_blocks = bw.blocks_left = argc-1;
 
-	retval = ext2fs_open_inode_scan(fs, 0, &scan);
+	retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
 	if (retval) {
 		com_err("icheck", retval, "while opening inode scan");
 		goto error_out;
@@ -117,7 +117,7 @@
 
 		bw.inode = ino;
 		
-		retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
+		retval = ext2fs_block_iterate(current_fs, ino, 0, block_buf,
 					      icheck_proc, &bw);
 		if (retval) {
 			com_err("icheck", retval,
@@ -140,10 +140,10 @@
 	printf("Block\tInode number\n");
 	for (i=0, binfo = bw.barray; i < bw.num_blocks; i++, binfo++) {
 		if (binfo->ino == 0) {
-			printf("%ld\t<block not found>\n", binfo->blk);
+			printf("%u\t<block not found>\n", binfo->blk);
 			continue;
 		}
-		printf("%ld\t%ld\n", binfo->blk, binfo->ino);
+		printf("%u\t%ld\n", binfo->blk, binfo->ino);
 	}
 
 error_out:
@@ -153,6 +153,3 @@
 		ext2fs_close_inode_scan(scan);
 	return;
 }
-
-
-
diff --git a/debugfs/lsdel.c b/debugfs/lsdel.c
index 8df894e..8dea6eb 100644
--- a/debugfs/lsdel.c
+++ b/debugfs/lsdel.c
@@ -95,13 +95,13 @@
 		exit(1);
 	}
 
-	block_buf = malloc(fs->blocksize * 3);
+	block_buf = malloc(current_fs->blocksize * 3);
 	if (!block_buf) {
 		com_err("ls_deleted_inodes", ENOMEM, "while allocating block buffer");
 		goto error_out;
 	}
 
-	retval = ext2fs_open_inode_scan(fs, 0, &scan);
+	retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
 	if (retval) {
 		com_err("ls_deleted_inodes", retval,
 			"while opening inode scan");
@@ -124,7 +124,7 @@
 		lsd.free_blocks = 0;
 		lsd.bad_blocks = 0;
 		
-		retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
+		retval = ext2fs_block_iterate(current_fs, ino, 0, block_buf,
 					      lsdel_proc, &lsd);
 		if (retval) {
 			com_err("ls_deleted_inodes", retval,
diff --git a/e2fsprogs-1.04.spec b/e2fsprogs-1.05.spec
similarity index 78%
rename from e2fsprogs-1.04.spec
rename to e2fsprogs-1.05.spec
index bdbd3a5..8643092 100644
--- a/e2fsprogs-1.04.spec
+++ b/e2fsprogs-1.05.spec
@@ -1,10 +1,10 @@
 Description: Tools for the second extended (ext2) filesystem 
 Name: e2fsprogs
-Version: 1.04
+Version: 1.05
 Release: 0
 Copyright: GPL
 Group: Utilities/System
-Source: tsx-11.mit.edu:/pub/linux/packages/ext2fs/e2fsprogs-1.04.tar.gz
+Source: tsx-11.mit.edu:/pub/linux/packages/ext2fs/e2fsprogs-1.05.tar.gz
 
 %package devel
 Description: e2fs static libs and headers
@@ -54,10 +54,11 @@
 /sbin/mkfs.ext2
 
 %ifarch i386
-/lib/libe2p.so.2.1
-/lib/libext2fs.so.2.0
+/lib/libe2p.so.2.2
+/lib/libext2fs.so.2.1
 /lib/libss.so.2.0
 /lib/libcom_err.so.2.0
+/lib/libuuid.so.1.0
 %endif
 
 /usr/bin/chattr
@@ -80,13 +81,20 @@
 /usr/lib/libext2fs_p.a
 /usr/lib/libss_p.a
 /usr/lib/libcom_err_p.a
+/usr/lib/libuuid.a
+/usr/lib/libuuid_p.a
 /usr/include/ss
 /usr/include/ext2fs
 /usr/include/et
+/usr/include/uuid
 
 %ifarch i386
-/lib/libe2p.so
-/lib/libext2fs.so
-/lib/libss.so
-/lib/libcom_err.so
+/usr/lib/libe2p.so
+/usr/lib/libext2fs.so
+/usr/lib/libss.so
+/usr/lib/libcom_err.so
+/usr/lib/libuuid.so
+
+%post
+rm -f /lib/libe2p.so /lib/libext2fs.so /lib/libss.so /lib/libcom_err.so
 %endif
diff --git a/version.h b/version.h
index 5e7dd9d..f2aae1b 100644
--- a/version.h
+++ b/version.h
@@ -6,6 +6,6 @@
  * under the GNU Public License.
  */
 
-#define E2FSPROGS_VERSION "1.04"
-#define E2FSPROGS_DATE "16-May-96"
+#define E2FSPROGS_VERSION "1.05"
+#define E2FSPROGS_DATE "9-Sep-96"