#!/bin/sh

umask 0022

# Defaults
keep="n"
CONFDIR="/etc/mkinitramfs"
verbose="n"
errors_to="2>/dev/null"

while getopts "d:ko:r:" flag; do
	case $flag in
	d)
		CONFDIR="${OPTARG}"
		if [ ! -d "${CONFDIR}" ]; then
			echo "${0}: ${CONFDIR}: Not a directory" >&2
			exit 1
		fi
		;;
	o)
		touch ${OPTARG}
		outfile="$(readlink -f ${OPTARG})"
		;;
	k)
		keep="y"
		;;
	esac
done

shift $((${OPTIND} - 1))

# For dependency ordered mkinitramfs hook scripts.
. /usr/share/initramfs-tools/scripts/functions
. /usr/share/initramfs-tools/hook-functions

. ${CONFDIR}/initramfs.conf
EXTRA_CONF=''
for i in ${CONFDIR}/conf.d/*; do
	EXTRA_CONF="${EXTRA_CONF} $(basename $i | grep '^[a-z0-9][a-z0-9\._-]*$' | grep -v '\.dpkg-.*$')";
done
for i in ${EXTRA_CONF}; do
. ${CONFDIR}/conf.d/${i}
done

if [ x${outfile} = x ]; then
	usage
fi

# And by "version" we really mean path to kernel modules
# This is braindead, and exists to preserve the interface with mkinitrd
if [ ${#} -ne 1 ]; then
	version=$(uname -r)
else 
	version="${1}"
fi

# Check that we're using a new enough kernel version, first for ourselves,
# then for each of the hooks, which can have a MINKVER variable defined
check_minkver ${version}
check_minkver ${version} /usr/share/initramfs-tools/hooks
check_minkver ${version} ${CONFDIR}/hooks

case ${version} in
/lib/modules/*/[!/]*)
        ;;
/lib/modules/[!/]*)
        version=${version#/lib/modules/}
        version=${version%%/*}
        ;;
esac

case ${version} in
*/*)
        echo $PROG: ${version} is not a valid kernel version >&2
        exit 1
        ;;
esac

if [ -d ${outfile} ]; then
	echo "${outfile} is a directory"
	exit 1
fi

MODULESDIR="/lib/modules/${version}"

if [ ! -e ${MODULESDIR} ]; then
	echo "Cannot find ${MODULESDIR}"
	exit 1
fi

DESTDIR=$(mktemp -t -d mkinitramfs_XXXXXX) || exit 1
__TMPCPIOGZ=$(mktemp -t mkinitramfs-OL_XXXXXX) || exit 1

DPKG_ARCH=`dpkg --print-installation-architecture`

# Export environment for hook scripts.
#
export MODULESDIR
export version
export CONFDIR
export DESTDIR
export DPKG_ARCH

# Private, used by 'catenate_cpiogz'.
export __TMPCPIOGZ

for d in bin conf/conf.d etc lib modules sbin scripts; do
    mkdir -p ${DESTDIR}/${d}
done

# MODULES=list case.  Always honour.
for x in ${CONFDIR}/modules /usr/share/initramfs-tools/modules.d/*; do
	if [ -f "${x}" ]; then
		add_modules_from_file ${x}
	fi
done

if [ "${MODULES}" = "dep" ]; then
	dep_add_modules
fi

if [ "${MODULES}" = "most" ]; then
	auto_add_modules
fi

if [ "${MODULES}" = "netboot" ]; then
	auto_add_modules base
	auto_add_modules net
fi

# Have to do each file, because cpio --dereference doesn't recurse down
# symlinks.

ln -s /usr/lib/klibc/bin/* ${DESTDIR}/bin
ln -s /lib/klibc-*.so ${DESTDIR}/lib
copy_exec /usr/share/initramfs-tools/init /init
cp -a /usr/share/initramfs-tools/scripts/* ${DESTDIR}/scripts
for f in $(cd ${CONFDIR}/scripts && \
	find . \( -name '*.dpkg*' -prune -o -name '*~' -prune \) \
		-o -type f -print); do
	mkdir --parents ${DESTDIR}/scripts/$(dirname ${f})
cp -p ${CONFDIR}/scripts/${f} ${DESTDIR}/scripts/$(dirname ${f})
done
echo "DPKG_ARCH=${DPKG_ARCH}" > ${DESTDIR}/conf/arch.conf
copy_exec ${CONFDIR}/initramfs.conf /conf
for i in ${EXTRA_CONF}; do
	copy_exec ${CONFDIR}/conf.d/${i} /conf/conf.d
done

# Busybox
rm -f ${DESTDIR}/bin/sh
ln -s /usr/lib/initramfs-tools/bin/busybox ${DESTDIR}/bin/sh
# This is ugly, but needed atm to make the builtins work =(
ln -s /usr/lib/initramfs-tools/bin/busybox ${DESTDIR}/bin/busybox

# Modutils
copy_exec /sbin/modprobe /sbin
copy_exec /sbin/depmod /sbin
copy_exec /sbin/rmmod /sbin
mkdir -p ${DESTDIR}/etc/modprobe.d
cp -a /etc/modprobe.d/* ${DESTDIR}/etc/modprobe.d

# FIXME: Remove this Raid block after Dapper releases
if [ -x /sbin/mdadm -a -x /sbin/mdrun -a ! -f /usr/share/initramfs-tools/hooks/md ]; then
	copy_exec /sbin/mdadm /sbin
	copy_exec /sbin/mdrun /sbin
	for x in md linear raid0 raid1 raid5 raid6 raid10; do
		manual_add_modules ${x}
	done
fi

# FIXME: Remove this LVM block after Dapper releases
if [ -x /sbin/vgchange -a -d /lib/lvm-200 -a ! -f /usr/share/initramfs-tools/hooks/lvm ]; then
	copy_exec /lib/lvm-200/vgchange /sbin
	for x in dm_mod dm_snapshot; do
		manual_add_modules ${x}
	done
fi

run_scripts /usr/share/initramfs-tools/hooks
run_scripts ${CONFDIR}/hooks

# Apply DSDT to initramfs
if [ -e ${CONFDIR}/DSDT.aml ]; then
	copy_exec ${CONFDIR}/DSDT.aml /
fi

(cd ${DESTDIR} && find . | cpio --quiet --dereference -o -H newc | gzip -9 >${outfile})

if [ -s ${__TMPCPIOGZ} ]; then
    cat ${__TMPCPIOGZ} >>${outfile}
fi

if [ "${keep}" = "y" ]; then
	echo "Working files in ${DESTDIR} and overlay in ${__TMPCPIOGZ}"
else
	rm -rf "${DESTDIR}"
	rm -rf "${__TMPCPIOGZ}"
fi

exit 0
