#!/bin/bash
#
# This is a management script for making a choice between using vdev
# or udev as /dev manager, with the prerequisite that the initramfs
# scripts for udev have been collated into a tgz.
#
# The choice is presented on the command line as "udev" or "vdev", or
# via "dialog", which offers a choice dialog. The default choice is vdev.

unalias rm >& /dev/null
unalias ln >& /dev/null
unalias mv >& /dev/null

ACTION=${1-vdev}

COMPATLIB=libudev.so.1.5.2
UDEVTGZ=/usr/share/vdev/udev-initramfs.tgz
CHOICE=/tmp/vdev-install-choice
rm -f $CHOICE

CURRENT=vdev
[ -f /etc/insserv/overrides/vdev ] && CURRENT=udev

if [ "$ACTION" = "$CURRENT" ] ; then
    echo "$ACTION is current choice" >&2
    exit 0
fi

# function: determine the latest udev library relative a compat library
# ALSO: remove any libudev.so.1* links
latest_udev_library() {
    local UDEV f
    for ff in $(dirname $1)/libudev.so.1* ; do
	[[ $ff = $1 ]] && continue
	if [ -h $ff ] ; then
	    rm $ff
	elif [[ "$(basename $ff)" > "$UDEV" ]] ; then
	    UDEV=$(basename $ff)
	fi
    done
    echo $UDEV
}

# function: ensure vdev's library is "highest version"
setup_libudev_compat() {
    local UDEV f DIR
    for f in /lib/*/$COMPATLIB ; do
	DIR=$(dirname $f)
	UDEV=$(latest_udev_library $f)
	[[ $UDEV > $COMPATLIB ]] && ln -s $COMPATLIB $DIR/$UDEV-override
    done
    ldconfig
}

# function: ensure udev's library is "highest version"
restore_libudev_compat() {
    local UDEV
    for f in /lib/*/$COMPATLIB ; do
	DIR=$(dirname $f)
	UDEV=$(latest_udev_library $f)
	[[ $UDEV < $COMPATLIB ]] && ln -s $UDEV $DIR/$COMPATLIB-override
    done
    ldconfig
}

# function
ischoice() {
    local c
    c=vdev
    [ -f $CHOICE ] && c=$(cat $CHOICE)
    [ "$1" = "$c" ] && echo on && return 0
    echo off
}

if [ "$ACTION" = dialog ] ; then
    if [ -x /usr/bin/dialog ] ; then
	if dialog --radiolist 'Select /dev/manager' 10 60 2 \
		  vdev 'use VDEV as /dev manager' $(ischoice vdev) \
		  udev 'use UDEV as /dev manager' $(ischoice udev) \
		  2> $CHOICE ; then
	    ACTION=$(cat $CHOICE)
	else
	    exit 1
	fi
    else
	echo "'dialog' needs package dialog, which is not installed." >&2
	echo "Please select 'udev' or 'vdev' on the commmand line." >&2
	exit 1
    fi
fi

case "$ACTION" in
    vdev)
	# Set up libudev.so.1 to use compat library
	setup_libudev_compat
	# Disable udev and enable vdev as rcS.d choice
	rm -f /etc/rcS.d/*udev /etc/rcS.d/*udev-finish
	ln -sTf ../init.d/vdev /etc/rcS.d/K03vdev
	mv -f /etc/insserv/overrides/vdev /etc/insserv/overrides/udev
	update-rc.d -f vdev enable S
	# Disable udev scripts and enable vdev init script
	find /usr/share/initramfs-tools -name udev -print0 | xargs -r0 rm
	cp -a /usr/share/vdev/initramfs-tools/* /usr/share/initramfs-tools/
	update-initramfs -u
	echo "*** NOTE: All set up for using vdev at next reboot"
	;;
    udev)
	# Restore libudev.so.1 from saved link
	restore_libudev_compat
	# Disable vdev and ensable udev as rcS.d choice
	ln -sTf ../init.d/udev /etc/rcS.d/K02udev
	rm -f /etc/rcS.d/*vdev
	mv -f /etc/insserv/overrides/udev /etc/insserv/overrides/vdev
	update-rc.d -f udev enable S
	ln -sTf ../init.d/udev-finish /etc/rcS.d/K11udev-finish
	update-rc.d -f udev-finish enable S
	# Disable vdev scripts and enable udev init script
	find /usr/share/initramfs-tools -name vdev -print0 | xargs -r0 rm
	[ -e $UDEVTGZ ] && tar xzf $UDEVTGZ -C /usr/share/initramfs-tools
	update-initramfs -u
	echo "*** NOTE: All set up for using udev at next reboot"
	;;
    *)
	echo "'$ACTION' means nothing. Please use udev, vdev or dialog"
	exit 1
	;;
esac

true
