#!/bin/bash
# Simple script to backup home directory.
#
# In this script I use the words incremental and differential to mean,
# respectively a backup containing the difference from the last backup
# (whichever type that was) and a backup containing the difference from
# the last full backup. I don't know if this is a convention or if I
# just made it up.
#
# Author: Thiago Jung Bauermann - thiago.bauermann at gmail.com

# we take errors very seriously here
set -e

# directory were all files will be generated
# this directory is excluded from the backup archive
backups_dir=$HOME/backups

# the name of the backup. this is not the final name, because
# it will be appended with -full, -incremental or -differential
backup_name=$backups_dir/$USER-`date -I`

# list of directories which will be skipped during backup
exclude_list=$HOME/pessoais/projetos/backup-scripts/exclude-files.txt

catalogues_dir=$backups_dir/catalogues

# this is the base dar command line which will be used
BACKUP_COMMAND="/usr/bin/dar                                            \
        -y                                                              \
        -m 256                                                          \
        -Z '*.ogg' -Z '*.mp3' -Z '*.jpg' -Z '*.JPG'  -Z '*.png'         \
        -Z '*.gz' -Z '*.zip' -Z '*.gif' -Z '*.bz2'                      \
        -s 695M                                                         \
        -R $HOME                                                        \
        -P `basename $backups_dir`                                      \
        -D                                                              \
        -X '*.iso' -X cscope.out                                        \
        -] $exclude_list"

# guarantee these directories exist
[ -d $backups_dir ] || mkdir -p $backups_dir
[ -d $catalogues_dir ] || mkdir -p $catalogues_dir

# the first argument is the name (with path) of the generated backup archive
# if present, the second argument is the backup which will be used as
# reference for differential and incremental backups
run_backup() {
    # do the backup
    echo Starting backup ...
    if [ $# -eq 1 ]; then
        $BACKUP_COMMAND -c $1
    elif [ $# -eq 2 ]; then
        $BACKUP_COMMAND -c $1 -A $2
    else
        return 1
    fi
}

# the first argument is the name (with path) of the backup
# archive to extract the catalogue from
generate_catalogue() {
    # generate a separate catalogue for the backup
    echo Generating catalogue ...
    /usr/bin/dar -C $catalogues_dir/`basename $1` -A $1
}

# performs a full backup
full_backup() {
    run_backup ${backup_name}-full
    generate_catalogue ${backup_name}-full
}

# performs a backup using the last backup (either full, diff or incr)
# as reference
incremental_backup() {
    typeset latest

    latest=`ls -1 $catalogues_dir/*.dar | tail -n 1` 
    run_backup ${backup_name}-incremental ${latest%.?.dar}
    generate_catalogue ${backup_name}-incremental
}

# performs a backup using the last full backup as reference
differential_backup() {
    typeset latest

    latest=`ls -1 $catalogues_dir/*-full*.dar | tail -n 1` 
    run_backup ${backup_name}-differential ${latest%.?.dar}
    generate_catalogue ${backup_name}-differential
}

show_help() {
    echo Script to back up home directory.
    echo Usage:
    echo
    echo "$0 { full | incremental | differential }"
}

# main section

case "$1" in
    full)
        full_backup
        ;;
    incremental)
        incremental_backup
        ;;
    differential)
        differential_backup
        ;;
    *)
        show_help
        exit 1
esac

