#!/bin/bash
#
# $Id: pingtimer,v 1.4 2008/01/24 10:47:36 geoff Exp geoff $
#
# Generate graphs of ping information for use by the FChart gkrellm plugin.
#
# Usage:
#
USAGE='Usage: pingtimer [-b base] [-i interval] [-w deadline] host ...'
#
# Options:
#
#   -b	Specify the base pathname of output files (default /tmp/pingtimer).
#   -i	Specify the interval between ping attempts (default 1).
#   -w	Specify the maximum time to wait for a response (default 1).
#	Only works if ping supports the -W switch.
#
# Output files:
#
#    $BASE.tmp	Temporary file used in generating final output
#    $BASE.txt	Ping information
#
# Each host given is repeatedly pinged in turn.  Nothing is done to
# protect against relatively long timeout (10 seconds) from failed
# pings.  The ping times (expressed in microseconds) are written to
# the chart file in host order.  Since FChart will only plot three
# values, only the first three hosts are meaningful (and in fact, only
# the first three are pinged).
#
# The alert level of FChart is always NORMAL.  The displayable
# parameterized strings are:
#
#	$0	Maximum of the three ping times
#	$1	First ping time
#	$2	Second ping time
#	$3	Third ping time
#	$4	Minimum of the three ping times
#	$5	Median of the three ping times
#	$6	Average of the three ping times
#
# All times are expressed in milliseconds.
#

BASE=/tmp/pingtimer
MAXHOSTS=3

INTERVAL=1
DEADLINE=1

while [ $# -gt 0 ]
do
    case "$1" in
	-b)
	    BASE="$2"
	    shift
	    ;;
	-i)
	    INTERVAL="$2"
	    shift
	    ;;
	-w)
	    DEADLINE="$2"
	    shift
	    ;;
	--)
	    shift
	    break
	    ;;
	-*)
	    echo "$USAGE" 1>&2
	    exit 2
	    ;;
	*)
	    break
	    ;;
    esac
    shift
done

if [ $# -eq 0 ]
then
    echo "$USAGE" 1>&2
    exit 2
fi

#
# Find out if ping can handle -W
#
if ping -c 1 -W 1 localhost >/dev/null 2>&2
then
    wSwitch="-W $DEADLINE"
else
    wSwitch=
fi

trap 'rm -f "$BASE".tmp*; exit 1' 1 2 15
trap 'rm -f "$BASE".tmp*; exit 0' 13

pid0=
pid1=
pid2=
while :
do
    sleep $INTERVAL &
    n=0
    for i
    do
	ping -c 1 $wSwitch "$i" \
	  | sed -n '/^64 bytes from/s/^.*time=\([0-9.]*\).*$/\1/p' \
	  | awk '{print int($1 * 1000 + 0.5)}' \
	  > "$BASE".tmp.$n &
	pid=$!
	eval pid$n=\$pid
	(( n++ ))
	if (( $n >= $MAXHOSTS ))
	then
	    break
	fi
    done
    wait $pid0 $pid1 $pid2
    cat "$BASE".tmp.? \
      | tr \\012 ' ' \
      > "$BASE".tmp
    echo '' >> "$BASE".tmp
    max=`cat "$BASE".tmp.? | sort -rn | grep -v '^$' | head -1`
    echo 'NORMAL' >> "$BASE".tmp
    echo $max | awk '{printf "%.3f\n", $1 / 1000}' >> "$BASE".tmp
    cp "$BASE".tmp "$BASE".txt
    #
    # Wait until the next ping is due
    #
    wait
done

rm -f "$BASE".tmp*

# $Log: pingtimer,v $
# Revision 1.4  2008/01/24 10:47:36  geoff
# Fix a bug in the last delta that caused all pings to be mashed together.
#
# Revision 1.3  2008/01/24 10:40:00  geoff
# Ping the hosts in parallel so that the wait times don't sum to impact
# the total time.  Never ping more than three hosts.
#
