Home | History | Annotate | Line # | Download | only in hooks
      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 
      8 export LC_ALL=C
      9 
     10 event="$1"
     11 shift
     12 
     13 wedgedir=/dev/wedges
     14 
     15 recurse()
     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 
     33 simple_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 
     58 ord()
     59 {
     60 	printf %2.2x "'$1"
     61 }
     62 
     63 encode()
     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 
     84 remove_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 
     95 wedge_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 
    122 add_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 
    149 for 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
    163 done
    164