david/sshbackup
david
/
sshbackup
Archived
1
0
Fork 0
This repository has been archived on 2023-12-23. You can view files and clone it, but cannot push or open issues or pull requests.
sshbackup/sshbackup

303 lines
7.6 KiB
Bash
Executable File

#!/bin/bash
# ************************************* #
# #
# sshbackup #
# #
# ************************************* #
# **** config section ****
version="0.4.0"
author="david@socialnerds.org"
configfile="$HOME/.sshbackup"
#rsync options.
rsyncoptions="-qpogEthrzl --numeric-ids --no-motd"
#dotglob option removes bug while rsyncing folder with no visible files in it.
remotecmd="shopt -s dotglob; /usr/bin/sudo /usr/bin/rsync"
localcmd="/usr/bin/rsync"
sshkeyfile="$HOME/.ssh/id_rsa"
versions=999
config=0
sshkey=0
list=0
bandwidth=0
options=$*
# **** function definitions ****
bashtrap()
{
echo
echo "CTRL+C detected."
echo "commiting suicide."
exit 1
}
usage()
{
echo
echo "usage: sshbackup <options> source destination [versions]"
echo "source/destination example: [[user@]server:]/path/to/files"
echo
echo "OPTIONS:"
echo " -h, --help show this message"
echo " -v, --version version information"
echo
echo " -l, --list <file> list of sources and destinations"
echo " -c, --config <file> alternate config file [~/.sshbackup]"
echo " -s, --sshkey <file> alternate sshkey [~/.ssh/id_rsa]"
echo " -b, --bandwidth <kbps> bandwidth limit in kbit per second"
echo
}
version()
{
echo
echo -e "vesion: \033[1;37m$version\033[0m"
echo "author: $author"
echo
}
preflight()
{
#amiroot?
if [ $(whoami) != "root" ]; then
echo "aborting mission. you must be root."
return 1
fi
#source and destination path?
if [ -z $sourcepath ]; then
echo "aborting mission. no source path given."
return 1
elif [ -z $destpath ]; then
echo "aborting mission. no destination path given."
return 1
fi
#if remote source or destination check for sshkey
if [[ $sourcepath =~ .*@.* ]] || [[ $destpath =~ .*@.* ]]; then
if [ -r $sshkeyfile ]; then
#echo "sshkeyfile found. continuing."
:
else
echo "aborting mission. no sshkey found."
return 1
fi
fi
return 0
}
sshbackup()
{
#creating local rsync options var
local cmdopt="$rsyncoptions"
#move existing versions
local num=$versions
while [ -d "$destpath/0" ]; do
if [ -d "$destpath/$num" ]; then
mv $destpath/$num $destpath/$((num+1))
fi
let num--
done
#create destpath if not existing
mkdir -p $destpath/0
#add link-destination option if existing
if [ -d $destpath/1 ]; then
cmdopt="$cmdopt --link-dest=$destpath/1"
fi
#bandwidth limit
if [
#run rsync
$localcmd $cmdopt -e "ssh -q -i $sshkeyfile" --rsync-path="$remotecmd" $sourcepath $destpath/0
if [ $? -ne "0" ]; then
return 1
fi
#removing obsolet version(s)
local i=1
while [ -d $destpath/$((versions+i)) ]; do
rm -rf $destpath/$((versions+i))
let i++
done
return 0
}
# **** start of script ****
#initialize bashtrap
trap bashtrap INT
# **** option handler ****
if [ -z $1 ]; then
usage
exit 0
fi
for option in $options; do
case "$option" in
-h|--help)
usage
exit 0
;;
-v|--version)
version
exit 0
;;
-c|--config)
config=1
;;
-l|--list)
list=1
;;
-s|--sshkey)
sshkey=1
;;
-b|--bandwidth)
bandwidth=1
;;
*)
if [ $config -eq 1 ]; then
if [ -r "$option" ]; then
configfile=$option
config=0
else
echo "aborting mission. cannot read configfile. [$option]"
exit 1
fi
elif [ $sshkey -eq 1 ]; then
if [ -r $option ]; then
sshkeyfile=$option
sshkey=0
else
echo "aborting mission. cannot read sshkeyfile. [$option]"
exit 1
fi
elif [ $bandwidth -eq 1 ];then
#TODO: better check if its a number (from 1 to gigabit)
if [ -z $option ]; then
limit=$option
bandwidth=0
else
echo "aborting mission. bandwidth limit not given. [-b $option]"
exit 1
fi
elif [ $list -eq 1 ]; then
if [ -r $option ]; then
listfile=$option
list=0
else
echo "aborting mission. cannot read listfile. [$option]"
exit 1
fi
else
if [[ $option =~ ^-.* ]]; then
echo "aborting mission. unknown option given. [$option]"
usage
exit 1
#TODO: what if source or destination is a number?
elif [ -z "${option//[0-9]/}" ]; then
versions="$option"
else
if [ -z "$sourcepath" ]; then
if [[ $option =~ .*@.* ]]; then
sourcepath="${option%/}/*"
elif [[ $option =~ ^/.* ]]; then
sourcepath="${option%/}/*"
else
sourcepath="$(pwd)/${option%/}/*"
fi
else
if [ -z "$destpath" ]; then
if [[ $option =~ ^/.* ]]; then
destpath="${option%/}"
else
destpath="$(pwd)/${option%/}"
fi
fi
fi
fi
fi
;;
esac
done
if [ -r "$configfile" ]; then
source "$configfile"
fi
#read list if listfile is given
if [ -r "$listfile" ]; then
while read line; do
# find first letter
fletter=${line:0:1}
if [ -z $fletter ]; then
#skip line it's empty
:
elif [ $fletter = "#" ]; then
#skip line it's a comment
:
else
sourcepath=""
destpath=""
for option in $line; do
if [ -z "${option//[0-9]/}" ]; then
versions="$option"
else
if [ -z "$sourcepath" ]; then
if [[ $option =~ .*@.* ]]; then
sourcepath="${option%/}/*"
elif [[ $option =~ ^/.* ]]; then
sourcepath="${option%/}/*"
else
sourcepath="$(pwd)/${option%/}/*"
fi
else
if [ -z "$destpath" ]; then
if [[ $option =~ ^/.* ]]; then
destpath="${option%/}"
else
destpath="$(pwd)/${option%/}"
fi
fi
fi
fi
done
if ( preflight ); then
sshbackup
fi
fi
done < "$listfile"
else
if ( preflight ); then
sshbackup
fi
fi
# **** end of script ****
exit 0