#!/bin/sh

set -e

test -f /sbin/discover || exit 0

CONFFILE=/etc/discover.conf
SKIPFILE=/etc/discover-autoskip.conf

case "$1" in
    start|restart) ;;
    stop|reload|force-reload) exit 0 ;;
esac

# Determine the hardware to scan for by extracting "boot" lines from
# the config file:
if [ -f $CONFFILE ]
then
    ARGUMENTS=$(sed "s/#.*$//" $CONFFILE | grep "^boot " | cut -c6-)
    # Deal with pre-0.9.7 syntax:
    ARGUMENTS=$(echo $ARGUMENTS | sed "s/,/ /g")
fi

# Detect hardware:
echo -n "Detecting hardware: " >&2
MODULES=$(/sbin/discover --module $ARGUMENTS)
echo $MODULES >&2

if [ -f /var/state/discover/crash ]
then
    # The system crashed trying to load a module during the last boot
    # cycle, so add an appropriate "skip" line to the skip file:
    echo "skip $(cat /var/state/discover/crash)" >> $SKIPFILE
    rm -f /var/state/discover/crash
    sync
fi

# Determine if we should skip a given module:
skip ()
{
    # Check if it's configured to be skipped first.
    if [ -f $CONFFILE ]
    then
        if [ -f $SKIPFILE ]
        then
            CONFCMD="cat $CONFFILE $SKIPFILE"
        else
            CONFCMD="cat $CONFFILE"
        fi
        for M in $($CONFCMD | \
                   sed "s/#.*$//" | \
                   awk '{ if ($1 == "skip") print $2 }')
        do
            if [ "$M" = "$1" ]
            then
                return 0
            fi
        done
    fi

    # We passed all tests; don't skip it.
    return 1;
}

# Load the appropriate modules:
for MODULE in $MODULES
do
    # See if we should skip $MODULE:
    if [ "$MODULE" = "ignore" -o "$MODULE" = "unknown" ]
    then
        continue
    fi

    if skip $MODULE
    then
        echo "Skipping $MODULE.  Edit $CONFFILE and/or $SKIPFILE to reenable it." >&2
        continue
    fi

    if expr "$MODULE" : "Server:.*" > /dev/null 2>&1
    then
        # silently skip X server "modules"
        continue
    fi

    if ! (modprobe -l ${MODULE}.o | grep ${MODULE}.o) > /dev/null
    then
        echo "Skipping $MODULE; assuming it is compiled into the kernel." >&2
        continue
    fi

    echo "Loading $MODULE:" >&2

    # Note the module being loaded in /var/state/discover/crash. If loading
    # the module crashes the machine, this file will exist at the next
    # boot, and we'll add an appropriate "skip" line to the conffile so we
    # don't try to load it again.
    echo $MODULE > /var/state/discover/crash
    sync

    modprobe $MODULE

    # The module loaded without incident, so we can safely remove the crash
    # file.
    rm -f /var/state/discover/crash
    sync
done

# Remove all old optical drive mount points:
for CDMOUNT in /cdrom?
do
    rm -rf $CDMOUNT
done

# Link /dev/cdromX to all detected CD/DVD drives, and create mount points:
CDNUM=0
for CDROM in $(discover --device cdrom)
do
    if [ ! -e $CDROM ]
    then
        echo -n "discover reports that $CDROM is a CD/DVD device, but it " >&2
        echo "does not exist.  Not updating /dev/cdrom$CDNUM." >&2
    elif [ ! -b $CDROM ]
    then
        echo -n "discover reports that $CDROM is a CD/DVD device, but it " >&2
        echo "is not a block device.  Not updating /dev/cdrom$CDNUM." >&2
    elif [ -e /dev/cdrom$CDNUM -a ! -L /dev/cdrom$CDNUM ]
    then
        echo -n "/dev/cdrom$CDNUM exists and is not a symlink.  Not updating " >&2
        echo "/dev/cdrom$CDNUM." >&2
        CDNUM=$(( $CDNUM + 1 ))
    else
        ln -fs $CDROM /dev/cdrom$CDNUM
        mkdir /cdrom$CDNUM
        CDNUM=$(( $CDNUM + 1 ))
    fi
done

# Link /dev/cdrom to the appropriate device:
if [ -e /dev/cdrom0 ]
then
    if [ -L /dev/cdrom -o ! -e /dev/cdrom ]
    then
        ln -fs /dev/cdrom0 /dev/cdrom
        ln -fs /cdrom0 /cdrom
    else
        echo "/dev/cdrom exists and is not a symlink.  Not updating /dev/cdrom." >&2
    fi
else
    echo "No CD/DVD drives found." >&2
fi

# Unmount the first stage ramdisk, if it is mounted.
if grep /initrd /proc/mounts > /dev/null 2>&1
then
    umount /dev/ram0
    if [ "$?" = "0" ]
    then
        if command -v freeramdisk > /dev/null 2>&1
        then
            /usr/sbin/freeramdisk /dev/ram0
        fi
    fi
fi

# vim:ai:et:sts=4:sw=4:tw=0:
