#!/bin/sh
#VOLDEMORT 0.6
#Last revised, S. Timm 2/20/03
#Last bug fixes S. Timm 4/14/03
# Major revisions in 0.6 to read from the database instead of relying
# on .flavors, .clusters, .nodelist files.
# also add options -e for alternate rsh command
# 
#rsync_push script
#
# Subroutines:
#
printHelp() {
            echo "rsync_push [-h]"
            echo "           [-r]"
            echo "           [-c <cluster>] [-f <flavor>]"
            echo "           [-b <prefix> <start> <end> | -B <prefix> <range> | -l <filename> ]"
            echo "           [ -R -F -S -P -T -L ]"
            echo "           [ -K ] "
            ecbo "           [ -C ] "
            echo "           [ -i | -I ]"
            echo "           [-q | -v]"
            echo "           [ -y ]"
            echo "           [ -e <rsh_command> ] "
            echo "           [ -E <rcp_command> ] "
            echo "           [ -w <workgroup> ] "
            echo "  Functional order of commands"
            echo "  Commands that control where to push to:"
            echo " -c  Push for this cluster--default is ALL clusters"
            echo " -f  Push for this OS flavor--default is ALL flavors"
            echo " -b  push to numbered range of nodes only"
            echo " -B  push for range such as 1 3 5-7 (range in quotes)"
	    echo " -l <filename> push to list of nodes in filename"
            echo " Note: -b, -B, -l are mutually exclusive, if more than one"
	    echo " are specified the last option specified will win."
	    echo " The nodes pushed are an and of the nodes selected with"
            echo " (-c & -f) & (-b | -B | -l )" 
            echo " Default if nothing specified is to push everything in the DB"
            echo ""
            echo "  Commands that control what you push:"
            echo " -R  Don't push things in the RPMS directory"
            echo " -F  Don't push things in the files directory"
            echo " -S  Don't push things in the scripts directory"
            echo " -P  Don't push things in the prescripts directory"
            echo " -T  Don't push things in the tarballs directory"
            echo " -L  Don't push things in /etc/workgroup dir"
            echo " -K  Don't attempt kerberos kinit"
            echo " Default is to push everything"            
	    echo " -w  specify the workgroup you are pushing (default is Farms)"
            echo ""
            echo "  Commands that control the behavior of the push"
            echo " -e  command to pass along to rsync's -e option (default is /usr/krb5/bin/rsh)"
            echo " -E  Alternate rcp command--default is /usr/krb5/bin/rcp)"
            echo " -r  Retry the push for nodes that failed"
            echo " -q  quiet--nothing to stdout"
            echo " -v  verbose (the more v's the more verbose)"
            echo " -y  batch mode--answer yes to are you sure"
            echo ""
            echo "  Commands that govern what happens before and after push"
            echo " -i  Install mode--force execution of new prescripts and scripts"
            echo " -I  Install mode--force execution of all prescripts and scripts"
            echo "  default is that new scripts are not executed on normal push or pull"
            echo " -C  Clear RPM, prescripts, scripts directories (if selected)"
}
#***************************************************
# Read a file with one item per line and make it into a list that
# fits into one environment variable
#***************************************************
linetovar() {
  MEMLIST=""
  if [ $DEBUG -gt 2 ] 
  then
    echo "in linetovar"
  fi
  for line in $MEMFILE
    do
        if [ $DEBUG -gt 2 ]
        then
          echo "$line"
        fi
	if [ "$line" != "" ] 
	then
	    testchar=`echo $line | cut -c1`
	    if [ "$testchar" != "#" ]
	    then
		MEMLIST="$MEMLIST $line"
	    fi
	fi
    done
}
#**********************************************
# Load in SYSLIST by building a  linear list
#**********************************************

load_list_buildlist(){
	    i=$SUFIX_START
	    while [ $i -le $SUFIX_STOP ]
	    do
		SYSLIST="$SYSLIST $PREFIX$i"
		i=`expr $i + 1`
	    done
}

#**********************************************
# Load in SYSLIST by building a ranged list
#**********************************************

load_list_buildrange(){
	    for i in $SUFIX_RANGE
	    do
		case "$i" in
		    *-*)
			start=`echo $i | cut -d\- -f1`
			end=`echo $i | cut -d\- -f2`
			if [ $start -gt $end ]
			then
			    echo "Range: $d, is not in ascending order."
	        	    echo "Reversing order."
			    tmp=$start
			    start=$end
			    end=$tmp
			fi
        		i=$start
        		while [ $i -le $end ]
        		do
			    SYSLIST="$SYSLIST $PREFIX$i"
			    i=`expr $i + 1`
        		done
			;;
		    [1-9]*)
                	SYSLIST="$SYSLIST $PREFIX$i"
			;;
		    *)
			echo "Please make sure that args are space separated."
			exit 1
			;;
		esac
	    done
}
load_list_file(){
if [ -e "$LISTFILE" ] 
then
    MEMFILE="`cat $LISTFILE`"
    linetovar
    SYSLIST="$MEMLIST"
fi
}
load_list_file(){
if [ -e ${RSYNC_HOME}/clusters/common/db/failed ] 
then
    mv  ${RSYNC_HOME}/clusters/common/db/failed  ${RSYNC_HOME}/clusters/common/db/failed.1
    MEMFILE="`cat ${RSYNC_HOME}/clusters/common/db/failed.1`"
    linetovar
    FAILLIST="$MEMLIST"
fi
}
hostcheck(){
    FINALHOST=""
    for checkhost in $HOSTCHECK
    do
	for refhost in $SYSLIST
	do
	    if [ ${checkhost} == ${refhost} ]
	    then
		FINALHOST="$FINALHOST $checkhost"
	     fi
	done
    done
}
failcheck(){
    FINALHOST=""
    for checkhost in $HOSTCHECK
    do
	for refhost in $FAILLIST
	do
	    if [ ${checkhost} == ${refhost} ]
	    then
		FINALHOST="$FINALHOST $checkhost"
	     fi
	done
    done
}
#this subroutine adds a node to the failed file
#if it isn't already there
failadd() {
    found="no"
    for infail in $INFAILFILE
    do
	if [ "${host}" == "${infail}" ]
	then
	    found="yes"
	fi
    done
    if [ "${found}" == "no" ]
    then
	INFAILFILE="${INFAILFILE} ${host}"
        echo ${host} >> ${RSYNC_HOME}/clusters/common/db/failed
    fi
}
#
#Push logic --assumes you are in the directory from which you want to push 
# the files, $host is set to the host you want to push to. $PUSHDIR (in case of files) 
# is the list of directories to push out, should not have leading / in the path.
#
hostpush(){
		if [ $DEBUG -gt 2 ]
		then
		    echo "in hostpush, category ${category}"
		fi
                case ${category} in
                files)
#
#  Now loop across each directory
#  Note that with rsync -avz any subdirectories of /etc will also 
#  get pushed out and the corresponding subdirectories created on the
#  worker nodes.--nested do 5A
#
		    for dir in $PUSHDIR
		    do
                        if [ $DEBUG -gt 1 ]
                        then
			    echo ${dir}
                        fi
#
# Allow for the fact that rsync on sgi machines is in /usr/local/bin
# /usr/sbin/rsync which is also there is something totally different.
#
			if [ $DEBUG -le 0 ]
                        then 
			    if [ "${flavor:0:5}" != "Linux" ] 
			    then 
				$RSYNC_PATH -az --exclude '*Makefile' -e ${RSHCMD}  --rsync-path=/usr/local/bin/rsync ${dir} ${host}:/
			    else
				$RSYNC_PATH -az --exclude '*Makefile' -e ${RSHCMD}  ${dir} ${host}:/
			    fi
			else
			    if [ "${flavor:0:5}" != "Linux" ] 
			    then 
				$RSYNC_PATH -avz --exclude '*Makefile' -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync ${dir} ${host}:/
			    else
				$RSYNC_PATH -avz --exclude '*Makefile' -e ${RSHCMD}  ${dir} ${host}:/
			    fi
                        fi
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
			fi
#    End of RSYNC_PUSHDIR loop (nested do 5A)
		    done 
		    ;;
                tarballs)
                TMPTAROUT=/tmp/tarballs.out_$$
                TMPTARERR=/tmp/tarballs.err_$$
                TMPTAR=/tmp/tarballs_$$
                TMPTGZ=/tmp/tgz_$$
                cat /dev/null > $TMPTAROUT
		cat /dev/null > $TMPTARERR
		cat /dev/null > $TMPTGZ
		cat /dev/null > $TMPTAR
#
#  Now loop across each directory
#  Note that with rsync -avz any subdirectories of /etc will also 
#  get pushed out and the corresponding subdirectories created on the
#  worker nodes.--nested do 5A
#
		    for dir in $PUSHDIR
		    do
                        if [ $DEBUG -gt 1 ]
                        then
			    echo ${dir}
                        fi
#
# Allow for the fact that rsync on sgi machines is in /usr/local/bin
# /usr/sbin/rsync which is also there is something totally different.
# On all rsync commands for tarballs we capture the output 
# of the rsync command, i.e., which files were synced, to a file $TMPTAROUT
# Then we use the output to determine which tarballs were actually
# synced this time.
#
			if [ $DEBUG -le 0 ]
                        then 
			    if [ "${flavor:0:5}" != "Linux" ] 
			    then 
				$RSYNC_PATH -aqz --exclude '*Makefile' -e ${RSHCMD}  --rsync-path=/usr/local/bin/rsync ${dir} ${host}:/  >> $TMPTAROUT 2>> $TMPTARERR
			    else
				$RSYNC_PATH -aqz --exclude '*Makefile' -e ${RSHCMD}  ${dir} ${host}:/  >> $TMPTAROUT  2>> $TMPTARERR
			    fi
			else
			    if [ "${flavor:0:5}" != "Linux" ] 
			    then 
				$RSYNC_PATH -avz --exclude '*Makefile' -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync ${dir} ${host}:/  >> $TMPTAROUT  2>> $TMPTARERR
			    else
				$RSYNC_PATH -avz --exclude '*Makefile' -e ${RSHCMD}  ${dir} ${host}:/  >>  $TMPTAROUT  2>> $TMPTARERR
			    fi
                        fi
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
			fi
#    End of RSYNC_PUSHDIR loop (nested do 5A)
#    
#
		    done 
		    if [ -s $TMPTAROUT ]
		    then
			grep tar $TMPTAROUT > $TMPTAR
			grep tgz $TMPTAROUT > $TMPTGZ
			if [ -s $TMPTAR ] || [ -s $TMPTGZ ]
			then
			if [ "${flavor:0:5}" != "Linux" ]
			then
				   $RSYNC_PATH -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync $TMPTAR ${host}:/root/bin/tarballs/tar.list
				   $RSYNC_PATH -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync $TMPTGZ ${host}:/root/bin/tarballs/tgz.list
		        else
				   $RSYNC_PATH -e ${RSHCMD}  $TMPTAR ${host}:/root/bin/tarballs/tar.list
				   $RSYNC_PATH -e ${RSHCMD}  $TMPTGZ ${host}:/root/bin/tarballs/tgz.list
			fi
			${RSHCMD} -n $host "$RSYNC_HELPERS/run.tarballs"
			fi
                    fi
		    ;;
# For RPMS we presume there are only Linux flavors.
		RPMS)
                    if [ "$CLEAR" == "yes" ] 
		    then
			${RSHCMD} -n ${host} "rm /root/bin/RPMS/*"
                    fi
		    if [ $DEBUG -le 0 ]
                    then
			$RSYNC_PATH -aqz --exclude '*Makefile' -e ${RSHCMD}  *.rpm ${host}:/root/bin/RPMS/
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
                        else
			${RSHCMD} -n $host "$RSYNC_HELPERS/run.RPMS "
			fi
		    else
			$RSYNC_PATH -avz --exclude '*Makefile'  -e ${RSHCMD} *.rpm ${host}:/root/bin/RPMS/
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
                        else
			${RSHCMD} -n $host "$RSYNC_HELPERS/run.RPMS "
			fi
		    fi
                    ;;
		prescripts) 
                    if [ "$CLEAR" == "yes" ] 
		    then
			${RSHCMD} -n ${host} "rm /root/bin/prescripts/*"
                    fi
		    if [ $DEBUG -le 0 ]
		    then
			    if [ "${flavor:0:5}" != "Linux" ] 
			    then 
				$RSYNC_PATH -qlptgoDz --exclude '*Makefile' -e ${RSHCMD}  --rsync-path=/usr/local/bin/rsync * ${host}:/root/bin/prescripts
			    else
				$RSYNC_PATH -qlptgoDz --exclude '*Makefile' -e ${RSHCMD} * ${host}:/root/bin/prescripts
			    fi
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
                        else
#Only attempt to run the prescripts if they were successfully pushed
#and the -i or -I flag is set
                            if [ "$INSTALLMODE" == "new" ]
			    then
				${RSHCMD}  -n ${host} "$RSYNC_HELPERS/run.prescripts"
			    fi
			    if [ "$INSTALLMODE" == "all" ]
			    then
				${RSHCMD}  -n ${host} "$RSYNC_HELPERS/run.prescripts -I"
			    fi
			fi
		    else
			    if [ "${flavor:0:5}" != "Linux" ] 
			    then 
				$RSYNC_PATH -lptgoDvz --exclude '*Makefile' -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync * ${host}:/root/bin/prescripts
			    else
				$RSYNC_PATH -lptgoDvz --exclude '*Makefile' -e ${RSHCMD}  *  ${host}:/root/bin/prescripts
			    fi
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
			else
#Only attempt to run the prescripts if they were successfully pushed
#and the -i or -I flag is set
			    if [ "$INSTALLMODE" == "new" ] 
			    then
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.prescripts"
			    fi
			    if [ "$INSTALLMODE" == "all" ]
			    then
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.prescripts -I"
			    fi
			fi
		    fi
		    ;;
		scripts) 
                    if [ "$CLEAR" == "yes" ] 
		    then
			${RSHCMD} -n ${host} "rm /root/bin/scripts/*"
                    fi
		    if [ $DEBUG -le 0 ]
		    then
			if [ "${flavor:0:5}" != "Linux" ] 
			then
			$RSYNC_PATH -qlptgoDz --exclude '*Makefile' -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync * ${host}:/root/bin/scripts
                        else
			$RSYNC_PATH -qlptgoDz --exclude '*Makefile' -e ${RSHCMD}  * ${host}:/root/bin/scripts/
                        fi
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
			else
			    if [ "$INSTALLMODE" == "new" ] 
			    then
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.scripts"
			    fi
			    if [ "$INSTALLMODE" == "all" ]
			    then
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.scripts -I"
			    fi
			
			fi
		    else
			if [ "${flavor:0:5}" != "Linux" ]
                        then
			$RSYNC_PATH -lptgoDvz --exclude '*Makefile' -e ${RSHCMD} --rsync-path=/usr/local/bin/rsync * ${host}:/root/bin/scripts
			else
			$RSYNC_PATH -lptgoDvz --exclude '*Makefile' -e ${RSHCMD} * ${host}:/root/bin/scripts/
			fi
			RETVAL=$?
			if [ ${RETVAL} != 0 ]
			then
			    if [ $DEBUG -gt 0 ]
                            then
				echo ${RETVAL}
                            fi 
			    failadd
                        else
			    if [ "$INSTALLMODE" == "new" ] 
			    then
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.scripts"
			    fi
			    if [ "$INSTALLMODE" == "all" ]
			    then
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.scripts -I"
			    fi
			fi
		    fi
		    ;;
                esac
}
dbsplit() {
if [ $DEBUG -gt 2 ]
then
    echo $DBLINE
fi
DB_HOST="$(echo $DBLINE | cut -d ':' -f1)"
DB_CLUSTER="$(echo $DBLINE | cut -d ':' -f2)"
DB_FLAVOR="$(echo $DBLINE | cut -d ':' -f3)"
DB_DISK="$(echo $DBLINE | cut -d ':' -f4)"
DB_BAUDRATE="$(echo $DBLINE | cut -d ':' -f5)"
DB_APIC="$(echo $DBLINE | cut -d ':' -f6)"
DB_NODESPEC="$(echo $DBLINE | cut -d ':' -f7)"
DB_SUBCLUSTER="$(echo $DBLINE | cut -d ':' -f8)"

}
#
#  BEGIN MAIN PROGRAM EXECUTION
#
#Source the global config file
if [ -x "$VOLDEMORT_CONF" ] 
then
    . $VOLDEMORT_CONF
else
    . /etc/voldemort_push.conf
fi
RETRY="no"; export RETRY
PRESCRIPTPUSH="yes"; export PRESCRIPTPUSH
RPMPUSH="yes"; export RPMPUSH
FILEPUSH="yes"; export FILEPUSH
SCRIPTPUSH="yes"; export SCRIPTPUSH
TARPUSH="yes"; export TARPUSH
LINUXPUSH="yes"; export LINUXPUSH
INSTALLMODE="none"; export INSTALLMODE
AREYOUSURE="no"; export AREYOUSURE
WORKGROUP="Farms"; export WORKGROUP
CLEAR="no"; export CLEAR
KERBEROS="yes"; export KERBEROS
DHCP="no"; export DHCP
DEBUG=1; export DEBUG
RSHCMD="/usr/krb5/bin/rsh" ; export RSHCMD
RCPCMD="/usr/krb5/bin/rcp" ; export RCPCMD
RSYNC_PATH="/usr/bin/rsync" ; export RSYNC_PATH
RSYNC_ALTPATH="/usr/local/bin/rsync" ; export RSYNC_ALTPATH
#
# Make sure local rsync executable is here.
#
if [ ! -x "$RSYNC_PATH" ]
then
    if [ ! -x "$RSYNC_ALTPATH" ]
    then
	echo "neither /usr/bin/rsync nor /usr/local/bin/rsync found"
	exit
    else
	RSYNC_PATH="$RSYNC_ALTPATH"
    fi
fi
	
INFAILFILE=""; export INFAILFILE
#Parse the options passed to the program
while [ $# != 0 ]
do 
	case $1 in 
            -h | -help | --help) printHelp ; exit 0 ;;
            -r | --retry) RETRY="yes"; export RETRY ; load_list_failed ; shift 1 ;;
            -c) test $# -lt 2 && { printHelp ; exit 1 ; }
                RSYNC_CLUSTER="$2" ; export RSYNC_CLUSTER ; shift 2 ;;
            -f) test $# -lt 2 && { printHelp ; exit 1 ; }
                RSYNC_FLAVOR="$2" ; export RSYNC_FLAVOR; shift 2 ;;
	    -b)  test $# -lt 4 && { printHelp ; exit 1 ; }
	        PREFIX="$2" ; SUFIX_START="$3" ; SUFIX_STOP="$4" ; load_list_buildlist ; LISTMADE="yes" ; shift 4 ;;
	    -B)  test $# -lt 3 && { printHelp ; exit 1 ; }
	        PREFIX="$2" ; SUFIX_RANGE="$3" ; load_list_buildrange ; LISTMADE="yes" ; shift 3 ;;
            -P) PRESCRIPTPUSH="no" ; export PRESCRIPTPUSH ; shift 1 ;;
            -R) RPMPUSH="no" ; export RPMPUSH ; shift 1 ;;
            -F) FILEPUSH="no" ; export FILEPUSH ; shift 1 ;;
            -S) SCRIPTPUSH="no" ; export SCRIPTPUSH ; shift 1 ;;
            -T) TARPUSH="no" ; export TARPUSH ; shift 1 ;;
            -L) LINUXPUSH="no" ; export LINUXPUSH ; shift 1 ;;
            -K) KERBEROS="no" ; export KERBEROS ; shift 1 ;;
            -d) DHCP="yes" ; export DHCP ; shift 1 ;;
            -q) DEBUG=0 ; shift 1 ;;
            -v*) PAR=$1 ; DEBUG=`echo ${PAR:1} | wc -c` ; echo "Debug level $DEBUG" ; shift 1 ;;
	    -i) INSTALLMODE="new" ; export INSTALLMODE ; shift 1 ;;
            -I) INSTALLMODE="all" ; export INSTALLMODE ; shift 1 ;;
            -C) CLEAR="yes" ; export CLEAR ; shift 1 ;;
            -l) LISTFILE="$2" ; export LISTFILE ; load_list_file ; LISTMADE="yes" ;  shift 2 ;;
            -e) RSHCMD="$2"; export RSHCMD ; shift 2 ;;
            -E) RCPCMD="$2"; export RCPCMD ; shift 2 ;;
            -y) AREYOUSURE="yes" ; export AREYOUSURE ; shift 1;;
            -w) WORKGROUP="$2"; export WORKGROUP ; shift 2 ;;
             *) printHelp; break
	esac
done
if [ "$KERBEROS" == "yes" ] 
then
#
#
# Get a kerberos ticket, make sure we don't clobber anyone
# else's credential cache--especially important if running in cron.
    KRB5CCDIR=/tmp/voldemort_$$; export KRB5CCDIR
    KRB5CCNAME=${KRB5CCDIR}/krb5cc_voldemort_$$; export KRB5CCDIR
    if [ -e $KRB5CCDIR ]
    then
	rm -Rf $KRB5CCDIR
    fi
    mkdir $KRB5CCDIR
    /usr/krb5/bin/kinit -k
fi
#
#     If not in retry mode, reset the failed list
#
    if [ "$RETRY" == "no" ]
    then
	if [ -e ${RSYNC_HOME}/clusters/common/db/failed ]
	then
	    mv ${RSYNC_HOME}/clusters/common/db/failed ${RSYNC_HOME}/clusters/common/db/failed.1
	fi
    fi
#
#    Determine what categories we are pushing
#
CATLIST=""
if [ $DEBUG -gt 2 ]
then 
    echo ${PRESCRIPTPUSH} ${RPMPUSH} ${FILEPUSH} ${SCRIPTPUSH} ${TARPUSH} ${LINUXPUSH}
fi
if [ ${PRESCRIPTPUSH} == "yes" ]
then              
    CATLIST="prescripts "
fi
if [ ${RPMPUSH} == "yes" ]
then              
    CATLIST="${CATLIST} RPMS"
fi
if [ ${FILEPUSH} == "yes" ]
then              
    CATLIST="${CATLIST} files"
fi
if [ ${SCRIPTPUSH} == "yes" ]
then              
    CATLIST="${CATLIST} scripts"
fi
if [ ${TARPUSH} == "yes" ]
then              
    CATLIST="${CATLIST} tarballs"
fi
if [ ${LINUXPUSH} == "yes" ]
then              
    CATLIST="${CATLIST} linux"
fi

###
###   Write confirmation of what we are about to do:

if [ $DEBUG -gt 0 ] 
then
    if [ "$RSYNC_CLUSTER" == "" ] 
    then
	echo "Pushing for all clusters"
    else
	echo "Pushing for cluster $RSYNC_CLUSTER"
    fi
    if [ "RSYNC_FLAVOR" == "" ]
    then 
	echo "Pushing for all flavors"
    else 
	echo "Pushing for flavor $RSYNC_FLAVOR"
    fi
    echo "Pushing for categories $CATLIST"
    if [ "$LISTMADE" == "yes" ] 
    then
	 echo "Pushing only for hosts: $SYSLIST"
    fi
fi


###
### Print the are-you-sure message
if [ "$AREYOUSURE" == "no" ] 
then
    echo "Are you sure? (yes/no)"
    read AREYOUSURE
    if [ "$AREYOUSURE" != "yes" ]
    then
	exit
    fi
fi

### New main loop---Loop through database line by line, push for 
### all that match
#
#   Change stdin to read from the database
exec 6<&0
exec < $RSYNC_HOME/clusters/common/db/nodes.conf
#
#   Begin database while loop 1
#
while read DBLINE 
do
    dbsplit
#
#   Nested If structure 1A  (cluster)
#
    if [ $DEBUG -gt 2 ] 
    then
	echo "$RSYNC_CLUSTER $DB_CLUSTER"
    fi
    if [ "$RSYNC_CLUSTER" == "" ] || [ "$RSYNC_CLUSTER" == "$DB_CLUSTER" ]
    then
#
#   Nested If structure 1B  (flavor)
#
	if [ $DEBUG -gt 2 ] 
	then
	    echo "$RSYNC_FLAVOR $DB_FLAVOR"
        fi
	if [ "$RSYNC_FLAVOR" == "" ] || [ "$RSYNC_FLAVOR" == "$DB_FLAVOR" ]
	then
	    cluster=$DB_CLUSTER
	    flavor=$DB_FLAVOR
	    host=$DB_HOST
	    if [ "$flavor" == "Linux+2.4.18" ]
	    then
		linuxrelease="731"
	    elif [ "$flavor" == "Linux+2.4" ]
	    then 
		linuxrelease="711"
	    elif [ "$flavor" == "Linux+2.2" ]
	    then
		linuxrelease="612"
            else
		linuxrelease="$flavor"
	    fi
	    if [ $DEBUG -gt 1 ] 
	    then
		echo "$cluster $flavor $host"
            fi
#
#Check to see if this host is in the host list
#
	    if [ "$LISTMADE" == "yes" ]
	    then
		HOSTCHECK="$host"
		hostcheck
		host="$FINALHOST"
	    fi
#
#If we are in retry mode, check to see if this host is in failed list.
#
	    if [ "$RETRY" == "yes" ] && [ "$host" != "" ]
	    then
		HOSTCHECK="$host"
		failcheck
		host="$FINALHOST"
	    fi
#
#        Nested IF structure 1C   (host)
#
	    if [ "$host" != "" ]
	    then
#
#   Ping host to be sure it is up
#
		hostup="no"
		if [ -e /tmp/ping.err ]
		then
		    rm /tmp/ping.err
		fi
		if [ -e /tmp/ping.out ]
		then
		    rm /tmp/ping.out
		fi
		ping -c1 -w2 $host > /tmp/ping.out 2> /tmp/ping.err
		pingcount="`grep received /tmp/ping.out | cut -d' ' -f4`"
		if [ -s /tmp/ping.err ] || [ "$pingcount" != "1" ]
		then 
		    if [ $DEBUG -gt 2 ] 
		    then
			echo "$host not pingable"
		    fi
		    if [ "$DHCP" = "yes" ] 
		    then
			hostdhcp="$host.dhcp"
			rm /tmp/ping.err
			rm /tmp/ping.out
			ping -c1 -w2 $hostdhcp > /tmp/ping.out 2> /tmp/ping.err
			pingcount="`grep received /tmp/ping.out | cut -d' ' -f4`"
			if [ -s /tmp/ping.err ] || [ "$pingcount" != "1" ]
			then
			    if [ $DEBUG -gt 2 ] 
			    then
				echo "$hostdhcp not pingable"
			    fi
			    failadd
			else
			    host=$hostdhcp
			    hostup="yes"
			fi
		    else
		    failadd
		    fi
		else
		hostup="yes"
		fi
#
#  Fetch the location of the helper applications of this node
#  should be in database in future, right now we have to 
#  pull it off of /etc/voldemort.conf on each node.
#  rsh/rcp has to be enabled for this to work.
#  Also note that sometimes ping -c1 -w2 won't put anything
#  in stderr even if the node is down.  Have to check 
#  for that as well, also if the kerberos on the node is 
#  misconfigured.  If so, we don't continue with the node.
                if [ "$hostup" == "yes" ]
		then
   		if [ -x $RCPCMD ] 
		then
                    if [ -e /tmp/rcp.err ]
		    then
			rm /tmp/rcp.err
		    fi
                    if [ -e /tmp/voldemort.conf ]
		    then
			rm /tmp/voldemort.conf
	            fi
		    KERBFAULT=""
		    NOROUTE=""
		    $RCPCMD -x root@${host}:/etc/voldemort.conf /tmp/voldemort.conf 2>/tmp/rcp.err
		    if [ -s /tmp/rcp.err ]
		    then
			KERBFAULT="`grep 'Server rejected authentication' /tmp/rcp.err`"
			NOROUTE="`grep 'No route to host' /tmp/rcp.err`"
			if [ "$KERBFAULT" != "" ] || [ "$NOROUTE" != "" ] 
			then
			    hostup="no"
			    failadd
			fi
                    fi
                    HELPLINE="`grep RSYNC_HELPERS /tmp/voldemort.conf`"
		    if [ "$HELPLINE" != "" ]
		    then
			echo $HELPLINE > /tmp/helpline.sh
			chmod 755 /tmp/helpline.sh
			. /tmp/helpline.sh
		    else
			RSYNC_HELPERS=/sbin
		    fi
		else
		    RSYNC_HELPERS=/sbin
		fi
		fi
#
#
		if [ "$hostup" == "yes" ] 
		then

		    
#
#   Second nested DO--category
#
		for category in $CATLIST
		do
		    cd ${RSYNC_HOME}/clusters/${cluster}
		    if [ $DEBUG -gt 1 ]
		    then 
			echo "$category"
		    fi
#
#   Nested IF 2A--category exists
#
		    if [ -d ${category} ] || ( [ -d /export/linux/${linuxrelease}/i386/Fermi/workgroups/${WORKGROUP} ] && [ "$category" == "linux" ]  )
		    then
			if [ "${category}" == "files" ] || [ "${category}" == "tarballs" ]
			then
			    DIRLIST=""
			    MEMFILE=""
			    RSYNC_PUSHDIR=""
			    MEMFILE="`cat ${RSYNC_HOME}/clusters/${cluster}/${category}/${flavor}/.pushdir`"
			    linetovar
			    RSYNC_PUSHDIR="$MEMLIST"
			fi
			if [ $DEBUG -gt 0 ]
			then
			    echo ${host}
			fi
#
#         Nested IF 2B  (linux vs other)
#
			if [ "${category}" == "linux" ]
			then
			    if [ -d "/export/linux/${linuxrelease}/i386/Fermi/workgroups/${WORKGROUP}" ]
			    then
				cd /export/linux/${linuxrelease}/i386/Fermi/workgroups/${WORKGROUP}
				$RSYNC_PATH -avz -e ${RSHCMD} * ${host}:/etc/${WORKGROUP} 
				${RSHCMD} -n ${host} "$RSYNC_HELPERS/run.comps"
			     fi
			else
			    cd ${RSYNC_HOME}/clusters/${cluster}/${category}/${flavor}
			    PUSHDIR="$RSYNC_PUSHDIR"
                            if [ $DEBUG -gt 2 ]
			    then
				pwd
				echo "$PUSHDIR"
			    fi
			    hostpush

#      Nested IF 2c--host specific
			    if [ -d "${host}" ] && [ "$DB_NODESPEC"=='Y' ]
			    then
				cd ${host} 
				if  [ "${category}" == "files" ]
				then
				    MEMLIST=""
				    HOST_PUSHDIR=""
#determine directories that should be pushed for this host only
				    if [ -e .pushdir ]
				    then
					MEMFILE="`cat .pushdir`"
					linetovar
					HOST_PUSHDIR="$MEMLIST"
					PUSHDIR="$HOST_PUSHDIR"
				    fi
				fi
				hostpush
				cd ..
#End of nested IF 2c--host specific
			    fi
			    SUBCLUSLIST=$DB_SUBCLUSTER
#    
#    Nested do 3  (subclusters)
			    for subcluster in $SUBCLUSLIST
			    do 
				if [ $DEBUG -gt 1 ]
				then 
				    echo ${subcluster}
				    pwd
				fi
				cd ${subcluster}
				SUBHOSTDIRLIST=""
				SUBHOST_PUSHDIR=""
				MEMFILE=""
#determine directories that should be pushed for this host only
				if [ -e .pushdir ]
				then
				    MEMFILE="`cat .pushdir`"
				    linetovar
				    SUBHOST_PUSHDIR="$MEMLIST"
				fi
				PUSHDIR="$SUBHOST_PUSHDIR"
				hostpush
				cd ..
#    End of SUBCLUSTER loop       (Nested do 3)
			        if [ $DEBUG -gt 2 ] 
				then
				    pwd
				fi
			    done
#    End nested IF cluster 2b  (linux vs other)
			fi
#    End nested IF cluster 2a (category exists)
		    fi
#    End FOR loop 2  (category) 
		    if [ $DEBUG -gt 2 ]
		    then
			pwd
		    fi
		done
		fi
#    End nested IF 1C (host)
	    fi
#    End nested IF 1B  (flavor)
	fi
#    End nested IF 1A  (cluster)
     fi
#    End of database while loop 1
done
if [ "$KERBEROS" == "yes" ]
then
    /usr/krb5/bin/kdestroy
    rm -Rf $KRB5CCDIR
fi