# Physical block devices (devArray), virtual block devices (mapArray)
# and Mount points (mntArray) to be used
devArray=(/dev/hda1 /dev/hda2)
mapArray=(swap tmp)
mntArray=(swap /tmp)

# cryptsetup-luks binary
LUKS_BIN=/sbin/cryptsetup-luks

# Functions to mount and umount devices
function do_mount(){
for (( i=0 ; i < ${#devArray[@]} ; ++i )) ; do

   dev=${devArray[$i]}
   map=${mapArray[$i]}
   mnt=${mntArray[$i]}

   if [ -z "$dev" ] || [ ! -e "$dev" ] ; then
      echo "Unable to find \"$dev\"" >&2
      continue
   fi

   # swap and /tmp are re-created on each reboot
   # there is no need to check the whether it is a LUKS volume
   if [ $map != "swap" ] && [ $map != "tmp" ] ; then
      if ! $LUKS_BIN isLuks "$dev" ; then
         echo "\"$dev\" doesn't seem to be a Luks encrypted volume" >&2
         continue
      fi
   fi

   # now check whether device is already opened
   if [ -z "$map" ] ; then
      echo "Map name unspecified for \"$dev\"" >&2
      continue
   elif [ -e "/dev/mapper/$map" ]; then
      echo "\"/dev/mapper/$map\" already exists" >&2
      continue
   fi

   # there is no mount point for swap, so skip the check for swap
   if [ $map != "swap" ] ; then
      if [ -z "$mnt" ] || [ ! -d "$mnt" ] ; then
     	   echo "Unable to find mount point for \"$dev\"" >&2
         continue
      fi
   fi

   echo "Next device in list is \"$dev\" to be used as \"$map\"." 

   # swap has to be treated separately
   if [ $map = "swap" ] ; then
	do_mount_swap;
	continue
   fi

   # /tmp has to be treated separately
   if [ $map = "tmp" ] ; then
	do_mount_tmp;
	continue
   fi

   # open and mount device
   $LUKS_BIN luksOpen "$dev" "$map"
   /bin/mount "/dev/mapper/$map" "$mnt"
done
}

function do_umount(){
for (( i=0 ; i < ${#devArray[@]} ; ++i )) ; do
   mnt=${mntArray[$i]}
   map=${mapArray[$i]}

   # swap has to be treated separately
   if [ $map = "swap" ] ; then
	do_umount_swap;
	continue
   fi

   # during umount /tmp is just an ordinary mount which can be handled
   # just like any other LUKS file system
   if grep $mnt /etc/mtab > /dev/null; then
      fuser -m $mnt > /dev/null || (/bin/umount $mnt; $LUKS_BIN luksClose $map)
   else
      echo $mnt is not mounted!
	   if [ -e /dev/mapper/$map ]; then
	      echo "Removing the mapper " $map
	      $LUKS_BIN luksClose $map
	   fi
   fi
done
}

function do_check_cryptsetup(){
   if ! $LUKS_BIN --help | grep -q luksFormat ; then
      echo "This script requires cryptsetup with LUKS support" >&2
   exit 1
fi
}

function do_mount_swap(){
   $LUKS_BIN -s 256 -d /dev/urandom create $map $dev
   /sbin/mkswap /dev/mapper/$map
   /sbin/swapon /dev/mapper/$map
}

function do_umount_swap(){
   /sbin/swapoff /dev/mapper/$map
   $LUKS_BIN remove $map
}

function do_mount_tmp(){
   $LUKS_BIN -s 256 -d /dev/urandom create $map $dev
   /sbin/mkfs.ext2 > /dev/null /dev/mapper/$map
   /bin/mount /dev/mapper/$map $mnt
}

case "$1" in
   start)
      echo "Mounting crypto file systems"
	do_check_cryptsetup
	do_mount
        ;;
   stop)
      echo "Unmounting crypto file systems"
	do_check_cryptsetup
	do_umount
        ;;
   *)
      echo "Usage: $0 {start|stop}"
      exit 1
      ;;
esac
