#!/usr/bin/env bash
#
# variables.
#
# Copyright 2015 - 2019 Einhard Leichtfuß
#
# This file is part of rsync-backup.
#
# rsync-backup is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# rsync-backup 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with rsync-backup. If not, see .
#
## CONSTANTS
typeset -r CONFIG=/etc/rsync-backup/config
typeset -r RET_TYPES='
RET_SUCCESS RET_FAILURE RET_BADSYNTAX RET_FILE_ERR RET_ERROR'
typeset -r RET_SUCCESS=0
typeset -r RET_FAILURE=1
typeset -r RET_BADSYNTAX=2
typeset -r RET_FILE_ERR=4
typeset -r RET_ERROR=8
typeset -r DATEFMT='%Y-%m-%d_%H%M%S'
# Shell options:
# nullglob: In case of a non-matching glob, return nothing.
# dotglob: Include dotfiles (except . and ..) in glob matching.
typeset -r SHOPTS='dotglob'
typeset -r SHOPTS_AFTER_GET_ARGS='nullglob'
# Always give these variables and functions to remotely executed commands,
# as they are very commonly used.
# These will not be listed as required.
# Note that $host is given as argument to run_function.
typeset -r REMOTE_DEFAULT_VARS="$RET_TYPES verbose debug host"
typeset -r REMOTE_DEFAULT_FUNS='prefixed_write message debug error
debug_error'
## Global program variables.
typeset src src_path src_host
typeset dest dest_path dest_host
typeset -a filter_args
typeset -i n
## Variables that may be configured.
typeset RSYNC=rsync
typeset verbose=true
typeset debug=true
# Location to put mirrored trees on the source.
typeset src_mirror_reldir='.backup'
typeset -a rsync_base_args
typeset -a rsync_mirror_args
typeset -a rsync_transfer_args
typeset -A bakpath
typeset -A filter_file
typeset filter_file_all # Applied after specific filter.
# Base arguments for rsync (-rptogAXlHS, --timeout=, --numeric-ids, --info=).
# These are used both for creation of the source mirror and the transfer of
# that mirror to the destination. In both cases, attributes may be added.
rsync_args=(
--recursive
--perms --times --owner --group
--acls --xattrs
--links
--hard-links
--sparse
--numeric-ids
--timeout=60
#-vv
--info=progress2
)
source "$CONFIG"
# Set the globabl variables $src, $dest_path and $filter_args according to
# command line parameters and the configuration.
#
# $@: command line parameters
#
# requires the shell option nullglob to be _unset_. (for test -v to work)
#
function get_args
{
if [ $# -eq 0 ]
then
message "Usage: $exec_name []" 2>&1
return $RET_BADSYNTAX
fi
local l_src="$1"
local l_dest
# Set $src_path, $src_host and $src.
resolve_host_path src "$l_src" || return $?
if [ $# -gt 1 ]
then
l_dest="$2"
elif [[ -v bakpath[$src] ]] # $# -eq 1
then
l_dest="${bakpath[$src]}"
else
error "Backup path for \"$src\" neither configured" \
"nor specified on command line."
return $RET_BADSYNTAX
fi
# Set $dest_path, $dest_host and $dest.
resolve_host_path dest "$l_dest" || return $?
filter_args=()
if [[ -v filter_file[$src] && -f "${filter_file[$src]}" ]]
then
filter_args+=("--filter=merge ${filter_file[$src]}")
fi
if [[ -v filter_file_all && -f "$filter_file_all" ]]
then
filter_args+=("--filter=merge ${filter_file_all}")
fi
return $RET_SUCCESS
}
# Split host:target like rsync and convert local (!) relative paths to
# absolute ones. This is needed at least for $src_path which is used as
# key for associative arrays.
#
# The results are written to the global variables $, $_host
# and $_path, where is either src or dest. $ gets
# set to the original to be resolved string, unless we are local, i.e.
# there is no host.
#
# Note: This is not a place for bash to shine. Perl for instance would do
# this much more easily.
#
# Examples:
# - a:b -> (a, b)
# - a/b:c -> ('', a/b:c)
#
# $1: which global variables to set: (src|dest)
# $2: path string potentially containing host prefix
#
# sets: ${$1}_host: host name (may be empty)
# ${$1}_path: path (absolute, if local, i.e. ${$1}_host='')
# ${$1}: ${$1}_path, if ${$1}_host='',
# ${$1}_host:${$1}_path (= $2), elsewise.
#
function resolve_host_path
{
local vtype="$1"
local combined="$2"
local host path
# Split host and path.
host=${combined%%:*}
if [[ "$host" == "$combined" || "$host" =~ '/' ]]
then
host=''
path="$combined"
# Resolve to absolute directory.
# pwd -P avoids symlinks.
# Do not resolve symlimks in ${path} or test for its existance.
# `- realpath could do that.
if ! [[ "$path" =~ / ]]
then
path="$(pwd -P)/${path}"
fi
combined="$path"
else
path="${combined#*:}"
fi
# Set global variables.
if [[ "$vtype" == 'src' ]]
then
src_host="$host"
src_path="$path"
src="$combined"
else # "$vtype" == 'dest'
dest_host="$host"
dest_path="$path"
dest="$combined"
fi
return $RET_SUCCESS
}
# vi: ft=bash ts=2 sw=2 noet