#!/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