#!/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="${OPTAGS}"
		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

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

if dpkg --compare-versions "${version}" lt 2.6.12; then
	echo "Kernel version too old.  initramfs-tools requires at least 2.6.12."
	exit 1
fi

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

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

# Private, used by 'catenate_cpiogz'.
export __TMPCPIOGZ

for d in bin conf 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

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

ln -s /usr/lib/klibc/bin/* ${DESTDIR}/bin
ln -s /usr/lib/klibc/lib/* ${DESTDIR}/lib
copy_exec /usr/share/initramfs-tools/init /init
cp -a /usr/share/initramfs-tools/scripts/* ${DESTDIR}/scripts
for f in $(cd /etc/mkinitramfs/scripts && \
	find . \( -name '*.dpkg*' -prune -o -name '*~' -prune \) \
		-o -type f -print); do
	mkdir --parents ${DESTDIR}/scripts/$(dirname ${f})
cp -p /etc/mkinitramfs/scripts/${f} ${DESTDIR}/scripts/$(dirname ${f})
done
copy_exec ${CONFDIR}/initramfs.conf /conf
cp -a /etc/udev ${DESTDIR}/etc

# Hack until udev is built with klibc
copy_exec /sbin/udev /sbin
copy_exec /sbin/udevstart /sbin

# Busybox
rm ${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
copy_exec /etc/modprobe.d/aliases /etc/modprobe.d

# Raid
copy_exec /sbin/mdadm /sbin
copy_exec /sbin/mdrun /sbin

# LVM
copy_exec /lib/lvm-200/vgchange /sbin

run_scripts /usr/share/initramfs-tools/hooks
run_scripts /etc/mkinitramfs/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
