#!/bin/sh

if [ -z "$HALD_ACTION" ] ; then
    exit 0;
fi

CONFIG_FILE=/etc/sysconfig/hal-mount-subfs
[ -r "$CONFIG_FILE" ] && . "$CONFIG_FILE"

LOG_NAME=$(basename $0)

function clear_stale_mount_points {
	IFS=
	mount_media_list="`cut -f2 -d ' ' /proc/mounts |grep '^/media'`"
	for dir in /media/*; do
		[ -d "$dir" ] || continue
		echo $mount_media_list | grep -q "^${dir}$" && continue
		[ -r "$dir/.auto_managed_mount_point" ] || continue
		MD5sum=`basename "$dir" |md5sum |cut -f1 -d' '`
		[ "`cat "$dir/.auto_managed_mount_point"`" == "$MD5sum" ] && {
			rm -f "$dir/.auto_managed_mount_point"
			rmdir "$dir"
		}
	done
}

get_fstab_entry() {
	fstab_entry=`grep -E "^${HAL_PROP_BLOCK_DEVICE}[[:blank:]]" /etc/fstab`

	[ -z "$fstab_entry" ] && 
		fstab_entry=`grep -E "^UUID=${HAL_PROP_VOLUME_UUID}[[:blank:]]" /etc/fstab`

	[ -z "$fstab_entry" ] && 
		fstab_entry=`grep -E "^LABEL=${HAL_PROP_VOLUME_LABEL}[[:blank:]]" /etc/fstab`

	[ -n "$fstab_entry" ] && fstab_entry=`echo "$fstab_entry" |tr " " "\t" |cut -f1`
}


mount_device() {

	if [ "$HAL_PROP_VOLUME_POLICY_SHOULD_MOUNT" == "false" -o "$HAL_PROP_STORAGE_POLICY_SHOULD_MOUNT" == "false" ]; then
		initlog -n $LOG_NAME -s "$HAL_PROP_BLOCK_DEVICE should not be mounted"
		exit
	fi

	if [ ! "$CLEAR_STALE_MOUNT_POINTS" == "no" ]; then
		clear_stale_mount_points
	fi

	grep -q "^$HAL_PROP_BLOCK_DEVICE " /proc/mounts && {
		initlog -n $LOG_NAME -s "$HAL_PROP_BLOCK_DEVICE has already mounted (${HAL_PROP_VOLUME_MOUNT_POINT})"
		exit
	}

	if [ "$IGNORE_FSTAB_ENTRIES" == "yes" ]; then
		get_fstab_entry;
		if [ -n "$fstab_entry" ]; then
			initlog -n $LOG_NAME -s "$fstab_entry exist in /etc/fstab, will not be mounted."
			exit
		fi
	fi

	if [ "$HAL_PROP_INFO_CATEGORY" == "storage" ]; then
		mount_filesystem=$HAL_PROP_STORAGE_POLICY_MOUNT_FILESYSTEM
		mount_option_fs=$HAL_PROP_STORAGE_POLICY_MOUNT_OPTION_FS
		mount_options=$HAL_PROP_STORAGE_POLICY_MOUNT_OPTIONS
		desired_mount_point=$HAL_PROP_STORAGE_POLICY_DESIRED_MOUNT_POINT
	elif [ "$HAL_PROP_INFO_CATEGORY" == "volume" ]; then
		mount_filesystem=$HAL_PROP_VOLUME_POLICY_MOUNT_FILESYSTEM
		mount_option_fs=$HAL_PROP_VOLUME_POLICY_MOUNT_OPTION_FS
		mount_options=$HAL_PROP_VOLUME_POLICY_MOUNT_OPTIONS
		desired_mount_point=$HAL_PROP_VOLUME_POLICY_DESIRED_MOUNT_POINT
	else
		initlog -n $LOG_NAME -s "Unknown type for $HAL_PROP_BLOCK_DEVICE"
		exit
	fi

	mount_filesystem=${mount_filesystem:-"subfs"}
	mount_option_fs=${mount_option_fs:-"auto"}
	mount_option_fs="fs=$mount_option_fs"


	LABEL=$HAL_PROP_VOLUME_LABEL
	[ -n "$LABEL" ] && {
#		SAFELABEL=`udevinfo --query=env --name $HAL_PROP_BLOCK_DEVICE |grep "^ID_FS_LABEL_SAFE=" |cut -f2- -d "="`
		SAFELABEL=`udevadm info --query=env --name $HAL_PROP_BLOCK_DEVICE |grep "^ID_FS_LABEL_SAFE=" |cut -f2- -d "="`
		[ -n "$SAFELABEL" ] && LABEL=$SAFELABEL
	} || LABEL=${HAL_PROP_BLOCK_DEVICE##/dev/}

	desired_mount_point=${desired_mount_point:-$LABEL}

	while [ -e "/media/$desired_mount_point" ]; do
		tail_mp=${desired_mount_point##*_}
		echo "$tail_mp" | grep -qvE "[^[:digit:]]" && \
			desired_mount_point="${desired_mount_point%_*}_$(($tail_mp + 1))" || \
			desired_mount_point="${desired_mount_point}_1"
	done

	MOUNTPOINT="/media/${desired_mount_point}"
	mkdir -p "$MOUNTPOINT" || {
		initlog -n $LOG_NAME -s "Error creating mount point"
		exit 1
	}
	echo ${desired_mount_point} |md5sum |cut -f1 -d' ' > $MOUNTPOINT/.auto_managed_mount_point

	if echo "$mount_options" | grep -q ",flush" && [ `uname -r |cut -f1 -d- |tr -d .` -lt 2622 ]; then
		mount_options="`echo $mount_options |sed -e 's/,flush//'`"
	fi

	if [ -n "$HAL_PROP_VOLUME_UUID" ]; then 
		uuid="uuid ${HAL_PROP_VOLUME_UUID}, "
	else
		uuid=
	fi

	if [ "$mount_option_fs" == "fs=ntfs-3g" ]; then
		mount_option_fs="$mount_option_fs,program=/sbin/net-submountd,interval=4"
	fi

	initlog -n $LOG_NAME -s "Mounting $HAL_PROP_BLOCK_DEVICE to /media/${desired_mount_point}, ${uuid}label ${LABEL}, type ${mount_filesystem}, options ${mount_option_fs},${mount_options}"

	if [ "$UNLOCK_CDROM_TRAY" == "yes" ]; then
		[ "`hal-get-property --udi "$HAL_PROP_INFO_PARENT" --key storage.drive_type`" == "cdrom" ] && echo "0" > /proc/sys/dev/cdrom/lock
	fi

	mount -n -t ${mount_filesystem} $HAL_PROP_BLOCK_DEVICE "$MOUNTPOINT" -o ${mount_option_fs},${mount_options} && {
		hal-set-property --udi "$HAL_PROP_INFO_UDI" --key "volume.is_mounted" --bool true
		hal-set-property --udi "$HAL_PROP_INFO_UDI" --key "volume.mount_point" --string "/media/${desired_mount_point}"
	} || {
		initlog -n $LOG_NAME -s "Mounting failure"
		exit 1
	}
}


do_unmount() {
	MOUNT_POINT="$1"
	initlog -n $LOG_NAME -s "Trying unmount $MOUNT_POINT"

	[ -d "$MOUNT_POINT" ] || {
		initlog -n $LOG_NAME -s "Mount point $MOUNT_POINT not found"
		return
	}

	count=1
	while umount $UMOUNT_OPTIONS "$MOUNT_POINT" 2>/dev/null && [ $count -lt 10 ]; do
		count=$(($count + 1));
	done

	grep "$MOUNT_POINT" /proc/mounts >/dev/null && {
		initlog -n $LOG_NAME -s "Umount $MOUNT_POINT failed. Mount point will not be removed."
		exit 1
	}

        MD5sum=`basename "$MOUNT_POINT" |md5sum |cut -f1 -d' '`
	if [ -r "$MOUNT_POINT/.auto_managed_mount_point" ] && [ "`cat "$MOUNT_POINT/.auto_managed_mount_point"`" == "$MD5sum" ]; then
		rm -f "$MOUNT_POINT/.auto_managed_mount_point" && \
		rmdir "$MOUNT_POINT" && \
		initlog -n $LOG_NAME -s "$MOUNT_POINT successfully unmounted and removed."
	else
		initlog -n $LOG_NAME -s "Not my mountpoint $MOUNT_POINT, will not be removed."
		exit 1
	fi
	
}


case $HALD_ACTION in
    add)
	if [ -n "$HAL_PROP_BLOCK_DEVICE" ]; then
		/sbin/modprobe -l |grep "/subfs\.ko$" || initlog -n $LOG_NAME -s "Warning! kernel-modules-subfs package is not installed for your kernel!"
		mount_device
	fi
	;;

    remove)
	if [ -n "$HAL_PROP_BLOCK_DEVICE" ]; then
		
		if [ "$IGNORE_FSTAB_ENTRIES" == "yes" ]; then 
			get_fstab_entry;
			if [ -n "$fstab_entry" ]; then
				initlog -n $LOG_NAME -s "$fstab_entry exist in /etc/fstab, will not be unmounted."
				exit
			fi
		fi

		echo $HAL_PROP_VOLUME_UNMOUNT_VALID_OPTIONS |grep -q "lazy" && UMOUNT_OPTIONS="-l"

		while MOUNT_LINE=`grep -m 1 "^$HAL_PROP_BLOCK_DEVICE " /proc/mounts`; do
			set -- $MOUNT_LINE
			do_unmount "`printf "$2"`"
		done

	fi
	;;
esac
