#!/bin/sh

# initramfs magic

PREREQ=""
prereqs()
{
	echo "$PREREQ"
}

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

. /usr/share/initramfs-tools/hook-functions

# Begin real processing below this line

CONFFILE="/etc/opencrypt/opencrypt.conf"

. /usr/share/opencrypt/functions.sh

# add own error message as copy_file do not provide it
custom_copy_file() {
	local type src target
	type="${1}"
	src="${2}"
	target="${3:-$2}"

	if [ ! -f "$src" ]; then
		echo "E: missing file $src"
		exit 2
	fi
	copy_file "$type" "$src" "$target"
}

# add own error message as copy_exec do not provide it
custom_copy_exec() {
	local src target
	src="${1}"
    target="${2:-$1}"

	if [ ! -f "$src" ]; then
		echo "E: missing file $src"
		exit 2
	fi
	copy_exec "$src" "$target"
}

package_is_installed() {
	local package="$1"
	/bin/dpkg-query --status $package >/dev/null 2>&1
	return $?
}

check_package() {
	local package="$1"
	if ! package_is_installed $package ; then
		echo "E: missing package $package"
		echo "E: please install it"
		exit 2
	fi
}

if [ ! -f "$CONFFILE" ]; then
	echo "E: missing $CONFFILE"
	exit 1
fi

load_params

if [ "x$WAITFOR" != "x" -a ! -L "/sys/class/net/$WAITFOR" ]; then
	echo "E: network device $WAITFOR seems to be missing"
	echo "E: fix WAITFOR in opencrypt.conf"
	exit 1
fi

if [ "x$FIREWALL" != "x" -a "$FIREWALL" != "nftables" -a "$FIREWALL" != "iptables" ]; then
	echo "E: invalid FIREWALL value: $FIREWALL"
	exit 1
fi

if [ "$FIREWALL" = "nftables" -a ! -f "/etc/opencrypt/nftables.conf" ]; then
	echo "W: FIREWALL set to nftables but no rules found"
	echo "W: you should set rules in /etc/opencrypt/nftables.conf"
fi

if [ "$FIREWALL" = "iptables" -a ! -f "/etc/opencrypt/iptables.conf" -a ! -f "/etc/opencrypt/ip6tables.conf" ]; then
	echo "W: FIREWALL set to iptables but no rules found"
	echo "W: you should set rules in /etc/opencrypt/iptables.conf"
	echo "W: and/or /etc/opencrypt/ip6tables.conf"
fi

for m in $(get_remote_modes); do
	if ! is_remotemode_valid "$m" ; then
		echo "E: invalid REMOTEMODE value: $m"
		exit 1
	fi
done

if ! used_network_modes ; then
	if [ "x$WAITFOR" != "x" ]; then
		echo "W: WAITFOR set but networking will not be used"
	fi
	if [ "x$FIREWALL" != "x" ]; then
		echo "W: FIREWALL set but networking will not be used"
	fi
	if [ "$BOND" = "yes" ]; then
		echo "W: BOND set but networking will not be used"
	fi
	if [ "$WPASUPPLICANT" = "yes" ]; then
		echo "W: WPASUPPLICANT set but networking will not be used"
	fi
fi

# sync with verbose level from update-initramfs
[ "$verbose" = "y" ] && VERBOSE="yes"
[ "$VERBOSE" = "yes" ] && verbose="y"

for file in /etc/opencrypt/* /usr/share/opencrypt/*.sh ; do
	custom_copy_file config "$file"
done

# busybox-static forces its own PATH
# so we need busybox package to use our /usr/local/bin
# or no busybox at all
if package_is_installed busybox-static ; then
	echo "E: package busybox-static conflicts with opencrypt"
	echo "E: please remove it or replace it with busybox"
	exit 1
fi

# of course we need cryptsetup
# cryptsetup-initramfs will copy cryptsetup but also some
# mandatory libs such as libgcc_s.so
# so we let him do his good job

# we need some binaries. Either via busybox or as standalone binary.
if [ "$BUSYBOX" = "n" -o "x$BUSYBOXDIR" = "x" ]; then
	for binary in "echo" "cat" "rm" "sha256sum" "grep" "cp" "cut" "mount" "umount" "rm" "expr" "sed" ; do
		custom_copy_exec "/bin/$binary"
	done
	check_package util-linux
	custom_copy_exec /sbin/blkid
fi

if [ "$WPASUPPLICANT" = "yes" ]; then
	[ "$VERBOSE" = "yes" ] && echo "installing wpasupplicant"
	check_package wpasupplicant
	custom_copy_exec /sbin/wpa_supplicant
	custom_copy_exec /sbin/wpa_cli
	custom_copy_exec /sbin/wpa_action
	custom_copy_exec /bin/wpa_passphrase
	for file in /etc/wpa_supplicant.conf /etc/wpa_supplicant/* ; do
		custom_copy_file config "$file"
	done
	for file in /etc/network/*/wpasupplicant /etc/network/*/wireless-tools ; do
		custom_copy_file config "$file"
	done
	[ "$VERBOSE" = "yes" ] && echo "installing iw"
	check_package iw
	custom_copy_exec /sbin/iw
	[ "$VERBOSE" = "yes" ] && echo "installing iwconfig"
	check_package wireless-tools
	custom_copy_exec /sbin/iwconfig
fi

if [ "$BOND" = "yes" ]; then
	[ "$VERBOSE" = "yes" ] && echo "installing ifenslave"
	check_package coreutils
	for file in /etc/network/*/ifenslave ; do
		custom_copy_file config "$file"
	done
	# needed by ifenslave
	custom_copy_exec /bin/printenv
fi

if [ "x$OC_MODULES" != "x" ]; then
	[ "$VERBOSE" = "yes" ] && echo "installing additionnal modules"
	for module in $OC_MODULES ; do
		manual_add_modules "$module"
	done
fi

# if usr-is-merged /sbin and /bin are a link to /usr/sbin and /usr/bin
# and function custom_copy_file in hook-functions will create a link to
# ramfs /usr/sbin, so to busybox, instead of copying the real command
# so we take care to copy /usr/sbin/xxx and not /sbin/xxx
#
# get real ifup/ifdown/ifquery and run-parts
# busybox don't accept some interfaces stances such as "inet"
# and don't know how to source interfaces.d/*

if used_network_modes ; then
	[ "$VERBOSE" = "yes" ] && echo "installing ifup"
	check_package ifupdown

	if [ -L "/sbin" -o ! -f "/sbin/ifup" ]; then
		custom_copy_exec /usr/sbin/ifup /usr/local/bin/ifup
	else
		custom_copy_exec /sbin/ifup /usr/local/bin/ifup
	fi
	ln -rs "$DESTDIR/usr/local/bin/ifup" "$DESTDIR/usr/local/bin/ifdown"
	ln -rs "$DESTDIR/usr/local/bin/ifup" "$DESTDIR/usr/local/bin/ifquery"

	# we need debianutils for /bin/run-parts used by ifup
	check_package debianutils
	custom_copy_exec /usr/bin/run-parts /usr/local/bin/run-parts

	[ "$VERBOSE" = "yes" ] && echo "installing network interfaces"
	for file in /etc/network/interfaces /etc/network/interfaces.d/* ; do
		[ -f "$file" ] && custom_copy_file config "$file"
	done

	[ "$VERBOSE" = "yes" ] && echo "installing network dirs"
	# ifup needs some dirs even if empty
	for dir in "if-down.d" "if-post-down.d" "if-pre-up.d" "if-up.d" ; do
		mkdir -p "$DESTDIR/etc/network/$dir"
	done

	[ "$VERBOSE" = "yes" ] && echo "installing ip"
	check_package iproute2
	# get real ip as busybox doesn't list correct state
	if [ -L "/sbin" -o ! -f "/bin/ip" ]; then
		custom_copy_exec /usr/bin/ip /usr/local/bin/ip
	else
		custom_copy_exec /bin/ip /usr/local/bin/ip
	fi
fi

if [ "$FIREWALL" = "iptables" ]; then
	# use iptables to setup a firewall during initramfs
	[ "$VERBOSE" = "yes" ] && echo "installing iptables"
	check_package iptables
	custom_copy_exec /sbin/iptables-restore
	custom_copy_exec /sbin/ip6tables-restore
elif [ "$FIREWALL" = "nftables" ]; then
	# use nft to setup a firewall during initramfs
	[ "$VERBOSE" = "yes" ] && echo "installing nft"
	check_package nftables
	custom_copy_exec /sbin/nft
	# nftables.conf could use services and protocol by name
	custom_copy_file config /etc/protocols /etc/protocols
	custom_copy_file config /etc/services /etc/services
fi

if used_remote "wget" ; then
	[ "$VERBOSE" = "yes" ] && echo "installing wget"
	check_package wget
	# we need real wget to use TLS
	if [ -L "/sbin" -o ! -f "/bin/wget" ]; then
		custom_copy_exec /usr/bin/wget /usr/local/bin/wget
	else
		custom_copy_exec /bin/wget /usr/local/bin/wget
	fi
fi

if used_remote "arp" ; then
	[ "$VERBOSE" = "yes" ] && echo "installing arp"
	check_package net-tools
	custom_copy_exec /sbin/arp
fi

if used_remote "ssh" ; then
	[ "$VERBOSE" = "yes" ] && echo "installing ssh"
	# we need a clean ssh user
	if ! grep -qs '^root:' "${DESTDIR}/etc/passwd"; then
		echo "root:x:0:0:root:/:/bin/sh" >> "${DESTDIR}/etc/passwd"
	fi
	check_package openssh-client
	custom_copy_exec /bin/ssh
fi

[ "$VERBOSE" = "yes" ] && echo "installing backup crypttab"
tmpcrypt="/tmp/$$-crypttab"
while read MAP CRYPT KEY PARAM ; do
    MAP=$(echo "$MAP" | cut -d'#' -f1)
    if [ "$KEY" = "none" -a "x$MAP" != "x#" -a "x$MAP" != "x" ]
    then
        echo "$MAP $CRYPT $KEY $PARAM" >> "$tmpcrypt"
    fi
done < "/etc/crypttab"
copy_file config "$tmpcrypt" /etc/opencrypt/crypttab
rm -f "$tmpcrypt"
