#!/bin/sh
#-----------------------------------------------#
# teedlescript for backing stuff up             #
# version 0.3                                   #
#-----------------------------------------------#        
#
# Read only variables change at your own risk ;p
#
DATE=`date +%d%m%Y-%H%M`
FILE="backup.${DATE}.tgz"
TBLOCK=/tmp/tblock
SIZELOG=/tmp/sizelog
#
# User changable variables below this point
#
#DEBUG="set -x"
SOURCE=/some/dir
TARGET=/some/other/dir
MANUAL=1
ADDY=
#
# end of variables...you don't really need to read further
#

${DEBUG}

trap 'doCleanup' SIGINT

# Test sourcedir
testSource()
{
${DEBUG}
if [ -d ${SOURCE} ] ; then
    return
    else
        echo "source directory ${SOURCE} does not exist!" && doCleanup 1 >/dev/null 2>&1
fi
if [ -r ${SOURCE} ] ; then
    return
    else
        echo "source directory ${SOURCE} exists but is not readable!" && doCleanup 1 >/dev/null 2>&1
fi
}

# Test targetdir
testTarget()
{
${DEBUG}

if [ -d ${TARGET} ] ; then
    return
           else
        echo "target directory ${TARGET} does not exist!" && doCleanup 1 >/dev/null 2>&1
fi
if [ -r ${TARGET} ] ; then
    return
    else
        echo "target directory ${TARGET} exists but is not readable!" && doCleanup 1 >/dev/null 2>&1
fi
if [ -w ${TARGET} ] ; then
    return
    else
        echo "target directory ${TARGET} exists but is not writable!" && doCleanup 1 >/dev/null 2>&1
fi
}

# Test backup file
testFile()
{
${DEBUG}

if [ ! -f ${TARGET}/${FILE} ] ; then
    return
        else
        echo "backup file ${FILE} already exists in ${TARGET}!" && doCleanup 1 >/dev/null 2>&1
fi
}

# Test sizelog
testSizelog()
{
${DEBUG}

if [ -f ${SIZELOG} ] ; then
    FIRSTBACKUP=0
    else FIRSTBACKUP=1
fi
}

# size check
sizeCheck()
{
${DEBUG}

bsize=`du -sk ${SOURCE} | awk '{ print $1 }'`
dsize=$[$bsize*2]
tsize=`df -k ${TARGET} | tail -1 | awk '{ print $4 }'`

if [ $tsize -lt $dsize ] ; then 
    if [ ${MANUAL} -eq 1 ] ; then
        echo "teedlebackup WARNING: backup target ${TARGET} less than twice the source size!" 
    else
        logger -t teedlebackup "WARNING: backup target ${TARGET} less than twice the source size!"
    fi
fi

if [ $tsize -le $bsize ] ; then
    if [ ${MANUAL} -eq 1 ] ; then
                echo "teedlebackup FATAL: backup target ${TARGET} less or equal to the source size!" && doCleanup 1 >/dev/null 2>&1
        else
                logger -t teedlebackup "FATAL: backup target ${TARGET} less or equal to the source size!"
        if [ ${ADDY} ]; then
            echo "teedlebackup: FATAL: backup target ${TARGET} less or equal to the source size!" | mail -s "`hostname` teedlebackup FATAL message" ${ADDY}
        fi
        doCleanup 1
        fi
fi
}

#
# stuff
# 

# set / remove /check a lockfile
doLockfile()
{
${DEBUG}

case "$1" in
  set)
        touch ${TBLOCK}
        ;;
  del)
        rm ${TBLOCK}
        ;;
  check)
        [ ! -f ${TBLOCK} ]
        ;;
esac
}

# do the backup
doBackup()
{
${DEBUG}

cd ${SOURCE} ; tar cf - * | (cd ${TARGET}; gzip - > ${FILE})

}

# clean up after ourselves on doCleanup
doCleanup()
{
${DEBUG}

if [ ! $1 ] ; then
    if [ "${KILLME}" ]; then
        kill ${KILLME} > /dev/null 2>&1
        echo "teedlebackup FATAL: exiting on user request!"
        exit 1
    fi
exit 1
fi

doLockfile check

if [ $? -eq 0 ] ; then
    if [ "${KILLME}" ]; then
        kill ${KILLME} > /dev/null 2>&1
        exit $1
    fi
  else
    if [ "${KILLME}" ]; then
        kill ${KILLME} > /dev/null 2>&1
        doLockfile del
    fi
    exit $1
fi
}

# pretty twisty thing to show the user we're doing things
twist()
{
while true ;
do
        for i in \- \\ \| \/ \- \\ \| \/
        do
                echo -ne "$i \r"
                sleep 0.3
        done
done
}

#
# MAIN PROGRAM wheee!
#

if  [ ${MANUAL} -eq 1 ] ; then
    echo "teedlebackup WARNING: starting at `date`"
    else
    logger -t teedlebackup "WARNING: starting at `date`"
fi

# start pretty thing
if  [ ${MANUAL} -eq 1 ] ; then
    twist & 
    KILLME=$!
fi

# we might be root
if [ `id -u` -eq 0 ]; then ROOT=1
fi

doLockfile check

if [ $? -eq 0 ] ; then break
  else
        if  [ ${MANUAL} -eq 1 ] ; then
            echo "teedlebackup FATAL: a lockfile exists at ${TBLOCK}!" && doCleanup >/dev/null 2>&1
            else
            logger -t teedlebackup "FATAL: a lockfile exists at ${TBLOCK}!"
            if [ ${ADDY} ]; then
                echo "teedlebackup: FATAL: a lockfile exists at ${TBLOCK}!" | mail -s "`hostname` teedlebackup FATAL message" ${ADDY}
            fi
        doCleanup
    fi
fi

doLockfile set

testSource

testTarget

testFile

testSizelog

sizeCheck

if [ ${FIRSTBACKUP} -eq 1 ] ; then break
    else
    if [ `cat ${SIZELOG}` -eq ${bsize} ] ; then
        if  [ ${MANUAL} -eq 1 ] ; then
            echo "teedlebackup FATAL: previous backup is same size as current backup at ${bsize} kb. No actions needed!" && doCleanup 1 >/dev/null 2>&1
            else
            logger -t teedlebackup "FATAL: previous backup is same size as current backup at ${bsize} kb. No actions needed!" 
                if [ ${ADDY} ]; then
                    echo "teedlebackup: FATAL: backup is same size as current backup at ${bsize} kb. No actions needed!" | mail -s "`hostname` teedlebackup FATAL message" ${ADDY}
                fi
            doCleanup 1
        fi
    fi
fi

#  so it's the first backup or we need to make one anyway so awy we go!     

if  [ ${MANUAL} -eq 1 ] ; then
    echo "teedlebackup WARNING: starting backup run at `date`"
    else
    logger -t teedlebackup "WARNING: starting backup run at `date`"
        if [ ${ADDY} ]; then
            echo "teedlebackup: WARNING: starting backup run at `date`" | mail -s "`hostname` teedlebackup WARNING message" ${ADDY}
        fi
fi

doBackup

# are we cool?
if [ $? -eq 0 ] ; then
    echo ${bsize} > ${SIZELOG}
    
    doLockfile del
    
    if  [ ${MANUAL} -eq 1 ] ; then
        echo "teedlebackup WARNING: completed backup run at `date`" && doCleanup 0 >/dev/null 2>&1
        else
        logger -t teedlebackup "WARNING: completed backup run at `date`" 
                if [ ${ADDY} ]; then
                    echo "teedlebackup: WARNING: completed backup run at `date`" | mail -s "`hostname` teedlebackup WARNING message" ${ADDY}
                fi
        doCleanup 0
    fi
# else we aint cool
    else
    if  [ ${MANUAL} -eq 1 ] ; then
        echo "teedlebackup FATAL: backup run went horribly wrong at `date`" && doCleanup 1 >/dev/null 2>&1
        else
        logger -t teedlebackup "FATAL: backup run went horribly wrong at `date`"
                if [ ${ADDY} ]; then
                    echo "teedlebackup: FATAL: backup run went horribly wrong at `date`!" | mail -s "`hostname` teedlebackup FATAL message" ${ADDY}
                fi
        doCleanup 1
        fi
fi