#!/bin/sh
#egan@us.ibm.com
#v2.0
#(c)IBM Corp
#PBS PSH
#

RSHC=ssh
MAXJOBS=1024

function killjobs
{
	if [ ! -z "$*" ]
	then
		kill $* >/dev/null 2>&1
	fi
	exit 1
}

trap "killjobs" 1 2 3 15 20

function usage {
	echo "\nUsage: pbspsh [-s] [node1,node2,node3,...] [command]\n"
}

function docommand
{
	JOBS=""
	nj=0

	for i in $(echo $NR | tr ',' ' ')
	do
		c=$((c+1))
		(if ping -c1 $i >/dev/null 2>&1
		then
			$RSHC $i "$COMMAND 2>&1" | sed "s/^/$i:	/"
		else
			echo "$i: noping"
		fi) &
		if [ -z "$SERIAL" ]
		then
			JOBS="$JOBS $!"
			if [ ! -z "$MAXJOBS" ]
			then
				nj=$((nj+1))
				while ((nj >= $MAXJOBS))
				do
					for j in $JOBS
					do
						if ! ps -p $j >/dev/null 2>&1
						then
							JOBS=$(echo $JOBS | sed "s/\b$j\b//")
							nj=$((nj-1))
						fi
					done
				done
			fi
		else
			wait $!
		fi
	done

	wait
}

if [ "$#" = "0" ]
then
	usage >&2
	exit 1
fi

if [ "$1" = "-s" ]
then
	SERIAL="on"
	shift
else
	SERIAL=""
fi

NR=$1

shift
COMMAND=$*

if [ -z "$COMMAND" ]
then
	usage
	exit
fi

docommand
