#!/bin/bash
#
# __copy1__
# __copy2__
#
# check for timelimit on process(es)
#
# USAGE:
#	ps_timelimit outfile timelimit process(es)
#
# WHERE:
#   outfile	filename (under $TEMPDIR) used to write
#		offending pids
#
#   timelimit	in seconds
#
#   process(es)	PIDs or process name(s) to check
#
# RETURNS
#
#   0 if none of the process(es) is over the timelimit
#   (in seconds) passed as argument
#
#   1 if one or more processes are over the timelimit,
#   and writes offending PIDs in the file
#
#	$TEMPDIR/<outfile>
#
# that can be used by action commands, for reports or to
# kill the offending processes, eg:
#
#	tfile=$TEMPDIR/myfile; kill `cat $tfile`
#
# or better
#
#	SAFEKILL `cat $TEMPDIR/myfile`
#
CMD=${CMD:-"$0"}
DEBUG=${DEBUG:-"false"}
cmd=`basename $0`

usage()
{
	echo "usage: $0 outfile secs_timelimit [ PID | processname ]" >&2
	exit 255
}

pdebug()
{
	$DEBUG && echo "D $cmd> $*" >&2
}

# (MAIN)

[ $# != 3 ] && usage

outfile=`basename $1`; shift
timelimit=$1 ; shift

case $1 in
  -*|"")	usage ;;
  [1-9][0-9]*)	out=`ps -ocomm,pid $1` ;;
  *)		out=`ps -ocomm,pid -C $1` ;;
esac

out=`echo "$out" | sed -e '1d'`

[ "$out" == "" ] && {
	pdebug "no processes named '$1'"
	exit 0
}

now=`stat --format='%Y' $TEMPDIR/now`
outfile="$TEMPDIR/$outfile"
psfile="$TEMPDIR/$cmd.psfile"
stat=0

cp /dev/null $outfile
echo "$out" >$psfile

exec 9<&0 <$psfile
while read pname pid
do
	tfile="$TEMPDIR/$cmd.$pid.first_seen"

	if [ -f $tfile ]
	then
		first_seen=`stat --format='%Y' $tfile`
		delta=`expr $now - $first_seen`
		pdebug "process $pname($pid), first_seen=$first_seen, now=$now, delta=$delta"
		[ $delta -gt $timelimit ] && {
			pdebug "timelimit=$timelimit, OVER"
			echo $pid >>$outfile
			stat=1
		}
	else
		pdebug "process $pname($pid) marked"
		echo "$pname $pid" >$tfile
	fi
done
exec 0<&9 9<&-

# purge old files
#
remove=
for pid in `(cd $TEMPDIR ; ls $cmd.*.first_seen 2>/dev/null \
		| sed -e "s/$cmd\.//" -e 's/\.first_seen//')`
do
	grep -q " $pid$" $psfile || remove="$remove $cmd.$pid.first_seen"
done
[ "$remove" != "" ] && {
	pdebug "purging old flagfiles: " $remove
	(cd $TEMPDIR ; rm -f $remove)
}

exit $stat
