From: Theodore Ts'o Date: Tue, 29 Apr 1997 14:51:31 +0000 (+0000) Subject: Many files: X-Git-Tag: E2FSPROGS-1_05~2 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=fc6d9d519aef67735918bf02c0fa8c9222008f76;p=tools%2Fe2fsprogs.git 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 + + * configure.in (AC_CHECK_FUNCS): Add fchown to list of functions + that we check. + +Wed Aug 28 14:42:12 1996 Miles Bader + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * configure.in: Make the default prefix be '' for Linux. + Thu May 16 11:12:30 1996 Theodore Ts'o * 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_PROGRAM = @INSTALL_PROGRAM@ 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 @@ LDFLAGS = @LDFLAGS@ ALL_LDFLAGS = $(LDFLAGS) RM = @RM@ LN = @LN@ +LN_S = @LN_S@ MV = @MV@ CP = @CP@ CHMOD = @CHMOD@ @@ -51,16 +51,19 @@ LIBSS = $(LIB)/libss@LIB_EXT@ 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 @@ SUBSTITUTE= $(top_builddir)/lib/substitute_sh # @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 @@ MANMODE= 444 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 @@ srcdir = @srcdir@ 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 @@ realclean: realclean-recursive realclean-local 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 @@ distribution_tar_file: (cd /tmp/dest; tar cf - . ) | gzip -9 \ > e2fsprogs-@E2FSPROGS_VERSION@-@BINARY_TYPE@.tar.gz - -Makefile: config.status $(srcdir)/Makefile.in - CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status - -config.status: $(srcdir)/configure - ./config.status --recheck -$(srcdir)/configure: $(srcdir)/configure.in - cd $(srcdir) && autoconf +SRCROOT = `echo e2fsprogs-@E2FSPROGS_VERSION@ | sed -e 's/-WIP//'` + +$(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 + + +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 @@ Added new flag to fsck which allows the root to be checked in parallel 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 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 @@ ac_help="$ac_help --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 @@ echo "Release date is ${E2FSPROGS_MONTH}, ${E2FSPROGS_YEAR}" + +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 @@ else 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 @@ echo "Building e2fsck statically by default" 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 @@ else 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 @@ else 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 @@ else ac_cv_c_cross=yes else cat > conftest.$ac_ext < conftest.$ac_ext < Syntax Error @@ -1346,7 +1427,7 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error @@ -1371,7 +1452,7 @@ else 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 @@ 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 @@ -1412,7 +1493,7 @@ if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 else cat > conftest.$ac_ext <&6 else cat > conftest.$ac_ext < #include @@ -1541,6 +1622,7 @@ if test "$cross_compiling" = yes -a "$ac_cv_sizeof_long" = ""; then 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 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1585,7 +1667,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1619,7 +1701,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1645,9 +1727,45 @@ cat >> confdefs.h <&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 < +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 <&6 else cat > conftest.$ac_ext < int main() { return 0; } @@ -1682,14 +1800,14 @@ if test "$e2fsprogs_cv_struct_st_flags" = yes; then 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 <&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 < +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 @@ -1778,61 +1927,65 @@ else CPPFLAGS="$CPPFLAGS -I$srcdir/include -I./include" fi -echo $ac_n "checking for optreset""... $ac_c" 1>&6 -if eval "test \"`echo '$''{'ac_cv_have_optreset'+set}'`\" = set"; then +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 - cat > conftest.$ac_ext < conftest.$ac_ext < + +int main() { return 0; } +int t() { +socket() +; return 0; } EOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "optreset" >/dev/null 2>&1; then +if eval $ac_link; then rm -rf conftest* - ac_cv_have_optreset=yes + eval "ac_cv_lib_socket=yes" else rm -rf conftest* - ac_cv_have_optreset=no + eval "ac_cv_lib_socket=no" fi rm -f conftest* +LIBS="$ac_save_LIBS" fi -echo "$ac_t""$ac_cv_have_optreset" 1>&6 -if test $ac_cv_have_optreset = yes; then - cat >> confdefs.h <<\EOF -#define HAVE_OPTRESET 1 -EOF - +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 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 "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 < -int main() { return 0; } -int t() { -struct ext2_inode i; i.i_frag = i.i_fsize = 0; -; return 0; } +#include EOF -if eval $ac_compile; then +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "optreset" >/dev/null 2>&1; then rm -rf conftest* - e2fsprogs_cv_struct_ext2_inode_frags=yes + ac_cv_have_optreset=yes else rm -rf conftest* - e2fsprogs_cv_struct_ext2_inode_frags=no + ac_cv_have_optreset=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 +echo "$ac_t""$ac_cv_have_optreset" 1>&6 +if test $ac_cv_have_optreset = yes; then cat >> confdefs.h <<\EOF -#define HAVE_EXT2_FRAGS 1 +#define HAVE_OPTRESET 1 EOF fi @@ -1841,7 +1994,7 @@ if eval "test \"`echo '$''{'e2fsprogs_cv_ioctl_ext2'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1868,30 +2021,35 @@ if test "$e2fsprogs_cv_ioctl_ext2" = yes; then 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_srcdir=$srcdir 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%@MCONFIG@%%g 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%@STATIC_LIB_EXT@%$STATIC_LIB_EXT%g 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%@CPP@%$CPP%g 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 @@ EOF cat >> $CONFIG_STATUS <> $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 @@ echo "Release date is ${E2FSPROGS_MONTH}, ${E2FSPROGS_YEAR}" 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=$withval, 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 @@ echo "Building e2fsck statically by default" ) 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_CHECK_TOOL(STRIP, strip, :) 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 @@ if test "$cross_compiling" = yes -a "$ac_cv_sizeof_long" = ""; then 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 @@ AC_MSG_RESULT($e2fsprogs_cv_struct_st_flags) 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 ], + [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 @@ else 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 @@ if test $ac_cv_have_optreset = yes; then 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 ], - [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 @@ if test "$e2fsprogs_cv_ioctl_ext2" = yes; then 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 lib || mkdir lib 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 * 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 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ top_builddir = .. +my_dir = debugfs INSTALL = @INSTALL@ @MCONFIG@ @@ -21,8 +22,8 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c \ $(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 @@ distclean: clean # 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 @@ dump.o: $(srcdir)/dump.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 \ $(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 @@ debugfs \- ext2 file system debugger .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 @@ file system (e.g /dev/hdXX). .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 -Dump the contents of an inode to stdout. +.I cat filespec +Dump the contents of the inode +.I filespec +to stdout. .TP -.I cd -Change the current working directory to specified directory +.I cd filespec +Change the current working directory to +.IR filespec . .TP -.I chroot -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 -Clear the contents of the inode corresponding to -.I file -.TP -.I dump -Dump the contents of an inode to a file. -.TP -.I expand_dir -Expand a directory. +.I clri file +Clear the contents of the inode +.IR file . +.TP +.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 filespec +Expand the directory +.IR filespec . .TP .I find_free_block [goal] Find the first free block, starting from @@ -58,57 +98,83 @@ Find the first free block, starting from and allocates it. .TP .I find_free_inode [dir [mode]] -Find a free inode and allocates it. -.TP -.I freeb -Mark the block as not allocated. -.TP -.I freei -Free the inode corresponding to -.I file +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 number +.I block +as not allocated. +.TP +.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 -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 -Print the file name corresponding to -.I inode -(currently not implemented - see ncheck). -.TP -.I initialize +.I initialize device blocksize Create an ext2 file system on .I device -.TP -.I kill_file -Remove a file and deallocates its blocks. -.TP -.I ln -Create a link. -.TP -.I ls [pathname] -Emulate the -.BR ls (1) -command. -.TP -.I modify_inode -Modify the contents of the inode corresponding to -.I file -.TP -.I mkdir +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 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 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 filespec +Print a listing of the files in the directory +.IR filespec . +.TP +.I modify_inode filespec +Modify the contents of the inode structure in the inode +.IR filespec . +.TP +.I mkdir filespec Make a directory. .TP -.I mknod [p|[[c|b] ]] -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 -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] -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 @@ Print the current working directory. Quit .B debugfs .TP -.I rm -Remove a file. -.TP -.I rmdir -Remove a directory. -.TP -.I setb -Mark the block as allocated. -.TP -.I seti -Mark in use the inode corresponding to -.I 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 filespec +Remove the directory +.IR filespec . +This function is currently not implemented. +.TP +.I setb block +Mark the block number +.I block +as allocated. +.TP +.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 -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 -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 -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 -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 +.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 . 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 @@ extern int optreset; /* defined by BSD, but not others */ #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, ¤t_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 @@ static void open_filesystem(char *device, int open_flags) 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 @@ void do_open_filesys(int argc, char **argv) char c; int open_flags = 0; - optind = 1; + optind = 0; #ifdef HAVE_OPTRESET optreset = 1; /* Makes BSD getopt happy */ #endif @@ -102,20 +104,20 @@ static void close_filesystem(NOARGS) { 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 @@ void do_init_filesys(int argc, char **argv) com_err(argv[0], 0, "Bad blocks count - %s", argv[2]); return; } - retval = ext2fs_initialize(argv[1], 0, ¶m, unix_io_manager, &fs); + retval = ext2fs_initialize(argv[1], 0, ¶m, + unix_io_manager, ¤t_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 @@ void do_show_super_stats(int argc, char *argv[]) { 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 @@ void do_show_super_stats(int argc, char *argv[]) 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 = ¤t_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 @@ static void dump_blocks(FILE *f, ino_t inode) 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 @@ static void dump_inode(ino_t inode_num, struct ext2_inode inode) { 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 @@ static void dump_inode(ino_t inode_num, struct ext2_inode inode) 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 @@ static void dump_inode(ino_t inode_num, struct ext2_inode inode) 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 @@ void do_stat(int argc, char *argv[]) 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 @@ void do_chroot(int argc, char *argv[]) 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 @@ void do_clri(int argc, char *argv[]) } 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 @@ void do_freei(int argc, char *argv[]) } 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 @@ void do_seti(int argc, char *argv[]) } 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 @@ void do_testi(int argc, char *argv[]) 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 @@ void do_freeb(int argc, char *argv[]) } 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 @@ void do_setb(int argc, char *argv[]) } 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 @@ void do_testb(int argc, char *argv[]) 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 @@ void do_modify_inode(int argc, char *argv[]) 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 @@ void do_modify_inode(int argc, char *argv[]) } 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 @@ void do_modify_inode(int argc, char *argv[]) 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 @@ void do_modify_inode(int argc, char *argv[]) &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 @@ void do_list_dir(int argc, char *argv[]) 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 @@ void do_change_working_dir(int argc, char *argv[]) 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 @@ void do_print_working_directory(int argc, char *argv[]) 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 @@ static void make_link(char *sourcename, char *destname) * 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 @@ static void make_link(char *sourcename, char *destname) } } - 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 @@ static void unlink_file_by_name(char *filename) basename = strrchr(filename, '/'); if (basename) { - *basename++ = '0'; + *basename++ = '\0'; dir = string_to_inode(filename); if (!dir) return; @@ -861,7 +922,7 @@ static void unlink_file_by_name(char *filename) 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 @@ void do_find_free_block(int argc, char *argv[]) } } 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 @@ void do_find_free_inode(int argc, char *argv[]) } 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 @@ struct copy_file_struct { 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 @@ static int copy_file_proc(ext2_filsys fs, 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 @@ static int copy_file_proc(ext2_filsys fs, 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 @@ static int copy_file_proc(ext2_filsys fs, 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 @@ static errcode_t copy_file(int fd, ino_t newfile) 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 @@ static errcode_t copy_file(int fd, ino_t newfile) /* * 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 @@ void do_write(int argc, char *argv[]) com_err(argv[0], 0, "Usage: write "); 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 @@ void do_write(int argc, char *argv[]) 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 @@ void do_mknod(int argc, char *argv[]) com_err(argv[0], 0, "Usage: mknod [p| [c|b] ]"); 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 @@ void do_mkdir(int argc, char *argv[]) } - 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 @@ static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr, 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 @@ void do_rm(int argc, char *argv[]) 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 @@ void do_rm(int argc, char *argv[]) } --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 @@ void do_show_debugfs_params(int argc, char *argv[]) { 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 @@ void do_expand_dir(int argc, char *argv[]) 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 @@ void main(int argc, char **argv) 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 #include #include +#include +#ifdef HAVE_GETOPT_H +#include +#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 @@ static int dump_block(ext2_filsys fs, blk_t *blocknr, int blockcnt, 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 @@ static void dump_file(char *cmdname, ino_t inode, int fd, char *outname) } 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 @@ void do_dump(int argc, char **argv) { ino_t inode; int fd; - - if (argc != 3) { - com_err(argv[0], 0, "Usage: dump_inode "); + char c; + int preserve = 0; + const char *dump_usage = "Usage: dump_inode [-p] "; + 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 @@ void do_cat(int argc, char **argv) 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 @@ void do_icheck(int argc, char **argv) } 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 @@ void do_icheck(int argc, char **argv) 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 @@ void do_icheck(int argc, char **argv) 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 @@ void do_icheck(int argc, char **argv) printf("Block\tInode number\n"); for (i=0, binfo = bw.barray; i < bw.num_blocks; i++, binfo++) { if (binfo->ino == 0) { - printf("%ld\t\n", binfo->blk); + printf("%u\t\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 @@ error_out: 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 @@ void do_lsdel(int argc, char **argv) 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 @@ void do_lsdel(int argc, char **argv) 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 @@ mv /usr/sbin/debugfs /sbin/debugfs /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 @@ mv /usr/sbin/debugfs /sbin/debugfs /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"