#!/bin/sh
#
# bootcd2disk
#
# DISK=auto, we will build an boot partition with size defined in BOOTS

TODO="-y"
if [ "$1" = "-i" ]; then
  TODO=""
  shift
fi

BOOTCD2DISKLIB=./bootcd2disk.lib
if [ -f $BOOTCD2DISKLIB ]; then
  echo "Using local $BOOTCD2DISKLIB"
  . $BOOTCD2DISKLIB $*
else
  BOOTCD2DISKLIB=/usr/share/bootcd/bootcd2disk.lib
  if [ -f $BOOTCD2DISKLIB ];then
    . $BOOTCD2DISKLIB $*
  else
    echo "Error: Mandatory lib $BOOTCD2DISKLIB not found! ABORT!"
    exit 1
  fi
fi

# getdata - print without empty lines and comments
getdata()
{
  echo "$*" | sed "s/#.*$//" | grep -v "^$"
}

### Main ###

A=""
while [ "$A" != "y" -a "$A" != "n" ]
do
  [ "$DISK" ] && echo "Harddisk $DISK will be erased!!!" | tee -a $ERRLOG >&2
  [ "$SWAP" ] && echo "Partition $SWAP will be newly created as SWAP !!!" | tee -a $ERRLOG >&2
  [ "$EXT2FS" ] && echo "Partition $EXT2FS will be newly created as $OPT !!!" | tee -a $ERRLOG >&2
  [ "$VFAT" ] && echo "Partition $VFAT will be newly created as vfat !!!" | tee -a $ERRLOG >&2
  echo -n "(y/n) " | tee -a $ERRLOG >&2
  if [ "$SCRIPT" ]; then
    A="y"
  else
    read A
  fi
  echo "$A" >> $ERRLOG >&2
done
if [ "$A" = "n" ]; then
  exit 1
fi

trap cleanup 2

lvmreset()
{
  if [ "$LVMGRP" -a "$LVMVOL" ]; then
    echo "--- Trying to deactivate LVM ---" | tee -a $ERRLOG >&2
    ignore "Reading all physical volumes.  This may take a while..."
    ignore "Found volume group \".*\" using metadata type lvm2"
    ignore "No volume groups found"
    run vgscan --quiet
    ignore "0 logical volume(s) in volume group \".*\" now active"
    ignore "No volume groups found"
    run vgchange --quiet --ignorelockingfailure -an
  fi


  if [ "$LVMGRP" -a "$LVMVOL" ]; then
    echo "--- Destroy old disk infos ---" | tee -a $ERRLOG >&2
    ignore "1+0 records in"
    ignore "1+0 records out"
    ignore "512 bytes (512 B) copied"
    run "
      getdata \"$LVMGRP\" | sed "s/vgcreate.*//" |
      while read grp dsks; do
        for dsk in \$dsks; do
          dd if=/dev/zero of=\$dsk bs=512 count=1
        done
      done
    "
  fi

  if [ "$LVMGRP" -a "$LVMVOL" ]; then
    echo "--- Check if lvm is deactivated ---" | tee -a $ERRLOG >&2
    run "
    getdata \"$LVMVOL\" |
    while read vol s grp cmd; do
      if [ -e /dev/mapper/\$grp-\$vol -o -e /dev/\$vol/\$grp ]; then
        echo \"Could not deactivate LVM. Please reboot and run again.\"
      fi
    done
    "
  fi
}
if [ "$LVMGRP" -a "$LVMVOL" ]; then
  TODO="$TODO \"lvmreset # deactivate lvm, delete lvm info on disk\""
fi

partdisk()
{
  echo "--- Partitioning Disk $DISK ---" | tee -a $ERRLOG >&2
  stdout "^ $DISK: "
  stdout "^sfdisk: ERROR: sector .* does not have an msdos signature"
  stdout "^No partitions found"
  run "echo \"$SFDISK\" | sfdisk -qL -uM $DISK >/dev/null"
}
if [ "$SFDISK" ]; then
  TODO="$TODO \"partdisk # partition Disk $DISK\""
fi


buildlvm()
{
  echo "--- pvcreate ---" | tee -a $ERRLOG >&2
  ignore "WARNING: Forcing physical volume creation on .* of volume group \".*\""
  ignore "Physical volume \".*\" successfully created"
  run "
    getdata \"$LVMGRP\" | sed "s/vgcreate.*//" |
    while read grp dsks; do
    for dsk in \$dsks; do
      pvcreate --quiet -d -ff -y \$dsk
    done
  done
  "

  echo "--- vgcreate ---" | tee -a $ERRLOG >&2
  ignore "Volume group \".*\" successfully created"
  ignore "0 logical volume(s) in volume group \".*\" now active"
  run "
    getdata \"$LVMGRP\" |
    while read grp dsks; do
      cmd=\"\$(echo \"\$dsks\"|sed \"s/.*\(vgcreate.*\)/\1/\"|grep vgcreate)\"
      if [ \"\$cmd\" ]; then
        \$cmd
      else
        vgcreate --quiet \$grp \$dsks
      fi
      vgchange --quiet -aey \$grp
  done
  "

  echo "--- lvcreate ---" | tee -a $ERRLOG >&2
  ignore "Logical volume \".*\" created"
  stdout "Rounding up size to full physical extent"
  run "
  getdata \"$LVMVOL\" |
  while read vol s grp cmd; do
    if [ \"\$cmd\" ]; then
      \$cmd
    else
      lvcreate -n \$vol -L \$s \$grp 
    fi
  done
  "

  echo "--- Activate LVM ---" | tee -a $ERRLOG >&2
  ignore "Reading all physical volumes.  This may take a while..."
  ignore "Found volume group \".*\" using metadata type lvm2"
  run vgscan --quiet
  ignore "[1-9][0-9]* logical volume(s) in volume group \".*\" now active"
  run vgchange --quiet -ay
}
if [ "$LVMGRP" -a "$LVMVOL" ]; then
  TODO="$TODO \"buildlvm # pvcreate, vgcreate, lvcreate, vgchange\""
fi

vfat()
{
  for i in $VFAT; do
    echo "--- Building Filesystem $i with mkdosfs ---" | tee -a $ERRLOG >&2
    stdout "^mkdosfs "
    run "mkdosfs $i"
  done
}
if [ "$VFAT" ]; then
  TODO="$TODO \"vfat # mkdosfs $VFAT\""
fi

extfs()
{
  OPT=""
  [ "$EXT3" = "yes" ] && OPT="-j"
  for i in $EXT2FS; do
    echo "--- Building Filesystem $i with mke2fs $OPT ---" | tee -a $ERRLOG >&2
    stdout "^mke2fs "
    run "mke2fs $OPT -q $i"
  done
}
if [ "$EXT2FS" ]; then
  TODO="$TODO \"extfs # mke2fs $EXT2FS\""
fi

swap()
{
  for i in $SWAP; do
    echo "--- making SWAP $i ---" | tee -a $ERRLOG >&2
    stdout "^Setting up swapspace"
    stdout "^no label, "
    run "mkswap $i"
  done
}
if [ "$SWAP" ]; then
  TODO="$TODO \"swap # mkswap $SWAP\""
fi

domount()
{
  echo "--- mounting DISK ---" | tee -a $ERRLOG >&2
  run "$MOUNT"

  #find mountpoints and exclude them, otherwise cpio might complain
  CPIOEXMOUNT="$(mount | grep /mnt/ | awk '{gsub(/\/mnt/,"")};{print}')"
  CPIOEXCLUDE=""
  if [ ! -z "$CPIOEXMOUNT" ];then
    for AEXCLUDE in $CPIOEXMOUNT; do
      CPIOEXCLUDE="$CPIOEXCLUDE -e '^$AEXCLUDE\$'"
    done
  fi
}
TODO="$TODO \"domount # mount all partitions to /mnt\""

copycdram()
{
  echo "--- copying CD and RAM ---" | tee -a $ERRLOG >&2
  run "find / -mount|grep -v -e '^/var.ro\>' -e '^/var\>' $CPIOEXCLUDE |cpio --quiet -pdum /mnt"
  run "cd /var.ro; find . -mount | cpio --quiet -pdum /mnt/var"
  run "find /mnt/etc /mnt/tmp /mnt/dev /mnt/home /mnt/root -type l | xargs -r rm"
  run rm -r /mnt/etc.ro /mnt/tmp.ro /mnt/dev.ro /mnt/home.ro /mnt/root.ro
  run cp -a -x /ram1/etc /ram1/tmp /ram1/home /ram1/root /mnt
  if [ -d /dev/.static/dev -a -x /etc/init.d/udev ]; then
    echo "--- handling udev ---" 
    # -- udev --
    # The filesystem has static device files in /dev.
    # But tmpfs is mounted over /dev and hides the static device files.
    # The static device files are mounted again in /dev/.static/dev/.
    # This means bootcd has only to copy /dev/.static/dev.
    run cp -a -x /ram1/dev/.static/dev /mnt
    run mkdir -p /mnt/dev/.static
    run chown root:root /mnt/dev/.static
    run chmod 700 /mnt/dev/.static
  else
    run cp -a -x /ram1/dev /mnt
  fi


  run rm -f /mnt/fastboot /mnt/cdboot.catalog /mnt/cdboot.img /mnt/ram1.cpio.gz /mnt/ram2.cpio.gz
  run rm -rf /mnt/rr_moved/ /mnt/isolinux/
  run rm /mnt/etc/rcS.d/S12bootcdram.sh \
    /mnt/etc/rcS.d/S13bootcdflop.sh \
    /mnt/usr/bin/bootcd2disk \
    /mnt/usr/bin/bootcdflopcp \
    /mnt/etc/bootcd/bootcd2disk.conf \
    /mnt/etc/bootcd/thisbootcd.conf
  run rmdir /mnt/ram1 /mnt/ram2

  echo "--- deleting NOT_TO_RAM symlinks ---" 
  NOT_TO_RAM_RO=$(find /ram1 /ram2 -xdev -type l | xargs /bin/ls -l | grep -e " -> /etc.ro/" -e " -> /home.ro/" -e " -> /root.ro/" | awk '{ print $(NF) }')
  for i in $NOT_TO_RAM_RO; do     # exp: i=/etc.ro/X11
    j=$(echo $i | sed "s/\.ro//") #   => j=/etc/X11
    run rm /mnt/$j                #   => /mnt/etc/X11 -> /etc.ro/X11
    run cp -a $i /mnt/$j
  done
}
TODO="$TODO \"copycdram # copy cd and ram to /mnt, delete unneeded stuff\""

do_after_copy()
{
  echo "--- do function after_copy ---" | tee -a $ERRLOG >&2
  after_copy
}

# only call the function, if it is defined
doit=$(egrep "^[[:space:]]*(function)*[[:space:]]*after_copy" $CONFDIR/bootcd2disk.conf)
if [ ! -z "$doit" ]; then
  TODO="$TODO \"do_after_copy # run function after_copy defined in bootcd2disk.conf\""
fi

do_fstab()
{
  echo "--- Building fstab ---" | tee -a $ERRLOG >&2
  run "echo \"$FSTAB\" > /mnt/etc/fstab"

  echo "--- Resetting mtab ---" | tee -a $ERRLOG >&2
  run "rm -f /mnt/etc/mtab"
}
TODO="$TODO \"do_fstab # create /mnt/etc/fstab\""

bootloadercfg()
{
  if [ "$GRUB" ]; then
    echo "--- Building grub/menu.lst ---" | tee -a $ERRLOG >&2
    run "echo \"$GRUB\" > /mnt/boot/grub/menu.lst"
  fi

  if [ "$LILO" ]; then
    echo "--- Building lilo.conf ---" | tee -a $ERRLOG >&2
    run "echo \"$LILO\" > /mnt/etc/lilo.conf"
  fi

  if [ "$ELILO" ]; then
    echo "--- Building elilo.conf ---" | tee -a $ERRLOG >&2
    run "echo \"$ELILO\" > /mnt/etc/elilo.conf"
  fi
}
TODO="$TODO bootloadercfg"

createsshkeys()
{
  # each installed PC gets a unique hostkey (only if hostkey already existed)
  create_host_keys /mnt/etc/ssh
}
if [ "$SSHHOSTKEY" = "yes" ]; then
  TODO="$TODO createsshkeys"
elif [ "$SSHHOSTKEY" != "no" ]; then
  warn 'SSHHOSTKEY is not defined as "yes" or "no".' \
       'It will be treated as "no".'
fi

enablecron()
{
  echo "--- Enabling turned off stuff ---" | tee -a $ERRLOG >&2
  for f in $DISABLE_CRON; do
    if [ -f /mnt/$f.no_run_on_bootcd ]; then 
      run rm /mnt/$f
      run mv /mnt/$f.no_run_on_bootcd /mnt/$f
    fi
  done
}
if [ "$DISABLE_CRON" ]; then
  TODO="$TODO enablecron"
fi

dogrub()
{
  [ -z "$GRUBBOOTDIR" ]&&GRUBBOOTDIR=0
  echo "--- Running grub ---" | tee -a $ERRLOG >&2
echo "root (hd0,$GRUBBOOTDIR)
setup (hd0)
quit
" | grub --batch
}
if [ "$GRUB" ]; then
  TODO="$TODO \"dogrub # run grub with root (hd0,$GRUBBOOTDIR), setup (hd0)\""
fi

dolilo()
{
  echo "--- Running lilo ---" | tee -a $ERRLOG >&2
  run "chroot /mnt mount /proc"
  stdout "^Added "
  run "chroot /mnt lilo -w"
  run "chroot /mnt umount /proc"
}
if [ "$LILO" ]; then
  TODO="$TODO dolilo"
fi

doelilo()
{
  echo "--- Running elilo ---" | tee -a $ERRLOG >&2
  run "chroot /mnt elilo"
}
if [ "$ELILO" ]; then
  TODO="$TODO doelilo"
fi

dounmount()
{
  echo "--- unmounting DISK ---" | tee -a $ERRLOG >&2
  run cp $ERRLOG /mnt/var/log
  run "$UMOUNT"
}
TODO="$TODO dounmount"

eval "interactive $TODO"

echo "Please Reboot now !" | tee -a $ERRLOG >&2
