1#!/bin/sh
2#
3# $FreeBSD$
4#
5
6# Print newline-separated list of devices available for mounting.
7# If there is a filesystem label - use it, otherwise use device name.
8print_available() {
9	local _fstype _fstype_and_label _label _p
10
11	for _p in ${DEVICES}; do
12		# XXX: Ingore /dev/md*
13		if [ "`echo ${_p} | sed -n '/^md/p'`" != "" ]; then
14			continue
15		fi
16
17		_fstype_and_label="$(fstyp -l "/dev/${_p}" 2> /dev/null)"
18		if [ $? -ne 0 ]; then
19			# Ignore devices for which we were unable
20			# to determine filesystem type.
21			continue
22		fi
23
24		_fstype="${_fstype_and_label%% *}"
25		if [ "${_fstype}" != "${_fstype_and_label}" ]; then
26			_label="${_fstype_and_label#* }"
27			# Replace plus signs and slashes with minuses;
28			# leading plus signs have special meaning in maps,
29			# and multi-component keys are just not supported.
30			_label="$(echo ${_label} | sed 's,[+/],-,g')"
31			echo "${_label}"
32			continue
33		fi
34
35		echo "${_p}"
36	done
37}
38
39# Print a single map entry.
40print_map_entry() {
41	local _fstype _p
42
43	_fstype="$1"
44	_p="$2"
45
46	case "${_fstype}" in
47	"exfat")
48		if [ -f "/usr/local/sbin/mount.exfat" ]; then
49			echo "-mountprog=/usr/local/sbin/mount.exfat,fstype=${_fstype},nosuid	:/dev/${_p}"
50		else
51			/usr/bin/logger -p info -t "special_media[$$]" \
52			    "Cannot mount ${_fstype} formatted device /dev/${_p}: Install sysutils/fusefs-exfat first"
53			exit 1
54		fi
55		;;
56	"ntfs")
57		if [ -f "/usr/local/bin/ntfs-3g" ]; then
58			echo "-mountprog=/usr/local/bin/ntfs-3g,fstype=${_fstype},nosuid	:/dev/${_p}"
59		else
60			/usr/bin/logger -p info -t "special_media[$$]" \
61			    "Cannot mount ${_fstype} formatted device /dev/${_p}: Install sysutils/fusefs-ntfs first"
62			exit 1
63		fi
64		;;
65	"ext2fs" | "msdosfs")
66		echo "-fstype=${_fstype},nosuid,async	:/dev/${_p}"
67		;;
68	*)
69		echo "-fstype=${_fstype},nosuid	:/dev/${_p}"
70		;;
71	esac
72}
73
74# Determine map entry contents for the given key and print out the entry.
75print_one() {
76	local _fstype _fstype_and_label _label _key _p
77
78	_key="$1"
79
80	_fstype="$(fstyp "/dev/${_key}" 2> /dev/null)"
81	if [ $? -eq 0 ]; then
82		print_map_entry "${_fstype}" "${_key}"
83		return
84	fi
85
86	for _p in ${DEVICES}; do
87		# XXX: Ingore /dev/md*
88		if [ "`echo ${_p} | sed -n '/^md/p'`" != "" ]; then
89			continue
90		fi
91
92		_fstype_and_label="$(fstyp -l "/dev/${_p}" 2> /dev/null)"
93		if [ $? -ne 0 ]; then
94			# Ignore devices for which we were unable
95			# to determine filesystem type.
96			continue
97		fi
98
99		_fstype="${_fstype_and_label%% *}"
100		if [ "${_fstype}" = "${_fstype_and_label}" ]; then
101			# No label, try another device.
102			continue
103		fi
104
105		_label="${_fstype_and_label#* }"
106		# Replace plus signs and slashes with minuses;
107		# leading plus signs have special meaning in maps,
108		# and multi-component keys are just not supported.
109		_label="$(echo ${_label} | sed 's,[+/],-,g')"
110		if [ "${_label}" != "${_key}" ]; then
111			# Labels don't match, try another device.
112			continue
113		fi
114
115		print_map_entry "${_fstype}" "${_p}"
116	done
117
118	# No matching device - don't print anything, autofs will handle it.
119}
120
121# XXX: Find a better way to get a list of media devices
122KERN_DISKS=`sysctl kern.disks`
123if [ $? -ne 0 ]; then
124	exit 1
125fi
126DEVICES=`echo ${KERN_DISKS} | awk '{$1=""; print substr($0,2)}' | awk '{gsub(" ", "\n"); print}' | sort`
127
128if [ $# -eq 0 ]; then
129	print_available
130	exit 0
131fi
132
133print_one "$1"
134exit 0
135
136