#!/bin/sh
#===============================================================================
#
#  trustfence-initramfs-init
#
#  Copyright (C) 2019 by Digi International Inc.
#  All rights reserved.
#
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License version 2 as published by
#  the Free Software Foundation.
#
#
#  !Description: Init script for Trustfence initramfs
#
#===============================================================================

HALT_TIME="10"

read_uboot_var() {
	eval "${2}=\"$(fw_printenv -n ${1} 2>/dev/null)\""
}

error() {
	[ "${#}" != "0" ] && printf "\n[ERROR]: %s\n\n" "${1}"
	echo "The system will halt in ${HALT_TIME} seconds"
	sleep "${HALT_TIME}"
	sync && busybox halt -f
}

# Main
#------------------------------------------------------------------------------
# Setup the environment.
export PATH=/bin:/sbin:/usr/bin:/usr/sbin

mkdir -p /proc /sys /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev

# Setup fw_printenv.
mkdir -p /var/lock

# Set kernel console loglevel
LOGLEVEL="$(sysctl -n kernel.printk)"
sysctl -q -w kernel.printk=4

for arg in $(cat /proc/cmdline); do
	case "${arg}" in
		init=*|rescue=1|root=*) eval ${arg};;
	esac
done

# Translate "PARTUUID=..." to real device
root="$(findfs ${root})"

# Jump to a rescue shell if requested
if [ -n "${rescue}" ]; then
	# Expand console and respawn if exited
	while true; do
		setsid cttyhack sh -l
		sleep 1
	done
fi

# Get encrypted partition list and remove duplicate entries
read_uboot_var encrypted_parts_list ENC_PARTS
ENC_PARTS=$(echo "${ENC_PARTS}" | tr ' ' '\n' | sort | uniq | tr '\n' ' ' | xargs)

for p in ${ENC_PARTS}; do
	# Translate partition name to block device
	block="/dev/mmcblk0p$(fdisk -l /dev/mmcblk0 | sed -ne "s,^[^0-9]*\([0-9]\+\).*\<${p}\>.*,\1,g;T;p")"

	# Open LUKS encrypted device
	trustfence-tool ${block} crypt${p}

	if [ ! "$?" = "0" ]; then
		error "unable to open encrypted partition ${p}"
	fi

	if [ "${p}" = "rootfs" ]; then
		# Reset root variable to the decrypted mapped device
		root="/dev/mapper/cryptrootfs"
	elif [ "${p}" = "update" ]; then
		# Mount update partition after mounting the rootfs
		UPDATE="/dev/mapper/cryptupdate"
	fi
done

# Mount mapped device
mkdir -p /newroot
FSTYPE="$(blkid ${root} | sed -e 's,.*TYPE="\([^"]\+\)".*,\1,g')"
mount ${FSTYPE:+-t ${FSTYPE}} ${root} /newroot

if [ -n "${UPDATE}" ]; then
	mkdir -p /newroot/mnt/update
	FSTYPE="$(blkid ${UPDATE} | sed -e 's,.*TYPE="\([^"]\+\)".*,\1,g')"
	mount ${FSTYPE:+-t ${FSTYPE}} ${UPDATE} /newroot/mnt/update
fi

#
# Clean-up and do the switch_root to the final rootfs
#
# - restore previous kernel console loglevel
# - umount virtual filesystems
#
[ -n "${LOGLEVEL}" ] && sysctl -q -w kernel.printk="${LOGLEVEL}"
mount --move /dev /newroot/dev
umount /sys /proc
exec switch_root /newroot ${init:-/sbin/init}
