Listing 9: fchange.sh
:
#######################################################
# fchange.sh: log and report changed files
# Copyright (C) 1996 Steve Isaacson
#######################################################
# fchange.sh - new and improved version.
# How to install.
# 1) mkdir $ctrldir and set the value below.
# 2) mkdir $ctrldir/logs
# 3) create $ctrldir/fchange.files
# 4) cp cdiff.sh $ctrldir
# 5) add an entry to your crontab
# make sure this is being run by a posix compliant shell
test "$((1))" = 1 || exec ksh $0 "$@"
test "$debugxv" && set -xv # primitive debugger
# set up trap
trap "cleanup 1" 1 2 15
# make sure everything is in the PATH
PATH=/bin:/usr/bin:/usr/ucb:.:/u/stevei/bin/`uname -n`:$PATH
export PATH
# set up variables
MAILER=/usr/bin/mailx ; export MAILER
# make your changes here
: ${ctrldir:=/u/stevei/fchange}
: ${filesfile:=$ctrldir/fchange.files}
: ${logdir:=$ctrldir/logs}
: ${fnpseudo:=$ctrldir/pseudo.sh}
newlist=$ctrldir/new.list
lastlist=$ctrldir/last.list
difflist=$ctrldir/diff.list
mailout=$ctrldir/mail.out.$$
# If you have access to a decent file locking program,
# define it here. If not, a simple locking scheme will
# be used below. The one I use is called lockfile.
unset LOCKPROG # assume we don't have it
whence lockfile > /dev/null && \
LOCKPROG="lockfile -n15 -l 0 -r 0"
UNLOCKPROG="rm -f"
LOCKFILE=$ctrldir/fchange.lck
# If abort file is present, exit.
test -f $ctrldir/abort && exit 0
#######################################################
cleanup()
#######################################################
# remove the lock file and exit with the appropriate
# status
{
$UNLOCKPROG $LOCKFILE
rm -f $mailout $difflist
exit $1
}
# cleanup()
# Initial sanity check
cd $ctrldir || cleanup 0
# See if we can fork 20 processes. If not, then bail.
whence fork > /dev/null && {
fork 20 >/dev/null 2>&1 || exit 0
}
# If file system is full, forget it.
test -x $ctrldir/space.chk && {
$ctrldir/space.chk || cleanup 0
}
# Make sure we have everything we need
whence $ctrldir/cdiff.sh > /dev/null || {
echo "Error: could not find $ctrldir/cdiff.sh"
cleanup 1
}
#######################################################
# create lockfile
#######################################################
# primitive locking mechanism
if test "$LOCKPROG"
then
# try to acquire the lock
$LOCKPROG $LOCKFILE >/dev/null 2>&1 || exit 0
else
test -f $LOCKFILE && exit 0 || date > $LOCKFILE
fi
#######################################################
# pseudo programs
#######################################################
# If there is a pseudo-file shell script there, run it.
test -x "$fnpseudo" && $fnpseudo
#######################################################
# new list
#######################################################
# read files file and create new list.
awk '/^(:|#|$)/ {next}
{print $1}' $filesfile | sort |
xargs ls -l > $newlist 2>&1
#######################################################
# compare last list
#######################################################
# Compare newlist with lastlist. If they're the same,
# then there is no work to do and we're done. If
# newlist and lastlist are different, then there is work
# to do and we'll use the difflist below.
# necessary first-time only
test -f $lastlist || > $lastlist
diff $newlist $lastlist > $difflist && {
rm -f $difflist
cleanup 0
}
#######################################################
# there is work to do
#######################################################
# Move the newlist to lastlist so we can use it the next
# time we're here.
mv $newlist $lastlist
#######################################################
# get to work
#######################################################
# read diff list, grabbing only certain lines.
awk '/^< / {print $NF}' $difflist |
while read fn
do
# grab the line from the files file
grep "$fn " $filesfile
done |
while read fn mail_to
do
# set track and showdiff flags. default is no
track=no ; showdiff=no
# now check for the flags
case "$mail_to" in
*track)
# set flag and strip off trailing track
track=yes ; mail_to=${mail_to%track} ;;
*showdiff)
# set flag and strip off trailing showdiff
showdiff=yes ; mail_to=${mail_to%showdiff} ;;
esac
# build unique log file name using the filename
sum=$(echo $fn | sum -r |
awk '{printf("%s_%s\n", $1, $2)}')
logname=$logdir/$sum
diffname=$logdir/$sum.diff
trackname=$logdir/$sum.track
# get last line in the log, or create the log
if test -f $logname
then
last_line=$(tail -1 $logname)
else
last_line=_none_
echo "#_name:$fn : $(date)" > $logname
fi
# get the current information about the file
if test -f $fn -o -c $fn
then
cur_line=$(ls -l $fn)
else
cur_line=_no_file_
fi
# if current line is same as last line, we're done.
test "$cur_line" = "$last_line" && continue
# or else something is different. so log new
# information.
echo "$cur_line" >> $logname
# and start writing our mail message
{
echo "$sum: $fn"
echo $last_line
echo $cur_line
} > $mailout
test "$track" = yes && {
echo "#_change: $(date)" >> $trackname
cat $fn >> $trackname
$ctrldir/cdiff.sh $trackname >> $mailout
}
test "$showdiff" = yes && {
echo "#_change: $(date)" >> $diffname.new
cat $fn >> $diffname.new
if test -f "$diffname"
then
diff $diffname.new $diffname >> $mailout
else
cat $diffname.new >> $mailout
fi
mv $diffname.new $diffname
}
$MAILER -s "fchange: $fn" "$mail_to" < $mailout \
> /dev/null
done
cleanup 0
============== END: fchange.sh ==================
|