#!/bin/bash
# $Id: rear 481 2011-05-24 08:39:25Z gdha $
#
# Relax & Recover
#
#    Relax & Recover 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 2 of the License, or
#    (at your option) any later version.

#    Relax & Recover 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 Relax & Recover; if not, write to the Free Software
#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# Authors: 
# Schlomo Schapiro <rear at schlomo.schapiro.org> [GSS]
# Gratien D'haese  <gdha at sourceforge.net> [GD]

# Versioning
PRODUCT="Relax & Recover"
VERSION="1.11.0"
RELEASE_DATE='$Date: 2011-05-24 10:39:25 +0200 (Tue, 24 May 2011) $'
# remove SVN related junk from release date
RELEASE_DATE="${RELEASE_DATE#\$Date: }"
RELEASE_DATE="${RELEASE_DATE% (*}"

COPYRIGHT="Copyright (C) 2006-2011
        Schlomo Schapiro, Immobilien Scout GmbH
        Gratien D'haese, IT3 Consultants"
STARTTIME=$SECONDS

# Allow workflows to set the exit code to a different value.
EXIT_CODE=0

# Program directories - they must be set here. Everything else is then dynamic

SHARE_DIR="/usr/share/rear"
CONFIG_DIR="/etc/rear"
VAR_DIR="/var/lib/rear"
CMD_OPTS=( "$@" )

# initialize defaults
STEPBYSTEP=
SIMULATE=
VEROSE=
DEBUG=
KEEP_BUILD_DIR=

# special test for long help option
test "${*//*--help*/--help}" == "--help" && WORKFLOW=help

# Parse options
while getopts "VvhdDSsqr:" Option
do
	case $Option in
	h ) WORKFLOW=help ;;
	V ) echo -e "$PRODUCT Version $VERSION / $RELEASE_DATE\n" ; exit 0 ;;
	v ) VERBOSE=1 ;;
	d ) DEBUG=1 ; VERBOSE=1 ;;
	D ) DEBUGSCRIPTS=1 ;;
	s ) SIMULATE=1 ; VERBOSE=1 ;;
	S ) STEPBYSTEP=1 ;;
	q ) QUIET=1 ;;
	r ) KERNEL_VERSION="$OPTARG" ;;
	* ) echo "ERROR: Unknown Option $Option specified." ;;
	esac
done
shift $(($OPTIND - 1))
# Move argument pointer to next.

# set workflow to first command line argument or to usage
if test -z "$WORKFLOW" ; then
	if test "$1" ; then
		WORKFLOW=$1 ; shift # not "$1" to get rid of compound commands
	else
		WORKFLOW=help
	fi
fi

# keep the remaining command line arguments to feed to the workflow
ARGS=( "$@" )

# the following workflows are always verbose
case "$WORKFLOW" in
	(validate|help|dump|mkdist|mktar|mk*rpm|mkdeb|shell|recover)
		VERBOSE=1
	;;
esac

# Make sure we have the necessary paths (eg. in cron), /sbin will be the first path to search.
# some needed binaries are in /lib/udev
for path in /usr/bin /bin /usr/sbin /sbin; do
    case ":$PATH:" in
        (*:"$path":*) ;;
        (*) if [[ -d "$path" ]]; then PATH=$path:$PATH; fi ;;
    esac
done
PATH=$PATH:/lib/udev

# are we root ?
if [ $(id --user) -ne 0 ]; then
	echo  "** ERROR **	$PRODUCT needs ROOT privileges!"
	exit 1
fi

# get full path to main script
SCRIPT_FILE="$(readlink -f $(type -p "$0" || echo "$0"))"

if ! type -p pidof >/dev/null ; then
	echo 1>&2 "** ERROR **        Required program 'pidof' missing, please check your PATH"
	exit 1
fi

# do not run if another instance is running. pidof -x will always report at least $$
if [ $$ != "$(pidof -x "$SCRIPT_FILE")" ] ; then
        echo 1>&2 "** ERROR **        $SCRIPT_FILE is already running, not starting again"
        exit 1
fi

# set some bash options
shopt -s nullglob extglob
hash -r

# make sure that we use only english
export LC_CTYPE=C LC_ALL=C LANG=C

# include default config
. $SHARE_DIR/conf/default.conf


test -r "$LOGFILE" && mv -f "$LOGFILE" "$LOGFILE".old 2>/dev/null # keep old log file
exec 2>"$LOGFILE" || echo "ERROR: Could not create $LOGFILE" 1>&2

# include functions
for script in $SHARE_DIR/lib/*.sh ; do
	. $script
done

LogPrint "$PRODUCT Version $VERSION / $RELEASE_DATE"
Log "Command line options: $0 ${CMD_OPTS[@]}"



v=""
verbose=""
# enable progress subsystem only in verbose mode, set some stuff that others can use
if test "$VERBOSE" ; then
	source $SHARE_DIR/lib/progresssubsystem.nosh
	v="-v"
	verbose="--verbose"
fi

# enable debug output of the progress pipe
if test "$DEBUG" ; then
        if test "$ProgressPID" ; then
                kill -WINCH $ProgressPID || BugError "Could not kill -PWR ProgressPID"
	fi
	KEEP_BUILD_DIR=1
fi

test "$SIMULATE" && LogPrint "Simulation mode activated, ReaR base directory: $SHARE_DIR"

# All workflows need to read the configurations first.
# Combine configuration files
Log "Combining configuration files"
Source "$CONFIG_DIR/os.conf"   # use this file to manually override the OS detection
Source "$CONFIG_DIR/$WORKFLOW.conf"
SetOSVendorAndVersion
# distribution configuration files
for config in "$ARCH" "$OS" \
               "$OS_MASTER_VENDOR" "$OS_MASTER_VENDOR_ARCH" "$OS_MASTER_VENDOR_VERSION" "$OS_MASTER_VENDOR_VERSION_ARCH" \
               "$OS_VENDOR" "$OS_VENDOR_ARCH" "$OS_VENDOR_VERSION" "$OS_VENDOR_VERSION_ARCH" ; do
               if test "$config" ; then
                       Source $SHARE_DIR/conf/"$config".conf
               fi
done
# user configuration files
for config in site local ; do
       Source $CONFIG_DIR/"$config".conf
done
# last thing is to overwrite variables if we are in the rescue system
Source "$CONFIG_DIR/rescue.conf" # set by rescue Stage

# check for requirements
# do we have all required binaries ?
MISSING_PROGRS=()
for f in "${REQUIRED_PROGS[@]}" ; do
	if ! type -p "$f" >/dev/null ; then
		MISSING_PROGS=( "${MISSING_PROGS[@]}" "$f" )
	fi
done
test "$MISSING_PROGS" &&  Error "cannot find required programs: ${MISSING_PROGS[@]}"

VERSION_INFO="
$PRODUCT Version $VERSION / $RELEASE_DATE
$COPYRIGHT
$PRODUCT comes with ABSOLUTELY NO WARRANTY; for details
see the GNU General Public License at http://www.gnu.org/licenses/gpl.html

Host $(uname -n) using Backup $BACKUP and Output $OUTPUT
Build date: $(date -R)
"

# create temporary work area and register removal exit task
BUILD_DIR="$( mktemp -d -t rear.XXXXXXXXXXXXXXX)" || Error "Could not create build area '$BUILD_DIR'"
QuietAddExitTask cleanup_build_area_and_end_program
Log "Using build area '$BUILD_DIR'"
ROOTFS_DIR=$BUILD_DIR/rootfs
TMP_DIR=$BUILD_DIR/tmp
mkdir -p $ROOTFS_DIR || Error "Could not create $ROOTFS_DIR"
mkdir -p $TMP_DIR || Error "Could not create $TMP_DIR"

# Check for and run the requested workflow
if type -t WORKFLOW_$WORKFLOW >/dev/null ; then
	Log "Running $WORKFLOW workflow"
	WORKFLOW_$WORKFLOW "${ARGS[@]}"
	Log "Finished running $WORKFLOW workflow"
else
	LogPrint "ERROR: The specified command '$WORKFLOW' does not exist !"
	EXIT_CODE=1
fi

exit $EXIT_CODE
