xref: /netbsd-src/sbin/devpubd/hooks/02-wedgenames (revision bcb7e68e0a9648a9002cea24cd834df43781eae1)
1#!/bin/sh
2#
3# $NetBSD: 02-wedgenames,v 1.8 2021/08/08 10:48:35 martin Exp $
4#
5# Try to maintain symlinks to wedge devices
6#
7
8export LC_ALL=C
9
10event="$1"
11shift
12
13wedgedir=/dev/wedges
14
15recurse()
16{
17	test -d "$1" &&
18	    ls -1af "$1" | while read n; do
19		case $n in
20		.|..)	;;
21		*)
22			echo "$1/$n"
23			if [ -L "$1/$n" ]; then
24				: #nothing
25			elif [ -d "$1/$n" ]; then
26				recurse "$1/$n"
27			fi
28			;;
29		esac
30	    done
31}
32
33simple_readlink()
34{
35	local x
36
37	x=$(test -e "$1" && ls -ld "$1")
38	case $x in
39	*'-> '*) echo ${x#*-> };;
40	esac
41}
42
43#ordtable=$(
44#	for n1 in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
45#	for n2 in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
46#		echo "\$'\x$n1$n2') x=$n1$n2;;"
47#	done
48#	done
49#)
50#
51#ord()
52#{
53#	local x
54#	eval "case \$1 in $ordtable esac"
55#	echo -n $x
56#}
57
58ord()
59{
60	printf %2.2x "'$1"
61}
62
63encode()
64{
65	local a b c
66
67	a=$1
68	b=
69	while [ -n "$a" ]; do
70		c="${a%"${a#?}"}"
71		a=${a#?}
72		case $c in
73		[][:alnum:]._:\;!^$\&~\(\)[{}=,+/-])
74			;;
75		*)
76			c=%%$(ord "$c")
77			;;
78		esac
79		b=${b}${c}
80	done
81	printf %s "$b"
82}
83
84remove_wedge() {
85	recurse "$wedgedir" | while read w; do
86		t=$(simple_readlink "$w")
87		if [ x"$t" = x"/dev/$1" ]; then
88			rm -f "$w"
89			basedir=${w%/*}
90			rmdir -p "$basedir" 2>/dev/null
91		fi
92	done
93}
94
95wedge_label() {
96	local l
97
98	# dkctl getwedgeinfo always outputs 2 "lines", the first
99	# contains the label (and may contain embedded \n chars)
100	# the second contains the size, offset, and type, and one
101	# trailing \n (stripped by the $()) - so we can safely
102	# extract the label by deleting from the final \n in the
103	# value getwedgeinfo prints to the end
104
105	l=$(dkctl "$1" getwedgeinfo)
106	l=${l%$'\n'*}
107	case "${l}" in
108	$1' at '*': '*)
109		l=${l#*: }
110		;;
111	*)
112		l=$1
113		;;
114	esac
115
116	# The trailing <END> is to ensure a trailing \n in the label
117	# is not deleted by a command substitution which invokes us.
118	# That will be rmeoved by the caller.
119	printf %s "${l}<END>"
120}
121
122add_wedge() {
123	local l n
124
125	l=$(wedge_label "$1")
126	l=${l%'<END>'}
127	case "$l" in */) l="${l}Wedge";; esac
128
129	n=$(encode "${l}")
130
131	(
132		umask 022
133
134		test -d "$wedgedir" || mkdir -m 755 "$wedgedir"
135		basedir="$wedgedir/$n"
136		basedir=${basedir%/*}
137		test -d "$basedir" || mkdir -p -m 755 "$basedir"
138		if oldlink=$(simple_readlink "$wedgedir/$n"); then
139			if [ x"$oldlink" != x"/dev/$1" ]; then
140				rm -f "$wedgedir/$n"
141				ln -s "/dev/$1" "$wedgedir/$n"
142			fi
143		else
144			ln -s "/dev/$1" "$wedgedir/$n"
145		fi
146	)
147}
148
149for device do
150	case $device in
151	dk*)
152		case $event in
153		device-attach)
154			remove_wedge "$device"
155			add_wedge "$device"
156			;;
157		device-detach)
158			remove_wedge "$device"
159			;;
160		esac
161		;;
162	esac
163done
164