#!/bin/bash
# WebBackup
# Version : 1.0
# Author : frederic%DOT%ple%AT%gmail%DOT%com
#
# 1.0 : first proper release
#

function usage {
	cat >&2 <<EOF

Usage :
	$(basename $0) [-h] [-q|v|d] [-V] -s NAME -m MIRROR_PATH [-x PATH [-x PATH [..]]] [-b BAK_PATH] -f USER:PWD@FTPHOST [ -u http://[USER:PWD@]BACKUPDBURL [-e BACKUPDBPATH] ] [-t|-z|-j] [-r 0|7|31|365]

	-h :	Print this help
	-q :	Be quiet.
	-v :	Be verbose
	-d :	Debug messages
	-V :	Print version
	-s :	NAME is the pretty name of the backuped file.
		It is used in the name of the archived file
	-m :	The web site is fully mirrored in the local directory MIRROR_PATH.
		When the site grows, only modifications are mirrored.
	-x :	Path exclusion. Don't backup PATH. PATH can be a regexp (see egrep)
	-b :	Archives files are stored into the local directory BAK_PATH
	-f :	Parameters for FTP connexion
	-u :	Parameters to acces to BackupDB directory. Optionnaly, you can specify a user/password
		if you protect BackupDB with HTTP Authentication
	-e :	Remove remote DB backup file (on web server) after being backuped. BACKUPDBPATH is the
		directory where backupDB is installed
	-t :	Archive file is not compressed (tar file)
	-z :	Archive file is compressed (gzip)
	-j :	Archive file is compressed (bzip2). This is the default
	-r :	Archive retention in days. Values accepted are 0, 7, 31, 365.
		0 means to not archive. Default is 31.
		
EOF
	case $1 in
	0)	exit 0
		;;
	1)	exit 1
		;;
	esac
}

function prn {
	# called prn PRIORITY("",v,d) MESSAGE
	case "$1" in
	d|v)	[ "$PARM_VERBOSE" == "d" -o "$PARM_VERBOSE" == "v" ] && echo "[verbose] $2"
		;;
	"")
		[ -z $PARM_VERBOSE ] && echo "$1"
		;;
	esac
}


CMDTAR=$(which tar)
CMDCURL=$(which curl)
CMDLFTP=$(which lftp)
CMDGZIP=$(which gzip)
CMDBZIP=$(which bzip2)
CMDDATE=$(which date)

if [ -z "$CMDTAR" -o -z "$CMDCURL" -o -z "$CMDLFTP" -o -z "$CMDGZIP" -o -z "$CMDBZIP" -o -z "$CMDDATE" ] ; then
	echo "ERROR : Unsatisfied dependancies ;" >&2
	echo -e "\t- 'tar' found at $CMDTAR\n\t- 'curl' found at $CMDCURL\n\t- 'lftp' found at $CMDLFTP\n\t- 'gzip' found at $CMDFOUND\n\t- 'bzip2' found at $CMDBZIP\n\t- 'date' found at $CMDDATE\n" >&2
	echo "Please fix them" >&2
	echo "Exiting" >&2
	exit 1
fi

PARM_VERBOSE=""
PARM_VERSION=""
PARM_NAME=""
PARM_MPATH=""
PARM_LFTPEXCLUDE=""
PARM_BPATH=""
PARM_FTP=""
PARM_URL=""
PARM_REMOVE_DBBAK=""
PARM_REAL_DBBAK=""
PARM_TAR=""
PARM_ROTATION=31

OPTIND=1
while [ 0 -eq 0 ]
do
	getopts 'hqvdVs:m:x:b:f:u:e:tzjr:' OPT || break
	case "$OPT" in
		h)	usage 0
			;;
		q|v|d)	if [ -n "$PARM_VERBOSE" ] ; then
				echo "ERROR : option -$PARM_VERBOSE is not compatible with -$OPT" >&2
				usage 1
			fi
			PARM_VERBOSE=$OPT
			[ $OPT == "d" ] && set -x
			;;
		V)	PARM_VERSION=$OPT
			;;
		s)	PARM_NAME="$OPTARG"
			;;
		m)	PARM_MPATH="$OPTARG"
			;;
		x)	PARM_LFTPEXCLUDE="${PARM_LFTPEXCLUDE}-x $OPTARG "
			;;
		b)	PARM_BPATH="$OPTARG"
			;;
		f)	PARM_FTP="$OPTARG"
			;;
		u)	PARM_URL="$OPTARG"
			;;
		e)	PARM_REMOVE_DBBAK="$OPTARG"
			;;
		t|z|j)	if [ -n "$PARM_TAR" ] ; then
				echo "ERROR : option -$PARM_TAR is not compatible with -$OPT" >&2
				usage 1
			fi
			PARM_TAR="$OPT"
			;;
		r)	if [ "$OPTARG" -ne 0 -a "$OPTARG" -ne 7 -a "$OPTARG" -ne 31 -a "$OPTARG" -ne 365 ] ; then
				echo "ERROR : illegal value $OPTARG" >&2
				usage 1
			fi
			PARM_ROTATION=$OPTARG
			;;
		*)	usage 1
			;;
	esac
done

# Check Parm
[ -z "$PARM_TAR" ] && PARM_TAR="j"
if [ -z "$PARM_NAME" ] ; then
	echo "ERROR : missing option -s" >&2
	usage 1
fi
if [ -z "$PARM_MPATH" ] ; then
	echo "ERROR : missing option -m" >&2
	usage 1
fi
if [ ! -d $PARM_MPATH ] ; then
	echo "ERROR : directory $PARM_MPATH not found" >&2
	usage 1
fi
if [ -n "$PARM_BPATH" -a ! -d "$PARM_BPATH" ] ; then
	echo "ERROR : directory $PARM_BPATH not found" >&2
	usage 1
fi
if [ -z "$PARM_FTP" ] ; then
	echo "ERROR : missing option -b" >&2
	usage 1
fi

# Begin

prn "" "Starting backup of $PARM_NAME at $(date)"

ORGPATH=$(pwd)

# Dump MySQL
if [ -z "$PARM_URL" ] ; then
	prn v "No URL found. Skipping database dump !"
else
	read URL URLU URLP <<-EOF
	$(echo $PARM_URL | perl -ne 'chomp; if ( /@/ ) { s/^(http:\/\/)(.*?)\:(.*?)@(.*)/$1$4 $2 $3/ } ; print $_ ; ')
	EOF
	
	prn d "URL=$URL URLU=$URLU URLP=$URLP"
	
	prn v "Start database dump at $(date)"
	$CMDCURL -s $([ -n "$URLU" ] && echo -n "--user $URLU:$URLP") -o /dev/null "$URL/backupDB.php?StartBackup=complete&nohtml=1" >/dev/null 2>&1
	prn v "End database dump at $(date)"
fi

# FTP mirror
prn v "Start FTP mirror at $(date)"
read FTPU FTPP FTPH <<-EOF
	$(echo $PARM_FTP | perl -ne 'chomp; if ( /@/ ) { s/^(.*?)\:(.*?)@(.*)/$1 $2 $3/ } ; print $_ ; ')
	EOF
if [ -z "$FTPU" -o -z "$FTPP" -o -z "$FTPH" ] ; then
	echo "Error : Incorrect FTP parameters (-f). Exiting" >&2
	usage 1
else
	cd $PARM_MPATH
	$CMDLFTP -u $FTPU,"$FTPP" -e "mirror $PARM_LFTPEXCLUDE -n -e ; quit" $FTPH
	cd -
fi
prn v "End FTP mirror at $(date)"

# Archive
if [ $PARM_ROTATION -eq 0 ] ; then
	prn v "Rotation is 0. Skipping archive !"
else
	case $PARM_ROTATION in
	7)	PARM_ROTATION=u
		;;
	31)	PARM_ROTATION=d
		;;
	365)	PARM_ROTATION=j
		;;
	esac
	ARCH_FILE=$PARM_BPATH/$PARM_NAME-$(date +%$PARM_ROTATION)
	case $PARM_TAR in
	t)	ARCH_FILE=$ARCH_FILE.tar
		;;
	j)	ARCH_FILE=$ARCH_FILE.tar.bz2
		;;
	z)	ARCH_FILE=$ARCH_FILE.tar.gz
		;;
	esac
	
	prn v "Start archiving at $(date)"
	cd $PARM_MPATH
	$CMDTAR $([ $PARM_TAR == "t" ] || echo -n "$PARM_TAR")cf $ARCH_FILE .
	cd -
	prn v "End archiving at $(date)"
fi

# Remove remote DB 
if [ -z "$PARM_REMOVE_DBBAK" ] ; then
	prn v "Skipping remote DB removal !"
else
	prn v "Removing remote DB"
	$CMDLFTP -u $FTPU,"$FTPP" -e "rm -f $PARM_REMOVE_DBBAK/backupdb/db_backup.sql.gz ; quit" $FTPH
fi

# End
prn "" "Ending backup of $PARM_NAME at $(date)"

