#!/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