Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Nov 1997 07:18:29 +1030 (CST)
From:      thyerm@camtech.net.au
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   misc/5147: Keeping your /etc directory up to date
Message-ID:  <199711232048.HAA00905@matte.camtech.net.au>
Resent-Message-ID: <199711251120.DAA05708@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         5147
>Category:       misc
>Synopsis:       Submission of a shell script to help -CURRENT users update /etc
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 25 03:20:01 PST 1997
>Last-Modified:
>Originator:     Matthew Thyer
>Organization:
Unorganised
>Release:        FreeBSD 3.0-CURRENT i386
>Environment:

Any FreeBSD user who updates their source tree will be affected by this problem.

>Description:

Whenever updates are applied to your source tree (using CTM, cvs or cvsup),
your /etc directory can become out of date.  Subsequent make worlds can fail
because of this.  For example: recently during the install phase of make world
the network group was required to exist.  As this group had only just been
added to the /usr/src/etc/group file, several people had a minor failure in
make world.  This caused some unneccessary traffic in the freebsd-current
mailing list.

>How-To-Repeat:

Whenever you cvs or cvsup or CTM update your source tree, your /etc directory
can become out of date.

>Fix:

I suggest that the shell script "etcud" that I have written be committed to
the source tree (possibly in the tools directory).  Users should be informed
of its existance by a short sentence in the FAQ or handbook.

The scripts description and the script are included below:

==============================================================================
START OF DESCRIPTION OF SCRIPT.  THE SCRIPT IS INCLUDED AFTER THIS DESCRIPTION
==============================================================================

It stands for "/etc update" and does MD5 checksum comparisons
between the files in /usr/src/etc and /etc.  (use -r if your
source is not in /usr/src).

Where the files differ it can show you the versions of each file
and the differences.  By default it just shows you which files
differ and which do not exist.

It doesn't actually change any files and it can be run as an
ordinary user.

Typical recommended usage is to run as "etcud -t -v".
That will compare all files except group, hosts, motd, shells,
rc.local and master.passwd and where differences are found it
will show you the RCS version strings.

You could also run it with '-d' to show diffs between the /etc and
/usr/src/etc versions.

You can just check a single file with "etcud -i ppp/ppp.conf.sample"
or any file with 'ppp' in its name with "etcud -n -i ppp"

Usage is:

Usage: etcud [-a] [-v] [-d] [-n] [-t] [-r <dir>] [-i <patt> | -e <patt>]
       -a          Also output information for files where the checksums match
       -v          Display RCS version strings if present
       -d          Display diffs between the files
       -n          Non-exact mode - i.e. dont use '-x' with egrep
       -t          Typical usage.  This is the same as etcud -e "group|hosts|motd|shells|rc.local|master.passwd"
       -r <dir>    Directory where the source distribution is found
       -i <patt>   Inclusion filename pattern (those files to check)
       -e <patt>   Exclusion filename pattern (those file to ignore)

Typical output of "etcud -t -v" is:
MISMATCH for /usr/src/etc/etc.i386/MAKEDEV /etc/etc.i386/MAKEDEV
/usr/src/etc/etc.i386/MAKEDEV VER> #    $Id: MAKEDEV,v 1.141 1997/08/28 12:14:14 jkh Exp $
        /etc/etc.i386/MAKEDEV VER> #    $Id: MAKEDEV,v 1.140 1997/05/11 00:34:36 jmg Exp $
MISMATCH for /usr/src/etc/etc.i386/rc.i386 /etc/etc.i386/rc.i386
/usr/src/etc/etc.i386/rc.i386 VER> #    $Id: rc.i386,v 1.31 1997/09/14 12:16:36 jkh Exp $
        /etc/etc.i386/rc.i386 VER> #    $Id: rc.i386,v 1.29 1997/07/06 07:19:12 peter Exp $
MISMATCH for /usr/src/etc/ppp/ppp.conf.sample /etc/ppp/ppp.conf.sample
/usr/src/etc/ppp/ppp.conf.sample VER> # $Id: ppp.conf.sample,v 1.20 1997/09/10 00:52:30 brian Exp $
        /etc/ppp/ppp.conf.sample VER> # $Id: ppp.conf.sample,v 1.15 1997/06/10 10:04:19 brian Exp $
MISMATCH for /usr/src/etc/ppp/ppp.linkup.sample /etc/ppp/ppp.linkup.sample
/usr/src/etc/ppp/ppp.linkup.sample VER> # $Id: ppp.linkup.sample,v 1.9 1997/09/21 02:10:41 brian Exp $
        /etc/ppp/ppp.linkup.sample VER> # $Id: ppp.linkup.sample,v 1.7 1997/06/10 10:04:20 brian Exp $
MISMATCH for /usr/src/etc/mtree/BSD.include.dist /etc/mtree/BSD.include.dist
/usr/src/etc/mtree/BSD.include.dist VER> #      $Id: BSD.include.dist,v 1.14 1997/09/28 09:20:48 markm Exp $
        /etc/mtree/BSD.include.dist VER> #      $Id: BSD.include.dist,v 1.13 1997/06/04 23:05:31 ache Exp $

===========================================================
END OF DESCRIPTION OF SCRIPT.  THE SCRIPT IS INCLUDED BELOW
===========================================================

#!/bin/sh
#
# etcud 1.5 - Compare /etc with /usr/src/etc to check for updated files.
#
# etcud [-a] [-v] [-d] [-n] [-t] [-r <directory>] [-i <pattern> | -e <pattern>]
#
# This script compares the MD5 checksums of all files found in the etc
# directory of the source distribution (/usr/src/etc by default) with
# those in /etc to alert you when /etc files need updating.
#
# Options:
#
#  -a          Also output information for files where the checksums match.
#  -v          Display RCS version strings if present.
#  -d          Display diffs between the files.
#  -n          Non-exact mode.  i.e. dont use '-x' with egrep for inclusion
#              and exclusion patterns.  For power users only!
#  -t          Typical usage.  This is the same as etcud -e $DEF_EXCL
#  -r <dir>    Set the root directory of the source distribution.
#  -i <patt>   Inclusion filename pattern (those files to check).
#  -e <patt>   Exclusion filename pattern (those file to ignore).
#
# Inclusion and exclusion patterns must be an egrep pattern which is a list
#    of file names separated by the pipe character.  The filenames must be
#    relative to the etc directory of the source distribution (/usr/src/etc
#    by default).
#
# By default the script will use egrep -x which means the patterns must
#    exactly match for the files to be included or excluded.  This is
#    generally what you want as you probably want to be able to type
#    "etcud -e hosts" to exclude the file /etc/hosts but not the file
#    /etc/hosts.lpd.  Power users can use -n to disable the use of -x
#    with egrep.  This can be useful when dealing with the ppp directory
#    for example.
#
# NOTES
#    -  You can use EITHER an exclusion OR an inclusion file pattern, not
#       both.  Subsequent uses will be ignored with a warning.
#
#    -  Use of the typical option (-t) will run etcud with the default
#       exclusion pattern, set at $DEF_EXCL below.  This mode overrides
#       any previously specified inclusion or exclusion patterns with a
#       warning.  This mode also silently ignores -n.
#
# AUTHOR:  Matthew Thyer  November 1997
#
###############################################################################
# The default directory for the source distribution
DEF_SRC_ROOT=/usr/src
# The typical exclusion list
DEF_EXCL="group|hosts|motd|shells|rc.local|master.passwd"
#
opt_all=0
opt_ver=0
opt_diffs=0
opt_non_exact=0
opt_typical=0
opt_inc=0
opt_exc=0
error=0
cmd_name=`basename $0`

usage ()
{
	echo "Usage: $cmd_name [-a] [-v] [-d] [-n] [-t] [-r <dir>] [-i <patt> | -e <patt>]"
	echo "       -a          Also output information for files where the checksums match"
	echo "       -v          Display RCS version strings if present"
	echo "       -d          Display diffs between the files"
	echo "       -n          Non-exact mode - i.e. dont use '-x' with egrep"
	echo "       -t          Typical usage.  This is the same as etcud -e \"$DEF_EXCL\""
	echo "       -r <dir>    Directory where the source distribution is found"
	echo "       -i <patt>   Inclusion filename pattern (those files to check)"
	echo "       -e <patt>   Exclusion filename pattern (those file to ignore)"
}

show_ver ()
{
	the_ver=`grep '$Id:' $src_files/$x`
	if [ $? -eq 0 ] ; then
		echo "$src_files/$x VER> $the_ver"
	fi
	the_ver=`grep '$Id:' /etc/$x`
	if [ $? -eq 0 ] ; then
		echo "        /etc/$x VER> $the_ver"
	fi
}

do_check ()
{
	if [ -r /etc/$x ] ; then
		if [ `md5 /etc/$x | cut -d' ' -f4` != `md5 $src_files/$x | cut -d' ' -f4` ] ; then
			echo MISMATCH for $src_files/$x /etc/$x
			if [ $opt_ver -eq 1 ] ; then
				show_ver
			fi
			if [ $opt_diffs -eq 1 ] ; then
				diff /etc/$x $src_files/$x
				echo
			fi
		elif [ $opt_all -eq 1 ] ; then
			echo CHECK OK for $src_files/$x /etc/$x
			if [ $opt_ver -eq 1 ] ; then
				show_ver
			fi
		fi
	else # the file is not readable.... why ? perhaps it doesn't exist
		if [ ! -f /etc/$x ] ; then
			echo NONEXISTANT /etc/$x.  Maybe you should cp -p $src_files/$x /etc/$x
		else
			echo -n /etc/$x is not readable....
			if [ `id -u` -ne 0 ] ; then
				echo perhaps you should be ROOT!
			else
				echo for some strange reason!!!
			fi
		fi
	fi
}

# The main program begins.....

# First get the options
while [ $# -ne 0 ] ; do
	case $1 in
	-a)	opt_all=1
	;;
	-v)	opt_ver=1
	;;
	-d)	opt_diffs=1
	;;
	-n)	opt_non_exact=1
	;;
	-t)	opt_typical=1
		if [ $opt_inc -eq 1 -o $opt_exc -eq 1 ] ; then
			echo "Warning: Typical usage overriding prior inclusion or exclusion pattern"
			opt_inc=0
		fi
		opt_exc=1
		patt=$DEF_EXCL
	;;
	-r)	shift
		if [ $# -eq 0 ] ; then
			error=1
			echo "Error: -r requires an argument"
			usage
			break
		else
			if [ -d $1 ] ; then
				SRC_ROOT=$1
			else
				error=1
				echo "Error: Source directory \"$1\" does not exist"
				usage
				break
			fi
		fi
	;;
	-i)	shift
		if [ $# -eq 0 ] ; then
			error=1
			echo "Error: -i requires an argument"
			usage
			break
		else
			if [ $opt_inc -eq 1 -o $opt_exc -eq 1 ] ; then
				echo "Warning: subsequent inclusion pattern ignored"
			else
				patt=$1
				opt_inc=1
			fi
		fi
	;;
	-e)	shift
		if [ $# -eq 0 ] ; then
			error=1
			echo "Error: -e requires an argument"
			usage
			break
		else
			if [ $opt_inc -eq 1 -o $opt_exc -eq 1 ] ; then
				echo "Warning: subsequent exclusion pattern ignored"
			else
				patt=$1
				opt_exc=1
			fi
		fi
	;;
	*)	error=1
		usage
		break
	;;
	esac
	shift
done

if [ $error -eq 1 ] ; then
	exit
fi

src_files=`echo ${SRC_ROOT:=$DEF_SRC_ROOT}/etc | sed 's/\/\/$//'`
cd $src_files

# Can only do non_exact mode if we are not doing a typical
egrep_flags="-x"
if [ $opt_non_exact -eq 1 -a $opt_typical -eq 0 ] ; then
	egrep_flags=""
fi

if [ $opt_exc -eq 1 ] ; then
	egrep_flags=$egrep_flags" -v "
fi

if [ $opt_inc -eq 1 -o $opt_exc -eq 1 ] ; then
	find . -type f -exec echo {} \; | sed 's/^\.\///' | egrep $egrep_flags $patt | while read x ; do
		do_check
	done
else
	find . -type f -exec echo {} \; | sed 's/^\.\///' | while read x ; do
		do_check
	done
fi

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711232048.HAA00905>