[comp.sources.misc] fsfilt filesystem filter program

mark@ems.mn.org (07/07/87)

	Here is a little program to help out those people who are not
fortunate enough to have a -mount option on their find command.  We are
currently using this program to help with our weekly backups.

Mark H. Colburn                mark@ems.mn.org
EMS/McGraw-Hill                ihnp4!meccts!ems!mark
9855 West 78th Street
Eden Prairie, MN   55344       +1 612 829 8200

   ``Don't tell me she don't love me, the money's just a mere formality...''

- ------------------------------ CUT HERE -------------------------------------
#! /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 shell archive."
# Contents:  Makefile README fsfilt.c weekback
# Wrapped by mark@ems on Sun Jun 28 16:58:07 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(2274 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X# fsfilt - filesystem filtering program for use with find.
X# Written by Mark H. Colburn
X# Copyright (C) 1987, Mark H. Colburn
X#
X# Permission is hereby granted to use or modify this program for any 
X# non-commercial purpose.
X#
X# AUTHOR(S)
X#	Mark H. Colburn
X#
X# %W% %G%
X#
X# HISTORY
X#
X
XHEADER   = 
XSOURCE   = fsfilt.c
XOBJECT   = fsfilt.o
XCFLAGS   = -O
XLDFLAGS  = -s
XSCCSDIR  = .
XMAKEFILE = Makefile
XLINT     = /usr/bin/lint -b -x -h
XPR       = /usr/local/bin/cpr
XLP       = lp
XGFLAGS	 = 
X
X
X#
X# Program construction rules
X#
X
Xfsfilt: $(OBJECT)
X	cc $(LDFLAGS) $(OBJECT) -o fsfilt
X
Xall: fsfilt
X
X#
X# Generic Makefile Rules
X#
X
Xinstall: all
X
Xbuild: $(SOURCE) $(HEADER) $(MAKEFILE)
X
Xedit:
X	@for file in $(SOURCE) $(HEADERS) $(MAKEFILE); do \
X		if [ ! -w $$file]; then \
X			get -e $(SCCSDIR)/s.$$file; \
X		fi; \
X	done
X
Xdelta:
X	@for file in $(SOURCE) $(HEADERS) $(MAKEFILE); do \
X		if [ -w $$file]; then \
X			delta $(SCCSDIR)/s.$$file; \
X		fi; \
X	done
X	rm -f $(SOURCE)
X	rm -f $(HEADER)
X	rm -f $(MAKEFILE)
X	get $(GFLAGS) $(SCCSDIR)/s.$(MAKEFILE)
X
Xclean:
X	rm -f a.out core
X	rm -f cosy
X	rm -f $(OBJECT)
X
Xclobber:
X	rm -f $(OBJECT)
X	rm -f $(SOURCE)
X	rm -f $(HEADER)
X	rm -f a.out core
X
Xlint: $(HEADER) $(SOURCE)
X	$(LINT) $(SOURCE)
X
Xprint: $(HEADER) $(SOURCE)
X	$(PR) $(HEADER) $(SOURCE) | $(LP) -T"COSY cosy"
X
Xdepend:
X# For the moment we are lazy and disregard /usr/include files because
X# the sources contain them conditionally. Perhaps we should use cpp.
X#		( /bin/grep '^#[ 	]*include' $$i | sed -n \
X#			-e 's,<\(.*\)>,"/usr/include/\1",' \
X#
X	for i in ${SOURCE}; do \
X		( /bin/grep '^#[ 	]*include[ 	]*"' $$i | sed -n \
X			-e 's/[^"]*"\([^"]*\)".*/\1/' \
X			-e H -e '$$g' -e '$$s/\n/ /g' \
X			-e '$$s/.*/'$$i': &/' -e '$$s/\.c:/.o:/p' \
X			>> makedep); done
X	@echo '/^# DO NOT DELETE THIS LINE/+2,$$d' >eddep
X	@echo '$$r makedep' >>eddep
X	@echo 'w' >>eddep
X	@echo 'q' >>eddep
X	@cp $(MAKEFILE) $(MAKEFILE).bak
X	ed - $(MAKEFILE) < eddep
X	@rm -f eddep makedep
X	@echo '# DEPENDENCIES MUST END AT END OF FILE' >> $(MAKEFILE)
X	@echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> $(MAKEFILE)
X	@echo '# see make depend above' >> $(MAKEFILE)
X	@rm -f $(MAKEFILE).bak
X
X# DO NOT DELETE THIS LINE
X
X# DEPENDENCIES MUST END AT END OF FILE
X# IF YOU PUT STUFF HERE IT WILL GO AWAY
X# see make depend above
END_OF_Makefile
if test 2274 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" 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\" \(1518 characters\)
sed "s/^X//" >README <<'END_OF_README'
X
X	 fsfilt - filesystem filter for find (System V).
X 
X	 This program is intended for machines without a -mount option 
X	 on their find(1) command.  We use this program for doing backups, 
X	 when we do not want find to cross mountpoints in the directory 
X	 structure.  This program will pick up the current working 
X	 directory, read the mount table (/etc/mnttab on system V machines) 
X	 and build a list of directories that should NOT be backed up.
X 
X	This program is inteneded to have find(1) output piped into it.  
X	Each filename is examined, and if it does not contain references 
X	to any of the children filesystems of the current filesystem, if 
X	any, then the filename is printed on standard output, otherwise 
X	it is trashed.
X
X 	An example command would be:
X		find . -print | fsfilt | cpio -ocB > /dev/rmt1
X 
X 	In addition to children filesystems, the tmp directory in both / 
X	and /usr are not backed up.  This dependancy is hardcoded into the 
X	source.
X
X
X	An example of how this program is used is given in the file
X	./backup.  This is the shell script which we use to backup
X	our machine each week.
X
X	This source is copyright (c) 1987 by Mark H. Colburn.
X	Permission is hereby given to use or modify this program for
X	any non-commercial purpose.  No gaurentee of fitness, or 
X	suitability for any purpose is expressed, or implied.
X	(There, have I covered my butt sufficiently? :-)
X
X	Please send any enhancements, comments or bugs to the author.
X 
X	Mark H. Colburn 
X        EMS/McGraw-Hill
X	(mark@ems.mn.org)
END_OF_README
if test 1518 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fsfilt.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"fsfilt.c\"
else
echo shar: Extracting \"fsfilt.c\" \(3655 characters\)
sed "s/^X//" >fsfilt.c <<'END_OF_fsfilt.c'
X/*
X * fsfilt - filesystem filter for find (System V).
X * 
X * This program is intended for machines without a -mount option on their 
X * find(1) command.  We use this program for doing backups, when we do not
X * want find to cross mountpoints in the directory structure.  This program
X * will pick up the current working directory, read the mount table
X * (/etc/mnttab on system V machines) and build a list of directories that
X * should NOT be backed up.
X * 
X * This program is inteneded to have find(1) output piped into it.  Each
X * filename is examined, and if it does not contain references to any of
X * the children filesystems of the current filesystem  (if any) then the
X * filename is printed on standard output, otherwise it is trashed.
X *
X * An example command would be:
X *	find . -print | fsfilt | cpio -ocB > /dev/rmt1
X * 
X * In addition to children filesystems, the tmp directory in both / and /usr
X * are not backed up.  This dependancy is hardcoded into the source.
X *
X * Please send any enhancements, comments or bugs to the author.
X * 
X * Author: Mark H. Colburn (mark@ems.mn.org)
X *         EMS/McGraw-Hill
X *
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include <mnttab.h>
X
X#define STRSIZ		200
X
Xvoid		perror();
Xint		nmnt;
Xstruct mnttab	fs[NMOUNT];
Xchar		except[NMOUNT][32];
Xint		numex = 0;
X
X/* ARGSUSED */
Xint	main(argc, argv)
Xint	argc;
Xchar   *argv[];
X{
X	int             i, found;
X	char            str[STRSIZ];
X
X	nmnt = read_mnttab();
X	get_exceptions();
X	while (!feof(stdin)) {
X		if (fgets(str, STRSIZ, stdin) == NULL && !feof(stdin))
X			perror("Unable to read stdin");
X		str[strlen(str) - 1] = '\0';
X		found = 0;
X		if (numex > 0)
X			for (i = 0; !found && i < numex; i++)
X				found = (strncmp(str, except[i],
X						 strlen(except[i])) == 0);
X		if (!found)
X			puts(str);
X	}
X	return (0);
X}
X
X
X/*
X * get_exceptions - get list of children filesystem of this directory
X */
X
Xint	get_exceptions()
X{
X	char            fsname[100], work[100], work1[100];
X	int		i, j, found = 0;
X	char		*cp;
X	char		*strindex();
X
X	(void) getcwd(fsname, 100);
X	if (strcmp(fsname, "/") == 0 || strcmp(fsname,"/usr") == 0)
X		(void) strcpy(except[numex++], "./tmp/");
X	for (i = 0; i < nmnt; i++) {
X		if (strncmp(fsname, fs[i].mt_filsys, strlen(fsname)) == 0 &&
X		    strcmp(fsname, fs[i].mt_filsys) != 0) {
X			if (strcmp(fsname, "/") == 0) 
X				(void) strcpy(work, fs[i].mt_filsys+
X				strlen(fsname));
X			else
X				(void) strcpy(work, fs[i].mt_filsys +
X				      strlen(fsname)+1);
X			if ((cp = strchr(work, '/')) == NULL) {
X				(void) strcpy(work1, work);
X				(void) strcat(work1, "/");
X			} else {
X				*(cp + 1) = '\0';
X				(void) strcpy(work1, work);
X			}
X			found = 0;
X			(void) sprintf(work,"./%s", work1);
X			for (j = 0; !found && j < numex; j++)
X				found = (strcmp(except[j], work) == 0);
X			if (!found)
X				strcpy(except[numex++], work);
X		}
X	}
X}
X
X/*
X * read_mount_table - get a list of all currently mounted filesystems
X */
X
Xint	read_mnttab()
X{
X	int             i, ret;
X	FILE           *fp;
X
X	if ((fp = fopen("/etc/mnttab", "r")) == NULL) {
X		(void) fprintf("Unable to open /etc/mnttab, exiting\n");
X		exit(1);
X	}
X	i = 0;
X	while (!feof(fp))
X		if (fread((char *) &fs[i], sizeof(struct mnttab), 1, fp) > 0)
X			i++;
X	(void) fclose(fp);
X	return (i);
X}
X
X
X/*
X * char *strindex(s1,s2) - return a pointer to where s2 exists in s1, or
X * NULL.
X */
X
Xchar	*strindex(s1, s2)
Xchar   *s1, *s2;
X{
X	register int    i;
X	register char  *cp;
X
X	i = strlen(s2);
X	if (strlen(s1) == i)
X		return (strcmp(s2, s1) ? NULL : s1);
X	if (strlen(s1) > i) {
X		for (cp = s1; *cp; cp++)
X			if (*cp == *s2 && strncmp(cp, s2, i) == 0)
X				return (cp);
X	}
X	return (NULL);
X}
END_OF_fsfilt.c
if test 3655 -ne `wc -c <fsfilt.c`; then
    echo shar: \"fsfilt.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f weekback -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"weekback\"
else
echo shar: Extracting \"weekback\" \(558 characters\)
sed "s/^X//" >weekback <<'END_OF_weekback'
XTD=/dev/9hi			# name of default tape drive
XFSFILT=/usr/local/etc/fsfilt	# location of fsfilt program
Xecho "Who should be notified upon completion? \c"
Xread NOTIFY
Xset `cat /etc/mountable | sort -r`
Xfor fsys in $*
Xdo
X	fsys=$2
X	fnam=$3
X	echo "Mount the backup for $fnam and press RETURN \c"
X	read return
X	cd $fnam
X	find . -print | $FSFILT | cpio -ocvB >$TD
X	(echo "backups of $fnam are complete") | write $NOTIFY
X	echo "backups of $fnam are complete"
X	shift 3 2>/dev/null
Xdone
Xtouch /usr/local/etc/DAY.DONE
X(echo "backups have been completed") | write $NOTIFY
END_OF_weekback
if test 558 -ne `wc -c <weekback`; then
    echo shar: \"weekback\" unpacked with wrong size!
fi
chmod +x weekback
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0

------- End of Forwarded Message