142 lines
5.1 KiB
Bash
Executable file
142 lines
5.1 KiB
Bash
Executable file
#!/bin/bash
|
|
MAX_NAME_WIDTH=50 # Maximal length of name next to the progress bar in percent (%)
|
|
|
|
tempdir=$(mktemp -d /tmp/backup-XXXXXXXXXX)
|
|
existing=()
|
|
|
|
recursive_backup() {
|
|
|
|
hashtemp=$(mktemp $tempdir/hashes-XXXXXXXXXXXXXXX.db) # /tmp dir for saving data and encrypting files
|
|
if [[ -n $(rclone lsf "backup:$hashdb" 2>/dev/null) ]]; then # if hash file exists, copy it to tmp dir
|
|
rclone cat "backup:$hashdb" > $hashtemp
|
|
fi
|
|
trap "cleanup $hashtemp $hashdb" SIGINT
|
|
trap "cleanup $hashtemp $hashdb" SIGTSTP
|
|
|
|
for dir in "${include[@]}"; do # go through all included directories
|
|
done_files=0
|
|
progress=0
|
|
total_files=$(wc -l <<<$(find "$dir" -type f)) # count all files for progress bar
|
|
action=""
|
|
for i in "${exclude[@]}"; do if [[ "$dir" == "$i" ]]; then continue; fi; done # if dir in exclude, skip it # TODO: POSSIBLE WHOOPSIE!
|
|
while read k; do # take every file and make a backup
|
|
if [[ ${k///} == $k ]]; then filepath="."; else filepath=${k%/*}; fi # if file in root of dir, change the path to not crash everything ,else get filepath
|
|
draw_progress $(($progress)) "$k" "$action"
|
|
#remotehash="$(cat $hashtemp | grep -n "$k")" # old databese
|
|
sqlcommand="SELECT hash FROM files WHERE backpath=\"${k}\";"
|
|
remotehash="""$(sqlite3 $hashtemp "$sqlcommand")""" # get hash from database
|
|
if [[ -z $remotehash ]]; then entryexists=0; else entryexists=1; fi # if file entry (and hash) exists, save as bool
|
|
localhash="$(md5sum "$k")" # hash of local version of file
|
|
localhash="${localhash%% *}"
|
|
done_files=$(($done_files+1))
|
|
progress=$(($done_files*100/$total_files))
|
|
if [[ "$remotehash" == "$localhash" ]]; then action="Skip"; continue; fi # if the has his the same, skip backuup
|
|
action="Backup"
|
|
draw_progress $(($progress)) "$k" "$action"
|
|
if [[ $enctype == "gpg" ]]; then
|
|
gpg -e -r "$RECIPIENT_ID" -o "$tempdir/${k##*/}.gpg" "$k"
|
|
backupfile="$tempdir/${k##*/}.gpg"
|
|
else
|
|
backupfile="$k"
|
|
fi
|
|
|
|
if [[ $filepath == "." ]]; then flpth=""; else flpth="/$filepath"; fi
|
|
backup "$backupfile" "backup:$backdir$flpth"
|
|
done <<< "$(find "$dir" -type f)"
|
|
done
|
|
cleanup $hashtemp $hashdb
|
|
}
|
|
backup() { # backup 1:<file> 2:<remotedir>
|
|
if [[ *"${existing[@]}"* == "$2" ]]; then # if remote directory is set as existing, don't check it's existence
|
|
df="Hi"
|
|
else
|
|
if [[ -n $(rclone lsd "$2" 1>/dev/null) ]]; then # check if directory doesn't exist on server
|
|
rclone mkdir "$2"
|
|
fi
|
|
existing=("${existing[@]}" "$2")
|
|
fi
|
|
bool=0
|
|
rclone copy "$1" "$2" && bool=1
|
|
#if [[ $remoteline == "0" && $bool == 1 ]]; then echo "$localhash" >> $hashtemp; else sed -i "${remoteline}s|.*|${localhash}|" $hashtemp; fi # TODO: SQL ######
|
|
if [[ $bool==1 && $entryexists == 1 ]]; then
|
|
sqlcommand="UPDATE files SET hash=\"${localhash}\" WHERE backpath=\"${2}\"" #set new hash in database
|
|
sqlite3 $hashtemp "$sqlcommand"
|
|
else
|
|
if [[ "$enctype" == "gpg" ]]; then encdata="$RECIPIENT_ID"
|
|
else encdata=""; fi
|
|
sqlcommand="INSERT INTO files(backpath,localroot,hash,backupenc,encdata) VALUES(\"${k}\",\"$(pwd)\",\"$localhash\",\"${enctype}\",\"${encdata}\");"
|
|
sqlite3 $hashtemp "$sqlcommand"
|
|
fi
|
|
}
|
|
cleanup() { # 1:hashtemp 2:hashdb
|
|
echo -e "\ncleaning up..."
|
|
cd ${1%/*}
|
|
localhfile=${2##*/}
|
|
mv "${1##*/}" "$localhfile"
|
|
rclone move "$localhfile" backup:${2%/*}
|
|
finish
|
|
}
|
|
finish() {
|
|
rmdir $tempdir || rm -rf $tempdir
|
|
exit
|
|
}
|
|
draw_progress() { # draw_progress 1:<done_progress> 2:<filename> 3:<Action>
|
|
|
|
window_length=$(tput cols); window_length=$(($window_length-3)) # get max window length
|
|
max_name_length=$(($window_length*$MAX_NAME_WIDTH/100)) # calc max length of filepath
|
|
if [[ ${#2} -gt $max_name_length ]]; then # if filepath too long, cut it, else add whitespace
|
|
name="$(cut -c -$max_name_length <<< "$2")"
|
|
else
|
|
name="$2"
|
|
if [[ ${#name} -lt $max_name_length ]]; then
|
|
for _ in $(seq ${#name} $max_name_length); do name+=" "; done
|
|
fi
|
|
fi
|
|
window_length=$(($window_length-${#name})) # get length of progress bar
|
|
prog=$(($1*$window_length/100))
|
|
tot=$((window_length-1))
|
|
#echo -e "prog $prog tot $tot done $1 total $2 win $window_length"; return
|
|
|
|
# Delete the last two lines
|
|
printf "\033[3K"
|
|
# Restore the cursor position
|
|
printf "\033[u"
|
|
echo "Progress: $progress% Action: $3 "
|
|
printf "["
|
|
for _ in $(seq 1 $prog); do
|
|
printf "#"
|
|
done
|
|
for _ in $(seq $prog $tot); do
|
|
printf "-"
|
|
done
|
|
printf "]$name\n"
|
|
}
|
|
|
|
|
|
if [[ $# -eq 0 ]]; then
|
|
echo "Please select a directory for backup!"
|
|
exit
|
|
fi
|
|
|
|
cd $1
|
|
curdir=$(pwd)
|
|
# save cursor position
|
|
printf "\033[s"
|
|
# print two dummy lines
|
|
printf "\n\n"
|
|
|
|
if [[ $# -eq 1 ]]; then
|
|
if [[ -f ".backup.env" ]]; then
|
|
source .backup.env
|
|
if [[ -z ${backdir+x} || -z ${hashdb+x} ]]; then echo "ERROR: env-file doesn't hold needed variables!"; exit; fi
|
|
if [[ -n ${include+x} ]]; then include+=(".backup.env"); else include=(*); fi
|
|
if [[ -z ${exclude+x} ]]; then exclude=("uc3rumcr3urc34u09q347c7055030785c3cc30mq3rcmu83qm3m.notanonionlink"); fi
|
|
if [[ -z ${enctype+x} ]]; then enctype="plain"; fi
|
|
else echo "ERROR: env-file doesn't exist!!"; exit; fi
|
|
recursive_backup $1
|
|
else
|
|
echo "too many args!"
|
|
exit
|
|
fi
|
|
|
|
rmdir $tempdir ||rm -rf $tempdir |