#!/bin/tcsh -f
# JLdL 09Oct09.
#
# Copyright (C) 2008-2009 by Jorge L. deLyra <delyra@fma.if.usp.br>.
# This program may be copied and/or distributed freely. See the
# _ terms and conditions in /usr/share/doc/<package>/copyright.
#
# This is the dynahostnis-system pseudo-daemon dynahostnisd.
#
# Monitor a remote client that has registered itself on the
# _ dynahostnis system and, if it stops responding to pings
# _ for more that a certain time, then unregister it.
#
# There should be a single instance of this script running
# _ for each remote-user/remote-host combination, while the
# _ corresponding remote host is online.
#
# On interruption, unregister; note that this does _not_ work
# _ in the case of a TERM signal sent to the shell running on
# _ the background, detached from any terminal.
onintr unregister
#
# Record the name this script was called with.
set name = `basename $0`
#
# Define the default waiting time between
# _ successful pings, in seconds.
set wtime = 600
#
# Define the configuration file.
set conffile = /etc/dynahost/$name.conf
#
# If the file exists, then source it.
if ( -f $conffile ) then
    source $conffile
endif
#
# Setting the waiting time to zero disables this daemon.
if ( $wtime < 1 ) then
    exit 0
endif
#
# Define the maximum tolerance time for an unreachable client,
# _ in units of 10 seconds; the waiting loop will end and the
# _ client will be unregistered after this number of consecutive
# _ unsuccessful pings, using a 10-second ping timeout.
@ ftime = $wtime / 10
#
# Get the remote username from the command line.
set ruser = $1
#
# Get the remote hostname from the command line.
set rhost = $2
#
# Get the remote IP address from the command line.
set raddr = $3
#
# Initialize a variable for the waiting time.
set wt = $wtime
#
# Initialize a counter for the ping failure timeout.
set ft = 0
#
# Loop until the unreachable-host timeout is reached.
while ( $ft < $ftime )
    #
    # Sleep for the waiting time.
    sleep $wt
    #
    # If the sleep is interrupted, then unregister the host.
    if ( $status != 0 ) goto unregister
    #
    # Ping quietly, no name resolution, one ping only,
    # _ with a no-response ping timeout of 10 sec.
    ping -q -n -c 1 -W 10 $raddr > /dev/null
    #
    # If the host is reachable, then restore the normal value
    # _ of the waiting time and reset the fail time to zero.
    if ( $status == 0 ) then
	set wt = $wtime
	set ft = 0
    #
    # If the host is unreachable, then set the waiting tome to
    # _ zero and count the number of times the ping failed.
    else
	set wt = 0
	@ ft = $ft + 1
    endif
    #
end
#
# The interruption target.
unregister:
#
# Define the location of the registration program.
set progfile = /usr/lib/dynahost/dynahostnis
#
# Only do this if this executable file exists.
if ( -fx $progfile ) then
    #
    # Unregister the remote host; in fact, register the host
    # _ with a zeroed IP address in order to do just that.
    set raddr = 000.000.000.000
    #
    # A retrial target.
    again:
    #
    # Execute the registration with the zeroed address.
    $progfile $ruser $rhost $raddr
    #
    # If there is an error, then enter a loop in order
    # _ to handle eventual locking delays.
    if ( $status != 0 ) then
	#
	# Wait for a bit.
	sleep 1
	#
	# Try again.
	goto again
	#
    endif
    #
endif
