#!/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" # rdisth - rdist home directory, using rdist and rsh/ssh # Steve Kinzler, kinzler@cs.indiana.edu, Sep 93/Jan 02 # http://www.cs.indiana.edu/~kinzler/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/csh -fc :) 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 '') hosts -l home;; *) cat;; esac > $tmpH || exit # rdist ####################################################################### hosts - rdist < $tmpH > $tmpA if test -s $tmpA then (echo 'HOSTS = ('; cat $tmpA; echo \)) > $tmpB || exit sed 's/#.*//; /^[ ]*$/d' < $homels | sort | awk '$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/#.*//; /^[ ]*$/d' < $homels | sort | awk '$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, $4 }' > $tmpA test ! -s $tmpA && exit > $tmpC || exit sed 's/#.*//; /^[ ]*$/d' < $homels | sort | awk '$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";; 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