#!/bin/sh -

case "$RSHCMD" in
ssh)	RSHCMD='ssh -q -x';;
esac

# eachhost - run the given command for each host listed on stdin
# Steve Kinzler, steve@kinzler.com, Oct 93
# https://kinzler.com/me/home.html#unix

s=; p=; v=; V=; o=; output=; d=; delay=; l=; user=; bad=

i=; input=/dev/null
(test -t 0 < /dev/tty) 2> /dev/null && input=/dev/tty

while :
do
	case $# in
	0)	break;;
	*)	case "$1" in
		-S)	s=r;;
		-s)	s=s;;
		-p)	p=p;;
		-v)	v=v;;
		-w)	v=w;;
		-V)	V=' ';;
		-W)	V='	';;
		-n)	i=n;	    input=/dev/null;;
		-i)	i=i; shift; input="$1";;
		-o)	o=o; shift; output="$1";;
		-d)	d=d; shift; delay="$1";;
		-l)	l=l; shift; user="-l $1";;

		--)	shift; break;;
		-h)	bad=t; break;;
		-*)	bad=t; echo "$0: unknown option ($1)" 1>&2;;
		*)	break;;
		esac
		shift;;
	esac
done

case "$bad" in
?*)	cat << EOF 1>&2
usage: $0 [ -S | -s ] [ -p ] [ -v | -w ] [ -V | -W ]
       [ -n ] [ -i file ] [ -o prefix ] [ -d seconds ] [ -l user ] [ command ]
The given command is run remotely on each host listed on stdin.
	-S	use rsh/remsh/rcmd, default \$RSHCMD or rsh
	-s	use ssh, default \$RSHCMD or rsh
	-p	prompt before processing each host
	-v	print each hostname before processing it
	-w	like -v but with the hostname highlighted
	-V	label any output lines with the hostname
	-W	like -V but with a tab following the label
	-n	close stdin on each command run
	-i	provide each command with the given file on stdin
	-o	place the output of each command in a local file
		  named by the given prefix plus the hostname
	-d	abort commands after the given number of delay seconds
	-l	run remote commands using the given user login
No command implies a remote login to the host.  If the command contains
the string "\$host", it is run locally rather than remotely with the
current hostname substituted for "\$host".  The default stdin for the
commands is /dev/tty if available and /dev/null if not.
EOF
	exit 1;;
esac

safe=
case "$d" in
?*)	if (safe -d 3 /bin/true) 2> /dev/null
	then
		safe=safe
		test "$delay" -ne 0 && safe="$safe -d $delay"
	else
		echo "$0: ignoring delay ($delay), safe(1) unavailable" 1>&2
	fi;;
esac

case "$s,$RSHCMD" in
s*)	rsh=ssh;;
r*|*,)	if   test -f /usr/bin/remsh; then rsh=/usr/bin/remsh
	elif test -f /usr/bin/rcmd;  then rsh=/usr/bin/rcmd
	else				  rsh=rsh
	fi;;
*)	rsh="$RSHCMD";;
esac

trap continue 2

while read host
do
	case "$p" in
	?*)	echo "$host? [n] " | tr -d '\012'
		read ans < /dev/tty
		case "$ans" in
		[yY]*)	;;
		*)	continue;;
		esac;;
	esac

	case "$v" in
	w)	echo "========== $host ==========" | color on_blue;;
	?*)	echo "$host";;
	esac

	case "$*" in
	*\$host*|*\${host*)
		case "$o$V" in
		o?)	eval "$@" < "$input" 2>&1 |
				sed "s/^/$host:$V/" > "$output$host";;
		o)	eval "$@" < "$input" > "$output$host" 2>&1;;
		?)	eval "$@" < "$input" 2>&1 | sed "s/^/$host:$V/";;
		*)	eval "$@" < "$input";;
		esac;;

	*)
		case "$o$V" in
		o?)	$safe $rsh "$host" $user ${1+"$@"} < "$input" 2>&1 |
				sed "s/^/$host:$V/" > "$output$host";;
		o)	$safe $rsh "$host" $user ${1+"$@"} < "$input" \
				> "$output$host" 2>&1;;
		?)	$safe $rsh "$host" $user ${1+"$@"} < "$input" 2>&1 |
				sed "s/^/$host:$V/";;
		*)	$safe $rsh "$host" $user ${1+"$@"} < "$input";;
		esac;;
	esac
done
