#! /bin/ksh
#
# upsd
#
# Simple shell script to monitor a set of network nodes.  If they all
# fail to respond to pings, assume the power has cut off and shut the 
# machine down.
#
# Andrew Smallshaw
# andrews@sdf.lonestar.org
# $Date: 2012/08/31 18:49:44 $
# $Revision: 1.9 $

# Space separated list of devices to poll.  Only one of these needs to
# respond for power to remain on.  IP addresses are generally preferred
# over hostnames so that a down DNS does not trigger a false positive.
DEVICES="10.93.1.195 10.93.1.196 10.93.0.4 epson cs1 brother"

# Minutes to wait before issuing shut down command.
SHUTDOWN_LATENCY=3

# Shut down this many minutes after the command is issued.
SHUTDOWN_DELAY=5

# File to store PID in for future reference
PIDFILE=/var/run/upsd.pid

# Poll set of devices, returns true if any respond.
poll() {
	for node in $DEVICES
	do
		if ping -c 1 -w 1 -Q -n "$node" >/dev/null 2>/dev/null
		then return 0
		fi
	done
	
	return 1
}

# Shut down the system
off() {
	shutdown -p +"$SHUTDOWN_DELAY" "upsd: power failure detected for `hostname`."
}

monitor() {
	TIMER=0

	while true
	do
		if poll
		then
			if [ $TIMER -ne 0 ]
			then TIMER=$(($TIMER - 1))
			fi
		else
			if [ $TIMER -eq $SHUTDOWN_LATENCY ]
			then
				logger -t "upsd[$$]" "Invoking shutdown command"				
				off
				
				# Do nothing for five minutes after scheduled shut down
				# time - in case shut down is cancelled for some reason
				sleep $((($SHUTDOWN_DELAY + 5) * 60))
				
				TIMER=0
			else
				logger -t "upsd[$$]" "Power failure detected"
				TIMER=$((TIMER + 1))
			fi
		fi
		
		sleep 60
	done
}

# Check script is running as superuser
if [ `whoami` != root ]
then
	echo "Must be run as superuser" >&2
	exit 1
fi

# Demonise script by reinvoking
if [ "$SECOND_RUN" != true ]
then
	SECOND_RUN=true nohup "$0" "$@" >/dev/null &
else
	echo $$ > "$PIDFILE"
	monitor
fi 

exit 0
