#! /bin/ksh
##########################################################################
# Title      :	checksccs - check consistency of SCCS files
# Author     :	Heiner Steven <heiner.steven@odn.de>
# Date       :	1998
# Requires   :	getent, sccs
# Category   :	Programming
# SCCS-Id.   :	@(#) checksccs	1.5 04/03/01
##########################################################################
# Description
#   This script checks for the following conditions:
#    o	Files that are not SCCS maintained (warning)
#    o	p-files that are older than s-files (error)
#    o	p-files that contain an invalid base revision number (error)
#    o	p-files that contain an invalid (existing) next revisio number (error)
#    o  p-files that contain a non-existing user id (error)
#    o	files that are writable, but are not checked out (error)
#    o	files that are checked-out, but have an expanded SCCS id keyword
#	(i.e. "@(#) file.c 1.2") instead of "'%'W'%'" (warning)
#    o	files that are older than their SCCS archive (warning)
#	(this may cause "make" to try to check-out the newer SCCS version)
#    o	directories that contain files, but no SCCS subdirectory (warning)
#
#  We need /bin/ksh for the following features:
#	"[ -ot ]"	(older than)
#	"D="${Path%/*}"	(dirname)
##########################################################################

PN=`basename "$0"`			# Program name
VER='1.5'

usage () {
    echo >&2 "$PN - check consistency of SCCS files, $VER
usage: $PN [directory ...]"
    exit 1
}

msg () {
    for msgLine
    do echo "$PN: $msgLine" >&2
    done
}

fatal () { msg "$@"; exit 1; }

set -- `getopt h "$@"`
[ $# -lt 1 ] && usage			# "getopt" detected an error

while [ $# -gt 0 ]
do
    case "$1" in
					# your flags here
	--)	shift; break;;
	-h)	usage;;
	-*)	usage;;
	*)	break;;			# First file name
    esac
    shift
done

# Default value: current directory
[ $# -lt 1 ] && set -- .

msg "checking files starting with directory $@"
find "$@" -type f -print |
    egrep -v '/SCCS/|/,' |
    while read Path
    do
	N=`basename "$Path"`		# File Name
	# The SunOS "dirname" script cannot handle blanks in
	# file names! Use build-in ksh functionality instead:
	#D=`dirname "$Path"`		# Directory
	D="${Path%/*}"
	if [ -d "$D/SCCS" ]
	then
	    (
		cd "$D"
		if [ -f "SCCS/s.$N" ]
		then			# SCCS file exists
		    if [ -f "SCCS/p.$N" ]
		    then			# File is checked-out
			if [ "SCCS/p.$N" -ot "SCCS/s.$N" ]
			then
			    echo "ERROR: p-file older than s-file: $Path"
			fi

			# Check validity of base and next version number from
			# p-file 
			pver=; nver=; uid=
			eval `awk '
				NF >= 5 {
				print "pver=\"" $1 "\"; nver=\"" $2 "\";" \
					"uid=\"" $3 "\""
				}' "SCCS/p.$N"`

			if [ -n "$pver" ]
			then
			    sccs get -p -r$pver "$N" >/dev/null 2>&1 ||
			    	echo "ERROR: p-file contains invalid base" \
					"version \"$pver\": $Path"
			fi

			if [ -n "$nver" ]
			then
			    sccs get -p -r$nver "$N" >/dev/null 2>&1 &&
			    	echo "ERROR: p-file contains invalid" \
					"(existing) next version" \
					"\"$nver\": $Path"
			fi

			if [ -n "$uid" ]
			then
			    getent passwd "$uid" >/dev/null 2>&1 ||
				echo "ERROR: p-file contains invalid" \
					"user id \"$uid\": $Path"
			fi

			# This file is checked out and should not contain
			# expanded SCCS ID keywords like '@(#)' or
			# the version number. The keywords should be
			# @(#)checksccs	1.3 or 1.3.
			if egrep '%[A-Z]%' "$N" >/dev/null 2>&1
			then
			    :			# Seems to be o.k.
			elif egrep '@\(#\)' "$N" >/dev/null 2>&1
			then
			    echo "WARNING: file may contain \"@(#)\" instead of \""'%''W''%'"\": $Path"
			fi
		    elif [ -w "$N" ]
		    then			# Not checked out
			echo "ERROR: writable, but not checked out: $Path"
		    elif [ "$N" -ot "SCCS/s.$N" ]
		    then
		    	echo "WARNING: checked-out file is older than SCCS archive: $Path"
		    fi
		else
		    echo "WARNING: no SCCS file: $Path"
		fi
	    )
	fi
    done

msg "searching for directories not SCCS maintained..."
find "$@" -type d ! -name SCCS -print |
	while read dir
	do
	    [ -d "$dir" ] || continue
	    if [ -d "$dir/SCCS" ]
	    then
	    	:
	    else
	    	# This is an error only if there is at least one file
		# in this directory
		n=0
		for file in "$dir"/*
		do
		    [ -f "$file" ] || continue
		    n=`expr $n + 1`
		done
		if [ $n -gt 1 ]
		then
		    echo "WARNING: non-empty directory without SCCS: $dir"
		fi
	    fi
	done
