2121# SOFTWARE.
2222# ###############################################################################
2323
24- VERSION=0.4.1
24+ VERSION=0.4.2
2525
2626# ######################################
2727# MISC HELPER FUNCTIONS
@@ -102,6 +102,7 @@ substr_index() {
102102 local PREMATCH=" ${HAYSTACK%% $NEEDLE * } "
103103 if [[ $PREMATCH != $HAYSTACK ]]; then
104104 echo ${# PREMATCH}
105+ return
105106 fi
106107 echo -1
107108}
@@ -423,6 +424,10 @@ parse_config() {
423424 if [[ ${CONFIG[BACKUP_TYPE]} == " mirror" && ${CONFIG[MIRROR_CONFLICT_ACTION]} != " update" && ${CONFIG[MIRROR_CONFLICT_ACTION]} != " delete" ]]; then
424425 PARSE_ERRORS+=(" Value of MIRROR_CONFLICT_ACTION must be either update or delete." )
425426 fi
427+ read -r -a source_dirs <<< " ${CONFIG[SOURCE_DIR]}"
428+ if [[ ${CONFIG[BACKUP_TYPE]} == " mirror" && ${# source_dirs[@]} -gt 1 ]]; then
429+ PARSE_ERRORS+=(" Backup type of mirror can only have a single SOURCE_DIR directory." )
430+ fi
426431 # Ensure ROTATE_SUBDIR is valid
427432 if [[ ${CONFIG[BACKUP_TYPE]} == " rotation" ]]; then
428433 MATCH_NUM0=$( substr_index " ${CONFIG[ROTATE_SUBDIR]} " " NUM0" )
@@ -874,7 +879,7 @@ dirpath_is_remote() {
874879 DIRPATH=" $1 "
875880 local COLON_IDX=$( substr_index " ${DIRPATH} " " :" )
876881 local SLASH_IDX=$( substr_index " ${DIRPATH} " " /" )
877- if [[ $COLON_IDX -ge " 0 " && $COLON_IDX -lt $SLASH_IDX ]]; then
882+ if [[ $COLON_IDX -ge 0 && $COLON_IDX -lt $SLASH_IDX ]]; then
878883 return 0
879884 fi
880885 return 1
@@ -891,31 +896,39 @@ command_check() {
891896 fi
892897
893898 # Test source access
894- dirpath_is_remote " ${CONFIG[SOURCE_DIR]} "
895- if [[ $? -eq 0 ]]; then
896- local COLON_IDX=$( substr_index " ${CONFIG[SOURCE_DIR]} " " :" ) +1
897- local SSH_CONNECT=${CONFIG[SOURCE_DIR]: 0: $COLON_IDX }
898- local SSH_SOURCE=${CONFIG[SOURCE_DIR]: 1+$COLON_IDX }
899- # Check SSH connection
900- ssh -o BatchMode=yes $SSH_CONNECT exit 0
901- if [[ $? != 0 ]]; then
902- echo " ERROR: Could not connect via SSH to ${SSH_CONNECT} "
903- exit 1
904- fi
905-
906- # Check remote directory
907- ssh -o BatchMode=yes $SSH_CONNECT " [[ ! -d $SSH_SOURCE || ! -r $SSH_SOURCE ]]"
899+ read -r -a SOURCE_DIRS <<< " ${CONFIG[SOURCE_DIR]}"
900+ LAST_SSH_CONNECT=
901+ for SRC_DIR in " ${SOURCE_DIRS[@]} " ; do
902+ dirpath_is_remote " ${SRC_DIR} "
908903 if [[ $? -eq 0 ]]; then
909- echo " ERROR: Cannot read from remote source directory of ${SSH_SOURCE} "
910- exit 1
911- fi
912- else
913- # Check local directory
914- if [[ ! -d ${CONFIG[SOURCE_DIR]} || ! -r ${CONFIG[SOURCE_DIR]} ]]; then
915- echo " ERROR: Cannot read from local source directory of ${CONFIG[SOURCE_DIR]} "
916- exit 1
904+ local COLON_IDX=$( substr_index " ${SRC_DIR} " " :" )
905+ local SSH_CONNECT=${SRC_DIR: 0: $COLON_IDX }
906+ local SSH_SOURCE=${SRC_DIR: 1+$COLON_IDX }
907+ if [[ -z $SSH_CONNECT ]]; then
908+ SSH_CONNECT=$LAST_SSH_CONNECT
909+ fi
910+ # Check SSH connection
911+ ssh -o BatchMode=yes $SSH_CONNECT exit 0
912+ if [[ $? != 0 ]]; then
913+ echo " ERROR: Could not connect via SSH to ${SSH_CONNECT} "
914+ exit 1
915+ fi
916+ LAST_SSH_CONNECT=$SSH_CONNECT
917+
918+ # Check remote directory
919+ ssh -o BatchMode=yes $LAST_SSH_CONNECT " [[ ! -d $SSH_SOURCE || ! -r $SSH_SOURCE ]]"
920+ if [[ $? -eq 0 ]]; then
921+ echo " ERROR: Cannot read from remote source directory of ${SSH_SOURCE} "
922+ exit 1
923+ fi
924+ else
925+ # Check local directory
926+ if [[ ! -d ${SRC_DIR} || ! -r ${SRC_DIR} ]]; then
927+ echo " ERROR: Cannot read from local source directory of ${SRC_DIR} "
928+ exit 1
929+ fi
917930 fi
918- fi
931+ done
919932
920933 # Test target access
921934 if [[ ! -d ${CONFIG[TARGET_DIR]} || ! -w ${CONFIG[TARGET_DIR]} ]]; then
@@ -1133,14 +1146,23 @@ hardlink_identicals() {
11331146# # Escape the rsync source path, including the user and host for remote ssh sources
11341147# # Output the escaped path
11351148escaped_rsync_source () {
1136- ESCPATH=$( epath_join ${CONFIG[SOURCE_DIR]} )
1137- dirpath_is_remote " ${CONFIG[SOURCE_DIR]} "
1138- if [[ $? == 0 ]]; then
1139- local COLON_IDX=$( substr_index " ${CONFIG[SOURCE_DIR]} " " :" ) +1
1140- local SSH_CONNECT=${CONFIG[SOURCE_DIR]: 0: $COLON_IDX }
1141- local SSH_SOURCE=${CONFIG[SOURCE_DIR]: 1+$COLON_IDX }
1142- ESCPATH=" ${SSH_CONNECT} :\" $( epath_join " $SSH_SOURCE " ) \" "
1143- fi
1149+ read -r -a SOURCE_DIRS <<< " ${CONFIG[SOURCE_DIR]}"
1150+ ESCPATH=
1151+ for SRC_DIR in " ${SOURCE_DIRS[@]} " ; do
1152+ TRAILSLASH=${SRC_DIR: -1}
1153+ if [[ $TRAILSLASH != " /" ]]; then
1154+ TRAILSLASH=
1155+ fi
1156+ ESCSRCPATH=" $( epath_join ${SRC_DIR} ) ${TRAILSLASH} "
1157+ dirpath_is_remote " ${SRC_DIR} "
1158+ if [[ $? == 0 ]]; then
1159+ local COLON_IDX=$( substr_index " ${SRC_DIR} " " :" )
1160+ local SSH_CONNECT=${SRC_DIR: 0: $COLON_IDX }
1161+ local SSH_SOURCE=${SRC_DIR: 1+$COLON_IDX }
1162+ ESCSRCPATH=" ${SSH_CONNECT} :\" $( epath_join " $SSH_SOURCE " ) ${TRAILSLASH} \" "
1163+ fi
1164+ ESCPATH=" ${ESCPATH} ${ESCSRCPATH} "
1165+ done
11441166 echo " $ESCPATH "
11451167}
11461168
@@ -1161,7 +1183,7 @@ runjob_sync() {
11611183 # Exclude PID_FILE from being synced
11621184 RSYNC_FLAGS=" ${RSYNC_FLAGS} --exclude=/${PID_FILE} "
11631185
1164- RSYNC_COMMAND=" ${CONFIG[RSYNC_PATH]} ${RSYNC_FLAGS} ${SYNC_FROM} / ${RUN_DIR} /"
1186+ RSYNC_COMMAND=" ${CONFIG[RSYNC_PATH]} ${RSYNC_FLAGS} ${SYNC_FROM} ${RUN_DIR} /"
11651187 log_entry " | Running rsync: $RSYNC_COMMAND "
11661188 RSYNC_COMMAND=" $RSYNC_COMMAND >> ${LOG_FILE} 2>&1"
11671189 eval $RSYNC_COMMAND
@@ -1233,7 +1255,7 @@ runjob_rotation() {
12331255 fi
12341256
12351257 SYNC_FROM=$( escaped_rsync_source )
1236- RSYNC_COMMAND=" ${CONFIG[RSYNC_PATH]} ${RSYNC_FLAGS} ${SYNC_FROM} / ${RUN_DIR} /"
1258+ RSYNC_COMMAND=" ${CONFIG[RSYNC_PATH]} ${RSYNC_FLAGS} ${SYNC_FROM} ${RUN_DIR} /"
12371259 log_entry " | Running rsync: $RSYNC_COMMAND "
12381260 RSYNC_COMMAND=" $RSYNC_COMMAND >> ${LOG_FILE} 2>&1"
12391261 eval $RSYNC_COMMAND
@@ -1275,7 +1297,7 @@ runjob_skipped_files() {
12751297 RSYNC_FLAGS=" ${RSYNC_FLAGS} --exclude=/${PID_FILE} "
12761298 fi
12771299
1278- RSYNC_COMMAND=" ${CONFIG[RSYNC_PATH]} ${RSYNC_FLAGS} ${SYNC_FROM} / ${RUN_DIR} /"
1300+ RSYNC_COMMAND=" ${CONFIG[RSYNC_PATH]} ${RSYNC_FLAGS} ${SYNC_FROM} ${RUN_DIR} /"
12791301 log_entry " | Checking for skipped files..."
12801302 log_entry " | Running rsync: $RSYNC_COMMAND "
12811303 SKIP_RESULTS=$( $RSYNC_COMMAND | tee -a $LOG_FILE 2>&1 )
0 commit comments