Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

#!/bin/sh
#
# $NetBSD: 02-wedgenames,v 1.8 2021/08/08 10:48:35 martin Exp $
#
# Try to maintain symlinks to wedge devices
#

export LC_ALL=C

event="$1"
shift

wedgedir=/dev/wedges

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
}

#ordtable=$(
#	for n1 in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
#	for n2 in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do
#		echo "\$'\x$n1$n2') x=$n1$n2;;"
#	done
#	done
#)
#
#ord()
#{
#	local x
#	eval "case \$1 in $ordtable esac"
#	echo -n $x
#}

ord()
{
	printf %2.2x "'$1"
}

encode()
{
	local a b c

	a=$1
	b=
	while [ -n "$a" ]; do
		c="${a%"${a#?}"}"
		a=${a#?}
		case $c in
		[][:alnum:]._:\;!^$\&~\(\)[{}=,+/-])
			;;
		*)
			c=%%$(ord "$c")
			;;
		esac
		b=${b}${c}
	done
	printf %s "$b"
}

remove_wedge() {
	recurse "$wedgedir" | 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
}

wedge_label() {
	local l

	# dkctl getwedgeinfo always outputs 2 "lines", the first
	# contains the label (and may contain embedded \n chars)
	# the second contains the size, offset, and type, and one
	# trailing \n (stripped by the $()) - so we can safely
	# extract the label by deleting from the final \n in the
	# value getwedgeinfo prints to the end

	l=$(dkctl "$1" getwedgeinfo)
	l=${l%$'\n'*}
	case "${l}" in
	$1' at '*': '*)
		l=${l#*: }
		;;
	*)	
		l=$1
		;;
	esac

	# The trailing <END> is to ensure a trailing \n in the label
	# is not deleted by a command substitution which invokes us.
	# That will be rmeoved by the caller.
	printf %s "${l}<END>"
}

add_wedge() {
	local l n

	l=$(wedge_label "$1")
	l=${l%'<END>'}
	case "$l" in */) l="${l}Wedge";; esac

	n=$(encode "${l}")

	(
		umask 022

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

for device do
	case $device in
	dk*)
		case $event in
		device-attach)
			remove_wedge "$device"
			add_wedge "$device"
			;;
		device-detach)
			remove_wedge "$device"
			;;
		esac
		;;
	esac
done