#!/bin/bash
#
# This file is part of vbackup.
#
# vbackup is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# vbackup is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with vbackup  If not, see <http://www.gnu.org/licenses/>.
#
# $Id: common.in 3393 2012-03-06 21:00:03Z v13 $
#
# Library helper functions
#

# autoconf directories
prefix="/usr"
exec_prefix="${prefix}"
bindir="${exec_prefix}/bin"
sbindir="${exec_prefix}/sbin"
libexecdir="${exec_prefix}/libexec"
localstatedir="${prefix}/var"
libdir="${exec_prefix}/lib"
sysconfdir="/etc"
datarootdir="${prefix}/share"
datadir="${datarootdir}"
mybindir="${datarootdir}/vbackup/bin"
myscriptdir="${datarootdir}/vbackup/scripts"
myconfdir="/etc/vbackup"
myhelperdir="${datarootdir}/vbackup/helpers"
sampledir="${datarootdir}/vbackup/samples"
wizdir="${datarootdir}/vbackup/wizard"

# Package information
PACKAGE_NAME="vbackup"
PACKAGE_VERSION="0.1.9"
PACKAGE_BUGREPORT="v13@v13.gr"
PACKAGE_LICENSE="GPLv3"
PACKAGE_COPYRIGHT="Copyright (c) 2006-2012 Stefanos Harhalakis"

# Lookup an executable
# Required for prepackaged vbackup
function h_lookup()
{
	(
	# Ensure that path contains /sbin and /usr/sbin
	export PATH="$PATH:/sbin:/usr/sbin"
	if [ -z "$1" ] ; then
		F=$(which "$2")
		if ! [ -z "$F" ] ; then
			echo "$F"
		fi
	else
		echo "$1"
	fi
	)
}

# Program locations
XFSDUMP=$(h_lookup "/usr/sbin/xfsdump" xfsdump)
GFIND=$(h_lookup "/usr/bin/find" find)
GTAR=$(h_lookup "/bin/tar" tar)
FDISK=$(h_lookup "/sbin/fdisk" fdisk)
SFDISK=$(h_lookup "/sbin/sfdisk" sfdisk)
MDADM=$(h_lookup "/sbin/mdadm" mdadm)
LVDISPLAY=$(h_lookup "/sbin/lvdisplay" lvdisplay)
VGDISPLAY=$(h_lookup "/sbin/vgdisplay" vgdisplay)
PVDISPLAY=$(h_lookup "/sbin/pvdisplay" pvdisplay)
SCP=$(h_lookup "" scp)
OPENSSL=$(h_lookup "/usr/bin/openssl" openssl)
SLAPCAT=$(h_lookup "" slapcat)
ECHO_E="echo -e"

# Location of main programs
B_BINDIR="$mybindir"
# Location of backup scripts
B_SCRIPTDIR="$myscriptdir"
# Location of helper scripts
B_HELPERDIR="$myhelperdir"

if [ -z "$MESSAGE_LEVEL" ] ; then
	MESSAGE_LEVEL=8
fi

#
# Return the current date in a custom format
#
# $1:	The format:
#	1:	YYMMDD
#
# Prints the date
#
h_formdate()
{
	# For now - only one format
	date "+%y%m%d"
}

#
# Helper function to transform a filename
#	$1 is the filename to transform
# Sets:
#	R		The resulted filename
#
h_transform()
{
	local D1

	D1=`h_formdate 1`
	L="$LEVEL"

	R=`echo "$1" | sed "s,%D1%,$D1,g" | sed "s,%L%,$L,g"`
}


#
# Helper function to form the destination directory
#	$1 is the destination filename
# Sets:
#	R_DESTDIR	The destination filename
#
h_formdest()
{
	h_transform "$1"

	R_DESTDIR="$DESTDIR0/$R/"
}

#
# Ensure that a directory exists. Create if it doesn't exist
# 	$1	Directory
#	$2	Permissions (or nothing)
h_ensuredir()
{
	if ! [ -d "$1" ] ; then
		h_msg 12 "h_ensuredir: Creating $1"
		mkdir -p "$1"
	fi

	if ! [ -z "$2" ] ; then
		h_msg 12 "h_ensuredir: Set permission of $1 to $2"
		chmod "$2" "$1"
	fi
}

#
# Same as h_ensuredir but displays an informational message too
#
h_ensuredestdir()
{
	if ! [ -d "$1" ] ; then
		h_msg 5 "Creating $1 (DESTDIR)"
	fi
	h_ensuredir "$1" "$2"
}

#
# Display a fatal error and exit with error code
#
#	$1	Errorcode or -x for no-exit
#	$2-	Message
#
#	if $1 is -x then don't exit
#
h_fatal()
{
	local	R
	local	EX

	if [ "x$1" = "x-x" ] ; then
		EX=0
	else
		R="$1"
		EX=1
	fi

	shift

	h_msg 1 "FATAL: $*"

	if [ "$EX" = "1" ] ; then
		exit $R
	fi
}


#
# Display an error that should terminate the program but leave
# error handling to the caller
#
#	$*	Message
#
h_error()
{
	h_msg 2 "ERROR: $*"

	return 0
}

#
# Display a warning 
#
#	$*	Message
#
h_warn()
{
	h_msg 3 "WARNING: $*"

	return 0
}

#
# Display/log a debug/information message
#
#	$1	Level:
#			0:	Always show
#			1:	Fatal error
#			2:	Error
#			3:	Warning
#			4:	Note
#			5:	Information (Rare messages)
#			6:	Information (Useful messages but not rare)
#			7:	Information (Not so useful)
#			10-19:	Debug
#				10-14:	Debug messages that don't flood
#				15-19:	Debug messages that may flood
#	$2-	Message
#
#	If $1 equals to "-n" then no new line is added at the end of
#	the message, all arguments are shifted one position to the left
#	and life goes on as expected
#
# TODO:
#	Add loging to file ? 
#	Add timestamp for debuging messages ?
#
h_msg()
{
	local	L
	local	N

	if [ "$1" = "-n" ] ; then
		N="-n"
		shift
	fi

	L="$1"
	shift

	[ "$L" -gt "$MESSAGE_LEVEL" ]  && return

	if [ "$L" -lt 10 ] ; then
		$ECHO_E $N "$*"
	else
		$ECHO_E $N "L$L: $*"
	fi

	return 0
}

#
# Display a message adding spaces
#
#	$1	Size
#	$2	Message
#
h_fixmsg()
{
	local	T
	local	N
	local	SZ

	N=`echo "$2" | wc -c | sed 's/ //g'`
	let N=$[N*1]

	T="$2"

	while ! [ "$N" -gt "$1" ] ; do
		let N++
		T="$T "
	done

	echo -n "$T"
}

#
# Check whether a variable is true or false
#
# True is 1, yes, on
# False is 0, no, off
# Everything else is error and returns the default
#
#	$1	Value to check
#	$2	Default value (used when $1 is empty)
#
# Return:
#	0: True
#	1: False
#	2: Error
#
h_is_true()
{
	local T

	if [ -z "$1" ] ; then
		T="$2"
	else
		T="$1"
	fi

	T=`echo "$T" | sed 's/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/g'`

	case "$T" in
		yes|y|1|on)
			return 0
			;;
		no|n|0|off)
			return 1
			;;
		*)
			return 2
			;;
	esac
}

#
# Internal funciton
# Common function to display the text beffore a question
h_ask_txt()
{
	clear
	if [ ! -z "$1" ] ; then
		echo
#		echo "------------------------------"
#		echo
		echo "$1"
		echo
	fi
}

#
# Ask a true/false question with an optional default answer
#
# Parameters:
# 	$1	Multi-line description text
#	$2	Sinle-line question
#	$3	Optional default answer (y/n)
#
# Return:
#	0	Yes
#	1	No
h_ask_yesno()
{
	local	prom ans ans2

	h_ask_txt "$1"

	prom="$2 (y/n) "
	if [ "$3" = "y" ] ; then
		prom="$prom[y] "
		ans2=y
	elif [ "$3" = "n" ] ; then
		prom="$prom[n] "
		ans2=n
	fi

	while true ; do
		read -p "$prom" ans
		if [ -z "$ans" ] && [ ! -z "$ans2" ] ; then
			ans=$ans2
		fi

		if [ "x$ans" = "xy" ] ; then
			return 0
		elif [ "x$ans" = "xn" ] ; then
			return 1
		fi
	done
}

#
# Ask a question and get a string as an answer
#
# Parameters:
#	Same as h_ask_yesno()
#
# Return:
#	$RET	The string that was entered
h_ask_str()
{
	local	prom ans

	h_ask_txt "$1"

	prom="$2 [$3] "

	read -p "$prom" RET

	if [ -z "$RET" ] ; then
		RET="$3"
	fi
}

#
# Split a filename in the form of PRIO-NAME.TYPE
# to PRIORITY, NAME, TYPE
#
# @param $1	The filename to split
#
# Return:
#	$R_PRIO	The priority
#	$R_NAME	The name
#	$R_TYPE	The type
h_split_fn()
{
	R_PRIO=$(echo "$1" | ( IFS=- read a b ; echo $a ) )
	R_NAME=$(echo "$1" | ( IFS=- read a b ; echo $b ) | \
			( IFS=. read a b ; echo $a ) )
	R_TYPE=$(echo "$1" | ( IFS=- read a b ; echo $b ) | \
			( IFS=. read a b ; echo $b ) )
}

