v05i068: Fsanalyze Version 4.1, Part 1/3
Michael J. Young
mjy at sdti.sdti.com
Wed Dec 7 10:08:56 AEST 1988
Posting-number: Volume 5, Issue 68
Submitted-by: "Michael J. Young" <mjy at sdti.sdti.com>
Archive-name: fsanalyze4.1/part01
This is a completely new version of fsanalyze, which I originally posted
almost a year ago. Major changes were made to port it to BSD file systems,
as well to fix a number of bugs that were reported to me. Unfortunately, it
is also a fair bit larger than the old version.
For those who don't remember the original program, fsanalyze is a tool that
measures file system fragmentation along with various other useful
file system statistics.
Please send comments, bug reports, fixes, and ideas for enhancements to me.
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 1 (of 3)."
# Contents: Changes MANIFEST Makefile Mkfile.sun Mkfile.sys5
# Mkfile.uport Mkfile.xenix README fragm.c fsanalyze.c patchlevel.h
# stats.c util.c
# Wrapped by mjy at sdti on Wed Nov 30 15:54:13 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Changes -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Changes\"
else
echo shar: Extracting \"Changes\" \(5025 characters\)
sed "s/^X//" >Changes <<'END_OF_Changes'
XRevision History:
X
X Version 2.0 was a major rewrite of fsanalyze that added the following new
X features:
X - The ability to analyze individual files
X - Display of the 10 most fragmented files in a file system
X - Enhanced error checking on the file system argument
X
X Version 2.01 contains a minor modification in which fsanalyze executes
X /etc/fsstat to determine the health of the file system before analyzing
X it.
X
X Version 2.02 contains a minor modification to print out a warning message
X if the file system being analyzed is currently mounted.
X
X Version 2.03 contains a fix for a minor bug in which the size of the
X volume data block size would be printed out incorrectly for large
X file systems.
X
X Version 2.04 incorporates the library function l3tol to access inode
X block numbers. This is the first version that was posted to the net
X a few months back.
X
X Version 3.00 contains major revisions for porting to Xenix, System
X V Release 3, and the BSD fast file system, as well as fixing many
X bugs and improprieties. Specific changes include:
X - Sparse files are now handled correctly. Thanks to John Limpert
X (johnl at gronk.uucp) for this one!
X - A bug in the way indirect blocks were factored into the
X fragmentation analysis was corrected.
X - Fragmentation has been re-defined as cylinder-to-cylinder seeks.
X Suboptimum placement within a cylinder is handled separately as
X "rotational delay". This resulted from the discovery by a number
X of people (thanks esp. to Steve Paddock and Dave Olson
X (olson at altos86.uucp)) that block interleaving wasn't handled
X correctly. After doing some experimenting with the System V mkfs,
X I came to the conclusion that its algorithm for optimal record
X placement is rather crude. For example, it does not take number
X of heads into account. So rather than enforce an algorithm that I
X couldn't duplicate very well anyway, I split it out as a separate
X statistic. This decision was confirmed when I ported fsanalyze to
X BSD, since the fast file system also makes the distinction between
X cylinder seeks and rotation delays.
X - new command-line arguments have been added to override file system
X block size, interleave factor, and number of sectors per cylinder.
X Normally, these numbers are derived from information in the super-
X block. However, not all file systems may store the information
X in a way expected by fsanalyze. Use these flags to override.
X Although all of the flags are supported for the BSD port, I doubt
X if they are useful.
X - Some function names and variables have been renamed to
X ensure uniqueness within 7 characters. Thanks to John
X Limpert for catching this.
X - The IS_SPECIAL macro has been rewritten. Thanks to Larry
X Cipriani and Dave Olson for catching the bugs here.
X - A number of new macros have been defined to make porting to
X BSD file systems easier. These are described in the new file
X fsconfig.h.
X - The relative cost of fragmentation is now reported as the average
X distance of each seek (in number of cylinders). This is reported
X as an average for the entire file system, as well as for each file.
X - Some files must span more than one cylinder simply because they are
X too large. Single-cylinder seeks due to size are ignored in the
X fragmentation calculation.
X - A makefile has been created to enhance portability. The
X makefile contains instructions for configuration of fsanalyze.
X
X Release 3.01 contains a few simple changes to enhance portability to
X XENIX/286, and adds the NUMOFFEND configuration parameter, which
X determines how many of the "top offender" (most fragmented) files
X are reported.
X
X Release 3.02 changes the rotation delay algorithm slightly to more closely
X reflect the BSD placement algorigthm. I still don't trust the results,
X since they are non-intuitive, and always too high for what I would expect
X from BSD. The other major change is the addition of a "wasted space"
X metric which reports unuseable space due to partial use of the last block
X of each file.
X
X Release 3.03 reports the total number of blocks used for indirection (and
X thus unavailable for data). I also made more changes to the rotation
X delay algorithm, providing a formula for BSD Opt_interleave that makes
X more sense than previous versions. The results still seem a bit too
X high, but they're more reasonable than before. This version also
X includes a complete code re-organization which makes it easier to pack
X into shell archives, and some other general cleanup in preparation for
X posting to Usenet.
X
X Release 3.04 contains minor changes to avoid namespace conflicts in the
X FS_TYPE and OS_TYPE macros. NFS support is also disassociated with the
X OS_TYPE.
X
X Release 4.1 contains no major changes from 3.04, but resulted from
X placing the code under SCCS.
END_OF_Changes
if test 5025 -ne `wc -c <Changes`; then
echo shar: \"Changes\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MANIFEST -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(1115 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X File Name Archive # Description
X-----------------------------------------------------------
X Changes 1 Revision History
X Info 2 Useful information on interpreting
X results
X MANIFEST 1 This file...
X Makefile 1 Guess.
X Mkfile.sun 1 Makefile for Suns
X Mkfile.sys5 1 Makefile for generic System V
X Mkfile.uport 1 Makefile for Microport System V/AT
X Mkfile.xenix 1 Makefile for XENIX/286
X README 1 Useful information
X chkfile.c 3 File Scanner
X fragm.c 1 Fragmentation heuristics
X fsanalyze.8 2 Manual page
X fsanalyze.c 1 main()
X fsanalyze.h 2 Global declarations
X fsconfig.h 3 System-dependent declarations
X init.c 2 System initialization
X patchlevel.h 1 Current patch level
X report.c 2 Print report
X stats.c 1 Statistics maintenance
X util.c 1 Inode-related utilities
END_OF_MANIFEST
if test 1115 -ne `wc -c <MANIFEST`; then
echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Makefile -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(2425 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X
X##
X## FSANALYZE makefile
X## Version : 4.1 - 88/11/16 17:27:40
X
X## One of the things FSANALYZE displays is a list of the most fragmented
X## files. OFFEND determines how many of those files to report.
X## The report is in double column format, so the number should be divisible
X## by 2. Ideally, this number should be set so that the report fits on
X## a single screen. For a 24-line display, the suggested number is 10,
X## which is the default.
XOFFEND = 10
X
X## File System type - Use the first definition for derivatives of the old
X## AT&T file system, including Version 7, System III, and System V
X## releases 2 and 3, and XENIX. Use the second definition for derivatives
X## of the BSD Fast File system without NFS. If NFS support is also included,
X## use the third definition.
XFS = FS_ATT
X#FS = FS_BSD
X#FS = FS_BSD_NFS
X
X## Operating system type - This definition is used for OS-dependencies within
X## a given file system. Use OS_ATT or OS_BSD if none of the other definitions
X## apply.
X#OS = OS_ATT
X#OS = OS_BSD
XOS = OS_UPORT_286 # Microport System V/AT (286-based - use _ATT for /386)
X#OS = OS_XENIX_286 # XENIX/286 (use _ATT for XENIX/386)
X
X## Uncomment the next line if you have the fsstat(1) command. Note that if
X## you are installing fsanalyze on a Microport System V/AT, this command
X## should be uncommented, since the is_ok macro as defined in fsconfig.h
X## will not work.
XFSSTAT = -DHAVE_FSSTAT
X
X## Where the executable should be placed...
XDESTDIR = /etc/local
X
X## Where the man file should be placed...
XMANDIR = /usr/man/man8
X
XCONFIG_FLGS = -DFS_TYPE=$(FS) -DOS_TYPE=$(OS) -DNUMOFFEND=$(OFFEND) $(FSSTAT)
X
X## edit as appropriate...
XCFLAGS = -O $(CONFIG_FLGS)
XLDFLAGS =
X
XOBJS = fsanalyze.o chkfile.o fragm.o init.o report.o stats.o util.o
XSRCS = fsanalyze.c chkfile.c fragm.c init.c report.c stats.c util.c
X
Xfsanalyze: $(OBJS)
X $(CC) $(LDFLAGS) -o fsanalyze $(OBJS)
X
Xinstall: fsanalyze manual
X mv fsanalyze $(DESTDIR)
X chmod 755 $(DESTDIR)/fsanalyze
X
Xclean:
X rm *.o fsanalyze
X
Xlint: $(SRCS) fsconfig.h fsanalyze.h
X lint -D_FS_TYPE=$(FS) -D_OS_TYPE=$(OS) $(FSSTAT) -p $(SRCS)
X
Xmanual: fsanalyze.8
X cp fsanalyze.8 $(MANDIR)
X chmod 444 $(MANDIR)/fsanalyze.8
X
Xchkfile.o : fsconfig.h fsanalyze.h
Xfragm.o : fsconfig.h fsanalyze.h
Xfsanalyze.o : fsconfig.h fsanalyze.h
Xinit.o : fsconfig.h fsanalyze.h patchlevel.h
Xreport.o : fsconfig.h fsanalyze.h
Xstats.o : fsconfig.h fsanalyze.h
Xutil.o : fsconfig.h fsanalyze.h
END_OF_Makefile
if test 2425 -ne `wc -c <Makefile`; then
echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Mkfile.sun -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Mkfile.sun\"
else
echo shar: Extracting \"Mkfile.sun\" \(2474 characters\)
sed "s/^X//" >Mkfile.sun <<'END_OF_Mkfile.sun'
X## @(#)$Id: Mkfile.sun, V4.1 88/11/16 17:27:58 $
X##
X## FSANALYZE makefile
X## Version : 4.1 - 88/11/16 17:27:58
X
X## One of the things FSANALYZE displays is a list of the most fragmented
X## files. OFFEND determines how many of those files to report.
X## The report is in double column format, so the number should be divisible
X## by 2. Ideally, this number should be set so that the report fits on
X## a single screen. For a 24-line display, the suggested number is 10,
X## which is the default.
XOFFEND = 10
X
X## File System type - Use the first definition for derivatives of the old
X## AT&T file system, including Version 7, System III, and System V
X## releases 2 and 3, and XENIX. Use the second definition for derivatives
X## of the BSD Fast File system without NFS. If NFS support is also included,
X## use the third definition.
X#FS = FS_ATT
X#FS = FS_BSD
XFS = FS_BSD_NFS
X
X## Operating system type - This definition is used for OS-dependencies within
X## a given file system. Use OS_ATT or OS_BSD if none of the other definitions
X## apply.
X#OS = OS_ATT
XOS = OS_BSD
X#OS = OS_UPORT_286 # Microport System V/AT (286-based - use _ATT for /386)
X#OS = OS_XENIX_286 # XENIX/286 (use _ATT for XENIX/386)
X
X## Uncomment the next line if you have the fsstat(1) command. Note that if
X## you are installing fsanalyze on a Microport System V/AT, this command
X## should be uncommented, since the is_ok macro as defined in fsconfig.h
X## will not work.
X#FSSTAT = -DHAVE_FSSTAT
X
X## Where the executable should be placed...
XDESTDIR = /etc/local
X
X## Where the man file should be placed...
XMANDIR = /usr/man/man8
X
XCONFIG_FLGS = -DFS_TYPE=$(FS) -DOS_TYPE=$(OS) -DNUMOFFEND=$(OFFEND) $(FSSTAT)
X
X## edit as appropriate...
XCFLAGS = -O $(CONFIG_FLGS)
XLDFLAGS =
X
XOBJS = fsanalyze.o chkfile.o fragm.o init.o report.o stats.o util.o
XSRCS = fsanalyze.c chkfile.c fragm.c init.c report.c stats.c util.c
X
Xfsanalyze: $(OBJS)
X $(CC) $(LDFLAGS) -o fsanalyze $(OBJS)
X
Xinstall: fsanalyze manual
X mv fsanalyze $(DESTDIR)
X chmod 755 $(DESTDIR)/fsanalyze
X
Xclean:
X rm *.o fsanalyze
X
Xlint: $(SRCS) fsconfig.h fsanalyze.h
X lint -D_FS_TYPE=$(FS) -D_OS_TYPE=$(OS) $(FSSTAT) -p $(SRCS)
X
Xmanual: fsanalyze.8
X cp fsanalyze.8 $(MANDIR)
X chmod 444 $(MANDIR)/fsanalyze.8
X
Xchkfile.o : fsconfig.h fsanalyze.h
Xfragm.o : fsconfig.h fsanalyze.h
Xfsanalyze.o : fsconfig.h fsanalyze.h
Xinit.o : fsconfig.h fsanalyze.h patchlevel.h
Xreport.o : fsconfig.h fsanalyze.h
Xstats.o : fsconfig.h fsanalyze.h
Xutil.o : fsconfig.h fsanalyze.h
END_OF_Mkfile.sun
if test 2474 -ne `wc -c <Mkfile.sun`; then
echo shar: \"Mkfile.sun\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Mkfile.sys5 -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Mkfile.sys5\"
else
echo shar: Extracting \"Mkfile.sys5\" \(2474 characters\)
sed "s/^X//" >Mkfile.sys5 <<'END_OF_Mkfile.sys5'
X## @(#)$Id: Mkfile.sys5, V4.1 88/11/16 17:28:35 $
X##
X## FSANALYZE makefile
X## Version : 4.1 - 88/11/16 17:28:35
X
X## One of the things FSANALYZE displays is a list of the most fragmented
X## files. OFFEND determines how many of those files to report.
X## The report is in double column format, so the number should be divisible
X## by 2. Ideally, this number should be set so that the report fits on
X## a single screen. For a 24-line display, the suggested number is 10,
X## which is the default.
XOFFEND = 10
X
X## File System type - Use the first definition for derivatives of the old
X## AT&T file system, including Version 7, System III, and System V
X## releases 2 and 3, and XENIX. Use the second definition for derivatives
X## of the BSD Fast File system without NFS. If NFS support is also included,
X## use the third definition.
XFS = FS_ATT
X#FS = FS_BSD
X#FS = FS_BSD_NFS
X
X## Operating system type - This definition is used for OS-dependencies within
X## a given file system. Use OS_ATT or OS_BSD if none of the other definitions
X## apply.
XOS = OS_ATT
X#OS = OS_BSD
X#OS = OS_UPORT_286 # Microport System V/AT (286-based - use _ATT for /386)
X#OS = OS_XENIX_286 # XENIX/286 (use _ATT for XENIX/386)
X
X## Uncomment the next line if you have the fsstat(1) command. Note that if
X## you are installing fsanalyze on a Microport System V/AT, this command
X## should be uncommented, since the is_ok macro as defined in fsconfig.h
X## will not work.
X#FSSTAT = -DHAVE_FSSTAT
X
X## Where the executable should be placed...
XDESTDIR = /etc/local
X
X## Where the man file should be placed...
XMANDIR = /usr/man/man8
X
XCONFIG_FLGS = -DFS_TYPE=$(FS) -DOS_TYPE=$(OS) -DNUMOFFEND=$(OFFEND) $(FSSTAT)
X
X## edit as appropriate...
XCFLAGS = -O $(CONFIG_FLGS)
XLDFLAGS =
X
XOBJS = fsanalyze.o chkfile.o fragm.o init.o report.o stats.o util.o
XSRCS = fsanalyze.c chkfile.c fragm.c init.c report.c stats.c util.c
X
Xfsanalyze: $(OBJS)
X $(CC) $(LDFLAGS) -o fsanalyze $(OBJS)
X
Xinstall: fsanalyze manual
X mv fsanalyze $(DESTDIR)
X chmod 755 $(DESTDIR)/fsanalyze
X
Xclean:
X rm *.o fsanalyze
X
Xlint: $(SRCS) fsconfig.h fsanalyze.h
X lint -D_FS_TYPE=$(FS) -D_OS_TYPE=$(OS) $(FSSTAT) -p $(SRCS)
X
Xmanual: fsanalyze.8
X cp fsanalyze.8 $(MANDIR)
X chmod 444 $(MANDIR)/fsanalyze.8
X
Xchkfile.o : fsconfig.h fsanalyze.h
Xfragm.o : fsconfig.h fsanalyze.h
Xfsanalyze.o : fsconfig.h fsanalyze.h
Xinit.o : fsconfig.h fsanalyze.h patchlevel.h
Xreport.o : fsconfig.h fsanalyze.h
Xstats.o : fsconfig.h fsanalyze.h
Xutil.o : fsconfig.h fsanalyze.h
END_OF_Mkfile.sys5
if test 2474 -ne `wc -c <Mkfile.sys5`; then
echo shar: \"Mkfile.sys5\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Mkfile.uport -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Mkfile.uport\"
else
echo shar: Extracting \"Mkfile.uport\" \(2475 characters\)
sed "s/^X//" >Mkfile.uport <<'END_OF_Mkfile.uport'
X## @(#)$Id: Mkfile.uport, V4.1 88/11/16 17:28:47 $
X##
X## FSANALYZE makefile
X## Version : 4.1 - 88/11/16 17:28:47
X
X## One of the things FSANALYZE displays is a list of the most fragmented
X## files. OFFEND determines how many of those files to report.
X## The report is in double column format, so the number should be divisible
X## by 2. Ideally, this number should be set so that the report fits on
X## a single screen. For a 24-line display, the suggested number is 10,
X## which is the default.
XOFFEND = 10
X
X## File System type - Use the first definition for derivatives of the old
X## AT&T file system, including Version 7, System III, and System V
X## releases 2 and 3, and XENIX. Use the second definition for derivatives
X## of the BSD Fast File system without NFS. If NFS support is also included,
X## use the third definition.
XFS = FS_ATT
X#FS = FS_BSD
X#FS = FS_BSD_NFS
X
X## Operating system type - This definition is used for OS-dependencies within
X## a given file system. Use OS_ATT or OS_BSD if none of the other definitions
X## apply.
X#OS = OS_ATT
X#OS = OS_BSD
XOS = OS_UPORT_286 # Microport System V/AT (286-based - use _ATT for /386)
X#OS = OS_XENIX_286 # XENIX/286 (use _ATT for XENIX/386)
X
X## Uncomment the next line if you have the fsstat(1) command. Note that if
X## you are installing fsanalyze on a Microport System V/AT, this command
X## should be uncommented, since the is_ok macro as defined in fsconfig.h
X## will not work.
XFSSTAT = -DHAVE_FSSTAT
X
X## Where the executable should be placed...
XDESTDIR = /etc/local
X
X## Where the man file should be placed...
XMANDIR = /usr/man/man8
X
XCONFIG_FLGS = -DFS_TYPE=$(FS) -DOS_TYPE=$(OS) -DNUMOFFEND=$(OFFEND) $(FSSTAT)
X
X## edit as appropriate...
XCFLAGS = -O $(CONFIG_FLGS)
XLDFLAGS =
X
XOBJS = fsanalyze.o chkfile.o fragm.o init.o report.o stats.o util.o
XSRCS = fsanalyze.c chkfile.c fragm.c init.c report.c stats.c util.c
X
Xfsanalyze: $(OBJS)
X $(CC) $(LDFLAGS) -o fsanalyze $(OBJS)
X
Xinstall: fsanalyze manual
X mv fsanalyze $(DESTDIR)
X chmod 755 $(DESTDIR)/fsanalyze
X
Xclean:
X rm *.o fsanalyze
X
Xlint: $(SRCS) fsconfig.h fsanalyze.h
X lint -D_FS_TYPE=$(FS) -D_OS_TYPE=$(OS) $(FSSTAT) -p $(SRCS)
X
Xmanual: fsanalyze.8
X cp fsanalyze.8 $(MANDIR)
X chmod 444 $(MANDIR)/fsanalyze.8
X
Xchkfile.o : fsconfig.h fsanalyze.h
Xfragm.o : fsconfig.h fsanalyze.h
Xfsanalyze.o : fsconfig.h fsanalyze.h
Xinit.o : fsconfig.h fsanalyze.h patchlevel.h
Xreport.o : fsconfig.h fsanalyze.h
Xstats.o : fsconfig.h fsanalyze.h
Xutil.o : fsconfig.h fsanalyze.h
END_OF_Mkfile.uport
if test 2475 -ne `wc -c <Mkfile.uport`; then
echo shar: \"Mkfile.uport\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Mkfile.xenix -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"Mkfile.xenix\"
else
echo shar: Extracting \"Mkfile.xenix\" \(2476 characters\)
sed "s/^X//" >Mkfile.xenix <<'END_OF_Mkfile.xenix'
X## @(#)$Id: Mkfile.xenix, V4.1 88/11/16 17:29:01 $
X##
X## FSANALYZE makefile
X## Version : 4.1 - 88/11/16 17:29:01
X
X## One of the things FSANALYZE displays is a list of the most fragmented
X## files. OFFEND determines how many of those files to report.
X## The report is in double column format, so the number should be divisible
X## by 2. Ideally, this number should be set so that the report fits on
X## a single screen. For a 24-line display, the suggested number is 10,
X## which is the default.
XOFFEND = 10
X
X## File System type - Use the first definition for derivatives of the old
X## AT&T file system, including Version 7, System III, and System V
X## releases 2 and 3, and XENIX. Use the second definition for derivatives
X## of the BSD Fast File system without NFS. If NFS support is also included,
X## use the third definition.
XFS = FS_ATT
X#FS = FS_BSD
X#FS = FS_BSD_NFS
X
X## Operating system type - This definition is used for OS-dependencies within
X## a given file system. Use OS_ATT or OS_BSD if none of the other definitions
X## apply.
X#OS = OS_ATT
X#OS = OS_BSD
X#OS = OS_UPORT_286 # Microport System V/AT (286-based - use _ATT for /386)
XOS = OS_XENIX_286 # XENIX/286 (use _ATT for XENIX/386)
X
X## Uncomment the next line if you have the fsstat(1) command. Note that if
X## you are installing fsanalyze on a Microport System V/AT, this command
X## should be uncommented, since the is_ok macro as defined in fsconfig.h
X## will not work.
X#FSSTAT = -DHAVE_FSSTAT
X
X## Where the executable should be placed...
XDESTDIR = /etc/local
X
X## Where the man file should be placed...
XMANDIR = /usr/man/man8
X
XCONFIG_FLGS = -DFS_TYPE=$(FS) -DOS_TYPE=$(OS) -DNUMOFFEND=$(OFFEND) $(FSSTAT)
X
X## edit as appropriate...
XCFLAGS = -O $(CONFIG_FLGS)
XLDFLAGS =
X
XOBJS = fsanalyze.o chkfile.o fragm.o init.o report.o stats.o util.o
XSRCS = fsanalyze.c chkfile.c fragm.c init.c report.c stats.c util.c
X
Xfsanalyze: $(OBJS)
X $(CC) $(LDFLAGS) -o fsanalyze $(OBJS)
X
Xinstall: fsanalyze manual
X mv fsanalyze $(DESTDIR)
X chmod 755 $(DESTDIR)/fsanalyze
X
Xclean:
X rm *.o fsanalyze
X
Xlint: $(SRCS) fsconfig.h fsanalyze.h
X lint -D_FS_TYPE=$(FS) -D_OS_TYPE=$(OS) $(FSSTAT) -p $(SRCS)
X
Xmanual: fsanalyze.8
X cp fsanalyze.8 $(MANDIR)
X chmod 444 $(MANDIR)/fsanalyze.8
X
Xchkfile.o : fsconfig.h fsanalyze.h
Xfragm.o : fsconfig.h fsanalyze.h
Xfsanalyze.o : fsconfig.h fsanalyze.h
Xinit.o : fsconfig.h fsanalyze.h patchlevel.h
Xreport.o : fsconfig.h fsanalyze.h
Xstats.o : fsconfig.h fsanalyze.h
Xutil.o : fsconfig.h fsanalyze.h
END_OF_Mkfile.xenix
if test 2476 -ne `wc -c <Mkfile.xenix`; then
echo shar: \"Mkfile.xenix\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f README -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(6616 characters\)
sed "s/^X//" >README <<'END_OF_README'
XFSANALYZE - File System Analyzer tool
XVersion : 4.1.1.2 - 88/11/30 15:53:38
X
XAuthor : Michael J. Young
XUSmail : Software Development Technologies, Inc.
X 375 Dutton Rd
X Sudbury MA 01776
XUUCP : harvard!sdti!mjy
XInternet : mjy at sdti.SDTI.COM
X
X =========================================================================
X Note : This program has been placed in the public domain to permit
X unrestricted distribution and use. I have placed no copyright on it, but
X I request that you keep me informed about any enhancements and bug fixes
X you make so I can keep an up-to-date copy for further distribution.
X =========================================================================
X
X This is a completely new version of fsanalyze which contains a number of
X bug fixes, new features, and enhanced portability. This version of
X fsanalyze has been ported to the BSD fast file system, and run
X successfully on a Sun. It has also run successfully under Ultrix,
X but some changes may be needed in the #include directives in
X the file "fsanalyze.h".
X
X For a complete revision history, see the file called "Changes". Other
X useful information may be found in the file called "Info".
X
XIntroduction:
X Fsanalyze is a simple tool that estimates file system fragmentation. It
X accomplishes this by scanning the data blocks for each i-node in the
X file system, looking for block numbers that are out of sequence. In
X effect, it is counting the number of disk seeks required to read the
X entire file in sequence. Fragmentation is then computed as the ratio
X of actual "seeks" to the potential number of "seeks" if the file were
X completely fragmented.
X
X Fsanalyze also provides a number of other useful statistics regarding the
X file system usage, including the number (and identity) of files that are
X very large, sparse files, and excessively large directories (i.e.,
X directory files that require data block indirection, making filename
X searches very inefficient).
X
X After the general file system statistics are displayed, fsanalyze lists
X the 10 most fragmented i-nodes in the file system. The 10 most
X fragmented files are listed in decreasing order of fragmentation based on
X the absolute number of fragments. For example, a 100-block file that
X contains 40 individual fragments is 39.39% fragmented (39 seeks / 99
X potential seeks), but is listed before a 2-block file that contains 2
X fragments (100% fragmented). Thus, larger fragmented files (which have a
X greater effect on file system performance) are listed before small files.
X
X In my estimation fsanalyze is completely safe, since it never writes to
X the file system that it is analyzing and uses only the standard I/O
X library to do its work. It should be possible to run fsanalyze on a
X write-protected file system, if you're worried. If anything should go
X wrong, the worst you will see is fseek() errors. Be that as it may,
X however, there is no express or implied warrantee as to safety or
X accuracy of the results. Use at your own risk.
X
XInstallation:
X
X For most systems, installing fsanalyze should consist simply of editing
X the Makefile and running make. The Makefile is self-documenting (yeah,
X I know, I know!). For convenience, I've included a number of different
X Makefiles that are configured for various systems. Ultrix users should
X be able to use the Sun version with no changes.
X
X Note that for Microport System V/AT systems, HAVE_FSSTAT should be
X defined, since the is_ok(fs) macro defined in fsanalyze.h will not work.
X
X Where fsanalyze is installed doesn't really matter, but I would recommend
X placing it somewhere in the root filesystem, which is always mounted. I
X typically run fsanalyze during my backup procedure, while my other
X filesystems are unmounted.
X
X Fsanalyze is not a setuid program, so the user must have read access to
X the file system to be analyzed. I run it as root for this reason, but
X if you're paranoid, it would be better just run it in the same group
X as the the file systems (sys on my system).
X
XUsage:
X fsanalyze [-flags] special [file [...]]
X
X If the optional file arguments are missing, the entire file system
X is analyzed. If present, the specified files are analyzed and reported
X individually.
X
X [flags] include the following:
X b# assume '#' bytes per logical block -- by default, this value
X is calculated automatically. Supported, but not useful, for
X BSD file systems.
X c# assume '#' sectors per disk cylinder -- by default,
X this value is determined by information in the superblock.
X d display i-node numbers as they are examined.
X e report file size inconsistencies - the inode numbers are reported
X for files where the file size and number of data blocks are
X inconsistent.
X g# assume an inter-block gap of '#' sectors -- by
X default this information is taken from the superblock. Not
X useful, for BSD file systems.
X i report double and triple indirection - the inode numbers are
X reported for files that contain double and/or triple indirection.
X o overrides error checking on file system. Use this flag if the
X file system you are analyzing is damaged. Note that fsanalyze
X may give erroneous results if used on a damaged file system, but
X the file system itself will not be modified.
X v Display current version number and patch level.
X
X Example:
X fsanalyze /dev/dsk/0s2 /* analyzes an entire file system */
X fsanalyze /dev/dsk/0s2 * /* analyzes all files in the current
X * directory of the file system */
X
X Since fsanalyze uses the superblock info ON THE DISK, more accurate
X results will be returned fsanalyze is run on an unmounted, or read-only
X mounted file system.
X
X Since fsanalyze does its work the old fashioned way (brute-force), it
X must scan through the file system inode by inode. It therefore takes
X a while to finish. Be patient.
X
XBugs:
X Please report any bugs (and possible fixes) to me, so I can keep my
X source up-to-date. I'm sure there are plenty of bugs, especially in the
X BSD-specific stuff. Since I don't have access to anything but my little
X Microport System V/AT system, it's hard for me to find portability bugs.
X
X Known Bugs include:
X 1. I don't trust the rotation delay statistics, especially for
X BSD file systems. The numbers seem to be much too high to be
X believable.
END_OF_README
if test 6616 -ne `wc -c <README`; then
echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fragm.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"fragm.c\"
else
echo shar: Extracting \"fragm.c\" \(4443 characters\)
sed "s/^X//" >fragm.c <<'END_OF_fragm.c'
Xstatic char sccsid[] = "@(#)$Id: fragm.c, V4.1 88/11/16 17:29:42 $";
X
X/*
X * fragm.c - fragmentation analysis
X * Version : 4.1 - 88/11/16 17:29:42
X *
X * Author : Michael J. Young
X * USmail : Software Development Technologies, Inc.
X * 375 Dutton Rd
X * Sudbury MA 01776
X * UUCP : harvard!sdti!mjy
X * Internet : mjy at sdti.SDTI.COM
X *
X * =========================================================================
X * Note : This program has been placed in the public domain to permit
X * unrestricted distribution and use. I have placed no copyright on it, but
X * I request that you keep me informed about any enhancements and bug fixes
X * you make so I can keep an up-to-date copy for further distribution.
X *
X * This program is being provided "as is", with no warrantee as to safety or
X * accuracy of results. Use at your own risk.
X * =========================================================================
X */
X
X/*
X * Modification History:
X *
X * Thu Jul 28 15:57:32 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Extracted from fsanalyze.c
X *
X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts
X *
X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Placed under SCCS
X */
X
X/*
X * Include files
X */
X#include "fsconfig.h"
X#include "fsanalyze.h"
X
X/*
X * must_seek : returns true if the two data blocks reside on different
X * disk cylinders.
X */
Xboolean must_seek (new_block, old_block)
Xdaddr_t new_block; /* next data block */
Xdaddr_t old_block; /* previous data block */
X{
X daddr_t old_cyl; /* base block of current cylinder */
X daddr_t new_cyl; /* base block of new cylinder */
X
X old_cyl = cylinder (fil_sys, old_block);
X new_cyl = cylinder (fil_sys, new_block);
X
X return (old_cyl != new_cyl);
X }
X
X/*
X * rotate_delay : returns true if the new data block is within the same
X * cylinder, but is not at the optimum position within the cylinder
X */
Xboolean rot_delay (new_block, old_block)
Xdaddr_t new_block; /* next data block */
Xdaddr_t old_block; /* previous data block */
X{
X daddr_t old_off; /* cylinder offset of current block */
X daddr_t new_off; /* cylinder offset of next block */
X
X old_off = cyl_pos (fil_sys, old_block);
X new_off = cyl_pos (fil_sys, new_block);
X
X return ((new_off != old_off + interleave) &&
X (new_off != (old_off + interleave) % cyl_size) &&
X (new_block != old_block + 1));
X }
X
X/*
X * seek_dist : returns the number of cylinders that must be traversed
X * to get from blk2 to blk1.
X */
Xlong seek_dist (blk1, blk2)
Xdaddr_t blk1; /* new block */
Xdaddr_t blk2; /* previous block */
X{
X daddr_t cyl1; /* base block of current cylinder */
X daddr_t cyl2; /* base block of new cylinder */
X
X cyl1 = cylinder (fil_sys, blk1);
X cyl2 = cylinder (fil_sys, blk2);
X
X return diff (cyl1, cyl2);
X }
X
X/*
X * minimum_seeks : returns the number of cylinders that the file spans just
X * by virtue of its size. Any single-cylinder seeks due to the sheer size
X * of the file will be ignored in the fragmentation calculation.
X */
Xlong minimum_seeks (file_size)
Xoff_t file_size; /* size of file from inode entry */
X{
X off_t bytes_per_cyl;
X
X bytes_per_cyl = (off_t)cyl_size * DEV_BSIZE;
X return (file_size / bytes_per_cyl);
X }
X
X/*
X * test_fragmentation : determines whether or not the two specified blocks
X * indicate that fragmentation has occurred. Disk seeks that are required
X * due to the sheer size of the file are ignored in the calculation. If
X * no disk seeks are required, a heuristic is used to determine if the
X * data blocks are optimally placed within the cylinder.
X */
Xvoid test_fragmentation (new_pos, old_pos, data)
Xdaddr_t new_pos; /* new block number */
Xdaddr_t old_pos; /* original block */
Xstruct file_data *data; /* file statistics data structure */
X{
X data->potential_seeks++;
X if (must_seek (new_pos, old_pos)){
X if (data->min_cost && seek_dist (new_pos, old_pos) == 1){
X data->min_cost--;
X }
X else {
X data->cost += seek_dist (new_pos, old_pos);
X data->seeks++;
X }
X }
X else if (rot_delay (new_pos, old_pos)){
X data->rotates++;
X }
X }
X
END_OF_fragm.c
if test 4443 -ne `wc -c <fragm.c`; then
echo shar: \"fragm.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fsanalyze.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"fsanalyze.c\"
else
echo shar: Extracting \"fsanalyze.c\" \(6212 characters\)
sed "s/^X//" >fsanalyze.c <<'END_OF_fsanalyze.c'
Xstatic char sccsid[] = "@(#)$Id: fsanalyze.c, V4.1 88/11/16 17:30:08 $";
X
X/*
X * fsanalyze.c - file system analyzer
X * Version : 4.1 - 88/11/16 17:30:08
X *
X * Author : Michael J. Young
X * USmail : Software Development Technologies, Inc.
X * 375 Dutton Rd
X * Sudbury MA 01776
X * UUCP : harvard!sdti!mjy
X * Internet : mjy at sdti.SDTI.COM
X *
X * =========================================================================
X * Note : This program has been placed in the public domain to permit
X * unrestricted distribution and use. I have placed no copyright on it, but
X * I request that you keep me informed about any enhancements and bug fixes
X * you make so I can keep an up-to-date copy for further distribution.
X *
X * This program is being provided "as is", with no warrantee as to safety or
X * accuracy of results. Use at your own risk.
X * =========================================================================
X */
X
X/*
X * Modification History:
X *
X * Date Author Description
X * ----------- -------- -----------------------------------------------
X * 28 Jul 1987 MJY Originated
X * 5 Oct 1987 MJY Capability to analyze individual files,
X * Added error checking to file system argument,
X * Added -o flag
X * Prints out volume and file system name in summary
X * 12 Oct 1987 MJY Use /etc/fsstat to do file system validity
X * checking
X * 9 Nov 1987 MJY print out warning if file system is mounted
X * 12 Nov 1987 MJY Volume size statistics now long instead of int
X * 7 Jan 1988 MJY Modified blk_no() to use l3tol()
X *
X * Wed Mar 9 17:51:38 EST 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Rewrite for portability between various versions of System V, esp.
X * SCO XENIX and 5.3 systems. First (incomplete) attempt at porting
X * to BSD 4.3. See README for details.
X *
X * Thu Apr 7 10:03:21 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Seeks for files that span cylinders due to their sheer size are
X * ignored. Average seek distance is now reported.
X *
X * Wed Apr 13 17:33:03 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Completed port to BSD. Fixed bug in inode numbering for BSD.
X * Symbolic links now handled correctly for individual files.
X *
X * Wed Jun 15 14:08:30 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Number of top offenders is now a configurable parameter via the
X * NUMOFFEND macro in fsconfig.h.
X *
X * Fri Jun 24 16:22:10 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Make top offender size report consistent with anal_file reports.
X *
X * Tue Jul 26 15:24:30 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Added wasted space metric
X * Modified BSD rotation delay algorithm
X *
X * Thu Jul 28 16:15:22 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Opt_interleave() formula now makes sense
X * Re-organized code and general cleanup in preparation for posting.
X *
X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts
X *
X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Placed under SCCS
X */
X
X/*
X * Include files
X */
X#include "fsconfig.h"
X#include "fsanalyze.h"
X
X/***************************************************************************
X * Global Variables *
X ***************************************************************************/
X
X/*
X * interface to system error messages
X */
Xextern char *sys_errlist[];
Xextern int sys_nerr;
X
X/*
X * error : performs a function similar to perror(3), but supports variable
X * argument lists. Prints out a formatted error string to stderr, followed if
X * possible by an appropriate system error message. Control is then
X * returned to the system with an error status. This function does not
X * return.
X */
X/* VARARGS0 */
Xvoid error (va_alist)
Xva_dcl /* varargs */
X{
X int err; /* 1st arg - error number */
X char *str; /* 2nd arg - error format string */
X va_list args;
X va_start(args);
X err = va_arg (args, int);
X str = va_arg (args, char *);
X vfprintf (stderr, str, args);
X if (err <= sys_nerr && err > 0)
X fprintf (stderr, "%s\n", sys_errlist[err]);
X else
X fprintf (stderr, "unknown error : %d\n", err);
X va_end(args);
X
X /*
X * print out partial report, if possible
X */
X if (fil_sys != NULL)print_report ();
X exit(1); /* exit with error status */
X }
X
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{
X int next_param;
X extern int stat ();
X struct stat f_stat;
X
X /*
X * perform various initialization functions
X */
X next_param = init (argc, argv);
X
X if (next_param == argc){
X /*
X * no individual files to check, scan entire file system
X */
X printf ("Analyzing file system %s...\n", special);
X
X /*
X * scan through all i-nodes in the file system
X */
X scan();
X
X /*
X * print out statistics summary
X */
X print_report();
X }
X else {
X /*
X * scan individual files instead of entire file system
X */
X printf (" \t Seek Wasted\n");
X printf (" Name \ti-node Fragments Size %% Dist Space\n");
X for (; next_param < argc; next_param++){
X if (stat (argv[next_param], &f_stat) != 0){
X error (errno, "error opening \"%s\"\n",
X argv[next_param]);
X /* NOTREACHED */
X }
X else {
X
X /*
X * make sure the inode belongs to the correct device
X * (for BSD systems with symbolic links)
X */
X if ((f_stat.st_dev == fs_device) &&
X !IS_SPECIAL (f_stat.st_mode)){
X anal_file (f_stat.st_ino, argv[next_param]);
X }
X }
X }
X }
X return (0);
X }
END_OF_fsanalyze.c
if test 6212 -ne `wc -c <fsanalyze.c`; then
echo shar: \"fsanalyze.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f patchlevel.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"patchlevel.h\"
else
echo shar: Extracting \"patchlevel.h\" \(950 characters\)
sed "s/^X//" >patchlevel.h <<'END_OF_patchlevel.h'
X/* @(#)$Id: patchlevel.h, V4.1 88/11/16 17:55:39 $ */
X
X/*
X * patchlevel.h - current patch level
X * Version : 4.1 - 88/11/16 17:55:39
X *
X * Author : Michael J. Young
X * USmail : Software Development Technologies, Inc.
X * 375 Dutton Rd
X * Sudbury MA 01776
X * UUCP : harvard!sdti!mjy
X * Internet : mjy at sdti.SDTI.COM
X *
X * =========================================================================
X * Note : This program has been placed in the public domain to permit
X * unrestricted distribution and use. I have placed no copyright on it, but
X * I request that you keep me informed about any enhancements and bug fixes
X * you make so I can keep an up-to-date copy for further distribution.
X *
X * This program is being provided "as is", with no warrantee as to safety or
X * accuracy of results. Use at your own risk.
X * =========================================================================
X */
X
X#define patch_level 0
X
END_OF_patchlevel.h
if test 950 -ne `wc -c <patchlevel.h`; then
echo shar: \"patchlevel.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f stats.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"stats.c\"
else
echo shar: Extracting \"stats.c\" \(5581 characters\)
sed "s/^X//" >stats.c <<'END_OF_stats.c'
Xstatic char sccsid[] = "@(#)$Id: stats.c, V4.1 88/11/16 17:31:26 $";
X
X/*
X * stats.c - file system statistics
X * Version : 4.1 - 88/11/16 17:31:26
X *
X * Author : Michael J. Young
X * USmail : Software Development Technologies, Inc.
X * 375 Dutton Rd
X * Sudbury MA 01776
X * UUCP : harvard!sdti!mjy
X * Internet : mjy at sdti.SDTI.COM
X *
X * =========================================================================
X * Note : This program has been placed in the public domain to permit
X * unrestricted distribution and use. I have placed no copyright on it, but
X * I request that you keep me informed about any enhancements and bug fixes
X * you make so I can keep an up-to-date copy for further distribution.
X *
X * This program is being provided "as is", with no warrantee as to safety or
X * accuracy of results. Use at your own risk.
X * =========================================================================
X */
X
X/*
X * Modification History:
X *
X * Thu Jul 28 16:02:51 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Extracted from fsanalyze.c
X *
X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts
X *
X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Placed under SCCS
X */
X
X#include "fsconfig.h"
X#include "fsanalyze.h"
X
X/*
X * calculated global statistics
X */
Xlong blocks = 0; /* running block count */
Xlong free_inodes = 0; /* number of unused i-nodes */
Xlong potential_seeks = 0; /* potential number of disk seeks
X * during sequential access of a
X * file */
Xlong seeks = 0; /* actual number of disk seeks
X * required during sequential access
X * of a file */
Xlong total_seek_distance = 0; /* actual distance of disk seeks
X * required during sequential access
X * of a file */
Xlong rotates = 0; /* number of disk rotation delays */
Xlong indirects = 0; /* number of files w/ more than
X * 10 data blocks */
Xlong double_indirects = 0; /* number of files w/ more than
X /* one level of indirection */
Xlong triple_indirects = 0; /* number of files w/ more than
X * two levels of indirection */
Xlong ind_blks = 0; /* number of blocks used for
X * indirection */
Xint big_directories = 0; /* number of directories with
X * indirection */
Xint num_directories = 0; /* number of directories */
Xint num_specials = 0; /* number of special files */
Xint linked_files = 0; /* number of multiply-linked files */
Xint sparse_files = 0; /* number of sparse files */
Xint size_errors = 0; /* number of file size discrepancies */
Xlong unuseable = 0; /* unuseable bytes due to external
X * fragmentation */
X
Xstruct file_data file_log[NUMOFFEND] = {0}; /* worst offenders */
X
X/*
X * init_stats : initializes per-file statistics structure
X */
Xvoid init_stats (data, inode, file_size)
Xstruct file_data *data; /* file stats to init */
Xint inode; /* i-node number */
Xlong file_size; /* file size */
X{
X data->inode = inode;
X data->total_blocks = data->data_blocks = 0;
X data->potential_seeks = data->seeks = data->rotates = 0;
X data->fragm = 0.0;
X data->sparse = 0;
X data->cost = 0;
X data->min_cost = minimum_seeks (file_size);
X data->rel_cost = 0.0;
X data->wasted = 0;
X }
X
X/*
X * log_stats : updates global statistics based on the current file statistics.
X * The current file is then checked to see if it qualifies as one of the
X * worst offenders (i.e., most fragmented) encountered thus far. The worst
X * offenders are determined based on their absolute number of disk seeks
X * required to read the entire file. Such an absolute test (viz a viz a
X * relative percentage test) ensures that very small, but fragmented, files
X * will not clutter the output.
X */
Xvoid log_stats (data)
Xstruct file_data *data; /* file statistics to be
X * logged */
X{
X int i, j; /* loop counters */
X
X
X /*
X * update global statistics
X */
X blocks += data->total_blocks;
X ind_blks += data->total_blocks - data->data_blocks;
X potential_seeks += data->potential_seeks;
X seeks += data->seeks;
X total_seek_distance += data->cost;
X rotates += data->rotates;
X data->fragm = data->potential_seeks ? (float)data->seeks/(float)data->potential_seeks : 0.0;
X data->rel_cost = (data->seeks ? (float)data->cost/(float)data->seeks : 0.0);
X unuseable += data->wasted;
X
X /*
X * update worst offender array
X */
X for (i = 0; i < NUMOFFEND; i++){
X if (data->seeks > file_log[i].seeks){
X for (j = NUMOFFEND-1; j > i; j--){
X file_log[j] = file_log[j-1];
X }
X file_log[i] = *data;
X break;
X }
X }
X }
X
END_OF_stats.c
if test 5581 -ne `wc -c <stats.c`; then
echo shar: \"stats.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f util.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"util.c\"
else
echo shar: Extracting \"util.c\" \(2687 characters\)
sed "s/^X//" >util.c <<'END_OF_util.c'
Xstatic char sccsid[] = "@(#)$Id: util.c, V4.1 88/11/16 17:31:35 $";
X
X/*
X * util.c - inode utilities
X * Version : 4.1 - 88/11/16 17:31:35
X *
X * Author : Michael J. Young
X * USmail : Software Development Technologies, Inc.
X * 375 Dutton Rd
X * Sudbury MA 01776
X * UUCP : harvard!sdti!mjy
X * Internet : mjy at sdti.SDTI.COM
X *
X * =========================================================================
X * Note : This program has been placed in the public domain to permit
X * unrestricted distribution and use. I have placed no copyright on it, but
X * I request that you keep me informed about any enhancements and bug fixes
X * you make so I can keep an up-to-date copy for further distribution.
X *
X * This program is being provided "as is", with no warrantee as to safety or
X * accuracy of results. Use at your own risk.
X * =========================================================================
X */
X
X/*
X * Modification History:
X *
X * Thu Jul 28 15:55:40 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Extracted from fsanalyze.c
X *
X * Mon Aug 08 11:27:39 EDT 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Revised OS_TYPE and FS_TYPE macros to avoid name-space conflicts
X *
X * Wed Nov 16 11:31:32 EST 1988 - M. Young (mjy at sdti.SDTI.COM),
X * Placed under SCCS
X */
X
X#include "fsconfig.h"
X#include "fsanalyze.h"
X
X/*
X * blk_no : given a pointer to an inode block number, returns a (daddr_t)
X * block number. Used to provide portable access to the direct data blocks
X * of an i-node.
X */
Xdaddr_t blk_no (off)
Xunsigned char *off; /* 3- or 4-byte offset */
X{
X daddr_t temp = 0;
X
X#if FS_TYPE == FS_ATT
X extern void l3tol();
X
X l3tol (&temp, off, 1);
X#endif
X
X#if FS_TYPE == FS_BSD
X temp = *((daddr_t *)off);
X#endif
X
X return temp;
X }
X
X/*
X * get_inodes : given an initial i-node number, reads a block of i-nodes
X * into an i-node array.
X */
Xvoid get_inodes (in, inp, num)
Xint in; /* inode number */
Xint num; /* # inodes to get */
Xstruct dinode *inp; /* buffer to hold info */
X{
X daddr_t position; /* computed position of the
X * first requested i-node */
X
X position = (daddr_t) inode_block(fil_sys, in) * block_size +
X (daddr_t) inode_offset(fil_sys, in) * sizeof(struct dinode);
X if (fseek (fsys, position, 0)){
X error (errno, "\nerror seeking inode %d, pos = %ld\n", in, position);
X /* NOTREACHED */
X }
X else {
X if (fread (inp, sizeof (struct dinode), num, fsys) != num){
X error (errno, "\nerror reading inode %d\n", in);
X /* NOTREACHED */
X }
X }
X }
X
END_OF_util.c
if test 2687 -ne `wc -c <util.c`; then
echo shar: \"util.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Mike Young
Software Development Technologies, Inc., Sudbury MA Tel: +1 508 443 5779
Internet: mjy at sdti.sdti.com UUCP: {harvard,mit-eddie}!sdti!mjy
More information about the Comp.sources.misc
mailing list