#! /bin/bsh -x
# Fermi Linux runacct script 
#
#@(#)$Id: runacct,v 1.1 2000/10/17 19:58:06 jonest Exp $ 
#@(#)$Author: jonest $
#@(#)$Log: runacct,v $
#@(#)Revision 1.1  2000/10/17 19:58:06  jonest
#@(#)Initial commit of the Fermi Linux Process Accounting.
#@(#)
#
# MAILCOM="mail root products adm" 
MAILCOM=${MAILCOM:-':'}

PATH=/usr/lib/acct:/bin:/usr/bin:/etc
export PATH
_MIN_BLKS=500
_adm=${ACCTDIR:-/var/adm}
_lib=/usr/lib/acct
_nite=${_adm}/acct/nite
_sum=${_adm}/acct/sum
_fsdev='/var/adm'
_statefile=${_nite}/statefile
_active=${_nite}/active
_lastdate=${_nite}/lastdate
_date="`date +%m%d`"
##########################################################################
##########################################################################
#        "make sure that 2 crons weren't started, or leftover problems"
##########################################################################
cd ${_adm}
date > ${_nite}/lock1
chmod 400 ${_nite}/lock1
ln ${_nite}/lock1 ${_nite}/lock
if test $? -ne 0 ; then
	echo "\r\n*********** 2 CRONS or ACCT PROBLEMS***********\r\n" | $MAILCOM
	echo "ERROR: locks found runacct aborted" >> ${_active}
fi
	
#       "Check for enough space in ${_fsdev} to do nitely accounting"
##########################################################################
_blocks=`df /var/adm | awk 'NR>1{print $4}'`
if [ $_blocks -le $_MIN_BLKS ] ; then
	echo " ERROR: not enough space in ${_fsdev} to do nitely accounting" >>  ${_active} 
	echo " ERROR: not enough space in ${_fsdev} to do nitely accounting" | $MAILCOM
	exit 1
fi

case $# in
0)
#	"as called by the cron each day"
	if test -r ${_lastdate} ; then
		echo "0000" >> ${_lastdate}
	fi
	if test "${_date}" = "`cat ${_lastdate}`" ; then
		 echo " ERROR: process accounting has already run for `date` " >> ${_active} 
		mv ${_active} ${_active}${_date}
		exit 1
	fi
	echo ${_date} > ${_lastdate}	
	echo SETUP > ${_statefile}
	;;

1)
#	"runacct MMDD  (date)  will restart at current state"
	_date=$1
	echo "Restarting accounting for ${_date} at `cat ${_statefile}`" >> ${_active}
	;;

2)
#	"runacct MMDD STATE  restart at specified state"
	_date=$1
	echo "Restarting accounting for for ${_date} at $2" >> ${_active}
	echo "$2" > ${_statefile}
	;;
*)
	;;
esac
##########################################################################


##########################################################################
#	"processing is broken down into seperate, restartable states"
#	"the statefile is updated at the end of each state so that the"
#	"next loop through the while statement switches to the next state"
##########################################################################

while [ 1 ]
do
case "`cat ${_statefile}`" in

SETUP)

#	"switch current pacct file"
	/usr/sbin/accton
	mv /var/log/pacct ${_nite}/spacct${_date}
	touch /var/log/pacct
	/usr/sbin/accton /var/log/pacct
	chmod 755 ${_nite}/spacct${_date}
	chown adm.adm ${_nite}/spacct${_date}
	echo "switched current pacct file" >> ${_nite}/active
	ls -l ${_nite}/spacct${_date} >> ${_nite}/active
	echo PROCESS > ${_statefile} 
	cat ${_statefile} >>${_active}
	;;


PROCESS)
#	"correlate Spacct and ptacct files by number"
	echo "Summing command accounting into user totals" >> ${_nite}/active
	${_lib}/acctprclx < ${_nite}/spacct${_date} > ${_sum}/tacct${_date}
	ls -l ${_sum}/tacct${_date} ${_nite}/spacct${_date} >> ${_nite}/active
	echo MERGETACCT > ${_statefile} 
	cat ${_statefile} >>${_active}
	;;

MERGETACCT)
#	"save each days tacct file in sum/tacct.${_date}"
#	"if sum/tacct gets corrupted or lost, could recreate easily"
#	"the mounthly acctg procedure should remove all sum/tacct files"
	if [ -s ${_sum}/tacct ] ; then
		echo "Merging ${_sum}/tacctprev and ${_sum}/tacct${_date}" >>${_active}
       		mv ${_sum}/tacct ${_sum}/tacctprev 
       		${_lib}/acctmerg < ${_sum}/tacctprev ${_sum}/tacct${_date} > ${_sum}/tacct
	else
		echo "Making new  ${_sum}/tacct " >>${_active}
       		${_lib}/acctmerg < ${_sum}/tacct${_date} > ${_sum}/tacct 
	fi
	echo " Acummulating summary files" >> ${_nite}/active
	ls -l ${_sum}/tacct ${_sum}/tacctprev  >> ${_nite}/active
	echo CLEANUP > ${_statefile} 
	cat ${_statefile} >>${_active}
	;;

CLEANUP)
#	" finally clear files; could be done next morning if desired"
	cd ${_adm}/acct
	rm -f nite/lock
	echo "Linux Process Accounting has completed." >> ${_active}
	echo COMPLETE > ${_statefile} 
	cat ${_statefile} >>${_active}
	exit 0
	;;

*)
	echo "ERROR: invalid state, Check Linux Process Accounting." >> ${_active}
	echo "${_statefile}" >> ${_active}
	rm -f ${_nite}/lock
	mv  ${_active}  ${_active}${_date}
	exit 1 
	;;
esac
##########################################################################
# completed run accounting
##########################################################################

done

