#!/bin/bash

# Move the latest backup file to a specified directory [usually, a flash
# device mounted under /mnt].

# Version: 1.1 Copyright 2013 Rafał Frühling <rafamiga@gmail.com>
# last revision: $Date: 2013-05-05 11:57:17 +0200 (sun) $
# LICENCE: GPL

# NOTE: do not put slashes at the end of pathnames below!

# source dir
FBDIR=/backup

# mount directory
MOUNTDIR=/mnt
SDDIR=${MOUNTDIR}/xmygrek-backup

# the files are names like this: _hostname-backupset-YY-mm-dd_HH-MM.(tar|sql).(bz2|gz)
FBREGEX='_\(.*\)-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]_[0-9][0-9]-[0-9][0-9]\.\(tar\|sql\)\.[bg]z2\?'

# warn if the latest backup is older than n hours (168 - a week; 744 - 31 days)
MAXOLD=60

# keep this many files in FBDIR
FBFILESKEEP=7

# sysop
SYSOP="rafamiga@gmail.com"

######## (no configuration directives below this line) #########

FBR2="s!^${FBDIR}/${FBREGEX}\$!\\1!"
FBDIRL=${#FBDIR}

# check if MOUNTDIR is mounted

if [ $( mount | grep -q " ${MOUNTDIR} " ; echo $? ) == 0 ]; then
	OUT1="[???] Mountpoint ${MOUNTDIR} is already mounted; let's try and use it..."
	echo "${OUT1}"
#	mount | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
else
	if [ $( mount "${MOUNTDIR}" ; echo $? ) != 0 ]; then
		OUT1="[!!!] Cannot mount ${MOUNTDIR}. Armageddon is here!"
		echo "${OUT1}"
		mount | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
		exit 1
	fi
fi

# let's find the core names
for EXTS in $( find ${FBDIR} -maxdepth 1 -type f | \
	grep -E '(tar|sql).[bg]z?' | sed -e ${FBR2} | sort -u ); do

	LASTBKP=$( find ${FBDIR} -maxdepth 1 -type f -name "_${EXTS}-*" | sort -nr | head -1 )

	if [ "${EXTS:0:${FBDIRL}}" = "${FBDIR}" ]; then
		OUT1="[???] Matched in a weird way: \"${EXTS}\", skiping"
		echo "${OUT1}"
#		echo "${OUT1}" | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
		continue
	fi

	if [ "${LASTBKP}" == "" ]; then
		OUT1="[???] Uknown state of backup of ${FBDIR}/${EXTS}, skiping"
		echo "${OUT1}"
		echo "${OUT1}" | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
		continue
	fi
	
	# check if the file is older than MAXOLD; %Y is a timestamp
	
	HOWOLD=$(( $(date +%s) / 3600 - $( stat --format %Y ${LASTBKP} ) / 3600 ))

	echo "[***] Last backup of ${FBDIR}/${EXTS} is ${HOWOLD} hours old"
	echo "[***]      found at: ${LASTBKP}"

	if [ ${MAXOLD} -lt ${HOWOLD} ]; then
		OUT1="[!!!] Last backup of ${FBDIR}/${EXTS} is too old at ${HOWOLD} hours!"
		OUT2="[!!!] $( ls -l ${LASTBKP} )"

		echo "${OUT1}"; echo "${OUT2}"
		ls -l ${FBDIR} | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
		continue
	fi                	

	# now copy the latest file to 
	if [ $( cp -fp "${LASTBKP}" "${SDDIR}/"; echo $? ) != 0 ]; then
		OUT1="[!!!] Trouble copying backup into ${SDDIR}/. No space left on ${MOUNTDIR}?"
		echo "${OUT1}"
		df ${MOUNDIR} | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
	fi

	SDKEEP=$( find "${SDDIR}/" -maxdepth 1 -type f -name "_${EXTS}-*" | sort -nr | head -1 )
	echo "[+++]      file ${SDKEEP} archived"

	# sanity check
	if [ "$( basename "${SDKEEP}" )" != "$( basename "${LASTBKP}" )" ]; then
                OUT1="[???] Copy mismatch detected at ${SDKEEP}"
		echo "${OUT1}"
		ls -l "${SDDIR}/" | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
	else # ok, delete if everything seems sane
		for SDRM in $( find "${SDDIR}/" -maxdepth 1 -type f -name "_${EXTS}-*" | \
			sort -nr | grep -v "${SDKEEP}" ); do
			if [ -f "${SDRM}" ]; then
				echo "[---]      removing old archived file: ${SDRM}"
				rm -f ${SDRM}
			else
		                OUT1="[???] Can't remove file ${SDRM}. Is it really a a file?!"
				echo "${OUT1}"
				ls -l "${SDDIR}/" | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
			fi
		done	
	fi                	

	# keep FBFILESKEEP files in FBDIR
	COUNT=0
	for NOKEEP in $( find ${FBDIR} -maxdepth 1 -type f -name "_${EXTS}-*" | sort -nr ); do
		COUNT=$(( ${COUNT}+1 ))
		[ ${COUNT} -lt ${FBFILESKEEP} ] && continue
		echo "[---]      removing old backup: ${NOKEEP}"
		rm -f "${NOKEEP}"
	done
	        
done

if [ $( umount "${MOUNTDIR}" ; echo $? ) != 0 ]; then
	OUT1="[!!!] Cannot UNMOUNT ${MOUNTDIR}. What's going on?!"
	echo "${OUT1}"
	echo "${OUT1}" | mail -s "$( hostname ) $0: ${OUT1}" ${SYSOP}
	exit 2
fi
