#!/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 <&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() { 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