#!/bin/bash

#######################################
# BCKROOT=   # Backup root
# BCKNAME=   # Backup name
# BCKSRC=    # Source dir
# BCKDIR=    # Backupdir
# KEEPDAYS=  # Keep days
# BCKOPTS="" # Rsync options
# BCKBATCH=  # Make backup batch (1)
#######################################

STATUSROOT=/var/spool/backup
LOGROOT=/var/log/backup

TODAY=`date +%y%m%d`

function dircheck() {

	#exit if backup root doesn't exist
	[ -d $BCKROOT ] || exit 21
	#exit if backup name doesn't exist
	[ "x$BCKNAME" == "x" ] && exit 27
	#exit if backup dir is /
	[ "x$BCKDIR" == "x" ] && exit 23
	#exit if source doesn't exist
	[ -n $BCKSRC ] || exit 25
	[ -d $BCKSRC ] || exit 25

	#make dirs
	[ -d $BCKDIR ] || mkdir $BCKDIR
	[ -d $BCKDIR/daily ] || mkdir $BCKDIR/daily
	[ -d $BCKDIR/weekly ] || mkdir $BCKDIR/weekly
	[ -d $BCKDIR/temp ] || mkdir $BCKDIR/temp

	[ -d $STATUSROOT ] || mkdir $STATUSROOT
	STATUSDIR=$STATUSROOT/$BCKNAME
	[ -d $STATUSDIR ] || mkdir $STATUSDIR

	if [ "x$BCKBATCH" == "x1" ]; then
	[ -d $BCKROOT/.batch ] || mkdir $BCKROOT/.batch
	[ -d $BCKROOT/.batch/$BCKNAME ] || mkdir $BCKROOT/.batch/$BCKNAME
	fi

}

function logme()
{
	MSG="$1"
	LTS=`date '+%T'`
	[ -d $LOGROOT ] || mkdir $LOGROOT
	echo "$LTS $BCKNAME $MSG" >>$LOGROOT/backup-$TODAY.log
	[ -n "$2" ] && echo "$BCKNAME $MSG"
}

function makebackup() {

	# check backup dirs
	dircheck

	DAY=`date +%u-%a`
	DAYY=`date +%u-%a -d "yesterday"`

	[ -d $BCKDIR/daily/$DAY ] || mkdir $BCKDIR/daily/$DAY
	[ -d $BCKDIR/daily/$DAYY ] || mkdir $BCKDIR/daily/$DAYY

	# get last successful backup
	if [ -L $BCKDIR/current ]; then
		blast=`readlink $BCKDIR/current`
		if [ "x$blast" == "xdaily/$DAY" ]; then
			blast="daily/$DAYY"
			logme "A backup was already done today" show
			if [ "x$BCKBATCH" == "x1" ]; then
				logme "Exiting" show
				exit 47
			else
				logme "Re-syncing" show
			fi
		fi
	else
		blast="daily/$DAYY"
	fi

	bsrc=$BCKSRC
	bdst=$BCKDIR/daily/$DAY

	WRITEBATCH=""
	if [ "x$BCKBATCH" == "x1" ]; then
		bbatchtmp=$BCKDIR/temp/$TODAY.batch
		bbatch=$BCKROOT/.batch/$BCKNAME/$TODAY.batch

		WRITEBATCH="--write-batch=$bbatchtmp"

		if [ -f $bbatch ]; then
			logme "A backup batch file already exists for today. Exiting." show
			exit 49
		fi
	fi

	#sync with current
	rsync -a -r -q -E --delete --delete-excluded --force $WRITEBATCH --link-dest=../../$blast $BCKOPTS $bsrc/ $bdst/ >>$LOGROOT/backup-$TODAY.log 2>&1
	ERR=$?

	if [ $ERR -eq 0 -o $ERR -eq 24 ]; then

		touch $bdst

		# create current link
		[ -L $BCKDIR/current ] && rm $BCKDIR/current
		ln -s daily/$DAY $BCKDIR/current

		# remove error status file
		if [ -f $STATUSDIR/$TODAY.error ]; then
			rm $STATUSDIR/$TODAY.error
		fi
		# create finished status file
		touch $STATUSDIR/$TODAY.finished

		if [ "x$BCKBATCH" == "x1" ]; then
			# move batch
			mv $bbatchtmp $bbatch
			rm $bbatchtmp.sh
			# delete old batch
			find $BCKROOT/.batch/$BCKNAME/ -mtime +7 -type f -name "*.batch" -delete
		fi
	else
		touch $STATUSDIR/$TODAY.error
	fi
}

function rotatebackup() {

	if [ "`date +%u`" == "7" ]; then

		# check backup dirs
		dircheck

		DAY=`date +%u-%a`

		[ -d $BCKDIR/daily/$DAY ] || exit 27

		# Run with low IO
		if [ -x /usr/bin/ionice ] && /usr/bin/ionice -c3 true 2>/dev/null; then
			IONICE="/usr/bin/ionice -c3"
		fi

		# create weekly
		src=$BCKDIR/daily/$DAY
		dst=$BCKDIR/weekly/$TODAY
		[ -d $dst ] || mkdir $dst
		$IONICE cp -a -l $src/* $dst/

		$IONICE find $BCKDIR/weekly/ -mindepth 1 -maxdepth 1 -mtime +$KEEPDAYS -exec rm -r {} \;
	fi
}

function backuproute() {

	# The originating script name should be backup-* or rotate-*

	sn=${0##*/}
	func=${sn%%-*}

	logme "start $func"

	[ "$func" == "backup" ] && makebackup
	[ "$func" == "rotate" ] && rotatebackup

	logme "end $func"

}
