#!/bin/sh
#
# bootcdbackup
#
#  bootcdbackup /dev/VolGroup00/LogVol00 otherdist /mnt/tmp/space [-nomount] [-2diskconf <file>] <$*>
#  1. mkdir /tmp/backup
#  2. [ -2diskconf ] || bootcdmk2diskconf -b -f /dev/VolGroup00/LogVol00 >/tmp/backup/bootcd2disk.conf
#  3. [ -nomount ] || bootcd2disk -onlymount -c /tmp/backup 
#  4. bootcd2disk -mkchroot /mnt/tmp/space <$*>
#  5. tar /mnt/tmp/space/chroot
#     chroot /mnt/tmp/space/chroot bootcdwrite
#     cp cdimage.iso 
#  6. [ -nomount ] || bootcd2disk -onlyunmount -c /tmp/backup 

CONFVARS="ERRLOG"
# directory created in builddir
BOOTCDDIR="bootcd"

TODOY="-y"
TODO=""
IMAGEURL=""
SCRIPT=""
CONFDIR="/etc/bootcd"
NOMOUNT=""
DISKCONF2=""
BACKUPDIR=""
BACKUPNAME=""
COPYDEST="/mnt"

# temporary directory
TMPDIR="/tmp/bootcdbackup"

# must be empty for run_cpio
IMGDIR=""

##################### nothing to configure behind this line ##################

cleanup()
{
  local TODO=""
  trap "" 2 EXIT
  TODO="$TODO \"rm -rf $TMPDIR\""
  [ "$CLEANCHROOT" ] && TODO="$TODO \"$CLEANCHROOT\""
  [ "$CLEANUMNT" ] && TODO="$TODO \"$CLEANUMNT\""
  [ "$TODO" ] && eval "interactive $TODOY $TODO"
}

unset $CONFVARS

[ -f /etc/bootcd/bootcdbackup.conf ] && . /etc/bootcd/bootcdbackup.conf

# read bootcd-run.lib
if [ -f ./bootcd-run.lib ]; then
  echo "Using local ./bootcd-run.lib" >&2
  . ./bootcd-run.lib
elif [ -f /usr/share/bootcd/bootcd-run.lib ]; then
  . /usr/share/bootcd/bootcd-run.lib 
else
  echo "Error: Mandatory lib bootcd-run.lib not found! ABORT!"
  exit 1
fi

# read bootcdbackup.lib
if [ -f ./bootcdbackup.lib ]; then
  echo "Using local ./bootcd-backuplib" >&2
  . ./bootcdbackup.lib
elif [ -f /usr/share/bootcd/bootcdbackup.lib ]; then
  . /usr/share/bootcd/bootcdbackup.lib 
else
  echo "Error: Mandatory lib bootcdbackup.lib not found! ABORT!"
  exit 1
fi

for i in $CONFVARS; do
  [ "`set | grep ^$i=`" ] || err "$i is not set in $CONFDIR/bootcdbackup.conf"
done

# ignore this output from bootcdwrite
bootcd2disk_ignore()
{
  local mm=$1

  in_stdout $mm "^--- copying CD and RAM to"
  in_stdout $mm "^--- handling udev ---$"
  in_stdout $mm "^--- deleting NOT_TO_RAM symlinks ---$"
  in_stdout $mm "^--- Building fstab ---$"
  in_stdout $mm "^--- Resetting mtab ---$"
  in_stdout $mm "^--- Building grub/menu.lst ---$"
  in_stdout $mm "^--- Enabling turned off stuff ---$"
  in_ignore $mm "^Please Reboot now !$"
}  

# function: usage
# get: $1 -- error string
usage()
{
  [ "$1" ] && echo  >&2 "$1"
  echo  >&2 "[-i] [-v] [-s] [-c <confdir>] [-url <url] [-e <directories>] [-nomount] [-2diskconf <file>] <dev> <name> <builddir>"
  echo  >&2 " $(basename $0) make an offline backup."
  echo  >&2 " syntax:  -i           -- interactiv operation"
  echo  >&2 "          -d           -- turn debug on"
  echo  >&2 "          -s           -- be silent and no interaction"
  echo  >&2  "     -e <directories> -- space seperated directories exclude from backup"
  echo  >&2 "          -c <confdir> -- use another configuration directory"
  echo  >&2 "          -url <url>   -- url from imageserver (overwrite IMAGEURL)"
  echo  >&2 "     -2diskconf <file> -- add your own bootcd2disk.conf for target system"
  echo  >&2 "                          (may be created with \"bootcdmk2diskconf\" on target disk)"
  echo  >&2 "          -nomount     -- don't mount target disk\n"
  echo  >&2 "          <dev>        -- device where to find the file \"fstab\" for the target disk"
  echo  >&2 "          <name>       -- name of the backup (no blanks!)"
  echo  >&2 "                          (used as directory /<name> where to find the tarball of the target disk)"
  echo  >&2 "                          (also used on bootcd2disk -c <name> to restore the backup)"
  echo  >&2 "          <builddir>   -- build the backup CD/DVD on this directory (need lot of space!)"
  echo  >&2 ""
  exit 1
}

############################## now the real things ###########################

cpiostar=""
excludes=""
cpiostar_option=""

# get options
while [ $# -gt 3 ]; do
  case "$1" in
     "-h"|"--help")
        usage
        ;;
     "-i")
        TODOY=""
        shift
        ;;
   "-url")
        IMAGEURL="$2"
        shift 2
        ;;
     "-d")
        dbgon
        shift
        ;;
     "-e")
        excludes="$2"
        shift 2
        ;;
     "-c")
        CONFDIR="$2"
        shift 2
        ;;
     "-s")
        SCRIPT="$1"
	shift
        ;;
     "-nomount")
        NOMOUNT="$1"
	shift
        ;;
     "-2diskconf")
        DISKCONF2="$2"
        shift 2
        ;;
# internal option, called from bootcdbackupwizard
# bootcdbackup [-i] [-e <dirs>] -cpiostar <head> <dir (write backup to)> <dir (get backup from)>
     "-cpiostar")
        cpiostar="yes"
        shift 1
        ;;
     "--star")
        cpiostar_option="-u star"
        shift
        ;;
     "--cpio")
        cpiostar_option="-u cpio"
        shift
        ;;
        *)
        usage "ERROR: option \"$1\" unknown!"
        ;;
  esac
done

# special for cpiostar
if [ "$cpiostar" ]; then
  RCPIO_EXCLUDE_DIRS="$excludes"
  IAHEAD="$1"
  [ "$TODOY" ] || cpiostar_option="-i $cpiostar_option"
  run_cpiostar $cpiostar_option -d $2 $3
  exit 0
fi


if [ $# -ne 3 ]; then
  usage "Wrong number of parameters"
fi

BACKUPDEV="$1"
BACKUPNAME="$2"
BACKUPDIR="$3/$BOOTCDDIR"
COPYDEST="$BACKUPDIR/chroot"

### Main ###

A=""
while [ "$A" != "y" -a "$A" != "n" ]
do
  echo -n "Directory $BACKUPDIR will be removed and created again!(y|n) " | tee -a $ERRLOG >&2
  if [ "$SCRIPT" ]; then
    A="y"
  else
    read A
    # Next line handles EOF from a pipe as (e)xit
    [ $? -ne 0 ] && A="n"
  fi
  echo "$A" >> $ERRLOG >&2
done
if [ "$A" = "n" ]; then
  exit 1
fi

CLEANTMP=""
CLEANUMNT=""
CLEANCHROOT=""
trap cleanup 2 EXIT

BOOTCD2DISK="bootcd2disk"
if [ -f ./bootcd2disk ]; then
  echo "using local ./bootcd2disk" | 
    if [ "$SCRIPT" ]; then cat >> $ERRLOG; else tee -a $ERRLOG >&2; fi
  BOOTCD2DISK="./bootcd2disk"
fi

BOOTCDMK2DISKCONF="bootcdmk2diskconf"
if [ -f ./bootcdmk2diskconf ]; then
  echo "using local ./bootcdmk2diskconf" | 
    if [ "$SCRIPT" ]; then cat >> $ERRLOG; else tee -a $ERRLOG >&2; fi
  BOOTCDMK2DISKCONF="./bootcdmk2diskconf"
fi

TODO=""
mm=0

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "Directory.*"
TODO="$TODO \"do_dir $TMPDIR # Create tmp directory \""


mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
if [ "$DISKCONF2" ]; then
  TODO="$TODO \"cp $DISKCONF2 $TMPDIR/\""
else
  dbg "--- Creating backup bootcd2disk.conf ---" 
  TODO="$TODO \"$BOOTCDMK2DISKCONF -b -f $BACKUPDEV > $TMPDIR/bootcd2disk.conf\""
fi

if [ ! "$NOMOUNT" ]; then
  mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
  TODO="$TODO \"$BOOTCD2DISK -onlymount -c $TMPDIR -s\""
  mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
  TODO="$TODO CLEANUMNT=\\\"$BOOTCD2DISK -onlyunmount -c $TMPDIR -s\\\"\""
fi

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"  
bootcd2disk_ignore $mm
TODO="$TODO \"$BOOTCD2DISK"
[ "$CONFDIR" = "/etc/bootcd" ] || TODO="$TODO -c $CONFDIR"
[ "$IMAGEURL" ] && TODO="$TODO -url $IMAGEURL"
TODO="$TODO -mkchroot $BACKUPDIR -s\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
TODO="$TODO CLEANCHROOT=\"rm -rf $BACKUPDIR\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
TODO="$TODO \"mkdir -p $COPYDEST/$BACKUPNAME\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_stdout $mm "^backup to .*"
in_ignore $mm "^find: WARNING: Hard link count is wrong for ./proc: .*"
in_stdout $mm "Permission denied$"
in_stdout $mm "^find: \./proc/.*"
in_stdout $mm "^cpio.*truncating inode number"
local RCPIO_EXCLUDE_DIRS="$(echo "$COPYDEST" | sed "s|^/mnt||") $EXCLUDE"
TODO="$TODO \"run_cpio $COPYDEST $BACKUPNAME\" # copy files to backup\""

# EXCLUDE=".$(echo "$COPYDEST" | sed "s|^/mnt||")"
# TODO="$TODO \"tar_ignore\""
# TODO="$TODO \"run \\\"(cd /mnt; tar c -z --exclude $EXCLUDE -f $COPYDEST/$BACKUPNAME/backup.tgz .)\\\"\""
mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
TODO="$TODO \"cp $TMPDIR/bootcd2disk.conf $COPYDEST/etc/bootcd/$BACKUPNAME\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
in_norun $mm # run the next without run 
TODO="$TODO \"chroot $COPYDEST bootcdwrite -s\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
TODO="$TODO \"mv $COPYDEST/var/spool/bootcd/cdimage.iso $BACKUPDIR/\""

mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
TODO="$TODO \"rm -r $COPYDEST\""

if [ ! "$NOMOUNT" ]; then
  mm=$(($mm+1)); eval IGNORE${mm}=\"\"; eval STDOUT${mm}=\"\"
  TODO="$TODO \"$BOOTCD2DISK -onlyunmount -c $TMPDIR -s\""
fi

eval "interactive -r $TODOY $TODO"
