#! /bin/bash 
# to run in debug mode: add ' -x' to the above shebang line
#
# N.B.  debug mode trace entries are written to stderr
# 
# ===========================================================================================================================================================================================================
#
# This script is normally invoked automatically by anacron
#
# The anacrontab file includes the following entries - edit with {sudo xed /etc/anacrontab} without the leading'# '
#
# # set standard environment variables
# SHELL=/bin/bash
# PATH=/home/john/live_files/software/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
# HOME=/root
# LOGNAME=root
# #
# # set environment variable to prevent 'Error: Unable to initialize GTK+, is DISPLAY set properly?' when running FreeFileSync
# DISPLAY=:0
# #
# # schedule entry
# 1    30    run_FFS   /home/john/live_files/software/scripts/run_FFS anacronjob
# #
#
# N.B.  Thunderbird is a Startup Application - the 30 minute delay is to allow it to load fully before anacron can initiate an anacronjob
#       and to give time for Firefox manual backups to be taken before an automatic monthly backup is taken
#
# to create a debug file of the run: append appropriate file redirection details to the anacrontab schedule entry - e.g.
#  > /home/john/live_files/backups/crontabs/run_FFS anacronjob_debug 2>&1
#
# =========================================================================================================================================================================================================
#
# This script may also be invoked automatically by cron
#
# The crontab file includes the following entries - edit with {crontab -e} without the leading'# '
#
# # set standard environment variables
# SHELL=/bin/bash
# MAILTO=""
# PATH=/home/john/live_files/software/scripts:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
# #
# # set environment variable to prevent 'Error: Unable to initialize GTK+, is DISPLAY set properly?' when running FreeFileSync
# DISPLAY=:0
# #
# # set environment variable to prevent 'No volume for device file' when running 'gio mount -d' commands
# DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
# #
# # schedule entry
# 30 20 * * * /home/john/live_files/software/scripts/run_FFS cronjob
# #
#
# to create a debug file of the run: append appropriate file redirection details to the crontab schedule entry - e.g.
#  > /home/john/live_files/backups/crontabs/run_FFS cronjob_debug 2>&1
#
# =========================================================================================================================================================================================================
#
# This script can also be invoked manually in a Terminal session by {script_name}{enter} - e.g. run_FFS
#
# The PATH, DISPLAY and DBUS_SESSION_BUS_ADDRESS environment variables are automatically set appropriately in Terminal
#
# to create a debug file of the run: append appropriate file redirection details to the Terminal command entry - e.g.
#  > /home/john/live_files/backups/crontabs/run_FFS manualjob_debug 2>&1
#
# N.B. if the job appears to be hanging in debug mode, check the debug file - the script could be waiting for input - e.g. a read or su command
#
# ===========================================================================================================================================================================================================

# 1) set initial variables
#
# current_dir:      used to return to start directory at end of manual job
# timestamp:        date & time at point of evaluation: yyyy_mm_dd @ hh:mm:ss - used to timestamp log file entries
# call_mode:        indicates whether the script was invoked manually or by (ana)cron - i.e. value of first argument ($1), null default = manualjob - e.g. anacronjob
# log_start:        specifies whether to create the log file (non-spawnedjob) or append to it (spawnedjob)
# script_name:      script's file name, stripped of the directory path - e.g. /home/john/live_files/software/scripts/run_FFS => run_FFS
# current_user:     username of current user
# debug_mode:       indicates whether bash is running in debug mode - i.e. 'on' =>  set -x or shebang with -x; 'off' => set +x or shebang without -x
# std_out:          device (no redirection) or filename (output redirected) of stdout - /dev/pts/0 => no redirection
# std_err:          device (no redirection) or filename (output redirected) of stderr - /dev/pts/0 => no redirection
# auth_user:        username of user permitted to run in non-anacronjob modes - e.g. john
# auth_group:       primary group of auth_user - e.g. john
# auth_home:        home directory of auth_user - e.g /home/john
# live_files_path:  path to live_files directory - e.g. /home/john/live_files
# backups_path:     path to backups directory - e.g. /home/john/live_files/backups
# job_logfile:      fully qualified name of the job log file - e.g. /home/john/live_files/backups/FreeFileSync/run_FFS_log
#
# N.B.  the cut -b2-5 ignores trailing spaces - hence, if running in debug mode, debug_mode will be set to 'on', not 'on '
#

current_dir=$(pwd)
call_mode=manualjob
log_start=''
script_name=$(basename $0)
current_user=$(whoami)
debug_mode=$(set -o | grep xtrace | cut -d ' ' -f 10 | cut -b2-5)
std_out=$(ls -la /proc/$$/fd | grep '1 ->' | cut -d ' ' -f 11)
std_err=$(ls -la /proc/$$/fd | grep '2 ->' | cut -d ' ' -f 11)
auth_user=john
auth_group=$(id -gn $auth_user)
auth_home=/home/$auth_user
live_files_path=$auth_home/live_files
backups_path=$live_files_path/backups
job_logfile=$backups_path/FreeFileSync/$script_name'_log'

if  [ ! -z $1 ]
    then
    call_mode=$1
fi
if  [ $call_mode = spawnedjob ]
    then
    log_start='-a'
fi

# ===========================================================================================================================================================================================================

# 2) create/append the log file & spawn non-root job to replace anacronjob
#
# N.B.  anacron jobs are run by user 'root', which can cause problems with permissions, etc.
#       e.g. creating a log file that $auth_user can't update (hence the 'chown $auth_user:$auth_group $job_logfile')
#
#       so, to avoid problems, an 'anacronjob' job will spawn a non-root version of itself and exit 
#       in effect, the 'spawnedjob' job runs as if it were a 'cronjob'
#
#       cron, manual and spawned jobs are only permitted to be run by $auth_user
#

# 2.1) create/append the log file
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting \in $call_mode mode on $timestamp | tee $log_start $job_logfile
if  [ $debug_mode = 'on' ]
    then
    echo $script_name: \bash debug mode is $debug_mode | tee -a $job_logfile
    if  [ $std_out != '/dev/pts/0' ]
        then
        echo $script_name: stdout is being redirected to $std_out | tee -a $job_logfile
    fi
    if  [ $std_err != '/dev/pts/0' ]
        then  
        echo $script_name: stderr is being redirected to $std_err | tee -a $job_logfile
    fi
fi

# 2.2) spawn non-root version
if  [ $call_mode = anacronjob ]
    then
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: spawning non-root job on $timestamp | tee -a $job_logfile
    echo '' >> $job_logfile
    chown $auth_user:$auth_group $job_logfile
    su -c "$0 spawnedjob &" - $auth_user
    echo ''
#   if bash is running in debug mode the spawned job will continue writing to the anacron job debug file
#   the second echo command will create a blank line between the anacronjob and spawnedjob trace entries
    exit
fi
if  [ $current_user != $auth_user ]
    then
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: $current_user is not permitted to run this script on $timestamp | tee -a $job_logfile
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: ended on $timestamp | tee -a $job_logfile
    exit     
fi

# ===========================================================================================================================================================================================================

# 3) set non-FreeFileSync variables
#
# msf_path:         path to miscellaneous system file backups directory - e.g. /home/john/live_files/backups/misc_sys_files
# tbird_bkp:        set non-null if Thunderbird backup was taken
# tbird_pid:        ID of Thunderbird process - e.g. 1669
# tbird_wid:        ID of main Thunderbird window - e.g. 0x04800010 - 10 characters long
# return_code:      copy of last executed command's exit code
# mount_status:     sum of 'gio mount' return_codes: non-zero => failure
# bkp_1:            name of primary backup partition - e.g. LIgnuX_bkp_1
# bkp_2:            name of seconary backup partition - e.g. LIgnuX_bkp_2
# bkp_1_dev:        device address of primary backup partition - e.g. /dev/sdc1
# bkp_2_dev:        device address of seconary backup partition - e.g. /dev/sdd1
#

msf_path="$backups_path"/misc_sys_files
tbird_bkp=''
tbird_pid=$(pidof thunderbird)
mount_status=0
bkp_1=LIgnuX_bkp_1
bkp_2=LIgnuX_bkp_2
bkp_1_dev=/dev/sdc1
bkp_2_dev=/dev/sdd1

# ===========================================================================================================================================================================================================

# 4) backup Desktop files
#
# Desktop is the only default directory used on this system and is not backed up anywhere else 
#

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: backing up Desktop files on $timestamp | tee -a $job_logfile
cp $auth_home/Desktop/* "$backups_path"/Desktop

# ===========================================================================================================================================================================================================

# 5) backup miscellaneous system files
#
# selected system files are backed up automatically by Timeshift
# /home/john files, including system-generated files, are excluded from the these backups 
#
# to allow for reinstatement, system files which have been specifically modified are also backed up
# the backup paths mirror the original paths - e.g.
# /home/john/.bashrc => /home/john/live_files/backups/misc_sys_files/home/john/.bashrc
# /etc/pulse/daemon.conf => /home/john/live_files/backups/misc_sys_files/etc/pulse/daemon.conf
#

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: backing up miscellaneous system files on $timestamp | tee -a $job_logfile
cp .bashrc "$msf_path"/home/john
cp /etc/fstab "$msf_path"/etc
cp /etc/logrotate.conf "$msf_path"/etc
cp /etc/pulse/daemon.conf "$msf_path"/etc/pulse

# ===========================================================================================================================================================================================================

# 6) close Thunderbird, taking an ImportExportTools backup if due & delete all Thunderbird backups except for the newest
#
# N.B   Thunderbird can have multiple windows - e.g. the main window, a read email window, an ImportExportTools window, etc. 
#       each window will share the same pid but have its own unique wid
#       tbird_wid will initially contain all of these 10 character wids, separated by spaces
#       if more than one window exists then Thunderbird is in use and will not be closed 
#
# Thunderbird is a Startup Application and so will still be running unless it has been closed in the meantime
#
# If Thunderbird is running (tbird_pid non-null) but has more than one window (tbird_wid length != 10)
# the initiate closedown - Ctrl&q - keystroke is not sent
# tbird_pid is set to null to indicate that a backup is not due
#
# If Thunderbird is running (tbird_pid non-null) and has only one window (tbird_wid length = 10)
# the initiate closedown - Ctrl&q - keystroke is sent
# the first ten second sleep allows time for one of the following to occur:
# either, Thunderbird closes - pidof subsequently returns null
# or, Thunderbird doesn't close (because a backup is due) - pidof subsequently returns non-null
# 
# N.B.  the ID of the main Thunderbird window will not have changed
#
# If a backup is due when Thunderbird is closed:
# the ImportExportTools backup prompt window will open
# it will then wait for a cancel/OK selection
# the OK option will have on-screen focus 
# sending a Return keystroke at this point will initiate the backup
#
# The read (manualjob) and 150 second sleep (non-manualjob) allows time for the backup to complete before the live_files FFS copies are taken
# The delays also ensure that the Thunderbird backup file has been created before its directory is checked for tidying
#

# 6.1) close Thunderbird, taking an ImportExportTools backup if due
if  [ ! -z $tbird_pid ]
    then
    tbird_wid=$(wmctrl -lp | grep $tbird_pid | awk -F\  '{ print $1 }')
    if [ ${#tbird_wid} != 10 ]
        then
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)      
        echo $script_name: skipping Thunderbird close - multiple windows open - assumed to be \in use on $timestamp | tee -a $job_logfile
        tbird_pid=''
    else
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: closing Thunderbird on $timestamp | tee -a $job_logfile
        xdotool key --window $tbird_wid --clearmodifiers ctrl+q
        sleep 10
        tbird_pid=$(pidof thunderbird)
    fi
    if  [ ! -z $tbird_pid ]
        then
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: initiating Thunderbird backup on $timestamp | tee -a $job_logfile
        xdotool key --window $tbird_wid --clearmodifiers Return
        tbird_bkp='backup'
        if  tty -s
            then
            read -p "$script_name: press any key once Thunderbird has closed"
        else
            sleep 150
        fi
    fi
fi

# 6.2) delete all Thunderbird backups except for the newest
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: tidying Thunderbird backup files on $timestamp | tee -a $job_logfile
cd "$backups_path"/Thunderbird
ls -1r $backups_path/Thunderbird | awk -F- '$1 == name{system ("rm -fr \""$0"\"")}{name=$1}'

# ===========================================================================================================================================================================================================

# 7) mount backup partitions
#
# N.B.  LIgnuX_bkp_1 and LIgnuX_bkp_2 are permanently connected, on /dev/sdc1 and /dev/sdd1 respectively
#       however, they are only mounted as and when required
#

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: mounting backup partitions on $timestamp | tee -a $job_logfile
gio mount -d $bkp_1_dev
return_code=$?
mount_status=$((mount_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: \mount $bkp_1 return_code = $return_code on $timestamp >> $job_logfile

gio mount -d $bkp_2_dev
return_code=$?
mount_status=$((mount_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: \mount $bkp_2 return_code = $return_code on $timestamp >> $job_logfile

if  [ $mount_status != 0 ]
    then
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: failed to \mount backup partition\(s\) on $timestamp | tee -a $job_logfile
    if  tty -s
        then
        read -p "$script_name: press any key once both backup partitions have been mounted successfully"
        mount_status=0
    else
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: ended on $timestamp | tee -a $job_logfile
        exit
    fi
fi

# ===========================================================================================================================================================================================================

# 8) initialise FreeFileSync variables
#
# 8.1) initialise non-date variables
#
# FFS_exec_path:    path to FreeFileSync executable - e.g. /home/john/live_files/software/FreeFileSync
# FFS_batch_path:   path to FreeFileSync batch configuration files directory - e.g. /home/john/live_files/backups/FreeFileSync/ffs_batch_files
# FFS_status:       sum of FreeFileSync return codes: non-zero => warning(s) and/or error(s)
# $bkp_1_path:      path to primary backup partition - e.g. /media/john/LIgnuX_bkp_1
# $bkp_2_path:      path to secondary backup partition - e.g. /media/john/LIgnuX_bkp_2
# run_status:       sum of FFS backup and unmount return codes: non-zero => warning(s) and/or error(s)
# FFS_logs_path:    path to FreeFileSync log files directory - e.g. /home/john/live_files/backups/FreeFileSync/logs
#

FFS_exec_path=$live_files_path/software/FreeFileSync
FFS_batch_path=$backups_path/FreeFileSync/ffs_batch_files
FFS_status=0
bkp_1_path=/media/$current_user/$bkp_1
bkp_2_path=/media/$current_user/$bkp_2
FFS_logs_path=$backups_path/FreeFileSync/logs

# 8.2) initialise date variables
#
# The following FreeFileSync live_files backups are taken:
# daily:    day_1_Monday .. day_7_Sunday
# weekly:   week_1_of_month .. week_{4 | 5 | 6}_of_month
# monthly:  month_01_January .. month_12_December
# yearly:   year_2019 .. year_nnnn
#
# N.B.  all weeks are ISO, with Monday as the first day of the week
#
#       strictly speaking, there is no need to take a day_1_Monday backup as the script will also take a week_n_of_month backup during the same run
#       however, it's easier accessing last Monday's backup directly than working out last Monday's week_of_month_number (and it keeps the set complete too) 
#
# Were the live_files backups to have day/week/month/year specifiers evaluated at the time the backups are started then the following anomalous situations can arise:
# i)    the daily backup starts shortly before midnight on the final day of a period - e.g. 23:59 on a Sunday - the last day of a weekly period
# ii)   the daily backup ends shortly after midnight on the first day of a new period - e.g. 0:01 on the Monday - the first day of a weekly period
# iii)  the weekly (and/or monthly and/or yearly) backup then runs
# iv.1) the day_1_Monday backup will not match any of the week_n_of_month backups until the next time the day_1_Monday and week_n_of_month backups are taken on the same day
# iv.2) the day_n_dayname backup corresponding to the first day of the new period will not match any of the period backups
#
# To preclude these anomalies, all live_files backups have day/week/month/year specifiers set to correspond to the timestamp of the first entry in the run's log file
#
# logstamp:         timestamp of first log file entry - e.g. 2019_08_07 @ 20:30:01
# logdate:          logstamp date element - e.g. 2019_08_07
# logyyyy:          logdate year: yyyy - e.g. 2019
# logmm:            logdate month: mm - e.g. 08
# logdd:            logdate day: dd - e.g. 07
# basedate:         logdate in date command -d option format: yyyymmdd - e.g. 20190807
# wkday:            day_of_week: 1 .. 7: - e.g. 3
# dayref:           day_of_week, preceded by 'day_' and succeeded by '_' and the long-form dayname - e.g. day_3_Wednesday
# fom:              first day of the current month in date command -d option format: yyyymm01
# fomwk:            week_number of first day of the current month: ww (01 .. 53) - e.g. 31
# offset:           used to calculate week_of_month_number: nn - e.g. 30
# basewk:           week_number of basedate: ww (01 .. 53) - e.g. 32
# wom:              week_of_month_number of basedate: w - i.e. basedate minus offset - e.g. 2
# N.B.              the final Monday in December may fall in week 01 of the following year, giving a negative value for wom
#                   in this case wom will be set to the correct week_of_month_number
#                   this will depend on the number of days in the final part-week - Mon-Wed => 5, Mon-Tue or Mon only => 6
# wkref:            week_of_month_number, preceded by 'week_' and succeeded by '_of_month' - e.g. week_2_of_month
# mthref:           month_number of basedate, preceded by 'month_' and succeeded by '_' and the long-form monthname - e.g. month_08_August
# yrref:            year of basedate, preceded by 'year_' - e.g. year_2019
#

logstamp=$(head -1 $job_logfile | cut -d ' ' -f 7-9)
logdate=$(echo $logstamp | cut -d ' ' -f 1)
logyyyy=$(echo $logdate | cut -b1-4)
logmm=$(echo $logdate | cut -b6-7)
logdd=$(echo $logdate | cut -b9-10)
basedate=$logyyyy$logmm$logdd
wkday=$(date +%u -d $basedate)
dayref='day_'$wkday'_'$(date +%A -d $basedate)
fom=$(date +%Y%m -d $basedate)01
fomwk=$(date +%V -d $fom)
offset=$[fomwk - 1]
basewk=$(date +%V -d $basedate)
wom=$[basewk - offset]

if  (( wom < 0 ))
    then
    if  (( logdd < 30 ))
        then
        wom=5
    else
        wom=6
    fi
fi

wkref='week_'$wom'_of_month'
mthref='month_'$(date +%m -d $basedate)'_'$(date +%B -d $basedate)
yrref=year_$(date +%Y)

# ===========================================================================================================================================================================================================

# 9) run FreeFileSync backups
#
# N.B.  FreeFileSync will abort if $auth_user does not have permission to access ~/.dbus
#       Error: Cannot open directory "/{auth_home}/.dbus".
#       Error Code 13: Permission denied [opendir]
#
#       read/write access to ~/.dbus and ~/.dbus/session-bus is sufficient to enable FreeFileSync to run
#

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting FreeFileSync jobs on $timestamp >> $job_logfile
echo $script_name: FreeFileSync return_codes\: >> $job_logfile
echo $script_name: 0 - Synchronization completed successfully >> $job_logfile
echo $script_name: 1 - Synchronization completed with warnings >> $job_logfile
echo $script_name: 2 - Synchronization completed with errors >> $job_logfile
echo $script_name: 3 - Synchronization was aborted >> $job_logfile
echo $script_name: FreeFileSync backups base\date\: $basedate >> $job_logfile

# 9.1) switch to FreeFileSync executable directory
cd $FFS_exec_path

# 9.2) run non-live_files backups – i.e. archive_files & music_files

# 9.2.1) archive_files
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting archive backups on $timestamp | tee -a $job_logfile

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting archive_primary on $timestamp >> $job_logfile
./FreeFileSync $FFS_batch_path/archive_primary.ffs_batch
return_code=$?
FFS_status=$((FFS_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: archive_primary return_code = $return_code on $timestamp >> $job_logfile

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting archive_secondary on $timestamp >> $job_logfile
./FreeFileSync $FFS_batch_path/archive_secondary.ffs_batch
return_code=$?
FFS_status=$((FFS_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: archive_secondary return_code = $return_code on $timestamp>> $job_logfile

# 9.2.2) music_files
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting music backups on $timestamp | tee -a $job_logfile

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting music_primary on $timestamp >> $job_logfile
./FreeFileSync $FFS_batch_path/music_primary.ffs_batch
return_code=$?
FFS_status=$((FFS_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: music_primary return_code = $return_code on $timestamp >> $job_logfile

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting music_secondary on $timestamp >> $job_logfile
./FreeFileSync $FFS_batch_path/music_secondary.ffs_batch
return_code=$?
FFS_status=$((FFS_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: music_secondary return_code = $return_code on $timestamp >> $job_logfile

# 9.3) run live_files backups – i.e. daily, weekly, monthly & yearly

# 9.3.1) live_files - daily
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting $dayref backups on $timestamp | tee -a $job_logfile

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting daily_primary on $timestamp >> $job_logfile
./FreeFileSync $FFS_batch_path/daily_primary.ffs_batch -dirpair $live_files_path $bkp_1_path/daily_backups/$dayref
return_code=$?
FFS_status=$((FFS_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: daily_primary return_code = $return_code on $timestamp >> $job_logfile

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: starting daily_secondary on $timestamp >> $job_logfile
./FreeFileSync $FFS_batch_path/daily_secondary.ffs_batch -dirpair $live_files_path $bkp_2_path/daily_backups/$dayref
return_code=$?
FFS_status=$((FFS_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: daily_secondary return_code = $return_code on $timestamp >> $job_logfile

# 9.3.2) live_files - weekly
if  [ $wkday = 1 ]
    then
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: starting $wkref backups on $timestamp | tee -a $job_logfile

    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: starting weekly_primary on $timestamp >> $job_logfile
    ./FreeFileSync $FFS_batch_path/weekly_primary.ffs_batch -dirpair $live_files_path $bkp_1_path/weekly_backups/$wkref
    return_code=$?
    FFS_status=$((FFS_status + return_code))
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: weekly_primary return_code = $return_code on $timestamp >> $job_logfile

    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: starting weekly_secondary on $timestamp >> $job_logfile
    ./FreeFileSync $FFS_batch_path/weekly_secondary.ffs_batch -dirpair $live_files_path $bkp_2_path/weekly_backups/$wkref
    return_code=$?
    FFS_status=$((FFS_status + return_code))
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: weekly_secondary return_code = $return_code on $timestamp >> $job_logfile
fi

# 9.3.3) live_files - monthly
if  [ $logdd = 01 ]
    then
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: starting $mthref backups on $timestamp | tee -a $job_logfile

    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: starting monthly_primary on $timestamp >> $job_logfile
    ./FreeFileSync $FFS_batch_path/monthly_primary.ffs_batch -dirpair $live_files_path $bkp_1_path/monthly_backups/$mthref
    return_code=$?
    FFS_status=$((FFS_status + return_code))
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: monthly_primary return_code = $return_code on $timestamp >> $job_logfile

    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: starting monthly_secondary on $timestamp >> $job_logfile
    ./FreeFileSync $FFS_batch_path/monthly_secondary.ffs_batch -dirpair $live_files_path $bkp_2_path/monthly_backups/$mthref
    return_code=$?
    FFS_status=$((FFS_status + return_code))
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: monthly_secondary return_code = $return_code on $timestamp >> $job_logfile

# 9.3.4) live_files - yearly
    if  [ $logmm = 01 ]
        then
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: starting $yrref backups on $timestamp | tee -a $job_logfile
    
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: starting yearly_primary on $timestamp >> $job_logfile
        ./FreeFileSync $FFS_batch_path/yearly_primary.ffs_batch -dirpair $live_files_path $bkp_1_path/yearly_backups/$yrref
        return_code=$?
        FFS_status=$((FFS_status + return_code))
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: yearly_primary return_code = $return_code on $timestamp >> $job_logfile
    
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: starting yearly_secondary on $timestamp >> $job_logfile
        ./FreeFileSync $FFS_batch_path/yearly_secondary.ffs_batch -dirpair $live_files_path $bkp_2_path/yearly_backups/$yrref
        return_code=$?
        FFS_status=$((FFS_status + return_code))
        timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
        echo $script_name: yearly_secondary return_code = $return_code on $timestamp >> $job_logfile
    fi
fi

# 9.4) report FFS status and set run status variable
if  [ $FFS_status != 0 ]
    then
    echo $script_name: FreeFileSync completed with warning\(s\) and\/or error\(s\) on $timestamp | tee -a $job_logfile
fi
run_status=$FFS_status

# ===========================================================================================================================================================================================================

# 10) unmount backup partitions

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: unmounting backup partitions on $timestamp | tee -a $job_logfile

gio mount -u $bkp_1_path
return_code=$?
mount_status=$((mount_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: unmount $bkp_1 return_code = $return_code on $timestamp >> $job_logfile

gio mount -u $bkp_2_path
return_code=$?
mount_status=$((mount_status + return_code))
timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: unmount $bkp_2 return_code = $return_code on $timestamp >> $job_logfile

if  [ $mount_status != 0 ]
    then
    run_status=$((run_status + mount_status))
    echo $script_name: one or both backup partition unmounts returned an error | tee -a $job_logfile
fi

# ===========================================================================================================================================================================================================

# 11) delete all FreeFileSync logs except for the newest of each, and all Libre_Office backup files more than 7 days old

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: tidying FreeFileSync log files and Libre_Office backup files on $timestamp | tee -a $job_logfile
cd $FFS_logs_path
ls -1ar . | awk -F\  '$1 == name{system ("rm \""$0"\"")}{name=$1}'

find "$backups_path"/Libre_Office -mtime +7 -exec rm {} \;

# ===========================================================================================================================================================================================================

# 12) return to original directory if running in Terminal (displaying log file if any errors or warnings), save log file if Thunderbird backup was taken, closedown

if  tty -s
    then
    cd $current_dir
fi

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
if  [ $run_status = 0 ]
    then
    echo $script_name: completed successfully on $timestamp | tee -a $job_logfile
else
    echo $script_name: completed with warning\(s\) and\/or error\(s\) on $timestamp | tee -a $job_logfile
    if  [ "0" == "$?" ]
        then
        read -p "$script_name: press any key to view the log file"
        echo
        cat $job_logfile
    fi
fi

timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
echo $script_name: ending on $timestamp | tee -a $job_logfile
if  [ ! -z $tbird_bkp ]
    then
    timestamp=$(date +%Y)'_'$(date +%m)'_'$(date +%d)' @ '$(date +%T)
    echo $script_name: saving log file on $timestamp | tee -a $job_logfile
    cp $job_logfile $backups_path/Thunderbird/$script_name'_'$tbird_bkp'_log'
fi

exit

