#!/bin/csh -f

# This script will remove entries in /etc/rmtab for hosts not
# responding to pings or not in xtab.
# If you are impatient, you can specify a single
# numeric argument which will be taken as a ping timeout interval, eg,
#	clean-rmtab 5

switch (`uname -s``uname -r`)
case SunOS4*:
	set path = ( /usr/etc $path ) # be sure to have showmount, mountd
	set XTAB = /etc/xtab
	set PS = /usr/bin/ps
	set SP = ""
	set MOUNTD = rpc.mountd
	breaksw
case SunOS5*:	
	set path =  ( /usr/sbin /usr/lib/nfs $path )
	set XTAB = /etc/dfs/sharetab
	set PS = /usr/ucb/ps
	set SP = " "
	set MOUNTD = mountd
	breaksw
default:
	exec echo ${0}: does not run on `uname -s` `uname -r`
endsw

set TIMEOUT

while($#argv)
	switch ("$1")
	case -c:
		set CLEANANYWAY
		shift
		breaksw
	case -d:
		set DEBUG
		shift
		breaksw
	case -t:
		set TIMEOUT = $2
		shift;shift
		breaksw
	case -v:
		set VERBOSE
		shift
		breaksw
	default:
		if (! $?NUM) then
		    set NUM = $1
		    shift
		    breaksw
		else if (! $?NUM2) then
		    set NUM2 = $1
		    shift
		    breaksw
		endif
		set DQ = '"'
		exec echo ${0}: "What do I do with $DQ$1$DQ?"
	endsw
end

umask 022

set AWKF = /tmp/clean-rmtab.awk
set DH = /tmp/dead-hosts.rmtab
set TMP = /tmp/`basename $0`.$$
cp /dev/null $DH
if (! $?NUM) set NUM = 100
if (! $?NUM2) then
	set NUM2 = 0
endif
@ NUM += $NUM2

set MPS = /tmp/mountd.ps
$PS axc | grep " $MOUNTD"'$' > $MPS
set MPSL = `cat $MPS | wc -l`
if ($MPSL == 1) then
	set MPSL = `cat $MPS | sed 's;\?;.;g'`
	set MP = $MPSL[1]
	set MC = `$PS ww${SP}$MP | sed -n "s;.*$MOUNTD;$MOUNTD;p"`
else
	echo cannot determine pid for mountd:
	cat $MPS
	exit
endif

if ($?VERBOSE) echo when done, will restart:
if ($?VERBOSE) $PS $MP
if ($?VERBOSE) echo restart command will be:
if ($?VERBOSE) echo "	" $MC

if ($?VERBOSE) echo compiling list of dead hosts:

#set HOSTS = `showmount | head -$NUM | tail +$NUM2` # note: this is not "/usr/etc/showmount"
				# because /usr/etc should be in path for
				# later "rpc.mountd" command (derived from
				# ps output) to work.

#set LAST = `showmount | tail -1`

#if ("$HOSTS" == "") set HOSTS = `grep -v "#" /etc/rmtab | sed 's;:.*;;' | sort -u | head -$NUM | tail +$NUM2`
#if ("$LAST" == "") set LAST = `grep -v "#" /etc/rmtab | sed 's;:.*;;' | sort -u| tail -1`

#if ("$HOSTS[$#HOSTS]" != "$LAST") echo "$HOSTS[$#HOSTS]", "$LAST"

#foreach h ( $HOSTS )
##foreach h ( `showmount` )
#	ping $h $TIMEOUT > /dev/null
#	if ($status) then
#		if ($?VERBOSE) echo "	" $h
#		echo $h >> $DH
#	endif
#end

showmount > $TMP

@ OFF = 1		# initial offset
@ CHUNK = 100		# how many files to process in a chunk

set MAX = `cat $TMP | wc -l`

while ($OFF <= $MAX)
	foreach HOST ( `tail +$OFF $TMP | head -$CHUNK` )
		ping $HOST $TIMEOUT > /dev/null
		if ($status) then
			if ($?VERBOSE) echo "	" $HOST
			echo $HOST >> $DH
		endif
	end
	@ OFF += $CHUNK
end

set DHL = `cat $DH | wc -l`
if ($DHL == 0) then
	if ($?CLEANANYWAY) then
		echo no dead hosts, cleaning rmtab anyway
	else
		exec echo no dead hosts, not cleaning rmtab
	endif
endif
##if ($DHL == 0) exec echo no dead hosts, not cleaning rmtab

cat > $AWKF << EOF
BEGIN { host=0 ; dead[host]="" ; filesys=0 ; live[filesys]="" }

/^[#]/	{next}

FILENAME == "$DH" {
	dead[host++]=\$1
	}

FILENAME == "$XTAB" {
	live[filesys++]=\$1
	}

FILENAME == "/etc/rmtab" {
	split(\$0,line,":")
	for (host in dead) {if (line[1] == dead[host]) next};
	c=split(line[2],candidate,"/")
	for (filesys in live) { 
		o=split(live[filesys],office,"/")
		if (o>c) continue
		p=1
		for (i=1; i<=o; i++) {
			if (office[i] != candidate[i]) {
				p=0
				break
				}
			}
		if (p) { print ; next }
		};
	}

EOF

if ($?VERBOSE) echo  kill $MP
if (! $?DEBUG) kill $MP

if ($?VERBOSE) echo "nawk -f $AWKF $DH $XTAB /etc/rmtab > /etc/rmtab.new"
nawk -f $AWKF $DH $XTAB /etc/rmtab > /etc/rmtab.new

if ($?VERBOSE) echo mv /etc/rmtab /etc/rmtab.OLD
if (! $?DEBUG) mv /etc/rmtab /etc/rmtab.OLD
if ($?VERBOSE) echo mv /etc/rmtab.new /etc/rmtab
if (! $?DEBUG) mv /etc/rmtab.new /etc/rmtab
if ($?VERBOSE) echo $MC
if (! $?DEBUG) $MC
