#!/bin/bash
LOCK_BASEDIR=/dev/shm/.rsnapshot-backup-scripts
t=$(mktemp --tmpdir=/dev/shm)
trap 'rm -f "${t}"' EXIT
#

_setlockfd()
{
    local i
    for ((i = 0; i < ${#_lockdict}; i++))
    do [ -z "${_lockdict[$i]}" -o "${_lockdict[$i]}" = "$1" ] && break
    done
    _lockdict[$i]="$1"
    let _lockfd=200+i
    _lockfile="$LOCK_BASEDIR/$1"
}

claim_lock()
{
    mkdir -p "$LOCK_BASEDIR"
    _setlockfd $1
    while true; do
        eval "exec $_lockfd<>$_lockfile"
        flock -x $_lockfd || return $?

        _fd_inum=`stat -L -c '%i' /proc/self/fd/$_lockfd`
        _file_inum=`sh -c "stat -c '%i' $_lockfile || true"`
        if [ x$_fd_inum = x$_file_inum ]; then break; fi
        eval "exec $_lockfd<&-"
    done
}

release_lock()
{
    _setlockfd $1
    rm "$_lockfile"
}

do_rsnapshot() {
      local cfg="$1"
      local interval=$2

      echo "running $interval"
      "$(type -P time)" -f 'runtime was %E' \
      "$(type -P nice)" -n 19 \
      "$(type -P ionice)" -c 3 \
      "$(type -P rsnapshot)" -x -c "${cfg}" ${interval}
}

do_work()
{
        local cfg="$1"
        local interval_name
        local rc
        local -i interval_cnt=0
        local -i j=0
        local -i num
        local -i interval_num
        local -i num_per_interval
        local -a backup
        #
        #
        grep -w ^interval "$cfg" > $t
        while read config name count rest
        do
                backup[$num]="$name.$count"
                num=$((++num))
        done < $t

        interval_num="${#backup[@]}"
        interval_cnt=0
        while test $interval_cnt -lt $interval_num
        do
                interval_name=${backup[$interval_cnt]%.*}
                num_per_interval=${backup[$interval_cnt]##*.}
                last_run=Lastrun.$interval_cnt.$interval_name

                cd '/Private'
                if test ! -d $last_run
                then
                        mkdir $last_run
                fi

                interval_done=true
                j=1
                while test $j -lt $num_per_interval
                do
                        if test -d $last_run/$j
                        then
                                : $(( j++ ))
                                continue
                        fi
                        mkdir $last_run/$j
                        interval_done=false
                        break
                done
                do_rsnapshot "$cfg" $interval_name
                rc=$?
                if test "$rc" != "0"
                then
                        touch "/Private/last.$interval_name.fail"
                        return $rc
                fi
                touch "/Private/last.$interval_name"
                if test "$interval_done" = "false"
                then
                        break
                fi
                rm -rf $last_run
                mkdir $last_run
                : $(( interval_cnt++ ))
        done
        return 0
}
#
if test -d '/Private' && rsync 'rsync://[fe80::201:2eff:fe94:56bd%uplink]:4/for-backup-priv'
then
  if pushd '/Private' > /dev/null
  then
    stat_root="`stat -c '%D' /`"
    stat_backup="`stat -c '%D' .`"
    if test -n "${stat_root}" && test -n "${stat_backup}" && test "${stat_root}" != "${stat_backup}"
    then
      claim_lock rsnapshot_pid_lock
      echo "claimed rsnapshot_pid_lock"
      do_work /usr/share/rsnapshot-backup-scripts/backup/rsnapshot.config.txt
      release_lock rsnapshot_pid_lock
      echo "released rsnapshot_pid_lock"
      popd > /dev/null
      (
      sync
      sync
      ) < /dev/null > /dev/null &
    fi
  fi
fi
