#!/bin/sh -e
# storage_enum - enumerated storage devices
#
# Copyright © 2005 Canonical Ltd.
# Author: Scott James Remnant <scott@ubuntu.com>
#
#	This program is free software; you can redistribute it and/or modify it
#	under the terms of the GNU General Public License as published by the
#	Free Software Foundation version 2 of the License.
#	
#	This program is distributed in the hope that it will be useful, but
#	WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#	General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License along
#	with this program; if not, write to the Free Software Foundation, Inc.,
#	51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA


# Figure out what type of device we've been called for
devname="$1"
case "$devname" in
    fd[0-9]*)
        type=floppy
	;;

    sd[a-z])
        type=disk
	;;

    sd[a-z][0-9]*)
        type=partition
        name=part${devname##sd[a-z]}
	disk=${devname%%[0-9]*}
	;;

    sr[0-9]*)
        type=cdrom
	;;

    hd[a-z])
        type=$(/lib/udev/ide_media $PHYSDEVPATH)
	;;

    hd[a-z][0-9]*)
        type=partition
	name=part${devname##hd[a-z]}
	disk=${devname%%[0-9]*}
	;;

    *)
	exit 1
	;;
esac


# Handle partitions, which don't need enumerating
if [ "$type" = "partition" ]; then
    subdir=$(sed -n -e "/^$disk /s/.* //p" /dev/.names)
    echo "discs/$subdir/$name"
    exit 0
fi

# Handle repeated calls to udevplug
for symlink in $(udevinfo -q symlink -n $devname); do
    case "$symlink" in
	discs/disc[0-9]*/disc)
	    if [ "$type" = "disc" ]; then
		echo "$symlink"
		exit 0
	    fi
	    ;;
	cdroms/cdrom[0-9]*)
	    if [ "$type" = "cdrom" ]; then
		echo "$symlink"
		exit 0
	    fi
	    ;;
	floppy/[0-9]*)
	    if [ "$type" = "floppy" ]; then
		echo "$symlink"
		exit 0
	    fi
	    ;;
    esac
done


# Get the next number atomically, the only way we reliably can
while ! mkdir /dev/.$type.lock 2>/dev/null; do
    sleep 1
done
if [ -e /dev/.$type.next ]; then
    enum=$(cat /dev/.$type.next)
else
    enum=0
fi
echo $(($enum + 1)) > /dev/.$type.next
rmdir /dev/.$type.lock


# Figure out the symlink name
case "$type" in
    disk)
	echo "$devname disc$enum" >> /dev/.names
	echo "discs/disc$enum/disc"
	;;

    cdrom)
	echo "cdroms/cdrom$enum"
	;;

    floppy)
	echo "floppy/$enum"
	;;
esac
