#!/bin/sh

#
# Standard initramfs preamble
#
prereqs()
{
    echo ""
}

case $1 in
prereqs)
	prereqs
	exit 0
	;;
esac

#
# Helper functions
#
cipher_modname() {
    # When changing this, don't forget to update the copy in
    # initramfs-tools-hook, as well as the list of all known cipher
    # modules in the iterate_cipher_module call near the end of
    # initramfs-tools-hook.
    case "$1" in
	NONE|XOR|AES*)
	    ;;
	twofish*)
	    echo loop_twofish
	    ;;
	blowfish*)
	    echo loop_blowfish
	    ;;
	serpent*)
	    echo loop_serpent
	    ;;
	mars*|rc6*|tripleDES)
	    echo "WARNING| (loop-aes) Don't know how to handle encryption type $1" 1>&2
	    ;;
	*)
	    echo "WARNING| (loop-aes) Unknown encryption type $1" 1>&2
	    ;;
    esac
}

get_options()
{
    # Do we have any settings from the /conf/conf.d/loopaesroot file?
    [ -r /conf/conf.d/loopaesroot ] && . /conf/conf.d/loopaesroot
    loopaes_opts="${LOOPAESOPTS}"

    # Does the kernel boot command line override them?
    for x in $(cat /proc/cmdline); do
	case $x in
	    loopaesopts=*)
		loopaes_opts=${x#loopaesopts=}
		;;
	esac
    done

    # Sanity check
    if [ -z "${loopaes_opts}" ]; then
	# Apparently the root partition isn't encrypted
	exit 0
    fi

    # If you change this, keep the version in initramfs-tools-script
    # in sync.
    local opt module
    local IFS=", "
    for opt in $loopaes_opts; do
	case $opt in
	    encryption=*)
		module="$(cipher_modname "${opt#encryption=}")"
		if [ -n "$module" ]; then
		    rootencryption="${rootencryption}${rootencryption:+:}${module}"
		fi
		losetup_opts="${losetup_opts} -e ${opt#encryption=}"
		;;
	    offset=*)
		losetup_opts="${losetup_opts} -o ${opt#offset=}"
		;;
	    sizelimit=*)
		losetup_opts="${losetup_opts} -s ${opt#sizelimit=}"
		;;
	    pseed=*)
		losetup_opts="${losetup_opts} -S ${opt#pseed=}"
		;;
	    phash=*)
		losetup_opts="${losetup_opts} -H ${opt#phash=}"
		;;
	    loinit=*)
		losetup_opts="${losetup_opts} -I ${opt#loinit=}"
		;;
	    itercountk=*)
		losetup_opts="${losetup_opts} -C ${opt#itercountk=}"
		;;
	    gpgkey=*)
		losetup_opts="${losetup_opts} -K ${opt#gpgkey=}"
		;;
	    gpghome=*)
		rootgpghome=${opt#gpghome=}
		;;
	    loop=*)
		rootloop=${opt#loop=}
		;;
	    *)
		# Presumably a non-supported or filesystem option
		;;
	esac
    done
}

#
# Begin real processing
#

# Define crypto variables
get_options

# Sanity check
if [ -z "${rootloop}" ]; then
    echo "root on loop enabled, but no loop device given"
    exit 1
fi

if [ -z "${rootgpghome}" ]; then
    rootgpghome=/.gnupg
fi
losetup_opts="${losetup_opts} -G ${rootgpghome}"

modprobe -q loop
for mod in "$rootencryption"; do
    modprobe -q "$mod"
done

while ! [ -b "${rootloop}" ]; do
      sleep 1
done

# Use /sbin/losetup to make sure that we get the loopaes modified one,
# not the busybox one.
while ! /sbin/losetup ${losetup_opts} "${rootloop}" "$ROOT"; do
	sleep 1
done

# init can now pick up new FSTYPE, FSSIZE and ROOT
echo "ROOT=\"${rootloop}\"" >> /conf/param.conf
exit 0

