#!/bin/bash

########################################################
# Calls rsync with a set of options Aaron Curley always uses.
# 
# A different set of options is used if the transfer is local 
#   or involves a remote host.
#   
# Version 7
########################################################

# careful - these options will delete any files that exist on the target but not on the source.  In other words, "newer" files could be erased.
RSYNC_COMMAND_LINE_LOCAL="rsync -i --stats -kK -rlt --protect-args --delay-updates --delete --delete-after --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r"
RSYNC_COMMAND_LINE_REMOTE="rsync -i --stats -kK -rlt -z --protect-args --fuzzy --delay-updates --delete --delete-after --chmod=Du=rwx,Dgo=rx,Fu=rw,Fgo=r"

# drop the rsync password file to use in the home directory
#   name the file "puthostnamehere.rsyncpw"
PASSWORD_FILE_OPTION="--password-file="
PASSWORD_FILE_DIR="$HOME/"
PASSWORD_FILE_SUFFIX=".rsyncpw"

SCRIPT_NAME="./rsync.sh"

BACK_OFF_TIME=60  # 60 seconds between unsuccessful/incomplete rsync attempts

# check that we have at least three parameters
if [ $# -gt 2 ]; then
        
        # get first parameter (specifies "local" or "remote")
        sync_mode="$1"
        # remove the first parameter from the list of params
        shift
        
        
        # check if next parameter is '--loop'.  If so, remove it.
        loop_option="$1"
        if [ "$loop_option" == '--loop' ]; then
                shift
                loop_option="yes"
        else
                loop_option=""
        fi
        
        
        if [ "$sync_mode" == 'local' ]; then
                
                # loop option not supported in local mode
                if [ "$loop_option" == 'yes' ]; then
                        echo "Error: Option --loop not supported with local mode."
                        echo ""
                        echo "Usage: $SCRIPT_NAME local|remote [--loop] [additional rsync options] source dest"
                        exit -3
                fi
                
                commandLine="${RSYNC_COMMAND_LINE_LOCAL}"
                echo "Command line: ${commandLine} $@"
                echo ""
                
                $commandLine "$@"
                exit $?
                
        elif [ "$sync_mode" == 'remote' ]; then
                
                targetHostname="$*"
                
                # trim anything after double-colon from args
                targetHostname=`echo "$targetHostname" | awk -F"::" '{print $1}'`
                # ensure we found the :: separator in the parameter string
                if [ "$targetHostname" == "$*" ]; then
                        echo "Error: Remote host must be supplied using  hostname::targetDir  format.  Aborting."
                        echo ""
                        echo "Usage: $SCRIPT_NAME local|remote [--loop] [additional rsync options] source dest"
                        exit -5
                fi
                
                # trim anything before the final space in the previously-trimmed string
                targetHostname=`echo "$targetHostname" | awk -F" " '{print $NF}'`

                # remove anything prior to any @ symbol (i.e. convert aaron@hostname --> hostname)
                targetHostname=`echo "$targetHostname" | awk -F"@" '{print $NF}'`
                
                
                echo "Identified hostname: $targetHostname"
                
                
                # verify the password file exists for the identified hostname
                if [ -f "${PASSWORD_FILE_DIR}${targetHostname}${PASSWORD_FILE_SUFFIX}" ]; then
                        
                        commandLine="${RSYNC_COMMAND_LINE_REMOTE} ${PASSWORD_FILE_OPTION}${PASSWORD_FILE_DIR}${targetHostname}${PASSWORD_FILE_SUFFIX} "
                        echo "Command line: ${commandLine} $@"
                        echo ""
                        
                        if [ "$loop_option" == 'yes' ]; then
                                
                                # Trap interrupts and exit instead of continuing the loop
                                trap "echo Exited!; exit -30;" SIGINT SIGTERM
                                
                                while [ 1 ]
                                do
                                        $commandLine "$@"
                                        if [ "$?" = "0" ] ; then
                                                exit 0
                                        else
                                                echo "Rsync failure. Backing off and retrying..."
                                                # sleep backofftime seconds
                                                sleep $BACK_OFF_TIME
                                        fi
                                done
                                exit 0
                        
                        # non-loop option
                        else
                                $commandLine "$@"
                                exit $?
                        fi
                        
                # password file does not exist for identified hostname
                else
                        
                        echo "Error: Password file for ${targetHostname} is missing.  Aborting."
                        echo ""
                        echo "Usage: $SCRIPT_NAME local|remote [--loop] [additional rsync options] source dest"
                        exit -5
                        
                fi
                
        # first param isn't "local" or "remote"
        else
                
                echo 'Error: neither "local" nor "remote" specified.  Aborting.'
                echo ""
                echo "Usage: $SCRIPT_NAME local|remote [--loop] [additional rsync options] source dest"
                exit -2
                
        fi
        
# no args
else
        echo "Usage: $SCRIPT_NAME local|remote [--loop] [additional rsync options] source dest"
        exit -1
fi
