#!/bin/bash
########################################################################
#### Script Name: rbxi
#### Version: 2.7.3
#### Date: 2015-02-20
#### Copyright (C) Harald Hope 2006-2015
####
#### This program is free software; you can redistribute it and/or modify it under
#### the terms of the GNU General Public License as published by the Free Software
#### Foundation; either version 3 of the License, or (at your option) any later version.
####
#### This program is distributed in the hope that it will be useful, but WITHOUT
#### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#### FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
####
#### Get the full text of the GPL here: http://www.gnu.org/licenses/gpl.txt
####
#### This is an rdiff-backup/rsync script which helps automate the backup process
#### Requires companion excludes-....txt files to run, those must be in the rbxi-data
#### directory
####
#### rbxi.tar.bz2 package download URL: http://smxi.org/rb [contains all needed files]
#### Script Home page: http://techpatterns.com/forums/about831.html
########################################################################
########################################################################
#### CHANGES
#### 2.7.3 2015-02-20 - updated date formats to: YYYY-MM-DD, fixed -J restart bug
#### that made rbxi fail to return proper exit code on error after restart
#### 2.7.2 4 September 2009 - last stable
########################################################################
#### VARIABLES
#### Make sure to change these to fit your installation
########################################################################
########################################################################
#### SCRIPT PATH VARIABLES
####--------------------------------------------------------------------
# Basic script layout markers
BA='=================================================================='
LI='------------------------------------------------------------------'
### if you do need to change one of these, make sure to change it in the
### user values file: rbxi-data/rbxi-values, not here, or you might lose
### your changes if you update this script.
### Script names/paths
# set this as absolute path for cron jobs if you need to, you'll have to
# update this manually every time you update the script:
LSOF='lsof'
LOGFILE_DIR='/var/log/'
SCRIPT_CONFIGS='/etc/rbxi.conf'
SCRIPT_NAME='rbxi'
SCRIPT_DATA='/rbxi-data/'
SCRIPT_README='readme-rbxi.htm'
SCRIPT_VALUES='rbxi-values'
# http://forums.macosxhints.com/archive/index.php/t-73839.html
# note, no other method works reliably to get the true script path, not dirname $0.
if type $LSOF &>/dev/null;then
SCRIPT_PATH=$( dirname $( $LSOF -p $$ | grep 'REG' | grep -Eo "/.*$(basename $0)$" ) )
# checking if the dirname method works
elif [ -d "$( dirname $0 )$SCRIPT_DATA" ];then
SCRIPT_PATH=$( dirname $0 )
fi
# in worst cases, you can manually set the script directory path here, uncomment and make the path
# explicit. Must not end with /, and must be the full path of the rbxi directory rbxi came with.
# you'll have to update this manually every time you update the script:
# example: SCRIPT_PATH='/home/fred/scripts/rbxi'
# SCRIPT_PATH=''
SCRIPT_DATA_DIR="$SCRIPT_PATH$SCRIPT_DATA"
SCRIPT_VERSION_NUMBER=$( grep -im 1 'version:' $SCRIPT_PATH/$SCRIPT_NAME | awk '{print $3}' )
SCRIPT_DOWNLOAD='http://rbxi.googlecode.com/svn/trunk/'
SCRIPT_DOWNLOAD_BRANCH_1='http://rbxi.googlecode.com/svn/branches/one/'
SCRIPT_DOWNLOAD_BRANCH_2='http://rbxi.googlecode.com/svn/branches/two/'
SCRIPT_DOWNLOAD_DEV='http://smxi.org/tests/'
#### EXCLUDE LIST FILE NAMES
# NOTE: can be a blank file, but most be located in same directory as rbxi
# if you want them in a different directory, use absolute system paths.
EXCLUDE_ROOT='excludes-root.txt'
EXCLUDE_HOME='excludes-home.txt'
EXCLUDE_DATA_1='excludes-data-1.txt'
EXCLUDE_DATA_2='excludes-data-2.txt'
EXCLUDE_DATA_3='excludes-data-3.txt'
EXCLUDE_DATA_4='excludes-data-4.txt'
EXCLUDE_DATA_5='excludes-data-5.txt'
EXCLUDE_DATA_6='excludes-data-6.txt'
EXCLUDE_DATA_7='excludes-data-7.txt'
EXCLUDE_DATA_8='excludes-data-8.txt'
EXCLUDE_DATA_9='excludes-data-9.txt'
EXCLUDE_DATA_10='excludes-data-10.txt'
EXCLUDE_ROOT_RS='excludes-root-rsync.txt'
EXCLUDE_HOME_RS='excludes-home-rsync.txt'
EXCLUDE_DATA_1_RS='excludes-data-1-rsync.txt'
EXCLUDE_DATA_2_RS='excludes-data-2-rsync.txt'
EXCLUDE_DATA_3_RS='excludes-data-3-rsync.txt'
EXCLUDE_DATA_4_RS='excludes-data-4-rsync.txt'
EXCLUDE_DATA_5_RS='excludes-data-5-rsync.txt'
EXCLUDE_DATA_6_RS='excludes-data-6-rsync.txt'
EXCLUDE_DATA_7_RS='excludes-data-7-rsync.txt'
EXCLUDE_DATA_8_RS='excludes-data-8-rsync.txt'
EXCLUDE_DATA_9_RS='excludes-data-9-rsync.txt'
EXCLUDE_DATA_10_RS='excludes-data-10-rsync.txt'
########################################################################
#### USER SPECIFIC VARIABLES - REQUIRES rbxi-data/rbxi-values file
####--------------------------------------------------------------------
# initializing user defined functions/scripted actions/variables just to be safe,
# must be prior to script rbxi-values sourcing
CONSOLE_BROWSER=''
EMAIL_START_ACTION=''
EMAIL_FINISH_ACTION=''
EMAIL_ERROR_ACTION=''
PRE_MOUNT_FUNCTION=''
POST_MOUNT_FUNCTION=''
POST_UMOUNT_FUNCTION=''
# variables that can be overridden in rbxi-values but which are commented out
LOGFILE_SIZE=100
## add in user variable values, sticky value file
# missing test will occur a bit later
if [ -f "$SCRIPT_DATA_DIR$SCRIPT_VALUES" ];then
source $SCRIPT_DATA_DIR$SCRIPT_VALUES
fi
### See the file rbxi-data/rbxi-values for variable lists and how to
### set them. That file will be the actual data used.
### rbxi cannot run without the user data values file: rbxi-data/rbxi-values
########################################################################
#### STATIC VARIABLES, SHOULD NOT REQUIRE CHANGES
####--------------------------------------------------------------------
#### INITIALIZE VARIABLES TO BE SET ELSEWHERE
HOME_BACKUP=''
ROOT_BACKUP=''
# these are optional, only used if DATA_x_DIR is/are set
DATA_1_BACKUP=''
DATA_2_BACKUP=''
DATA_3_BACKUP=''
DATA_4_BACKUP=''
DATA_5_BACKUP=''
DATA_6_BACKUP=''
DATA_7_BACKUP=''
DATA_8_BACKUP=''
DATA_9_BACKUP=''
DATA_10_BACKUP=''
# backup command string holders
HOME_BU_COMMAND=''
ROOT_BU_COMMAND=''
DATA_1_BU_COMMAND=''
DATA_2_BU_COMMAND=''
DATA_3_BU_COMMAND=''
DATA_4_BU_COMMAND=''
DATA_5_BU_COMMAND=''
DATA_6_BU_COMMAND=''
DATA_7_BU_COMMAND=''
DATA_8_BU_COMMAND=''
DATA_9_BU_COMMAND=''
DATA_10_BU_COMMAND=''
# set initial value
ENDING_1='...'
ENDING_2='...'
# for timer function
START_TIME=$( date +%s )
# initialize internal booleans
B_CLONE_HOME='false'
B_CLONE_ROOT='false'
B_CLONE_DATA_1='false'
B_CLONE_DATA_2='false'
B_CLONE_DATA_3='false'
B_CLONE_DATA_4='false'
B_CLONE_DATA_5='false'
B_CLONE_DATA_6='false'
B_CLONE_DATA_7='false'
B_CLONE_DATA_8='false'
B_CLONE_DATA_9='false'
B_CLONE_DATA_10='false'
B_DELETE_STATUS='false'
B_DRY_RUN='false'
B_IS_CLONE='false'
# initialize globals to be set later
BACKUP_CLEAR=''
BACKUP_DURATION=''
# only for logging/history purposes
BACKUP_JOB_NAME=''
BACKUP_JOB_NU='none'
CLONE_SOURCE_DIR=''
DELETION_TEXT=''
# spinning wheel pid value
GET_PID=''
RSYNC_DELETE=''
SCRIPT_OPTIONS="$@"
###################################################################
##### Functions
###################################################################
#### -------------------------------------------------------------------
#### Options/Parameters
#### -------------------------------------------------------------------
print_usage()
{
if [ "$1" == 'err' ];then
echo 'You entered an invalid option. Please use one of the following only:'
fi
echo '-A Add backup component. Overrides user set B_SKIP_DATA.. (d|h|hr|r|1-10)'
echo ' d - add all DATA; h - add HOME; r - add ROOT; add DATA 1-10'
echo '-b Automatic backup, non interactive.'
echo '-B Change default backup directory (1-10).'
echo '-c Automatic backup, clean older files, then runs non-interactive backup.'
echo '-C (rsync only) Clone root/home. Skips all data backups. Moves files directly to mounted location'
echo ' Sets the main mount subdirectory to '', then transfers files directly into that directory.'
echo ' Takes parameters: (h|r|1-10). Clone root, home, or a data direcory.'
echo '-d Automatic backup and delete, non interactive.'
echo '-D Change default backup sub directory (1-10).'
echo '-E Requires <1-10:1-10:1-10> for script start, finish, or error actions. Must be'
echo ' one or more, but does not need to be all three. Actions are user created. See readme for how-to.'
echo '-j Set script color scheme -j [0-5]: 0 - no colors; 1 - default, ok for dark/light or light/dark'
echo ' 2 - fancy dark on light; 3 - basic light on dark; 4 - fancy light on dark; 5 - smxi style'
echo '-J Start preset backup job (1-10). Cannot be used with any other option.'
echo '-l Use logging. Will override user rbxi-values setting.'
echo "-L Create symbolic link in /usr/local/bin to $SCRIPT_NAME"
echo '-m Skip the mounting option.'
echo '-M use alternate mount/umount set (1-10)'
echo '-o Override default backup application.'
echo '-P Requires <1-10:1-10:1-10> for pre mount, post mount, or post umount extra functions. Must be'
echo ' one or more, but does not need to be all three. Functions are user created. See readme for how-to.'
echo '-r Trigger --dry-run for rsync. This simulates the backup, but does not actually run it.'
echo '-R Show script readme file. Requires one of these console browsers (can also be set in rbxi-values):'
echo ' links2 elinks w3m links lynx'
echo '-s Show spinning wheel indicator.'
echo '-S Skip backup component (d|h|hr|1-10)'
echo ' d - skip all DATA; h - skip HOME; r - skip ROOT; skip DATA 1-10'
echo '-U Update script manually from svn server.'
echo '-v Show script version and last used information.'
echo '-V Use alternate rbxi-values file. Syntax: rbxi-values-<whatever you want>'
echo ' File must be located in rbxi-data, and must have the syntax of: rbxi-values-<something>'
echo '-h This help menu'
echo
echo 'In general, avoid using A, D, M, S unless you are creating a backup job -J, or if you want'
echo 'temporarily skip (-S) or add (-A) a specific directory.'
echo
echo '-S and -A can be used repeatedly, like so: -S 2 -S 5 -S 9'
echo 'Remember, -A should only be used to override SKIP... that has been set in rbxi-values.'
echo '-C overrides -A which overrides -S. -C will only clone the specific directory you set,'
echo 'directly to the destination directory, and switches off all other backup directories.'
echo '-C overrides -D, or default backup subdirectory, and sets it to null.'
echo '-D overrides default main mount backup directory, and uses that for -M'
exit 0
}
### this is not in a function because these variables need to be set on startup
# only use b or d, not both together. If you use both your old backups will be deleted.
# args: $1 - $@ - all args
# -A and -S can iterate repeatedly
get_options()
{
local opt='' setDirectory='' setSubDir='' setMount='' setPrePost=''
local setFullAdds='' setFullSkips='' setCloneData='' setEmailer=''
while getopts :A:bB:cC:dD:E:hj:J:LlmM:o:P:rRsS:UvV:z:!: opt
do
case $opt in
h) print_usage
;;
A) if [ -n "$( grep -E '^(d|h|r|rh|hr|[1-9]|10)$' <<< $OPTARG )" ];then
setFullAdds="$setFullAdds $OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
b) B_DO_BACKUP='true'
;;
B) if [ -n "$( grep -E '^([1-9]|10)$' <<< $OPTARG )" ];then
setDirectory="$OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
c) B_CLEAN_OLDER='true'
B_DO_BACKUP='true'
;;
C) if [ -n "$( grep -E '^(r|h|[1-9]|10)$' <<< $OPTARG )" ];then
setCloneData=$OPTARG
B_IS_CLONE='true'
else
error_handler 13 "-$opt $OPTARG"
fi
;;
d) B_DELETE_BACKUP='true'
B_DO_BACKUP='true'
;;
D) if [ -n "$( grep -E '^([1-9]|10)$' <<< $OPTARG )" ];then
setSubDir="$OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
E) if [ -n "$( grep -E '^([1-9]|10)?:([1-9]|10)?:([1-9]|10)?$' <<< $OPTARG )" ];then
setEmailer="$OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
j) if [ -n "$( grep -E '^([0-5])$' <<< $OPTARG )" ];then
COLOR_SCHEME=$OPTARG
set_script_colors
else
error_handler 13 "-$opt $OPTARG"
fi
;;
J) if [ -n "$( grep -E '^([1-9]|10)$' <<< $OPTARG )" ];then
set_or_print_backup_job "$OPTARG" 'set'
else
error_handler 13 "-$opt $OPTARG"
fi
;;
l) B_LOGGING='true'
;;
L) create_symbolic_link
exit 0
;;
m) B_SKIP_MOUNT='true'
;;
M) if [ -n "$( grep -E '^([1-9]|10)$' <<< $OPTARG )" ];then
setMount="$OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
o) if [ -n "$( grep -E '^(rd|rs)$' <<< $OPTARG )" ];then
case $OPTARG in
rd)
BACKUP_APP='rdiff-backup'
;;
rs)
BACKUP_APP='rsync'
;;
esac
else
error_handler 13 "-$opt $OPTARG"
fi
;;
P) if [ -n "$( grep -E '^([1-9]|10)?:([1-9]|10)?:([1-9]|10)?$' <<< $OPTARG )" ];then
setPrePost="$OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
r) B_DRY_RUN='true'
;;
R) show_script_readme
exit
;;
s) B_SPINNING_WHEEL='true'
ENDING_1=': '
ENDING_2=', watch the spinning wheel: '
;;
S) if [ -n "$( grep -E '^(d|h|r|rh|hr|[1-9]|10)$' <<< $OPTARG )" ];then
setFullSkips="$setFullSkips $OPTARG"
else
error_handler 13 "-$opt $OPTARG"
fi
;;
U) script_self_updater "$SCRIPT_DOWNLOAD" 'svn server'
;;
v) print_version_info 'opt'
exit 0
;;
V) # construct new user values file name, then test it, load it
SCRIPT_VALUES="$SCRIPT_VALUES-$OPTARG"
if [ -f "$SCRIPT_DATA_DIR$SCRIPT_VALUES" ];then
source $SCRIPT_DATA_DIR$SCRIPT_VALUES
set_script_colors
check_script_requires
else
error_handler 22
fi
;;
# set_or_print_backup_job will relaunch with job options and -z has the bu job nu for output
z) if [ -n "$( grep -E '^([1-9]|10)$' <<< $OPTARG )" ];then
BACKUP_JOB_NU=$OPTARG
fi
;;
!) # test for various supported methods
case $OPTARG in
1) B_TESTING_1='true'
;;
2) B_TESTING_2='true'
;;
3) B_TESTING_1='true'
B_TESTING_2='true'
;;
10) script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server'
;;
11) script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server'
;;
12) script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server'
;;
http*)
script_self_updater "$OPTARG" 'alt server'
;;
*) error_handler 11 "-$opt $OPTARG"
;;
esac
;;
*) error_handler 7 "-$OPTARG"
;;
esac
done
# note, because mount will use the first value, I have to set this here, to
# ensure the proper order. Or you can just set the stuff manually in your rbxi-values file
# Clone -C overrides Adds -A override skips -S. -A and -S can handle multiple iterations.
# -C overrides -D, backup subdirectory, and sets it to null
# -D overrides default main backup directory for -M
if [ -n "$setDirectory" ];then
set_backup_mount_point "$setDirectory"
fi
if [ -n "$setSubDir" ];then
set_backup_mount_point_directory "$setSubDir"
fi
if [ -n "$setFullSkips" ];then
set_skip_data "$setFullSkips"
fi
if [ -n "$setFullAdds" ];then
set_add_data "$setFullAdds"
fi
if [ -n "$setCloneData" ];then
set_clone_data "$setCloneData"
fi
if [ -n "$setMount" ];then
set_mount_data "$setMount"
fi
if [ -n "$setEmailer" ];then
set_emailer_data "$setEmailer"
fi
if [ -n "$setPrePost" ];then
set_pre_post_data "$setPrePost"
fi
}
#### -------------------------------------------------------------------
#### Error Handling
#### -------------------------------------------------------------------
# Error handling
# args: $1 - error number; $2 - optional, extra information
error_handler()
{
local error_message='' errorType='' extra2='' extra3='' cleanedMessage=''
case $1 in
50)
errorType="Event"
W=${M}
;;
*)
errorType="Error"
;;
esac
# assemble the error message
case $1 in
2) error_message="The component: ${C}MOUNT_BU_DISK${W} failed to successfully complete its task. Error code was: ${C}$2"
;;
3) error_message="The component: ${C}UNMOUNT_BU_DISK${W} failed to successfully complete its task. Error code was: ${C}$2"
;;
4) error_message="You must be logged in as ${C}root${W} to run this script."
;;
5) error_message="dependency not met: ${C}$2${W} not found in path"
;;
6) error_message="Your backup partition/directory ${C}$BACKUP_MOUNT_POINT${W} is not present.\nPlease make sure to create it or mount it up before you proceed."
;;
7) error_message="One of the options you entered in your script parameters: ${C}$2${W}\nIs not supported, or requires a further argument.\nFor a list of supported options, check the help menu: ${C}$SCRIPT_NAME -h"
;;
8) error_message="the self-updater failed, wget exited with error: ${C}$2${W}.\nYou probably need to be root.\nHint, to make for easy updates without being root, do: chown <user name> ${C}$SCRIPT_PATH/$SCRIPT_NAME"
;;
9) error_message="unset"
;;
10)
error_message="the alt download url you provided: ${C}$2${W}\nappears to be wrong, download aborted. Please note, the url\nneeds to end in ${C}/${W}, without ${C}$SCRIPT_NAME${W}, like: ${C}http://yoursite.com/downloads/"
;;
11)
error_message="unsupported testing option argument: ${C}-! $2"
;;
12)
error_message="the svn branch download url: ${C}$2${W}\nappears to be empty currently. Make sure there is an actual svn branch version\nactive before you try this again. Check http://code.google.com/p/inxi\nto verify the branch status."
;;
13)
error_message="The option argument you gave is not supported: ${C}$2"
;;
14)
error_message="You do not have the required backup application installed. Missing: ${C}$2"
;;
15)
error_message="You cannot use both ${C}-c${W} and ${C}-d${W}, only one or the other. Either you are clearing, or deleting."
;;
16)
error_message="${C}B_VARIABLES_SET='false'${W} in the file ${C}rbxi-data/$SCRIPT_VALUES${W} must be set to ${C}'true' before you can run $SCRIPT_NAME\nYou must configure that file first, then when you're done, you can the script."
;;
17)
error_message="The backup job you selected (${C}$2${W}) is empty. Please make sure you entered the right number."
;;
18)
error_message="The backup directory you selected (${C}$2${W}) is empty.\nYou cannot backup to, or mount, a blank directory."
;;
19)
error_message="Your backup program ${C}$BACKUP_APP${W} does not support the -C clone option."
;;
20)
error_message="The backup source directory: ${C}$2${W} does not exist. Unable to continue."
;;
21)
error_message="You are using an unsupported color scheme: ${C}$2"
;;
22)
error_message="Could not load user values file: ${C}$SCRIPT_DATA_DIR$SCRIPT_VALUES${W}\nPlease double check that the file exists and is in: ${C}$SCRIPT_DATA_DIR${W}\nExiting now."
;;
23)
error_message="Unable to locate the script data directory: ${C}$SCRIPT_PATH$SCRIPT_DATA\n${C}rbxi${W} requires the program ${C}$2${W} to create its paths if you start using a symbolic link.\nYou must install this application before you can run ${C}$SCRIPT_NAME${W} with a sybolic link.\nUnable to continue."
;;
24)
error_message="Your backup destination directory: ${C}$2${W}\ndoes not seem to exist. Please check your settings and make sure the directory\nyou are using actually exists."
;;
25)
error_message="Your backup application ${C}$BACKUP_APP${W} exited with error: ${C}$2${W}\nPlease check the source of the error and try again. Exiting $SCRIPT_NAME now."
;;
26)
error_message="The variable ${C}BACKUP_MOUNT_POINT${W} is empty. Backup directory mount cannnot continue."
;;
27)
error_message="The function: ${C}pre_mount_tasks${W} exited with error code: (${C}$2${W})"
;;
28)
error_message="The function: ${C}post_mount_tasks${W} exited with error code: (${C}$2${W})"
;;
29)
error_message="The function: ${C}post_umount_tasks${W} exited with error code: (${C}$2${W})"
;;
30)
error_message="The rbxi log directory ${C}$2${W} does not exist.\nPlease correct the path in rbxi-values LOGFILE_DIR='' before continuing."
;;
31)
error_message="User set Action returned error: $2"
;;
32)
error_message="No console browser detected in your system. Requires one of these: links2 elinks w3m links lynx"
;;
50)
error_message="User initiated script termination. Exiting $SCRIPT_NAME now."
;;
100)
error_message="$SCRIPT_NAME does not yet support the backup app you requested: ${C}$2${W}\nThis support should be coming sometime soon.\nCurrently supported backup applications are: rdiff-backup."
umount_backup_disk
;;
*) error_message="Unknown error number: ${C}$1"
;;
esac
log_function_data 'error' "$errorType ($1)\n$error_message"
run_emailer_tasks 'error' "$errorType ($1)\n$error_message"
# then print it and exit
echo -e "${W}$errorType ${C}$1${W}: $error_message${N}"
exit $1
}
# args: $1 type: start/error/data; $2 - data to be logged
log_function_data()
{
if [ "$B_LOGGING" == 'true' ];then
local data=$( echo -e "$2" | sed 's/\x1b\[[0-9]\{1,2\}\(;[0-9]\{1,2\}\)\{0,2\}m//g' )
local actionTime=$( date +"%R:%S" )
local logFile=${LOGFILE_DIR}${SCRIPT_NAME}.log
# check user error first
if [ ! -d $LOGFILE_DIR ];then
error_handler 30 "$LOGFILE_DIR"
fi
# I don't to try to handle various distro logrotate tools, so I'm making my own here
# going to rotate it at 100kB
if [ -f $logFile ];then
# this shouldn't have been necessary, but if on same line as -f test, gives error
# if no file exists.
if [ "$( du -s $logFile | awk '{print $1}' )" -gt $LOGFILE_SIZE ];then
mv -f $logFile ${LOGFILE_DIR}${SCRIPT_NAME}.1.log
fi
fi
# then make sure the file is ready to go
if [ ! -f $logFile ];then
touch $logFile
fi
case $1 in
start)
echo $BA >> $logFile
echo "Starting $SCRIPT_NAME at: $( date +"%Y %B %e - %R:%S" )" >> $logFile
echo "Script start options: $2" >> $logFile
echo $LI >> $logFile
if [ -f $SCRIPT_CONFIGS -a -n "$( cat $SCRIPT_CONFIGS )" ];then
echo "Previous Script Config Data:" >> $logFile
echo "$( cat $SCRIPT_CONFIGS )" >> $logFile
else
echo "Previous Script Config Data File Is Null." >> $logFile
fi
echo $LI >> $logFile
echo "Starting backup job." >> $logFile
;;
error|data)
echo -e "$actionTime: $data" >> $logFile
;;
esac
fi
}
#### -------------------------------------------------------------------
#### Utilities
#### -------------------------------------------------------------------
# set global color variables
# options: 0 - no colors; 1 - defaults; 2 light bkgd, fancy; dark background, simple
# 4 dark background, fancy; 4 smxi
set_script_colors()
{
# set colors # ="[40m" # black background
case "$COLOR_SCHEME" in
# colors off
0)
W='' # Warning message
E='' # script Error
S='' # Standard message
Q='' # Questions
M='' # Message
C='' # Command or Path
N='' # default system console color: Normal :: make last in colors
;;
# default, either dark or light background
''|1)
W="[0;31m" # Warning message
E="[1;31m" # script Error
S="[0;39m" # Standard message
Q="[1;39m" # Questions
M="[1;39m" # Message
C="[0;35m" # Command or Path
B="[0;39m" # black background
N="[0;39m" # default system console color: Normal
;;
# light background, fancy
2)
W="[0;31m" # Warning message
E="[1;31m" # script Error
S="[0;39m" # Standard message
Q="[1;34m" # Questions
M="[1;34m" # Message
C="[0;35m" # Command or Path
B="[0;34m" # black background
N="[0;39m" # default system console color: Normal :: make last in colors
;;
# dark background, simple
3)
W="[1;31m" # Warning message
E="[1;33m" # script Error
S="[0;39m" # Standard message
Q="[1;39m" # Questions
M="[1;39m" # Message
C="[1;35m" # Command or Path
B="[0;39m" # black background
N="[0;39m" # default system console color: Normal
;;
# dark background, fancy
4)
W="[1;31m" # Warning message
E="[1;33m" # script Error
S="[0;39m" # Standard message
Q="[1;36m" # Questions
M="[1;36m" # Message
C="[1;35m" # Command or Path
B="[0;34m" # black background
N="[0;39m" # default system console color: Normal :: make last in colors
;;
# dark background, smxi style
5)
W="[0;31m" # red: Warning message
E="[0;33m" # yellow: script Error
S="[1;32m" # green: Standard message
Q="[1;36m" # CYAN: Questions
M="[1;36m" # CYAN: Message
C="[1;35m" # MAGENTA: Command or Path
B="[1;34m" # BLUE: Message
N="[0;39m" # default system console color: Normal :: make last in colors
;;
*)
error_handler 21 "$COLOR_SCHEME"
;;
esac
# script layout stuff
BAR=${S}$BA${N}
EBAR=${E}$BA${N}
WBAR=${W}$BA${N}
MBAR=${M}$BA${N}
LINE=${S}$LI${N}
ELINE=${E}$LI${N}
MLINE=${M}$LI${N}
WLINE=${W}$LI${N}
SPACER=' '
}
create_symbolic_link()
{
local ulbLink="/usr/local/bin/$SCRIPT_NAME"
local scriptInPath=$( which $SCRIPT_NAME | grep -v "./$SCRIPT_NAME" )
if [ ! -L $ulbLink -a ! -f $ulbLink -a -z "$scriptInPath" ];then
check_is_root
# only do the linking if the path is real
if type $LSOF &>/dev/null;then
echo "${S}Creating link now...${N}"
ln -s $SCRIPT_PATH/$SCRIPT_NAME $ulbLink
else
echo "${C}$SCRIPT_PATH ${W}is not properly set, cannot automatically create symbolic link.${N}"
fi
else
echo "${M}$SCRIPT_NAME is already in your system path, or a link to it already exists.${N}"
fi
}
# args: $1 - main/v
print_history_data()
{
local lastBackupDirectory='Unset'
local lastBackupDate='Unset'
local lastBackupDuration='Unset'
local lastBackupApp='Unset'
local lastBackupJobNu='Unset'
local rdbuHistoryHolder=''
local rsyncHistoryHolder=''
local rdbuHistory='Unset'
local rsyncHistory='Unset'
local rdbuHistory2=''
local rsyncHistory2=''
if [ "$1" != 'main' ];then
M=''
C=''
N=''
S=''
fi
if [ -f $SCRIPT_CONFIGS ];then
lastBackupDirectory=$( grep 'last-backup-directory=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )
lastBackupDate=$( grep 'last-backup-date=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )
lastBackupDuration=$( grep 'last-backup-duration=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )
lastBackupApp=$( grep 'last-backup-app=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )
lastBackupJobNu=$( grep 'last-backup-job=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )
# add line breaks because output is too long for single line
rdbuHistoryHolder="$( grep 'rdbu-backup-history=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )"
rsyncHistoryHolder="$( grep 'rsync-backup-history=' $SCRIPT_CONFIGS | cut -d '=' -f 2 )"
rdbuHistory="$( cut -d '~' -f 1 <<< $rdbuHistoryHolder )"
rsyncHistory="$( cut -d '~' -f 1 <<< $rsyncHistoryHolder )"
if [ -n "$( grep '~' <<< $rdbuHistoryHolder )" ];then
rdbuHistory2="$( cut -d '~' -f 2 <<< $rdbuHistoryHolder )"
rdbuHistory2='echo " ${C}'$rdbuHistory2'${N}"'
fi
if [ -n "$( grep '~' <<< $rsyncHistoryHolder )" ];then
rsyncHistory2="$( cut -d '~' -f 2 <<< $rsyncHistoryHolder )"
rsyncHistory2='echo " ${C}'$rsyncHistory2'${N}"'
fi
fi
echo "${M}Last Backup Date: ${C}$lastBackupDate${N}"
echo "${M}Last Backup Directory: ${C}$lastBackupDirectory${N}"
echo "${M}Last Backup Program: ${C}$lastBackupApp${N}"
if [ "$lastBackupJobNu" == 'none' ];then
echo "${M}Your last backup did not use the ${C}Job${M} feature.${N}"
else
echo "${M}Last Backup Job Number: ${C}$lastBackupJobNu${N}"
fi
if [ "$1" == 'main' ];then
case "$BACKUP_APP" in
rdiff-backup)
echo "${M}Rdiff-backup history: ${C}$rdbuHistory${N}"
eval "$rdbuHistory2"
;;
rsync)
echo "${M}Rsync backup history: ${C}$rsyncHistory${N}"
eval "$rsyncHistory2"
;;
esac
else
echo "${M}Rdiff-backup history: ${C}$rdbuHistory${N}"
eval "$rdbuHistory2"
echo "${M}Rsync backup history: ${C}$rsyncHistory${N}"
eval "$rsyncHistory2"
fi
}
## print out version information for -v
print_version_info()
{
local last_modified=$( grep -im 1 'date:' $SCRIPT_PATH/$SCRIPT_NAME | awk '{print $3,$4,$5}' )
local versionRemote='' versionRemoteDate='' versionRemoteNumber='' remoteNotify=''
if [ "$B_UPDATE_NOTIFIER" == 'true' ];then
versionRemote=$( check_remote_version )
versionRemoteDate=$( cut -d ':' -f 2 <<< $versionRemote )
versionRemoteNumber=$( cut -d ':' -f 1 <<< $versionRemote )
if [ "$versionRemoteNumber" != "$SCRIPT_VERSION_NUMBER" ];then
remoteNotify='echo " ${M}(Newer version available: ${C}$versionRemoteNumber${M} Release Date: ${C}$versionRemoteDate${M})${N}"'
fi
fi
if [ "$1" == 'opt' ];then
echo $LINE
echo "$SCRIPT_NAME - the universal, portable, system backup script."
echo "Version: $SCRIPT_VERSION_NUMBER"
echo "Script Last Modified: $last_modified"
echo "Script Location: $SCRIPT_PATH${N}"
print_history_data
elif [ "$1" == 'main' ];then
echo " ${C}$SCRIPT_NAME${S} ${M}:: Version: ${C}$SCRIPT_VERSION_NUMBER${S} ${M}:: Released: ${C}$last_modified${N}"
eval "$remoteNotify"
fi
}
# args: $1 - download url, not including file name; $2 - string to print out
# note that $1 must end in / to properly construct the url path
script_self_updater()
{
local wget_error=0
local ua='-U s-tools/rbxi.updater'
echo "Starting $SCRIPT_NAME self updater."
echo "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
echo "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
# first test if path is good, need to make sure it's good because we're -O overwriting file
wget -q --spider $1$SCRIPT_NAME || wget_error=$?
# then do the actual download
if [[ $wget_error -eq 0 ]];then
wget $ua -q -O $SCRIPT_PATH/$SCRIPT_NAME $1$SCRIPT_NAME || wget_error=$?
if [[ $wget_error -eq 0 ]];then
SCRIPT_VERSION_NUMBER=$( grep -im 1 'version:' $SCRIPT_PATH/$SCRIPT_NAME | awk '{print $3}' )
echo "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
echo "To run the new version, just start $SCRIPT_NAME again."
exit 0
fi
fi
# now run the error handlers on any wget failure
if [[ $wget_error -gt 0 ]];then
if [[ $2 == 'svn server' ]];then
error_handler 8 "$wget_error"
elif [[ $2 == 'alt server' ]];then
error_handler 10 "$1"
else
error_handler 12 "$1"
fi
fi
}
show_script_readme()
{
local browser='' browser_path=''
for browser in $CONSOLE_BROWSER links2 elinks w3m links lynx
do
if [ -n "$( which $browser )" ];then
browser_path=$( which $browser )
break
fi
done
if [ -n "$browser_path" ];then
$browser_path $SCRIPT_PATH$SCRIPT_DATA$SCRIPT_README
else
error_handler 32
fi
}
# creates the spinning wheel if script starts with -s option, and shows completion
spinning_wheel_activity_indicator()
{
local completionText=''
if [ "$1" == 'delete' ];then
completionText='backup directories removed'
fi
if [ "$1" == 'backup' ];then
completionText="$2 backed up"
fi
echo -n ${S}
# while kill -0 $GET_PID
while [ -e /proc/$GET_PID ]
do
sleep $SLEEP_TIME_SPINNER
echo -n '|'
echo -ne "\b"
sleep $SLEEP_TIME_SPINNER
echo -n '/'
echo -ne "\b"
sleep $SLEEP_TIME_SPINNER
echo -n '-'
echo -ne "\b"
sleep $SLEEP_TIME_SPINNER
echo -n "\\"
echo -ne "\b"
done
echo -ne "\b $completionText"
echo ${N}
}
# args: $1 umount/
trap_handler()
{
local i=''
case "$1" in
umount)
echo
echo "${S}You are leaving $SCRIPT_NAME with the backup partition still mounted!"
echo "Waiting a few seconds to let disk writes sync before exiting...${N}"
# give the disk time sync its writes before umount...
# set in rbxi-values if you need to increase or decrease the time for premature
# or forced script exit for umount operation to work successfully.
for (( i=0; i < $SLEEP_TIME_UMOUNT; i++ ))
do
echo -n "${M}...tick${N}"
sleep $i
done
echo "${M}...done!${N}"
umount_backup_disk
run_pre_post_tasks 'post-umount'
# set trap to null to avoid loops for final exits
trap - INT TERM EXIT
error_handler 50
;;
esac
}
#### -------------------------------------------------------------------
#### basic tests
#### -------------------------------------------------------------------
# this will load/test anything that is required
check_script_requires()
{
# this test handles three cases:
# 1: constructing a path with possibly user hard-coded value for SCRIPT_PATH fails
# 2: constructing the path with dirname and rbxi-data fails to detect a directory
# 3: lsof does not exit in system
if [ ! -d "$SCRIPT_PATH$SCRIPT_DATA" ] && [ ! -d "$( dirname $0 )$SCRIPT_DATA" ] && ! type $LSOF &>/dev/null;then
error_handler 23 'lsof'
fi
## add in user variable values, sticky value file
if [ ! -f "$SCRIPT_DATA_DIR$SCRIPT_VALUES" ];then
error_handler 22
fi
}
check_is_root()
{
if [ "$( whoami )" != "root" ];then
error_handler 4
fi
}
check_startup_stuff()
{
check_is_root
create_etc_configs
check_bu_app_installed
if [ "$B_CLEAN_OLDER" == 'true' -a "$B_DELETE_BACKUP" == 'true' ];then
error_handler 15
fi
if [ "$B_VARIABLES_SET" != 'true' ];then
error_handler 16
fi
if [ "$B_IS_CLONE" == 'true' -a "$BACKUP_APP" != 'rsync' ];then
error_handler 19
fi
}
check_script_path()
{
local ExDir=$( dirname $0 )
if [ "$( pwd )" != "$ExDir" -a "$ExDir" != '.' ];then
cd $ExDir
fi
}
check_script_changes()
{
local oldBuMount='BACKUP_DIRECTORY'
local oldBuMountSub='BACKUP_SUB_DIR'
local updateBuMount=$( egrep "($oldBuMount|$oldBuMountSub)" $SCRIPT_DATA_DIR$SCRIPT_VALUES $SCRIPT_DATA_DIR$SCRIPT_README )
if [ -n "$updateBuMount" ];then
echo "${S}Updating your $SCRIPT_VALUES $SCRIPT_README files to use new variable names:"
echo "BACKUP_MOUNT_POINT replaces BACKUP_DIRECTORY"
echo "BACKUP_MOUNT_POINT_DIRECTORY replaces BACKUP_SUB_DIR"
echo "Please restart $SCRIPT_NAME after this is completed.${N}"
sed -i 's/BACKUP_DIRECTORY/BACKUP_MOUNT_POINT/g' $SCRIPT_DATA_DIR$SCRIPT_VALUES $SCRIPT_DATA_DIR$SCRIPT_README
sed -i 's/BACKUP_SUB_DIR/BACKUP_MOUNT_POINT_DIRECTORY/g' $SCRIPT_DATA_DIR$SCRIPT_VALUES $SCRIPT_DATA_DIR$SCRIPT_README
sed -i 's/2\.5\.[0-1]/2.5.2/g' $SCRIPT_DATA_DIR$SCRIPT_VALUES $SCRIPT_DATA_DIR$SCRIPT_README
echo "${S}Updated and exiting. Please restart $SCRIPT_NAME, sorry for the inconvenience.${N}"
exit 0
fi
}
check_bu_app_installed()
{
local pathExists='' appToCheck=''
# this must set error to /dev/null to avoid false positive in some cases
local appWhich="$( which $BACKUP_APP )"
# more handling is required for cron jobs, which might not show which output
case $BACKUP_APP in
rdiff-backup)
appToCheck=$RDIFF_PATH
;;
rsync)
appToCheck=$RSYNC_PATH
;;
esac
# checking the actual paths here, not relying on unreliable which output
if [ ! -x "$appWhich" -a ! -x $appToCheck ];then
error_handler 14 $BACKUP_APP
fi
}
# check to see if its' a local or remote directory
# args: $1 - directory path, check for :/ or @
check_directory_remote()
{
local isRemote=$( grep -E '(:/)' <<< "$1" )
if [ -d "$1" -o -n "$isRemote" ];then
return 0
else
return 1
fi
}
# args: $1 - directory full path to check
check_backup_source_directory()
{
check_directory_remote "$1"
local returnIs="$?"
echo -n "${S}Checking backup source ${C}$1${S}....${N}"
if [ "$returnIs" -eq 0 ];then
echo "${S}....${M}valid${N}"
else
echo "${S}....${W}INVALID${N}"
error_handler 20 "$1"
fi
}
# args: $1 - backup destination local directory
check_backup_destination_directory()
{
check_directory_remote "$1"
local returnIs="$?"
echo -n "${S}Checking backup destination ${C}$1${S}....${N}"
if [ "$returnIs" -eq 0 ];then
echo "${S}....${M}valid${N}"
else
echo "${S}....${W}INVALID${N}"
error_handler 24 "$1"
fi
}
check_remote_version()
{
local versionRemote=''
local ua='-U s-tools/rbxi.rb-version'
# get ip using wget redirect to stdout. This is a clean, text only IP output url.
versionRemote=$( wget $ua -q -O - http://smxi.org/rb/rb-version | grep 'rbxi=' | cut -d '=' -f 2 )
echo "$versionRemote"
}
create_etc_configs()
{
if [ ! -f $SCRIPT_CONFIGS ];then
touch $SCRIPT_CONFIGS
echo 'last-backup-directory=Unset' >> $SCRIPT_CONFIGS
echo 'last-backup-date=Unset' >> $SCRIPT_CONFIGS
echo 'last-backup-duration=Unset' >> $SCRIPT_CONFIGS
fi
if [ -z "$( grep 'rdbu-backup-history=' $SCRIPT_CONFIGS )" ];then
echo 'rdbu-backup-history=Unset' >> $SCRIPT_CONFIGS
fi
if [ -z "$( grep 'rsync-backup-history=' $SCRIPT_CONFIGS )" ];then
echo 'rsync-backup-history=Unset' >> $SCRIPT_CONFIGS
fi
if [ -z "$( grep 'last-backup-app=' $SCRIPT_CONFIGS )" ];then
echo 'last-backup-app=Unset' >> $SCRIPT_CONFIGS
fi
if [ -z "$( grep 'last-backup-job=' $SCRIPT_CONFIGS )" ];then
echo 'last-backup-job=Unset' >> $SCRIPT_CONFIGS
fi
}
#### -------------------------------------------------------------------
#### set data functions - primary, directory, backup commands, mount
#### -------------------------------------------------------------------
# load proper values for locations and command strings
set_primary_backup_data()
{
case "$BACKUP_APP" in
rsync)
# update global file names.
# First make sure no user error with the directory name occured with options
if [ -z "$BACKUP_MOUNT_POINT_RS" ];then
error_handler 18 'BACKUP_MOUNT_POINT_RS'
fi
# then remove this data, since we only use the primary directories
if [ "$B_IS_CLONE" == 'true' ];then
BACKUP_MOUNT_POINT_DIRECTORY_RS=''
fi
# note: these values were set in set_backup_mount_point
# and set_backup_mount_point_directory if -B or -D were used
# note: this is required for mounts
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_RS
BACKUP_LOCATION=$BACKUP_MOUNT_POINT_RS$BACKUP_MOUNT_POINT_DIRECTORY_RS
EXCLUDE_ROOT=$EXCLUDE_ROOT_RS
EXCLUDE_HOME=$EXCLUDE_HOME_RS
EXCLUDE_DATA_1=$EXCLUDE_DATA_1_RS
EXCLUDE_DATA_2=$EXCLUDE_DATA_2_RS
EXCLUDE_DATA_3=$EXCLUDE_DATA_3_RS
EXCLUDE_DATA_4=$EXCLUDE_DATA_4_RS
EXCLUDE_DATA_5=$EXCLUDE_DATA_5_RS
EXCLUDE_DATA_6=$EXCLUDE_DATA_6_RS
EXCLUDE_DATA_7=$EXCLUDE_DATA_7_RS
EXCLUDE_DATA_8=$EXCLUDE_DATA_8_RS
EXCLUDE_DATA_9=$EXCLUDE_DATA_9_RS
EXCLUDE_DATA_10=$EXCLUDE_DATA_10_RS
;;
rdiff-backup)
# First make sure no user error with the directory name occured with options
if [ -z "$BACKUP_MOUNT_POINT" ];then
error_handler 18 'BACKUP_MOUNT_POINT'
fi
BACKUP_LOCATION=$BACKUP_MOUNT_POINT$BACKUP_MOUNT_POINT_DIRECTORY
;;
esac
if [ -z "$BACKUP_LOCATION" ];then
error_handler 19
fi
check_backup_destination_directory "$BACKUP_MOUNT_POINT"
}
# these will be tested in the actual backup function for exist if local, or
# if have remote path syntax. rsync/rdiff will handle bad paths for remote
# destination directories.
# create backup directory then set backup directory names
set_backup_destination_data()
{
local month=$( date +%m )
# assemble the backup paths, if they are clones sub directory can be null
HOME_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$HOME_DIR" )
ROOT_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$ROOT_DIR" )
DATA_1_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_1_DIR" )
DATA_2_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_2_DIR" )
DATA_3_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_3_DIR" )
DATA_4_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_4_DIR" )
DATA_5_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_5_DIR" )
DATA_6_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_6_DIR" )
DATA_7_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_7_DIR" )
DATA_8_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_8_DIR" )
DATA_9_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_9_DIR" )
DATA_10_BACKUP=$( set_backup_destination_path "$BACKUP_LOCATION" "$DATA_10_DIR" )
}
# This makes sure that ending slashes do not occur in backup directory paths.
# args: $1 - $BACKUP_LOCATION; $2 - backup subdirectory. If null, use just use $1
set_backup_destination_path()
{
local backupPath=$1
if [ -n "$2" ];then
backupPath="$backupPath/$2"
fi
echo $backupPath
}
set_backup_commands()
{
local dryRun='' options=''
case "$BACKUP_APP" in
rsync)
if [ "$B_CLEAN_OLDER" == 'true' ];then
RSYNC_DELETE=' --delete --delete-excluded '
fi
if [ "$B_DRY_RUN" == 'true' ];then
dryRun=' --dry-run '
fi
# set commands
# note: extra options must END with ssh connection string
# NOTE: -a = -rlptgoD
# --acls only if needed
options=" --hard-links --xattrs --sparse --numeric-ids --times -a $dryRun $RSYNC_DELETE $RSYNC_EXTRA_OPTIONS"
HOME_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_HOME $options $HOME_PATH $HOME_BACKUP"
ROOT_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_ROOT $options $ROOT_PATH $ROOT_BACKUP"
DATA_1_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_1 $options $DATA_1_PATH $DATA_1_BACKUP"
DATA_2_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_2 $options $DATA_2_PATH $DATA_2_BACKUP"
DATA_3_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_3 $options $DATA_3_PATH $DATA_3_BACKUP"
DATA_4_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_4 $options $DATA_4_PATH $DATA_4_BACKUP"
DATA_5_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_5 $options $DATA_5_PATH $DATA_5_BACKUP"
DATA_6_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_6 $options $DATA_6_PATH $DATA_6_BACKUP"
DATA_7_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_7 $options $DATA_7_PATH $DATA_7_BACKUP"
DATA_8_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_8 $options $DATA_8_PATH $DATA_8_BACKUP"
DATA_9_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_9 $options $DATA_9_PATH $DATA_9_BACKUP"
DATA_10_BU_COMMAND="$RSYNC_PATH --exclude-from=$SCRIPT_DATA_DIR$EXCLUDE_DATA_10 $options $DATA_10_PATH $DATA_10_BACKUP"
# set text
BACKUP_CLEAR='Backing up'
# reset to false so main backup function can finish up
B_CLEAN_OLDER='false'
;;
rdiff-backup)
# set commands
# http://www.mail-archive.com/rdiff-backup-users@nongnu.org/msg01212.html
# --exclude-sockets to get rid of that dumb socket error
if [ "$B_CLEAN_OLDER" != 'true' ];then
# set commands
options=" --exclude-sockets $RDIFF_EXTRA_OPTIONS "
HOME_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_HOME $HOME_PATH $HOME_BACKUP"
ROOT_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_ROOT $ROOT_PATH $ROOT_BACKUP"
DATA_1_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_1 $DATA_1_PATH $DATA_1_BACKUP"
DATA_2_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_2 $DATA_2_PATH $DATA_2_BACKUP"
DATA_3_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_3 $DATA_3_PATH $DATA_3_BACKUP"
DATA_4_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_4 $DATA_4_PATH $DATA_4_BACKUP"
DATA_5_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_5 $DATA_5_PATH $DATA_5_BACKUP"
DATA_6_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_6 $DATA_6_PATH $DATA_6_BACKUP"
DATA_7_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_7 $DATA_7_PATH $DATA_7_BACKUP"
DATA_8_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_8 $DATA_8_PATH $DATA_8_BACKUP"
DATA_9_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_9 $DATA_9_PATH $DATA_9_BACKUP"
DATA_10_BU_COMMAND="$RDIFF_PATH $options --exclude-globbing-filelist $SCRIPT_DATA_DIR$EXCLUDE_DATA_10 $DATA_10_PATH $DATA_10_BACKUP"
# set text
BACKUP_CLEAR='Backing up'
else
# set commands
options=" --force --remove-older-than $RDIFF_REMOVE_TIME "
HOME_BU_COMMAND="$RDIFF_PATH $options $HOME_BACKUP"
ROOT_BU_COMMAND="$RDIFF_PATH $options $RDIFF_REMOVE_TIME $ROOT_BACKUP"
DATA_1_BU_COMMAND="$RDIFF_PATH $options $DATA_1_BACKUP"
DATA_2_BU_COMMAND="$RDIFF_PATH $options $DATA_2_BACKUP"
DATA_3_BU_COMMAND="$RDIFF_PATH $options $DATA_3_BACKUP"
DATA_4_BU_COMMAND="$RDIFF_PATH $options $DATA_4_BACKUP"
DATA_5_BU_COMMAND="$RDIFF_PATH $options $DATA_5_BACKUP"
DATA_6_BU_COMMAND="$RDIFF_PATH $options $DATA_6_BACKUP"
DATA_7_BU_COMMAND="$RDIFF_PATH $options $DATA_7_BACKUP"
DATA_8_BU_COMMAND="$RDIFF_PATH $options $DATA_8_BACKUP"
DATA_9_BU_COMMAND="$RDIFF_PATH $options $DATA_9_BACKUP"
DATA_10_BU_COMMAND="$RDIFF_PATH $options $DATA_10_BACKUP"
# set text
BACKUP_CLEAR="Removing all increments older than $RDIFF_REMOVE_TIME from"
fi
;;
esac
}
# all error null directory handling is done in the final set_primary_backup_data function
# args: $1 - backup directory number
set_backup_mount_point()
{
case $1 in
1)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_1
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_1_RS
;;
2)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_2
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_2_RS
;;
3)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_3
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_3_RS
;;
4)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_4
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_4_RS
;;
5)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_5
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_5_RS
;;
6)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_6
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_6_RS
;;
7)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_7
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_7_RS
;;
8)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_8
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_8_RS
;;
9)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_9
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_9_RS
;;
10)
BACKUP_MOUNT_POINT=$BACKUP_MOUNT_POINT_10
BACKUP_MOUNT_POINT_RS=$BACKUP_MOUNT_POINT_10_RS
;;
esac
}
# args: $1 - backup directory number
set_backup_mount_point_directory()
{
case $1 in
1)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_1
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_1_RS
;;
2)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_2
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_2_RS
;;
3)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_3
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_3_RS
;;
4)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_4
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_4_RS
;;
5)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_5
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_5_RS
;;
6)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_6
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_6_RS
;;
7)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_7
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_7_RS
;;
8)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_8
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_8_RS
;;
9)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_9
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_9_RS
;;
10)
BACKUP_MOUNT_POINT_DIRECTORY=$BACKUP_MOUNT_POINT_DIRECTORY_10
BACKUP_MOUNT_POINT_DIRECTORY_RS=$BACKUP_MOUNT_POINT_DIRECTORY_10_RS
;;
esac
}
# args: $1 - data in format: x:y:z where x/y/z are null or 1-5
set_emailer_data(){
local emailStart=$( cut -d ':' -f 1 <<< $1 )
local emailFinish=$( cut -d ':' -f 2 <<< $1 )
local emailError=$( cut -d ':' -f 3 <<< $1 )
if [ -n "$emailStart" ];then
case $emailStart in
1)
EMAIL_START_ACTION="$EMAIL_START_ACTION_1"
;;
2)
EMAIL_START_ACTION="$EMAIL_START_ACTION_2"
;;
3)
EMAIL_START_ACTION="$EMAIL_START_ACTION_3"
;;
4)
EMAIL_START_ACTION="$EMAIL_START_ACTION_4"
;;
5)
EMAIL_START_ACTION="$EMAIL_START_ACTION_5"
;;
6)
EMAIL_START_ACTION="$EMAIL_START_ACTION_6"
;;
7)
EMAIL_START_ACTION="$EMAIL_START_ACTION_7"
;;
8)
EMAIL_START_ACTION="$EMAIL_START_ACTION_8"
;;
9)
EMAIL_START_ACTION="$EMAIL_START_ACTION_9"
;;
10)
EMAIL_START_ACTION="$EMAIL_START_ACTION_10"
;;
esac
fi
if [ -n "$emailFinish" ];then
case $emailFinish in
1)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_1"
;;
2)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_2"
;;
3)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_3"
;;
4)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_4"
;;
5)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_5"
;;
6)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_6"
;;
7)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_7"
;;
8)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_8"
;;
9)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_9"
;;
10)
EMAIL_FINISH_ACTION="$EMAIL_FINISH_ACTION_10"
;;
esac
fi
if [ -n "$emailError" ];then
case $emailError in
1)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_1"
;;
2)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_2"
;;
3)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_3"
;;
4)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_4"
;;
5)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_5"
;;
6)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_6"
;;
7)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_7"
;;
8)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_8"
;;
9)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_9"
;;
10)
EMAIL_ERROR_ACTION="$EMAIL_ERROR_ACTION_10"
;;
esac
fi
}
# args: $1 - mount number
set_mount_data()
{
case $1 in
1)
MOUNT_BU_DISK=$MOUNT_BU_DISK_1
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_1
;;
2)
MOUNT_BU_DISK=$MOUNT_BU_DISK_2
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_2
;;
3)
MOUNT_BU_DISK=$MOUNT_BU_DISK_3
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_3
;;
4)
MOUNT_BU_DISK=$MOUNT_BU_DISK_4
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_4
;;
5)
MOUNT_BU_DISK=$MOUNT_BU_DISK_5
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_5
;;
6)
MOUNT_BU_DISK=$MOUNT_BU_DISK_6
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_6
;;
7)
MOUNT_BU_DISK=$MOUNT_BU_DISK_7
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_7
;;
8)
MOUNT_BU_DISK=$MOUNT_BU_DISK_8
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_8
;;
9)
MOUNT_BU_DISK=$MOUNT_BU_DISK_9
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_9
;;
10)
MOUNT_BU_DISK=$MOUNT_BU_DISK_10
UNMOUNT_BU_DISK=$UNMOUNT_BU_DISK_10
;;
esac
}
# args: $1 - backup job number; $2 - set/print
set_or_print_backup_job()
{
local backupJob='' backupJobData='' backupJobName=''
case $1 in
1)
backupJob="$BACKUP_JOB_1"
;;
2)
backupJob="$BACKUP_JOB_2"
;;
3)
backupJob="$BACKUP_JOB_3"
;;
4)
backupJob="$BACKUP_JOB_4"
;;
5)
backupJob="$BACKUP_JOB_5"
;;
6)
backupJob="$BACKUP_JOB_6"
;;
7)
backupJob="$BACKUP_JOB_7"
;;
8)
backupJob="$BACKUP_JOB_8"
;;
9)
backupJob="$BACKUP_JOB_9"
;;
10)
backupJob="$BACKUP_JOB_10"
;;
esac
if [ -n "$( grep ':' <<< $backupJob )" ];then
backupJobData=$( cut -d ':' -f 2-20 <<< $backupJob )
BACKUP_JOB_NAME=$( cut -d ':' -f 1 <<< $backupJob )
else
backupJobData=$backupJob
fi
if [ -n "$BACKUP_JOB_NAME" ];then
backupJobName=" ${C}$BACKUP_JOB_NAME${S}"
fi
# make sure the job has content
if [ -n "$backupJob" -a "$backupJob" != ':' ];then
if [ "$2" == 'set' ];then
echo "${S}Your job presets are: ${C}$backupJobData"
echo "${S}Restarting $SCRIPT_NAME to run backup job$backupJobName (Job No. ${C}$1${S}) now...${N}"
echo $LINE
sleep 1
exec $SCRIPT_PATH/$SCRIPT_NAME -z $1 $backupJobData
exit 0
elif [ "$2" == 'print' ];then
echo "${M}You are currently about to run backup job number: ${C}$BACKUP_JOB_NU"
echo "${S}Your job$backupJobName (Job No. ${C}$1${S}) presets are: ${C}$backupJobData${N}"
fi
else
error_handler 17 "$1"
fi
}
# args: $1 - data in format: x:y:z where x/y/z are null or 1-5
set_pre_post_data(){
local preMount=$( cut -d ':' -f 1 <<< $1 )
local postMount=$( cut -d ':' -f 2 <<< $1 )
local postUmount=$( cut -d ':' -f 3 <<< $1 )
if [ -n "$preMount" ];then
case $preMount in
1)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_1"
;;
2)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_2"
;;
3)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_3"
;;
4)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_4"
;;
5)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_5"
;;
6)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_6"
;;
7)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_7"
;;
8)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_8"
;;
9)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_9"
;;
10)
PRE_MOUNT_FUNCTION="$PRE_MOUNT_FUNCTION_10"
;;
esac
fi
if [ -n "$postMount" ];then
case $postMount in
1)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_1"
;;
2)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_2"
;;
3)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_3"
;;
4)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_4"
;;
5)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_5"
;;
6)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_6"
;;
7)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_7"
;;
8)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_8"
;;
9)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_9"
;;
10)
POST_MOUNT_FUNCTION="$POST_MOUNT_FUNCTION_10"
;;
esac
fi
if [ -n "$postUmount" ];then
case $postUmount in
1)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_1"
;;
2)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_2"
;;
3)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_3"
;;
4)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_4"
;;
5)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_5"
;;
6)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_6"
;;
7)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_7"
;;
8)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_8"
;;
9)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_9"
;;
10)
POST_UMOUNT_FUNCTION="$POST_UMOUNT_FUNCTION_10"
;;
esac
fi
}
#### -------------------------------------------------------------------
#### set add, skip, clone data
#### -------------------------------------------------------------------
# remember, -A overrides -S if they are the same SKIP item.
# args: $1 - items to add, loops through all.
set_add_data()
{
local addItem=''
for addItem in $1
do
case $addItem in
d)
B_SKIP_DATA_FULL='false'
B_SKIP_DATA_1='false'
B_SKIP_DATA_2='false'
B_SKIP_DATA_3='false'
B_SKIP_DATA_4='false'
B_SKIP_DATA_5='false'
B_SKIP_DATA_6='false'
B_SKIP_DATA_7='false'
B_SKIP_DATA_8='false'
B_SKIP_DATA_9='false'
B_SKIP_DATA_10='false'
;;
h)
B_SKIP_HOME='false'
;;
r)
B_SKIP_ROOT='false'
;;
rh|hr)
B_SKIP_HOME='false'
B_SKIP_ROOT='false'
;;
# note that B_SKIP_DATA_FULL='false' is required
# to override the block off switch for DATA
1)
B_SKIP_DATA_1='false'
B_SKIP_DATA_FULL='false'
;;
2)
B_SKIP_DATA_2='false'
B_SKIP_DATA_FULL='false'
;;
3)
B_SKIP_DATA_3='false'
B_SKIP_DATA_FULL='false'
;;
4)
B_SKIP_DATA_4='false'
B_SKIP_DATA_FULL='false'
;;
5)
B_SKIP_DATA_5='false'
B_SKIP_DATA_FULL='false'
;;
6)
B_SKIP_DATA_6='false'
B_SKIP_DATA_FULL='false'
;;
7)
B_SKIP_DATA_7='false'
B_SKIP_DATA_FULL='false'
;;
8)
B_SKIP_DATA_8='false'
B_SKIP_DATA_FULL='false'
;;
9)
B_SKIP_DATA_9='false'
B_SKIP_DATA_FULL='false'
;;
10)
B_SKIP_DATA_10='false'
B_SKIP_DATA_FULL='false'
;;
esac
done
}
# args: $1 - directory/ies to be cloned
set_clone_data()
{
case $1 in
h)
B_CLONE_HOME='true'
HOME_DIR='home'
B_SKIP_DATA_FULL='true'
B_SKIP_ROOT='true'
CLONE_SOURCE_DIR=$HOME_PATH
;;
r)
B_CLONE_ROOT='true'
ROOT_DIR=''
B_SKIP_DATA_FULL='true'
B_SKIP_HOME='true'
CLONE_SOURCE_DIR=$ROOT_PATH
;;
1)
set_clone_skip_data
B_CLONE_DATA_1='true'
DATA_1_DIR=''
CLONE_SOURCE_DIR=$DATA_1_PATH
;;
2)
set_clone_skip_data
B_CLONE_DATA_2='true'
DATA_2_DIR=''
CLONE_SOURCE_DIR=$DATA_2_PATH
;;
3)
set_clone_skip_data
B_CLONE_DATA_3='true'
DATA_3_DIR=''
CLONE_SOURCE_DIR=$DATA_3_PATH
;;
4)
set_clone_skip_data
B_CLONE_DATA_4='true'
DATA_4_DIR=''
CLONE_SOURCE_DIR=$DATA_4_PATH
;;
5)
set_clone_skip_data
B_CLONE_DATA_5='true'
DATA_5_DIR=''
CLONE_SOURCE_DIR=$DATA_5_PATH
;;
6)
set_clone_skip_data
B_CLONE_DATA_6='true'
DATA_6_DIR=''
CLONE_SOURCE_DIR=$DATA_6_PATH
;;
7)
set_clone_skip_data
B_CLONE_DATA_7='true'
DATA_7_DIR=''
CLONE_SOURCE_DIR=$DATA_7_PATH
;;
8)
set_clone_skip_data
B_CLONE_DATA_8='true'
DATA_8_DIR=''
CLONE_SOURCE_DIR=$DATA_8_PATH
;;
9)
set_clone_skip_data
B_CLONE_DATA_9='true'
DATA_9_DIR=''
CLONE_SOURCE_DIR=$DATA_9_PATH
;;
10)
set_clone_skip_data
B_CLONE_DATA_10='true'
DATA_10_DIR=''
CLONE_SOURCE_DIR=$DATA_10_PATH
;;
esac
# make sure no user error occured
check_backup_source_directory "$CLONE_SOURCE_DIR"
}
# set all data to false except for
# explicitly set clone item and FULL
set_clone_skip_data()
{
B_SKIP_DATA_FULL='false'
B_SKIP_DATA_1='true'
B_SKIP_DATA_2='true'
B_SKIP_DATA_3='true'
B_SKIP_DATA_4='true'
B_SKIP_DATA_5='true'
B_SKIP_DATA_6='true'
B_SKIP_DATA_7='true'
B_SKIP_DATA_8='true'
B_SKIP_DATA_9='true'
B_SKIP_DATA_10='true'
B_SKIP_HOME='true'
B_SKIP_ROOT='true'
}
# remember, -A overrides -S if they are the same SKIP item.
# args: $1 - items to skip, loops through all.
set_skip_data()
{
local skipItem=''
for skipItem in $1
do
case $skipItem in
d)
B_SKIP_DATA_FULL='true'
;;
h)
B_SKIP_HOME='true'
;;
r)
B_SKIP_ROOT='true'
;;
rh|hr)
B_SKIP_HOME='true'
B_SKIP_ROOT='true'
;;
1)
B_SKIP_DATA_1='true'
;;
2)
B_SKIP_DATA_2='true'
;;
3)
B_SKIP_DATA_3='true'
;;
4)
B_SKIP_DATA_4='true'
;;
5)
B_SKIP_DATA_5='true'
;;
6)
B_SKIP_DATA_6='true'
;;
7)
B_SKIP_DATA_7='true'
;;
8)
B_SKIP_DATA_8='true'
;;
9)
B_SKIP_DATA_9='true'
;;
10)
B_SKIP_DATA_10='true'
;;
esac
done
}
#### -------------------------------------------------------------------
#### primary backup tools
#### -------------------------------------------------------------------
run_backup_question()
{
local opt='' options='' doTheBackup='' removeBackup='' repeat=''
local removeDeleteOpt='' nullCloneSource='' cloneSource='' rsyncSim1=' backup' rsyncSim2=''
# need to check destination data here, after mount, but not need to recheck if same as
# initial
if [ "$BACKUP_LOCATION" != "$BACKUP_MOUNT_POINT" ];then
check_backup_destination_directory "$BACKUP_LOCATION"
fi
echo $MLINE
print_version_info 'main'
echo $MLINE
echo "${M}Working backup location: ${C}$BACKUP_LOCATION${N}"
echo $MLINE
print_history_data 'main'
echo $MLINE
if [ "$BACKUP_JOB_NU" != 'none' ];then
set_or_print_backup_job "$BACKUP_JOB_NU" 'print'
echo $LINE
fi
if [ "$BACKUP_APP" == 'rsync' ] && [ "$B_DRY_RUN" == 'true' -o -n "$( grep 'dry-run' <<< $RSYNC_EXTRA_OPTIONS )" ];then
echo "${M}You are using the ${C}rsync --dry-run${M} option, which simulates your backup."
echo "${S}This option lets you see what would happen, before you really run the backup."
echo $LINE
rsyncSim1=" ${C}simulate${S} the backup of"
rsyncSim2=" ${C}simulation${M} of a"
fi
if [ "$B_IS_CLONE" == 'true' ];then
if [ -z "$CLONE_SOURCE_DIR" ];then
nullCloneSource='echo -e "${M}Your Clone Source Directory is ${W}empty${M}.${S} Unless you are cloning ${C}root${S}, this is\nprobably a mistake. Make sure this is correct before you proceed please.\n"'
cloneSource='empty'
else
cloneSource=$CLONE_SOURCE_DIR
fi
echo "${M}You are about to run a$rsyncSim2 direct ${C}Clone job${M} (${C}-C${M}) using these directories:${S}"
echo "Source Directory: ${C}$cloneSource${S} :: Destination Directory: ${C}$BACKUP_MOUNT_POINT"
echo
eval "$nullCloneSource"
echo "${S}Cloning will sync all destination files with your source directory files, and remove"
echo "any obsolete files from the destination directory. ${W}BE CAREFUL WITH THIS!!!"
echo $LINE
echo "${C}1 - run-clone-job${S} - Clones the above Source Data to Destination directory."
echo
echo "${C}2 - quit${S} - Don't do the Clone after all, exit script."
options="run-clone-job quit"
else
case "$BACKUP_APP" in
rdiff-backup)
echo "${S}Backups use standard ${C}$BACKUP_APP${S} settings, which lets you restore from any time"
echo "period stored in the full backup. After first full backup, the next ones will be"
echo "incremental backups, which run much faster since they only backup changed files."
;;
rsync)
echo "${S}This will$rsyncSim1 your system to the backup directories you have already"
echo "set up for your ${C}$BACKUP_APP${S} backup."
;;
esac
echo $LINE
echo "${S}Please select one of the following numbers to assign the correct backup option."
echo "${C}1 - backup-normal${S} - Backs up as usual with $BACKUP_APP. Does not remove old backups."
case "$BACKUP_APP" in
rdiff-backup)
echo "${C}2 - clean-older${S} - Removes all backup increments older than your time setting: $RDIFF_REMOVE_TIME"
echo " After the cleanup, runs a new standard backup."
removeDeleteOpt='clean-older'
;;
rsync)
echo "${C}2 - clean-obsolete${S} - Removes all backed up up files that have been deleted from"
echo " your current install."
removeDeleteOpt='clean-obsolete'
;;
esac
echo "${C}3 - backup-and-delete-old${S} - Backs up but first deletes old backups. This is final, "
echo " so once you agree to remove, no restore of older material will be possible. This will"
echo " delete the backup that corresponds to the currently active primary backup directory."
echo
echo "${C}4 - quit${S} - Don't do the backup after all, exit script."
options="backup-normal $removeDeleteOpt backup-and-delete-old quit"
fi
echo $LINE
select opt in $options
do
log_function_data 'data' "User Option Selection: $opt"
case $opt in
backup-normal)
doTheBackup='true'
;;
backup-and-delete-old)
removeBackup='true'
doTheBackup='true'
;;
# rdiff-backup only
clean-older)
# first get rid of all older files and increments
B_CLEAN_OLDER='true'
run_backup_components
B_CLEAN_OLDER='false'
doTheBackup='true'
;;
# rsync only
clean-obsolete)
B_CLEAN_OLDER='true'
doTheBackup='true'
;;
run-clone-job)
B_CLEAN_OLDER='true'
doTheBackup='true'
;;
quit)
echo "${S}Ok, no backup today, exiting the script...${N}"
exit 0
;;
*)
echo $ELINE
echo "${E}You need to type in one of above the numbers!!${N}"
repeat='true'
;;
esac
break
done
if [ "$repeat" == 'true' ];then
run_backup_question
fi
if [ "$removeBackup" == 'true' ];then
remove_backups
fi
if [ "$doTheBackup" == 'true' ];then
run_backup_components
fi
}
remove_backups()
{
local options='' opt='' repeat='' deleteBackup='' directory='' directories=''
local backupDirectories=$( ls $BACKUP_LOCATION )
# dump line breaks
for directory in $backupDirectories
do
directories="$directories$directory "
done
if [ -z "$backupDirectories" ];then
directories='No Directories to Delete '
fi
echo $LINE
echo "${Q}Are you sure you want to delete the contents of your backup directories?${N}"
echo
echo "${S}These directories will be removed: ${C}$directories${S}in ${C}$BACKUP_LOCATION"
echo
echo "${C}1 - yes-delete${S} - Deletes ALL directories in ${C}$BACKUP_LOCATION"
echo "${C}2 - no-keep${S} - Keeps current data in ${C}$BACKUP_LOCATION${S} and backs up as normal."
echo "${C}3 - quit${S} - Quit, think about it later."
echo $LINE
options='yes-delete no-keep quit'
select opt in $options
do
log_function_data 'data' "User Option Selection: $opt"
case $opt in
yes-delete)
deleteBackup='true'
;;
no-keep)
echo $LINE
echo "${S}Ok, no deleting of them today."
echo
echo "Continuing with backup now...${N}"
;;
quit)
echo "${S}Ok, no backup today, exiting the script...${N}"
exit 0
;;
*)
echo $ELINE
echo "${E}You need to type in one of above the numbers!!${N}"
repeat='true'
;;
esac
break
done
if [ "$repeat" == 'true' ];then
remove_backups
fi
if [ "$deleteBackup" == 'true' ];then
delete_old_backup
fi
}
delete_old_backup()
{
local removedDirectories=$( ls $BACKUP_LOCATION ) directory=''
echo $LINE
if [ -n "$removedDirectories" ];then
log_function_data 'data' "delete_old_backup - Directories to be deleted:\n$removedDirectories"
GET_PID=''
echo -n "${S}Starting deletion of "
for directory in $removedDirectories
do
echo -n "${C}$directory${S} "
done
echo -n "in ${C}$BACKUP_LOCATION${N}"
echo
echo -n "${S}This could take a while, be patient$ENDING_2${N}"
if [ "$B_SPINNING_WHEEL" != 'true' ];then
echo
echo # clear that -n
fi
for directory in $removedDirectories
do
# as ghstryder pointed out, this should also be dry run supporting so people don't
# get unexpected result of deleting their actual backup with -r (--dry-run) option
if [ "$B_DRY_RUN" != 'true' ];then
if [ "$B_SPINNING_WHEEL" == 'true' ];then
rm -fr $BACKUP_LOCATION/$directory &
GET_PID="$!"
spinning_wheel_activity_indicator delete
wait
else
echo -n "${S}Deleting ${C}$BACKUP_LOCATION/$directory${S} now.....${N}"
rm -fr $BACKUP_LOCATION/$directory
echo "${S}... ${M}directory deleted${N}"
fi
else
echo -n "${S}Dry run (${C}-r${S}) emulation mode: Deleting ${C}$BACKUP_LOCATION/$directory${S} now.....${N}"
fi
done
else
echo -n "${M}There is nothing to delete, continuing with backup...${N}"
log_function_data 'data' "delete_old_backup - No Directories to be deleted"
fi
DELETION_TEXT=' deletion and'
echo
echo "${S}Starting backup now...${N}"
sleep $SLEEP_TIME_BACKUP
B_DELETE_STATUS='true'
}
run_backup_components()
{
# set rdiff-backup/rsync commands. Must be here because delete data might be
# set for rsync
set_backup_commands
# If you don't need excludes in /home, then just delete the exclude stuff, --exclude...
echo $LINE
log_function_data 'data' "run_backup_components: begin\n\n"
#backup home directory
if [ "$B_CLONE_HOME" == 'true' ] || [ "$HOME_DIR" != '' -a "$B_SKIP_HOME" != 'true' ];then
check_backup_source_directory "$HOME_PATH"
log_function_data 'data' "Starting Home Backup Command:\n$HOME_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}home${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $HOME_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup home
else
eval $HOME_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Home\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup system root directory
if [ "$B_CLONE_ROOT" == 'true' ] || [ "$ROOT_DIR" != '' -a "$B_SKIP_ROOT" != 'true' ];then
check_backup_source_directory "$ROOT_PATH"
log_function_data 'data' "Starting Root Backup Command:\n$ROOT_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}root${S} directory ${C}$ROOT_DESC${S}$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $ROOT_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $ROOT_DESC
else
eval $ROOT_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Root\n\n"
fi
if [ "$B_SKIP_DATA_FULL" != 'true' ];then
# backup optional user data 1
if [ "$B_CLONE_DATA_1" == 'true' ] || [ "$DATA_1_DIR" != '' -a "$B_SKIP_DATA_1" != 'true' ];then
check_backup_source_directory "$DATA_1_PATH"
log_function_data 'data' "Starting Data 1 Backup Command:\n$DATA_1_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_1_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_1_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_1_DESC
else
eval $DATA_1_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 1\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 2
if [ "$B_CLONE_DATA_2" == 'true' ] || [ "$DATA_2_DIR" != '' -a "$B_SKIP_DATA_2" != 'true' ];then
check_backup_source_directory "$DATA_2_PATH"
log_function_data 'data' "Starting Data 2 Backup Command:\n$DATA_2_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_2_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_2_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_2_DESC
else
eval $DATA_2_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 2\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 3
if [ "$B_CLONE_DATA_3" == 'true' ] || [ "$DATA_3_DIR" != '' -a "$B_SKIP_DATA_3" != 'true' ];then
check_backup_source_directory "$DATA_3_PATH"
log_function_data 'data' "Starting Data 3 Backup Command:\n$DATA_3_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_3_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_3_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_3_DESC
else
eval $DATA_3_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 3\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 4
if [ "$B_CLONE_DATA_4" == 'true' ] || [ "$DATA_4_DIR" != '' -a "$B_SKIP_DATA_4" != 'true' ];then
check_backup_source_directory "$DATA_4_PATH"
log_function_data 'data' "Starting Data 4 Backup Command:\n$DATA_4_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_4_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_4_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_4_DESC
else
eval $DATA_4_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 4\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 5
if [ "$B_CLONE_DATA_5" == 'true' ] || [ "$DATA_5_DIR" != '' -a "$B_SKIP_DATA_5" != 'true' ];then
check_backup_source_directory "$DATA_5_PATH"
log_function_data 'data' "Starting Data 5 Backup Command:\n$DATA_5_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_5_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_5_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_5_DESC
else
eval $DATA_5_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 5\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 2
if [ "$B_CLONE_DATA_6" == 'true' ] || [ "$DATA_6_DIR" != '' -a "$B_SKIP_DATA_6" != 'true' ];then
check_backup_source_directory "$DATA_6_PATH"
log_function_data 'data' "Starting Data 6 Backup Command:\n$DATA_6_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_6_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_6_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_6_DESC
else
eval $DATA_6_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 6\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 7
if [ "$B_CLONE_DATA_7" == 'true' ] || [ "$DATA_7_DIR" != '' -a "$B_SKIP_DATA_7" != 'true' ];then
check_backup_source_directory "$DATA_7_PATH"
log_function_data 'data' "Starting Data 7 Backup Command:\n$DATA_7_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_7_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_7_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_7_DESC
else
eval $DATA_7_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 7\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 8
if [ "$B_CLONE_DATA_8" == 'true' ] || [ "$DATA_8_DIR" != '' -a "$B_SKIP_DATA_8" != 'true' ];then
check_backup_source_directory "$DATA_8_PATH"
log_function_data 'data' "Starting Data 8 Backup Command:\n$DATA_8_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_8_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_8_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_8_DESC
else
eval $DATA_8_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 8\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 9
if [ "$B_CLONE_DATA_9" == 'true' ] || [ "$DATA_9_DIR" != '' -a "$B_SKIP_DATA_9" != 'true' ];then
check_backup_source_directory "$DATA_9_PATH"
log_function_data 'data' "Starting Data 9 Backup Command:\n$DATA_9_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_9_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_9_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_9_DESC
else
eval $DATA_9_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 9\n\n"
sleep $SLEEP_TIME_BACKUP
fi
# backup optional user data 10
if [ "$B_CLONE_DATA_10" == 'true' ] || [ "$DATA_10_DIR" != '' -a "$B_SKIP_DATA_10" != 'true' ];then
check_backup_source_directory "$DATA_10_PATH"
log_function_data 'data' "Starting Data 10 Backup Command:\n$DATA_10_BU_COMMAND"
echo -n "${S}$BACKUP_CLEAR ${C}$DATA_10_DESC${S} directory$ENDING_1${N}"
if [ "$B_SPINNING_WHEEL" == 'true' ];then
GET_PID=''
eval $DATA_10_BU_COMMAND &
GET_PID="$!"
spinning_wheel_activity_indicator backup $DATA_10_DESC
else
eval $DATA_10_BU_COMMAND || error_handler 25 "$?"
echo
fi
log_function_data 'data' "Finished Data 10\n\n"
sleep $SLEEP_TIME_BACKUP
fi
fi
log_function_data 'data' "run_backup_components: end\n$LI\n"
# this is set to false either in the main rsync assigner or by rdiff feature
if [ "$B_CLEAN_OLDER" != 'true' ];then
finish_backup
else
echo $LINE
echo "${S}Ok, finished cleaning up older backup increments, running main backup now...${N}"
sleep $SLEEP_TIME_BACKUP
fi
}
#### -------------------------------------------------------------------
#### Backup start/pre/post/finish functions
#### -------------------------------------------------------------------
mount_backup_disk()
{
local retNu=0
if [ "$MOUNT_BU_DISK" != '' -a "$B_SKIP_MOUNT" != 'true' ];then
# found a possible error case here with null backup directory:
log_function_data 'data' "BACKUP_MOUNT_POINT: $BACKUP_MOUNT_POINT\nMount Data: $MOUNT_BU_DISK"
if [ -z "$BACKUP_MOUNT_POINT" ];then
error_handler 26
fi
echo -n "${S}Mounting backup drive/partition to ${C}$BACKUP_MOUNT_POINT${S}....${N}"
eval $MOUNT_BU_DISK || retNu=$?
if [ "$retNu" -eq 0 ];then
echo "${S}....${M}mounted${N}"
log_function_data 'data' "Mounted"
else
echo "${S}....${W}MOUNT FAILED!${N}"
error_handler 2 "$retNu"
fi
# set the trap here
trap 'trap_handler umount' INT TERM EXIT
fi
}
# args: $1 - start/finish/error; $2 - data to be processed, error message, script start options
run_emailer_tasks()
{
# strip out colors if present
local data=$( echo -e "$2" | sed 's/\x1b\[[0-9]\{1,2\}\(;[0-9]\{1,2\}\)\{0,2\}m//g' )
local actionTime=$( date +"%Y %B %e - %R:%S" )
# then construct the string
data="Rbxi $1: $actionTime\n$data"
# note that the action must be in quotes when you execute it with eval
case $1 in
start)
if [ -n "$EMAIL_START_ACTION" ];then
log_function_data 'data' "Begin emailer task: start action"
echo $LINE
echo "${S}Running user action: ${C}start${N}"
eval "$EMAIL_START_ACTION"
fi
;;
finish)
if [ -n "$EMAIL_FINISH_ACTION" ];then
log_function_data 'data' "Begin emailer task: finish action"
echo $LINE
echo "${S}Running user action: ${C}finish${N}"
eval "$EMAIL_FINISH_ACTION"
fi
;;
error)
if [ -n "$EMAIL_ERROR_ACTION" ];then
log_function_data 'data' "Begin emailer task: error action"
echo $LINE
echo "${S}Running user action: ${C}error${N}"
eval "$EMAIL_ERROR_ACTION"
fi
;;
esac
}
# args: $1 - pre-mount/post-mount/post-umount
run_pre_post_tasks()
{
# note that the function must be in quotes when you declare it with eval
case $1 in
pre-mount)
if [ -n "$PRE_MOUNT_FUNCTION" ];then
log_function_data 'data' "Begin pre post tasks: pre mount function"
echo $LINE
echo "${S}Running user defined function: ${C}pre_mount_tasks()${N}"
eval "$PRE_MOUNT_FUNCTION"
pre_mount_tasks || error_handler 27 "$?"
fi
;;
post-mount)
if [ -n "$POST_MOUNT_FUNCTION" ];then
log_function_data 'data' "Begin pre post tasks: post mount function"
echo $LINE
echo "${S}Running user defined function: ${C}post_mount_tasks()${N}"
eval "$POST_MOUNT_FUNCTION"
post_mount_tasks || error_handler 28 "$?"
fi
;;
post-umount)
if [ -n "$POST_UMOUNT_FUNCTION" ];then
log_function_data 'data' "Begin pre post tasks: error function"
echo $LINE
echo "${S}Running user defined function: ${C}post_umount_tasks()${N}"
eval "$POST_UMOUNT_FUNCTION"
post_umount_tasks || error_handler 29 "$?"
fi
;;
esac
}
#### -------------------------------------------------------------------
#### Backup completion functions
#### -------------------------------------------------------------------
finish_backup()
{
# set the DURATION global here as well prior to updating configs
print_the_end_time
update_configs
umount_backup_disk
run_pre_post_tasks 'post-umount'
print_complete_message
log_function_data 'data' "Backup Job Completed.\n\n"
run_emailer_tasks 'finish' "Completed. Start Options: $SCRIPT_OPTIONS"
}
update_configs()
{
local backupDate=$( date +"%Y-%m-%d - %R" )
local cloneJob='' backupJobName=''
if [ "$B_IS_CLONE" == 'true' -a -n "$CLONE_SOURCE_DIR" ];then
cloneJob=" :: Cloned: $CLONE_SOURCE_DIR"
fi
if [ -n "$BACKUP_JOB_NAME" ];then
backupJobName=" ($BACKUP_JOB_NAME)"
fi
local backupString="Location: $BACKUP_LOCATION :: Date: $backupDate~Run Time: $BACKUP_DURATION :: Deletion: $B_DELETE_STATUS :: Job No: $BACKUP_JOB_NU$backupJobName$cloneJob"
echo $LINE
echo "${S}Updating backup records now...${N}"
sed -i "s%last-backup-directory=.*%last-backup-directory=$BACKUP_LOCATION%" $SCRIPT_CONFIGS
sed -i "s/last-backup-date=.*/last-backup-date=$backupDate/" $SCRIPT_CONFIGS
sed -i "s/last-backup-duration=.*/last-backup-duration=$BACKUP_DURATION/" $SCRIPT_CONFIGS
sed -i "s/last-backup-app=.*/last-backup-app=$BACKUP_APP/" $SCRIPT_CONFIGS
sed -i "s/last-backup-job=.*/last-backup-job=$BACKUP_JOB_NU/" $SCRIPT_CONFIGS
case "$BACKUP_APP" in
rdiff-backup)
sed -i "s%rdbu-backup-history=.*%rdbu-backup-history=$backupString%" $SCRIPT_CONFIGS
;;
rsync)
sed -i "s%rsync-backup-history=.*%rsync-backup-history=$backupString%" $SCRIPT_CONFIGS
;;
esac
log_function_data 'data' "Completed Backup Config Data:\n$( cat $SCRIPT_CONFIGS )\n$LI\n"
}
# do some arithmetic on time
print_the_end_time()
{
local endTime=$( date +%s )
local completedTime=$(( $endTime - $START_TIME ))
local hours=$(( $completedTime / 3600 ))
local remainingMinutes=$(( $completedTime % 3600 ))
local minutes=$(( $remainingMinutes / 60 ))
local seconds=$(( $remainingMinutes % 60 ))
local hourText='' minuteText='' secondText='' plural=''
# set hours, if needed
if [ "$hours" -ne 0 ];then
if [ "$hours" -gt 1 ];then
plural='s'
else
plural=''
fi
hourText=" ${C}$hours${S} hour$plural,"
fi
# set minutes
if [ "$minutes" -gt 1 -o "$minutes" -eq 0 ];then
plural='s'
else
plural=''
fi
minuteText=" ${C}$minutes${S} minute$plural,"
# set seconds
if [ "$seconds" -gt 1 -o "$seconds" -eq 0 ];then
plural='s'
else
plural=''
fi
secondText=" ${C}$seconds${S} second$plural"
echo "${S}The$DELETION_TEXT backup took$hourText$minuteText$secondText to complete.${N}"
# zero pad the data
minutes=$( printf %02d $minutes )
seconds=$( printf %02d $seconds )
BACKUP_DURATION=$hours:$minutes:$seconds
}
umount_backup_disk()
{
local retNu=0
if [ "$MOUNT_BU_DISK" != '' -a "$B_SKIP_MOUNT" != 'true' ];then
log_function_data 'data' "BACKUP_MOUNT_POINT: $BACKUP_MOUNT_POINT\nUmount Data: $UNMOUNT_BU_DISK"
echo
echo -n "${S}Unmounting your backup partition $BACKUP_MOUNT_POINT now...${N}"
eval $UNMOUNT_BU_DISK || retNu=$?
if [ "$retNu" -eq 0 ];then
echo "${S}.....${M}successfully unmounted.${N}"
log_function_data 'data' "Umount successful."
else
echo "${S}.....${W}UMOUNT FAILED!${N}"
error_handler 3 "$retNu"
fi
trap - INT TERM EXIT
fi
}
print_complete_message()
{
echo $MLINE
echo "${M}Ok, all done backing up for today!"
echo $MLINE
}
###################################################################
##### EXECUTE SCRIPT COMPONENTS
###################################################################
set_script_colors
check_script_requires
get_options "$@"
run_emailer_tasks 'start' "Start Options: $SCRIPT_OPTIONS"
# Make sure user is logged in as root first and that backup location is present
check_startup_stuff
log_function_data 'start' "$SCRIPT_OPTIONS"
# this sets the correct startup path so that exclude lists load correctly
check_script_path
# any updates that need to be run will be run here, should only be required
# at rare intervals.
check_script_changes
# set rsync/rdiff-backup variables
set_primary_backup_data
# initialize the backup directory values
set_backup_destination_data
run_pre_post_tasks 'pre-mount'
# then, if you use this, mount your backup drive
mount_backup_disk
run_pre_post_tasks 'post-mount'
# note that this block only runs if the -a,-c, or -d flags are used, or if these
# are set in a job or preset file.
# for option deletion-run/run/clean-run. You can only run one of these, not more.
if [ "$B_DELETE_BACKUP" == 'true' ];then
delete_old_backup
# this is for rdiff only, we need to run first the cleanup job, then
# next send it to the main backup.
elif [ "$B_CLEAN_OLDER" == 'true' -a "$BACKUP_TYPE" == 'rdiff-backup' ];then
run_backup_components
# must reset so we don't run the rdiff-cleanup stuff again
B_CLEAN_OLDER='false'
fi
# skip the intro question and do it automatically
if [ "$B_DO_BACKUP" == 'true' ];then
run_backup_components
# otherwise ask what options to use
else
run_backup_question
fi
## extra information:
#SpecialFileError var/run/acpid.socket Socket error: AF_UNIX path too long
#SpecialFileError var/run/dbus/system_bus_socket Socket error: AF_UNIX path too long
#SpecialFileError var/run/dirmngr/socket Socket error: AF_UNIX path too long
#SpecialFileError var/run/mysqld/mysqld.sock Socket error: AF_UNIX path too long
#SpecialFileError var/run/pcscd.comm Socket error: AF_UNIX path too long
#SpecialFileError var/run/xdmctl/dmctl/socket Socket error: AF_UNIX path too long
#SpecialFileError var/run/xdmctl/dmctl-:0/socket Socket error: AF_UNIX path too long
exit 0
###**EOF**###
syntax highlighted by Code2HTML, v. 0.9.1