#!/bin/sh -

ssh=`which ssh`	# path to ssh binary to use with `rdist -P`

dftdelay=1800	# default rdist/rsh timeout in seconds, if available

report=rdistd	# "old" or "new" style reporting; "rdistd" choses based on
		# the presence of rdistd

#tarargs=o	# Note: with "o", permissions on rsh-distributed directories
tarargs=	# and subdirectories will not be propagated; needed for some
		# old tars, eg r32v2; but BusyBox tars like palmpre's don't
		# support "o"

## 2017-05-03 ALUDEL-WIN:.ssh/Makefile
# FROM = 10.17.86.44
# rdisth-pull:
#	rsync -e 'ssh -q -x' -HazPv --delete --force --stats \
#	$(FROM):.bash_profile	$(FROM):.cshrc		$(FROM):.emacs	  \
#	$(FROM):.exrc		$(FROM):.inputrc	$(FROM):.login	  \
#	$(FROM):.lynxrc		$(FROM):.mailrc		$(FROM):.muttrc	  \
#	$(FROM):.plan		$(FROM):.profile	$(FROM):.project  \
#	$(FROM):.tkremindrc	$(FROM):.vimrc		$(FROM):.xsession \
#	$(FROM):binp		$(FROM):etc		$(FROM):libp	  \
#	$(FROM):manp				..

## 2022-09-27 AKINZLER:.ssh/Makefile
# FROM = ukinzler
# RSYNC= rsync -e "$$RSHCMD -q -x" -HazPv --delete --force --stats
# dailyp:
#	for f in `sed -n 's/	.*<-$$//p' ../etc/homels`; do	\
#		$(RSYNC) $(FROM):$$f ..; done;			\
#	$(RSYNC) $(FROM):.ssh/config .;				\
#	dailyh -d -u -g -l; dailyl

# rdisth - rdist home directory, using rdist and rsh/ssh
# Steve Kinzler, steve@kinzler.com, Sep 93/Jan 02
# https://kinzler.com/me/home.html#homedir

cd || exit $?

stdin=; delay=; opts=; hosts=; nodo=; quiet=; shx=; bad=

while :
do
	case $# in
	0)	break;;
	*)	case "$1" in
		-)	stdin=$1;;
		-d)	shift; delay="$1";;
		-m)	shift; opts="$opts -m $1"; hosts="$hosts@$1@";;
		-n|-N)	opts="$opts -n"; nodo=$1;;
		-q)	opts="$opts $1"; quiet=$1;;
		-x)	shx=$1;;

		-old)	report=old;;
		-new)	report=new;;

		--)	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 [ - ] [ -d seconds ] [ -m host ] ... [ -n ] [ -q ]
       [ homefile ... ]
	-	read hosts listing on stdin instead of hosts(1)
	-d	abort rdists after the given number of delay seconds
		  (default as with safe(1), if available)
	-m	restrict rdists to the given hosts (default from hosts(1))
	-n	no execute, just print commands
	-q	quiet mode, don't print routine reporting information
EOF
	exit 1;;
esac

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

homels=${HOMELS-etc/homels}

tmpA=/tmp/rhA$$
tmpB=/tmp/rhB$$
tmpC=/tmp/rhC$$
tmpH=/tmp/rhH$$
trap "rm -f $tmpA $tmpB $tmpC $tmpH; exit" 0 1 2 13 15

case "$stdin" in
'')	${HOSTSLCMD-hosts -l home};;
*)	cat;;
esac > $tmpH || exit

# rsync srsync ################################################################

# Note: rsync/srsync support could be considered but could be tricky to
#	implement the "dist-as"/"rename" feature (ie eg "foo <- bar" in
#	etc/homels).  It's much more widely available these days than
#	rdist, but then the rsh/ssh method always works and is quite
#	satisfactory.

# rdist #######################################################################

hosts - rdist < $tmpH > $tmpA

if test -s $tmpA
then
	(echo 'HOSTS = ('; cat $tmpA; echo \)) > $tmpB || exit

	sed 's/^#.*//; s/[ 	][ 	]*#.*//; /^[ 	]*$/d;
	     s/		*/	/g' < $homels |
	sort | awk -F'	' '$2 == "<-" {
		if (NF == 2) $3 = $1
		print $1 ":", $3, "-> ${HOSTS}\n\tinstall -R", $1, ";"
	     }' >> $tmpB || exit

	case "$nodo" in
	-N)	cat $tmpB;;
	esac

	$safe rdist -f $tmpB $opts ${1+"$@"}
fi

# srdist ######################################################################

hosts - srdist < $tmpH > $tmpA

if test -s $tmpA
then
	(echo 'HOSTS = ('; cat $tmpA; echo \)) > $tmpB || exit

	sed 's/^#.*//; s/[ 	][ 	]*#.*//; /^[ 	]*$/d;
	     s/		*/	/g' < $homels |
	sort | awk -F'	' '$2 == "<-" {
		if (NF == 2) $3 = $1
		print $1 ":", $3, "-> ${HOSTS}\n\tinstall -R", $1, ";"
	     }' >> $tmpB || exit

	case "$nodo" in
	-N)	cat $tmpB;;
	esac

	$safe rdist -P "$ssh" -f $tmpB $opts ${1+"$@"}
fi

# rsh ssh #####################################################################

hosts - -l rsh ssh < $tmpH | awk '{ print $1, $'"${HOSTSRSHCOL-4} }" > $tmpA
test ! -s $tmpA && exit

> $tmpC || exit
sed 's/^#.*//; s/[ 	][ 	]*#.*//; /^[ 	]*$/d;
     s/		*/	/g' < $homels |
sort | awk -F'	' \
    '$2 == "<-" && NF == 2 { print $1 }
     $2 == "<-" && NF >= 3 { print "mv", $3, $1 >> "'$tmpC'" }' > $tmpB || exit

case $# in
0)	files=`cat $tmpB`;;
*)	files=`echo $* | tr ' ' '\012' | sort | comm -12 $tmpB -`;;
esac
case "$files" in
'')	exit;;
esac

case "$report" in
rdistd)		case "`(rdistd < /dev/null) 2>&1`" in
		'')	report=new;;
		*)	report=old;;
		esac;;
old|new)	;;
*)		echo "$0: invalid report style ($report)" 1>&2; report=new;;
esac

cat << EOF > $tmpB || exit
	PATH=$PATH; export PATH
	umask `umask`
	cd || exit
	rm -fr .rdisth-new .rdisth-old
	trap 'cd && rm -fr .rdisth-new .rdisth-old & exit' 0 1 2 13 15
	mkdir .rdisth-new .rdisth-old || exit
	cd .rdisth-new || exit
	case "\`(opsys) 2> /dev/null\`" in
	r32v2)	errs=\`tar -xfb ../.rdisth-tar 1 2>&1\`;;
	*)	errs=\`tar -xf  ../.rdisth-tar   2>&1\`;;
	esac
	rm -f ../.rdisth-tar
	case "\$errs" in
	?*)	echo "\$errs" 1>&2; exit;;
	esac
EOF

case $# in
0)	cat $tmpC;;
*)	for arg
	do
		awk '$3 == "'"$arg"'"' $tmpC
	done;;
esac >> $tmpB

cat <<'EOF' >> $tmpB || exit
	trap '' 1 2 13 15
	ls -a | sed '/^\.$/d; /^\.\.$/d' |
	while read file
	do
EOF

case "$quiet" in
'')	case "$report" in
	old)	echo 'echo "installing: $file"';;
	new)	echo 'echo "$HOST: $file: installing"';;
	esac >> $tmpB;;
esac

cat <<'EOF' >> $tmpB || exit
		test ! -f ../"$file" -a ! -d ../"$file" ||
			mv ../"$file" ../.rdisth-old
		case "$?" in
		0)	mv "$file" ..;;
		esac
	done
EOF

case "$nodo" in
-N)	cat $tmpB;;
esac

errs=`tar -c${tarargs}f $tmpC $files 2>&1`
case "$errs" in
?*)	echo "$errs" 1>&2; exit;;
esac

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

while read host xsh
do
	case "$hosts" in
	''|*@"$host"@*)	;;
	*)		continue;;
	esac

	case "$xsh" in
	rsh)	xsh="$rsh";;
	ssh)	xsh="$xsh -q -x";;
	esac

	case "$quiet" in
	'')	case "$report" in
		old)	echo "updating host $host with $xsh";;
		new)	echo "$host: updating host $host with $xsh";;
		esac;;
	esac

	case "$nodo" in
	'')	$safe /bin/sh -c "
			$xsh $host \(/bin/echo HOST=$host\; /bin/cat\) \
				\> .rdisth-run < $tmpB &&
			$xsh $host /bin/cat \> .rdisth-tar < $tmpC &&
			$xsh $host /bin/sh $shx ./.rdisth-run
			$xsh $host /bin/rm -f .rdisth-run .rdisth-tar" \
		      < /dev/null;;

	*)	case "$quiet" in
		'')	(echo "$files"; awk '/^mv/ { print $3 }' $tmpB) |
			sort |
			case "$report" in
			old)	sed 's/^/installing: /';;
			new)	sed "s/^/$host: /; s/$/: installing/";;
			esac;;
		esac;;
	esac

	case "$quiet" in
	'')	case "$report" in
		new)	echo "$host: updating of $host finished";;
		esac;;
	esac

done < $tmpA
