#!/bin/sh
# backupsync
# Mirror using rsynch and do decremental backup
#
# (c) 2004, Eko M. Budi, for VLocity Linux
# Released under GNU GPL

usage(){
clear
cat<<EOF
backupsync - mirror and decremental backup 

This utility is designed to mirror a directory (mostly /home)
using rsync. Additionally, it backup the files that are going
to be replaced/deleted by the operation using compression utility.

Usage: backupsync [options] <command> [files ...] 
Options are:
  -c, --config  : configuration file, default=/etc/backupsync.conf
  -v, --verbose : shows activations
  
Command is one of:
  -b, --backup      : backup to the backup-archive (default)
  -s, --list-sync   : simulate the synchronization
  -d, --list-delete : list the files that will be deleted
  -u, --list-update : list the files that will be updated
  -h, --help        : shows this message

Files:
/etc/backupsync.conf          : default configuration
/etc/cron/daily/zbackupsynch  : cron entry
EOF
}

message()
{
cat<<EOF
This directory contains the decremental backup files created by backupsync.
The files are:
  - VOLUME-DATE.tar.bz2 : the archive (not exist if no backup that date)
  - VOLUME-DATE.deleted : deleted file list
  - VOLUME-DATE.updated : updated file list

EOF
}

LOG_FILE=/var/log/backupsync.log
LOG_ROTATE=200
CONFIG_FILE=/etc/backupsync.conf
MOUNTED=0

echol() {
    echo "$*"
    echo $* >> $LOG_FILE
}

log_start() {
    local LOG_GO=""
    echol "Backupsync on `date`"
    mv $LOG_FILE $LOG_FILE.bak
    tail -n $LOG_ROTATE $LOG_FILE.bak | while read LINE; do
	if [ "$LOG_GO" ]; then
	    echo "$LINE" >> $LOG_FILE
	elif [ "`echo $LINE | cut -f-2 -d ' '`" = "Backupsync on" ]; then
	    echo "$LINE" > $LOG_FILE
	    LOG_GO=1
	fi
    done
}

clean_exit()
{
    if [ "$BACKUP_DEV" ]; then
	umount $BACKUP_DEV
    fi
    if [ "$SYNC_DEV" ]; then
	umount $SYNC_DEV
    fi
    exit $1
}

load_config() {
    if [ ! -r $CONFIG_FILE ]; then
	echol "Configuration $CONFIG_FILE is not exist."
	exit 1
    fi

    . $CONFIG_FILE

    echol "Backupsync on `date`"
    echo "Source base : $SOURCE_BASE"
    echo "Destination : $SYNC_DIR [$SYNC_DEV]"
    echo "Backup      : $BACKUP_DIR [$BACKUP_DEV]"

    if [ "$SYNC_DEV" ]; then
	umount $SYNC_MNT 2> /dev/null
	umount $SYNC_DEV 2> /dev/null
	echo "Mounting $SYNC_DEV"
	mount $SYNC_DEV $SYNC_MNT $SYNC_OPTIONS || clean_exit 1
    fi

    if [ "$BACKUP_DEV" ]; then
	umount $BACKUP_MNT 2> /dev/null
	umount $BACKUP_DEV 2> /dev/null
	echo "Mounting $BACKUP_DEV"
	mount $BACKUP_DEV $BACKUP_MNT $BACKUP_OPTIONS || clean_exit 1
    fi
}

####################################################
# The engine
list_delete()
{
    CWD=$PWD
    cd $SOURCE_BASE
    rsync -nRa --delete --delete-excluded --existing --ignore-existing \
	--exclude="$EXCLUDE_LIST" $SOURCE_LIST $SYNC_DIR | \
	grep -vE '(^$|^building file list|^wrote .*bytes|^total size)' | \
	cut -f2 -d ' '
    cd $CWD
}

list_update()
{
    CWD=$PWD
    cd $SOURCE_BASE
    rsync -nRa --existing \
	--exclude="$EXCLUDE_LIST" $SOURCE_LIST $SYNC_DIR | \
	grep -vE '(^$|^building file list|^wrote .*bytes|^total size)'
    cd $CWD
}

list_new()
{
    CWD=$PWD
    cd $SOURCE_BASE
    rsync -nRa --ignore-existing \
	--exclude="$EXCLUDE_LIST" $SOURCE_LIST $SYNC_DIR | \
	grep -vE '(^$|^building file list|^wrote .*bytes|^total size)'
    cd $CWD
}

list_sync()
{
    echo "DELETING:"
    list_delete
    echo "UPDATING:"
    list_update
    echo "ADDING:"
    list_new
}

do_sync()
{
    BACKUP_FILE="${VOLNAME}_`date +%F`"
    if [ -f $BACKUP_DIR/$BACKUP_FILE.tar.bz2 ]; then
	sleep 2
	BACKUP_FILE="${BACKUP_FILE}_`date +%T`"
    fi
    mkdir -p $BACKUP_DIR/$BACKUP_FILE
    echol "Synchronizing $SOURCE_BASE to $SYNC_DIR"
    CWD=`pwd`
    cd $SOURCE_BASE;
    if [ "$BACKUP_DIR" ]; then
	rsync $VERBOSE -aR --delete --delete-excluded \
	    --backup --backup-dir=$BACKUP_DIR/$BACKUP_FILE \
	    --exclude="$EXCLUDE_LIST" $SOURCE_LIST $SYNC_DIR
	if ! rmdir $BACKUP_DIR/$BACKUP_FILE 2>/dev/null; then
	    echol "Backing up $BACKUP_FILE"
	    cd $BACKUP_DIR/$BACKUP_FILE
	    tar $VERBOSE -cjf ../$BACKUP_FILE.tar.bz2 .
	    cd ..
	    rm -rf $BACKUP_FILE
	fi
    else
	rsync $VERBOSE -aR --delete --delete-excluded \
	    --exclude="$EXCLUDE_LIST" $SOURCE_LIST $SYNC_DIR
    fi
    cd $CWD
}

################################################
# MAIN PROG
if [ -z "$1" ]; then
    usage
    clean_exit
fi

while [ "$1" ]; do
case $1 in
    --backup-cron)
	if [ "$CRON_ACTIVATED" = "1" ]; then
	    backup_quick $@
	else
	    echol "Cron backup is not activated"
	fi
	;;
    --config|-c)
	CONFIG_FILE=$2
	shift
	;;
    --verbose|-v)
	VERBOSE="-v"
	;;
    --backup|-b|"")
	load_config
	do_sync
	clean_exit
	;;
   --list-delete|-d)
	load_config
	list_delete $@
	clean_exit
	;;
   --list-update|-u)
	load_config
	list_update $@
	clean_exit
	;;
   --list-sync|-s)
	load_config
	list_sync $@
	clean_exit
	;;
   --help|-h|*)
	usage
	clean_exit
	;;
esac
shift
done

clean_exit
