#!/bin/sh
#
# $NetBSD: $
#
# Try to maintain symlinks to disks with names
#

export LC_ALL=C

event="$1"
shift

diskdir=/dev/disk

recurse()
{
	test -d "$1" &&
	    ls -1af "$1" | while read n; do
		case $n in
		.|..)	;;
		*)
			echo "$1/$n"
			if [ -L "$1/$n" ]; then
				: #nothing
			elif [ -d "$1/$n" ]; then
				recurse "$1/$n"
			fi
			;;
		esac
	    done
}

simple_readlink()
{
	local x

	x=$(test -e "$1" && ls -ld "$1")
	case $x in
	*'-> '*) echo ${x#*-> };;
	esac
}

remove_disk() {
	recurse "$diskdir" | while read w; do
		t=$(simple_readlink "$w")
		if [ x"$t" = x"/dev/$1" ]; then
			rm -f "$w"
			basedir=${w%/*}
			rmdir -p "$basedir" 2>/dev/null
		fi
	done
}

disk_identifier() {
	local l disk usenext=""

	if l=$(scsictl "$1" identify vpd 2>/dev/null); then
		while IFS=: read k v; do
			if [ -n "$usenext" ]; then
				disk="$usenext${k#*[! ]}"
				usenext=""
			elif [ "$k" = "VPD Serial" ]; then
				usenext=ser-
			elif [ "$k" = $'\tlun naa' ]; then
				disk="naa-${v# }"
			fi
		done <<-EOF
		${l}
		EOF
	fi
	if l=$(atactl "$1" identify 2>/dev/null); then
		while IFS=: read k v; do
			if [ "$k" = "World Wide Name" ]; then
				disk="wwn-${v# }"
			fi
		done <<-EOF
		${l}
		EOF
	fi

	printf %s "$disk"
}

add_disk() {
	local n

	n=$(disk_identifier "$1")
	test -n "$n" || return

	(
		umask 022

		test -d "$diskdir" || mkdir -m 755 "$diskdir"
		basedir="$diskdir/$n"
		basedir=${basedir%/*}
		test -d "$basedir" || mkdir -p -m 755 "$basedir"
		if oldlink=$(simple_readlink "$diskdir/$n"); then
			if [ x"$oldlink" != x"/dev/$1" ]; then
				rm -f "$diskdir/$n"
				ln -s "/dev/$1" "$diskdir/$n"
			fi
		else
			ln -s "/dev/$1" "$diskdir/$n"
		fi
	)
}

for device do
	case $device in
	sd*|wd*)
		case $event in
		device-attach)
			remove_disk "$device"
			add_disk "$device"
			;;
		device-detach)
			remove_disk "$device"
			;;
		esac
		;;
	esac
done
