#!/bin/busybox ash
# Install busybox's applets as symlinks
/bin/busybox --install -s

. /init_functions

msg ":: Loading Initramfs"
/bin/mount -t proc proc /proc
/bin/mount -t sysfs sys /sys
if grep -q devtmpfs /proc/filesystems 2>/dev/null; then
  /bin/mount -n -t devtmpfs udev /dev -o mode=0755,size=10M,nosuid
else
  /bin/mount -n -t tmpfs udev /dev -o mode=0755,size=10M,nosuid
fi

read CMDLINE </proc/cmdline
export CMDLINE

export root=""
export init=""
echo "/sbin/modprobe" > /proc/sys/kernel/modprobe

# set default mount handler
mount_handler="default_mount_handler"

# if available, start udevd at this stage
if [ -x /sbin/udevd ]; then
    msg ":: Starting udevd..."
    echo > /proc/sys/kernel/hotplug
    /sbin/udevd --daemon --resolve-names=never
    export udevd_running=1
    msg "done."
else
    export udevd_running=0
fi

for cmd in ${CMDLINE}; do
    case "${cmd}" in
        \#*) break ;; # ignore everything after a # in the commandline
        # The kernel passes those to the kernel on its own
        [0123456Ss]) ;;
        [0-9]*) ;;
        single) ;;
        rw) readwrite="yes" ;;
        ro) readwrite="no" ;;
        # only export stuff that does work with ash :)
        *=*) rhs="$(echo "${cmd}" | cut -d= -f2-)"
             cmd="$(echo "${cmd}" | cut -d= -f1 | sed 's|\.|_|g')"
             cmd="$(echo "${cmd}" | sed 's|-|_|g')=${rhs}"
             (echo "${cmd}" | grep -qe '^[0-9]') || export "${cmd}"
             ;;
        *)   cmd="$(echo "${cmd}" | sed 's|\.|_|g')"
             cmd="$(echo "${cmd}" | sed 's|-|_|g')"
             (echo "${cmd}" | grep -qe '^[0-9]') || export "${cmd}=y"
             ;;
    esac
done

if [ -n "${disablehooks}" ]; then
    for d in $(echo "${disablehooks}" | sed 's|,| |g'); do
        export "hook_${d}=disabled"
    done
fi

if [ -n "${disablemodules}" ]; then
    for d in $(echo "${disablemodules}" | sed 's|,| |g'); do
        export "mod_${d}=disabled"
    done
fi

if [ -n "${earlymodules}" ]; then
    for m in $(echo "${earlymodules}" | sed 's|,| |g'); do
        /sbin/modprobe -q ${m} > /dev/null 2>&1
    done
fi

. /config

for m in ${MODULES}; do
    TST=""
    eval "TST=\$mod_${m}"
    if [ "${TST}" != "disabled" ]; then
        /sbin/modprobe -q ${m} > /dev/null 2>&1
    fi
done

# If rootdelay is empty or not a non-negative integer, set it to 10
if [ -z "${rootdelay}" ] || ! [ "${rootdelay}" -ge 0 ]; then
    export rootdelay=10
fi

if [ -e "/hooks" ]; then
    for h in ${HOOKS}; do
        TST=""
        eval "TST=\$hook_${h}"
        if [ "${TST}" != "disabled" ]; then
            run_hook () { msg "${h}: no run function defined"; }
            if [ -e "/hooks/${h}" ]; then
               . /hooks/${h}
               msg ":: Running Hook [${h}]"
               run_hook
            fi
        fi
    done
fi

if [ "${break}" = "y" ]; then
    echo ":: Break requested, type 'exit' to resume operation"
    launch_interactive_shell
fi

if [ -f "/message" ]; then
    msg "$(cat /message)"
fi

# Mount root at /new_root
mkdir -p /new_root
${mount_handler} /new_root

[ -z "${init}" ] && init="/sbin/init"
if [ "$(stat -c %D /)" = "$(stat -c %D /new_root)" ]; then
    # Nothing got mounted on /new_root. This is the end, we don't know what to do anymore
    # We fall back into a shell, but the shell has now PID 1
    # This way, manual recovery is still possible.
    err "Failed to mount the real root device."
    echo "Bailing out, you are on your own. Good luck."
    echo
    launch_interactive_shell --exec
elif [ ! -x "/new_root${init}" ]; then
    # Successfully mounted /new_root, but ${init} is missing
    # The same logic as above applies
    err "Root device mounted successfully, but ${init} does not exist."
    echo "Bailing out, you are on your own. Good luck."
    echo
    launch_interactive_shell --exec
fi

#Special handling if udev is running
udevpid=$(/bin/pidof udevd)
if [ -n "${udevpid}" ]; then
    # Settle pending uevents, then kill udev
    /sbin/udevadm settle
    /bin/kill ${udevpid} > /dev/null 2>&1
    while /bin/pidof udevd >/dev/null; do
        sleep 0.1
    done
fi

mount --move /proc /new_root/proc
mount --move /sys /new_root/sys
mount --move /dev /new_root/dev
exec /sbin/switch_root -c /dev/console /new_root ${init} "$@"
