#!/bin/sh

# Automount script, called for sd[a-z]1 devices by custom command in mdev.conf or udev

mount_base="/media"
tmpmount_base="/tmp/trymount"
mountinfo_base="/tmp/automount_info"

# support udev
if [ -z "$MDEV" ]; then
    MDEV=$(basename "$DEVNAME")
fi

case $DEVPATH in
    /block/*)
        # udevstart calls an extra time with a /block/* DEVPATH, ignore it.
        exit 0
        ;;
    *)
        ;;
esac

cd /dev

mountinfo_media="${mountinfo_base}/media"
mountinfo_device="${mountinfo_base}/device"
mountinfo_file="${mountinfo_device}/$MDEV"

rwaccess="ro"

grep -v "manuimage=1" /proc/cmdline
manu_image=$?

read roku_dev_mode rest < /proc/cmdline
if [ "$manu_image" = "1" ] || [ "$roku_dev_mode" = 'dev=1' ] ; then
	rwaccess="rw"
fi

FILESYSTEMS="vfat ntfs hfsplus ext3 ext2"
MOUNT_OPTS="-o noatime,${rwaccess},nodev,nosuid"
APP_UID=`id -u app`
APP_GID=`id -g app`
MOUNT_OPTS_UID=",gid=${APP_GID},uid=${APP_UID}"
VFAT_OPTS=",shortname=mixed,utf8"

# Log stdout and stderr (enable/disable by switching commented lines)
#exec 1>/tmp/automount.log
exec 1>/dev/null
exec 2>&1
set -x

# Work out next available auto mount location
# Arguments:
#    $1: Directory path
#    $2: Filename prefix
#    $3: Filename suffix
getmountpoint()
{
	n=1

	# Start mmcblk at 6+
	if echo $MDEV | grep -q mmcblk; then
		n=6
	fi

	while [ $n -lt 256 ]
	do
		mkdir "$1/$2${n}$3"
		if [ "$?" -eq 0 ] ; then
			echo "$2${n}$3"
			return
		fi
		let n=n+1
	done
}

if [ "$ACTION" = remove ] ; then
	if [ -e "$mountinfo_file" ] ; then
		mountpoint="$(cat $mountinfo_file)"
		umount -f -l "${mount_base}/${mountpoint}"
		rmdir "${mount_base}/${mountpoint}"
		rm -rf $mountinfo_file "${mountinfo_media}/${mountpoint}"

		# Unmount succeeded
		echo "==> Unmounted $MDEV (${mount_base}/${mountpoint})" >/dev/console

		# Send a "removed" message to the application
		plethora msg-send /app-msd "r$mountpoint"
	fi

	exit 0
else
	mkdir -p $mountinfo_device $mountinfo_media $tmpmount_base $mountinfo_base

	# Get a temporary available mount point. The reason for using a temporary is
	# because many mounts may be attempted simultaneously. But if a mount is
	# unsuccessful, we don't want it using up space in the "ext[1-9]" name domain
	# even temporarily, since it would mean that a device with only one valid
	# partition could get mounted at ext9 (or worse!).
	tmpmountpoint=$(getmountpoint ${tmpmount_base} trymount "")

	valid=0
	for mountattempt in 1 2 3 4 5
	do
		echo "Mount attempt $mountattempt."
		for fs in ${FILESYSTEMS}
		do
			if [ $fs == "ntfs" ] ; then
				if ntfs-3g ${MOUNT_OPTS}${MOUNT_OPTS_UID} $MDEV "${tmpmount_base}/${tmpmountpoint}" ; then
				valid=n
				break
			fi
			elif [ $fs == "vfat" ] ; then
				if mount -t $fs ${MOUNT_OPTS}${VFAT_OPTS}${MOUNT_OPTS_UID} $MDEV "${tmpmount_base}/${tmpmountpoint}" ; then
				valid=v
				break
			fi
			elif [ $fs == "hfsplus" ] ; then
				if mount -t $fs ${MOUNT_OPTS}${MOUNT_OPTS_UID} $MDEV "${tmpmount_base}/${tmpmountpoint}" ; then
				valid=h
				break
			fi
			elif [ $fs == "ext2" ] ; then
				if mount -t $fs ${MOUNT_OPTS} $MDEV "${tmpmount_base}/${tmpmountpoint}" ; then
				valid=2
				break
				fi
			elif [ $fs == "ext3" ] ; then
				if mount -t $fs ${MOUNT_OPTS} $MDEV "${tmpmount_base}/${tmpmountpoint}" ; then
				valid=3
				break
				fi
			fi
		done
		if [ $valid != 0 ] ; then
			echo "SUCCESS on attempt $mountattempt. fs=$fs" > /dev/console
			break
		fi
	done

	if [ $valid != 0 ] ; then
		# Get the next available mount point. Note that this directory is created
		# in the mountinfo_media directory, not in mount_base.
		newmountpoint=$(getmountpoint ${mountinfo_media} ext ":")

		# If there is a residual device mounted, make sure it's cleaned up
		if [ -e "${mount_base}/${newmountpoint}" ] ; then
			umount -f -l "${mount_base}/${newmountpoint}"
		else
			# Create the new directory where this will be permanently mounted
			mkdir -p "${mount_base}/${newmountpoint}"
		fi

		# Move the temporary mount to the new mount point
		mount -o move "${tmpmount_base}/${tmpmountpoint}" "${mount_base}/${newmountpoint}"
		rmdir "${tmpmount_base}/${tmpmountpoint}"
		mountpoint=${newmountpoint}

		echo $mountpoint > "$mountinfo_file"
		echo $MDEV > "${mountinfo_media}/${mountpoint}/device"
		/sbin/blkid -c /dev/null /dev/$MDEV > "${mountinfo_media}/${mountpoint}/blkid"

		# Mount succeeded
		echo "==> Mounted $fs ($valid) $MDEV on ${mount_base}/${mountpoint}" > /dev/console

		# Send an "inserted" message to the application
		plethora msg-send /app-msd "i$valid$mountpoint"

		exit 0
	fi

	# Mount attempts failed... remove mount directory
	rmdir "${tmpmount_base}/${tmpmountpoint}"
fi
