#!/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=false; else entryexists=true; fi # if file entry (and hash) exists, save as bool localhash="$(md5sum "$k")" # hash of local version of file 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 touch missing-files.txt while read i; do # TODO: DELETE THIS PART sfile="${i#* }" if [[ -f "$sfile" ]]; then df="Hi"; else echo "Missing: $sfile"; echo "$sfile" >> missing-files.txt; fi done <<<$(cat $hashtemp) cleanup $hashtemp $hashdb } backup() { # backup 1: 2: 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 ]]; 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(\'${2}\',\'$(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: 2: 3: 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 else echo "too many args!" exit fi rmdir $tempdir ||rm -rf $tempdir