#!/bin/bash
. /init_functions
# add sh symlink
ln -s /bin/bash /bin/sh
ln -s /sbin/modprobe /bin/modprobe

msg ":: Loading Initramfs"

/bin/mount -t sysfs none /sys
/bin/mount -t proc  none /proc

read CMDLINE </proc/cmdline
export CMDLINE

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

# 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
    msg "done."
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 :)
        *=*) 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
        /bin/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"
    PS1="ramfs$ " /bin/sh -i
fi

if [ "${root}" = "" -a "${ip}" = "" ]; then
    # enter install environment
    exec /sbin/init
else
    if [ -f "/message" ]; then
        msg "$(cat /message)"
    fi

    mkdir -p /new_root
    if [ -z "${nfsroot}" -a "${root}" != "/dev/nfs" ]; then
        if [ ${root:0:5} != "/dev/" ] || ! poll_device "${root}" ${rootdelay}; then
            msg "\nRoot device '${root}' doesn't exist. Attempting to create it."
            rootdev=""
        if [ ${root:0:5} = "/dev/" ]; then
            # It might be a block device (/dev/sda)
           if [ -f /sys/block/${root:5}/dev ]; then
               rootdev="$(cat /sys/block/${root:5}/dev | sed 's|:| |')"
               # It might be a partition on any block device (/dev/sda1)
           else
               for dir in /sys/block/*; do
                   if [ -f ${dir}/${root:5}/dev ]; then
                       rootdev="$(cat ${dir}/${root:5}/dev | sed 's|:| |')"
                       break
                   fi
               done
           fi
           # It might be a major/minor pair (8:1)
           elif echo ${root} | grep -q :; then
               rootdev="$(echo ${root} | sed 's|:| |')"
               root="/dev/root"
           # It might be major/minor encoded as a single hex-number (lilo-style) (801)
           elif [ ${#root} -le 4 -a ${#root} -gt 2 ] && echo "${root}" | grep -qe '^[A-Fa-f0-9]*$'; then
               str_offset=$((${#root}-2))
               major=$(printf "%d" 0x${root:0:${str_offset}})
               minor=$(printf "%d" 0x${root:${str_offset}})
               rootdev="${major} ${minor}"
               root="/dev/root"
           fi
           if [ -n "${rootdev}" ]; then
               msg "Creating root device ${root} with major $(echo "${rootdev}" | cut -d\   -f1) and minor $(echo "${rootdev}" | cut -d\   -f2)."
               mknod ${root} b ${rootdev}
           else
               err "Unable to determine major/minor number of root device '${root}'."
               echo "You are being dropped to a recovery shell"
               echo "    Type 'exit' to try and continue booting"
               PS1="ramfs$ " /bin/sh -i
               msg "Trying to continue (this will most likely fail) ..."
           fi
       fi
       # We didn't build filesystem support into busybox,
       # instead we use util-linux-ng's blkid for best compatibility
       if [ -n "${rootfstype}" ]; then
           fstype="${rootfstype}"
       else
           fstype=$(eval $(/sbin/blkid -o udev -p "${root}"); echo $ID_FS_TYPE)
           if [ -z "${fstype}" ]; then
             err "Unable to determine the file system type of ${root}:"
             echo "Either it contains no filesystem, an unknown filesystem,"
             echo "or more than one valid file system signature was found."
             echo
             echo "Try adding"
             echo "    rootfstype=your_filesystem_type"
             echo "to the kernel command line."
             echo
             echo "You are now being dropped into an emergency shell."
             launch_interactive_shell
             msg "Trying to continue (this will most likely fail) ..."
           fi
        fi
      if [ "${readwrite}" = "yes" ]; then
        rwopt="rw"
      else
        rwopt="ro"
      fi
      mount ${fstype:+-t ${fstype}} -o ${rwopt}${rootflags:+,${rootflags}} "${root}" /new_root
    else
        if [ -z "$nfs_server" -o -z "$nfs_path" ]; then
            err "Unable to mount root filesystem over NFS: wrong parameters."
            echo "You are being dropped to a recovery shell"
            echo "    Type 'exit' to try and continue booting"
            launch_interactive_shell
            msg "Trying to continue (this will most likely fail) ..."
        fi
        nfsmount ${nfs_option:+-o ${nfs_option}} "${nfs_server}:${nfs_path}" /new_root
    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 -9 ${udevpid} > /dev/null 2>&1
        /bin/sleep 0.01
    fi

    umount /proc
    umount /sys
    [ -z "${init}" ] && init="/sbin/init"
    exec /sbin/switch_root -c /dev/console /new_root ${init} "$@"
fi