#!/bin/bash
#
# Incremental Backup Script 0.1
# Copyright by Matteo Mattei <matteo.mattei@gmail.com>
# This software is relased under the GPL license and so
# you can modify or distribuite this in your freedom ;-)

if [ $# -lt 2 ]
then
	echo "Usage: $0 SOURCE DEST [RSYNC_OPTS]"
	exit 1
fi

# CONFIGURATION
BACKUP_PATH=$1; shift                             # SOURCE PATH
DEV=$1; shift                                     # DESTINATION DIRECTORY (must exists)
RSYNC_OPTIONS="-HAXa --numeric-ids --delete --ignore-errors --one-file-system $@" # RSYNC OPTIONS
DST_NAME=".backup"                                # FINAL ARCHIVE NAME (backup_1, backup_2 ecc..)
N_SNAPSHOT=7                                      # NUMBER OF SAVED ARCHIVES


# VAR INITIALIZATION
DATE=`date +"%y-%m-%d"`
DIR="`echo $DEV | sed -e 's/\/$//'`"
MLF="/dev/null"

# ERROR TOLERANT GREP
tgrep()
{
	grep "$@"
	return 0
}

RSYNC()
{
	#bernie: see http://www.sanitarium.net/golug/rsync_backups.html
	RSYNC_RSH="ssh -c arcfour -o Compression=no -x"

	rsync $RSYNC_OPTIONS --link-dest="${DIR}/${DST_NAME}/1/" --exclude "${DST_NAME}" \
		"$BACKUP_PATH" "${DIR}/" \
		2>&1 | tgrep -v vanished | tgrep -v 'some files'
	RSR=`echo $?`
	if [ "$RSR"=="0" ];then
		echo -e "\nBackup successfully done.\n">>$MLF
	else
		echo -e "\nBackup aborted.\n">>$MLF
	fi
}

RENDIR()
{
	local d="${DIR}/${DST_NAME}"

	# Safety net (4 slashes just in case)
	case "$d" in
		/|//|///|////) exit 666 ;;
	esac

	[ -d "$d/${N_SNAPSHOT}" ] && rm -rf "$d/${N_SNAPSHOT}"

	i=$N_SNAPSHOT
	while [ $i -gt 0 ]
	do
		TMPDST="$d/${i}"
		TMPDIR="$d/`expr $i - 1`"
		if [ -d "$TMPDIR" ]
		then
			echo "mv $TMPDIR $TMPDST" >> $MLF
			mv "$TMPDIR" "$TMPDST"
		fi
		i=`expr $i - 1`
	done
	TMPDST="$d/1"
	echo "moving from $DIR to $TMPDST" >> $MLF
	mkdir -p "$TMPDST"
	find "$DIR" -maxdepth 1 -print0 \
		| grep -z -E -v "^(${DIR}|$d)\$" \
		| xargs -0 -r mv --target-directory="$TMPDST" 2>&1 | tgrep -v 'resource busy'
}

TESTRSYNC()
{
	# Avoid crippling the incremental .backup/1/ -> .backup/ if the
	# remote host does not allow us to connect
	rsync --dry-run "$BACKUP_PATH" >/dev/null
	TRSR=$?
	if [ $TRSR -ne 0 ]; then
		echo "rsync test failed: $TRSR.  Aborting." >> $MLF
		exit $TRSR
	fi
}

######################
# MAIN
######################

# make sure to be root
if (( `id -u` != 0 )); then { echo "Sorry, must be root.  Exiting..."; exit; } fi

echo -e "Start backup log of $DATE \n" >>$MLF

#bernie: not really needed
TESTRSYNC
RENDIR
RSYNC
if [ "$RSR"=="0" ];
then
	exit 0
else
	exit 1
fi
