#!/bin/sh

WHITELIST=/etc/udev/mount.whitelist
BLACKLIST=/etc/udev/mount.blacklist
SCRIPTS=/etc/udev/removable.d

set -u
[ -d "/media" ] || mkdir /media
[ -d "/run/media/" ] || ln -s /media /run/media

[ "$ACTION" = add -o "$ACTION" = remove ] || exit

log_debug() {
	logger -t automount -p user.debug "$@"
}
log_err() {
	logger -t automount -p user.err "$@"
}

removable_filesystem() {
	local dev_root="$(tr ' ' '\n' < /proc/cmdline | sed -n -e 's|^root=\(.*\)|\1|p')"
	local dev_root_abs=$(readlink -f "$dev_root")
	local removable= disk=

	# NOTE: root=UUID=.... not supported
	#
	if [ "$dev_root_abs" = "$DEVNAME" ]; then
		# root partition, skip
		return 1
	elif grep -q "^$DEVNAME " /proc/mounts; then
		# already mounted, skip
		return 1
	fi

	# always removable
	if [ -s "$WHITELIST" ]; then
		if grep -q "^$DEVNAME$" "$WHITELIST"; then
			removable=1
		elif [ "$DEVTYPE" = "partition" ]; then
			# check if the whole disk is whitelisted
			disk=$(cd "/sys/$DEVPATH/.." && pwd)
			if grep -q "^/dev/${disk##*/}$" "$WHITELIST"; then
				removable=1
			fi
		fi
	fi

	# always as non-removable (whitelist has precedence)
	if [ -s "$BLACKLIST" -a -z "${removable:-}" ]; then
		if grep -q "^$DEVNAME$" "$BLACKLIST"; then
			removable=0
		elif [ "$DEVTYPE" = "partition" ]; then
			# check if the whole disk is blacklisted
			disk=$(cd "/sys/$DEVPATH/.." && pwd)
			if grep -q "^/dev/${disk##*/}$" "$BLACKLIST"; then
				removable=0
			fi
		fi
	fi

	if [ -n "${removable:-}" ]; then
		: # already decided
	elif [ -s "/sys/$DEVPATH/partition" -a -s "/sys/$DEVPATH/../removable" ]; then
		read removable < "/sys/$DEVPATH/../removable"
	elif [ -s "/sys/$DEVPATH/removable" ]; then
		read removable < "/sys/$DEVPATH/removable"
	fi

	if [ "${removable:-0}" = 1 ]; then
		log_debug "$DEVNAME: removable"
		return 0
	else
		log_debug "$DEVNAME: non-removable"
		return 1
	fi

}

rm_dir() {
	local mnt="$1"
	local mnt_flag="/tmp/.automount-${mnt##*/}"

	if [ -n "$mnt" -a -e "$mnt_flag" ]; then
		if rmdir "$mnt"; then
			rm -f "$mnt_flag"
		fi
	fi
}

try_mount() {
	local name="${DEVNAME##*/}"
	local mnt="/media/$name" mnt_ours=false

	if grep -q " $mnt " /proc/mounts; then
		log_err "$mnt: mount point busy"
		return 1
	fi

	if [ ! -d "$mnt" ]; then
		mnt_ours=true
		mkdir "$mnt"
	fi
	# Mount device read-only by default, so that the device does not become 
	# dirty when removed with out un-mounting.
	if mount -t "$ID_FS_TYPE" -o ro,sync,noatime "$DEVNAME" "$mnt"; then
		log_debug "$DEVNAME: successfully mounted at $mnt"
		if $mnt_ours; then
			touch "/tmp/.automount-$name"
		fi
		return 0
	fi
	rm_dir "$mnt"
	return 1
}

if [ "$ACTION" = "add" -a -n "${ID_FS_TYPE:-}" ]; then
	if removable_filesystem && try_mount; then
		for f in "$SCRIPTS"/*.sh; do
			[ -x "$f" ] || continue
			"$f" add "/media/${DEVNAME##*/}"
		done
	fi
elif [ "$ACTION" = "remove" ]; then
	for x in $(grep "^$DEVNAME " /proc/mounts | cut -d' ' -f2); do
		log_debug "$x: unmounting because $DEVNAME was removed"
		for f in "$SCRIPTS"/*.sh; do
			[ -x "$f" ] || continue
			"$f" remove "$x" || true
		done
		umount -l "$x" || true
	done

	rm_dir "/media/${DEVNAME##*/}"
fi
