#!/bin/ksh
# $Id: tickle.ksh,v 1.30 2010/11/19 18:52:28 jeramy Exp $
# Based on ideas from David Stevens, but not his code. -- ksb
#
PATH=/usr/local/bin:/bin:/usr/bin:/usr/ucb:/etc
TMP_TCK=/tmp/rtcl$$.$((RANDOM%100))
while [ -f $TMP_TCK ] ; do
	TMP_TCK="$TMP_TCK,$((RANDOM%100))"
done
# default values for all the flags, or leave unset for a ${flag-value) form
: ${MAIL_FLAG:=false}
: ${TRASH_FLAG:=false}
: ${ZOLONS:=45}
: ${TRASH_TIME:=1}
export TMP_TCK PATH ZOLONS MAIL_FLAG
trap 'rm -f $TMP_TCK' EXIT

progname=`basename $0`
usage="$progname: usage [-mt] [-L days] [dirs]
$progname: -h
$progname: -V"
slide='P=$1; shift; set _ -`expr _"$P" : _'\''-.\(.*\)'\''` ${1+"$@"}; shift'
param='if [ $# -lt 2 ]; then echo "$progname: missing value for $1" 1>&2 ; exit 1; fi'


# read an environment variable as well as the command line options:
# protect this script from leading -x's with a bogus underbar, then remove it
set _ $ZZZ ${1+"$@"}
shift

# Change fmt based on platform, thank the gnu guys. --ed
if [ `uname -s` -eq "Linux" ]; then
	FMT="fmt -w2500"; # max with with gnu fmt. --ed
else
	FMT="fmt 4096 4106";
fi

# get the options from the command line (+ any variables)
while [ $# -gt 0 ]
do
	case "$1" in
	-m)
		MAIL_FLAG=true
		shift
		;;
	-m*)
		MAIL_FLAG=true
		eval "$slide"
		;;
	-L)
		eval "$param"
		ZOLONS=$2
		shift ; shift
		;;
	-L*)
		ZOLONS=`expr _"$1" : _'-.\(.*\)'`
		shift
		;;
	-t)
		TRASH_FLAG=true
		shift
		;;
	-t*)
		TRASH_FLAG=true
		eval "$slide"
		;;
	--)
		shift
		break
		;;
	-V|-V*)
		echo "$progname: "'$Id: tickle.ksh,v 1.30 2010/11/19 18:52:28 jeramy Exp $'
		echo "$progname: Mail Cc: environment variable \$TICK_CC"
		echo "$progname: output format 'user: rcsfile versionnum -dellines +addlines *dayslocked'"
		exit 0
		;;
	-h|-h*)
		cat <<HERE
$usage
h	print this help message
L days	set the limit for stale locked files (presently $ZOLONS)
m	send mail to the offenders
V	output version information
dirs	source directories to scan for idle RCS locks
HERE
		exit 0
		;;
	-*)
		echo "$usage" 1>&2
		exit 1
		;;
	*)
		# process and continue for intermixed options & args
		break
		;;
	esac
done

# These snips know about the "TMP_TICK" variable name and file format --ksb
if $MAIL_FLAG ; then
	MAIL_SNIP='(
	echo "Each RCS cache file listed below has been idle for more than $ZOLONS days:
"
	sed -n -e "s/ %1://p" <$TMP_TCK
	) | Mail -s "Stale RCS locks by login %1" %1 $TICK_CC'
else
	MAIL_SNIP='sed -n -e "s/\(.*\) \(%1: \)/\2\1 /p" <$TMP_TCK'
fi

#If we pass L0, we don't want to set an mtime at all. 
#On Linux, mtime +0 won't return things less than a day old.
MTIME="-mtime +'$ZOLONS'"
(( $ZOLONS == 0 )) && MTIME=""

# We're going to get Permission errors and we don't want to see them,
# we might get errors from rlog (can't read RCS cache file) and we'll
# cut them out as well --ksb
#
find ${*:-.} -name RCS -type d -print 2>/dev/null |
$FMT |
xapply -f "find %1 -maxdepth 2 $MTIME -name \*,v -print" - |
xapply -f 'rlog -L -R %1' - 2>/dev/null |
xapply -f 'echo %1; rcsdiff -u %[1/-$/-$]/%[1/$,-$] %1 2>/dev/null |
	perl -e '\''$count{"-"} = $count{"+"} = -1;
		while(<STDIN>) {
			next unless /^([-+])/;
			$count{$1}++;
		}
		$count{"-"} = 0 if $count{"-"} < 0;
		$count{"+"} = 0 if $count{"+"} < 0;
		print "-" . $count{"-"} . " +" . $count{"+"} ."\n";'\' - |
xapply -2 -f 'echo "diff: %2"; rlog -L -h -l %1' - - |
awk 'BEGIN { S=0; }
	/^diff:/ { D=$2" "$3; T=$4; }
	/^RCS file:/ { F=$3 }
	/^locks/ { S=1; }
	/^access/ { S=0; }
	/^\t/{ if (S) print F" "$1" "$2" "D" "T; }' | \
perl -lane 'print "@F *". int( ((time() - (stat("$F[0]"))[9]) / 86400));' >$TMP_TCK

if $TRASH_FLAG ; then
	export TRASH_TIME
	find ${1:-.} -name RCS -type d -print0 2>/dev/null |
	xapply -fz 'find "%q1" -name RCS -o -name "-[Nn]o_rm_star" -size 0 -o -mtime -$TRASH_TIME -o ! -name \*,v -print' - |
	xapply -f 'W=`ls -l "%q1" |awk "{print \\\$3;}"`; echo "%q1 $W: trash in RCS cache directory"' - >>$TMP_TCK
fi

# We have a list of the lockers (file login: version -/+), process that into
# a nice report.  sort -u could be "oue" here, if we always had that.
sed -e 's/.* \([^ :]*\):.*/\1/' <$TMP_TCK |
sort -u |
xapply -f "$MAIL_SNIP" -

exit 0
