#!/bin/sh
# This script mounts eSata mass storage devices when they are plugged in
# and unmounts them when they are removed.
# Copyright (C) 2004, 2005 Martin Dickopp
#
# This file is free software; the copyright holder gives unlimited
# permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
#
set -e
exec > /dev/null 2>&1


# Log a string via the syslog facility.
log()
{
    if test $1 != debug || expr "$VERBOSE" : "[yY]" > /dev/null; then
	logger -p user.$1 -t "esatamount[$$]" -- "$2"
    fi
}

# Test if the first parameter is in the list given by the second
# parameter.
in_list()
{
    for v in $2; do
	test "$1" != "$v" || return 0
    done
    return 1
}


# Test if the configuration variables are set.
test -n "$MOUNTPOINTS" || { log err "MOUNTPOINTS not set"; exit 1; }
test -n "$FILESYSTEMS" || { log err "FILESYSTEMS not set"; exit 1; }
test -n "$MOUNTOPTIONS" || { log err "MOUNTOPTIONS not set"; exit 1; }

# Test if /sbin/udev_volume_id is executable.
test -x /sbin/udev_volume_id \
    || { log err "cannnot execute /sbin/udev_volume_id"; exit 1; }

# Test if /var/run/esatamount exists
test -d /var/run/esatamount || mkdir -p /var/run/esatamount/

umask 022

if test "$ACTION" = add; then
    
    # Do nothing if device is USB or sda, sdb or sdc.   
    if ! echo $DEVNAME | grep -q sda \
	&& ! echo $DEVNAME | grep -q sdb \
	&& ! echo $DEVNAME | grep -q sdc \
	&& ! readlink "/sys$DEVPATH/device" | grep -q /usb \
	&& ! readlink "/sys$DEVPATH/../device" | grep -q /usb ; then
 	# A block or partition device has been added.
        # Test if it is a PCI device. 
   	if readlink "/sys$DEVPATH/device" | grep -q /pci \
	    || readlink "/sys$DEVPATH/../device" | grep -q /pci ; then
	    log debug "$DEVNAME is a PCI device"

            # Check blacklist
            if [ -f /etc/esatamount/blacklist ] ; then
                echo $DEVNAME | grep -q -v -f /etc/esatamount/blacklist
                if [ $? -ne 0 ] ; then
                    log debug "'$DEVNAME' is a blacklisted device; exiting..."
                    exit 1
                fi
            fi

	    # Acquire lock.
	    log debug "trying to acquire lock /var/run/esatamount/.mount.lock"
	    lockfile-create --retry 3 /var/run/esatamount/.mount || \
	        { log err "cannot acquire lock /var/run/esatamount/.mount.lock"; exit 1; }
	    trap '( lockfile-remove /var/run/esatamount/.mount )' 0
 	    log debug "acquired lock /var/run/esatamount/.mount.lock"

	    # Test if the device contains a filesystem.  If it doesn't, no
	    # further action is required, but calling udev_volume_id has the
	    # side effect that the partition table is read and partition
	    # devices are created.
	    if /sbin/udev_volume_id "$DEVNAME" | egrep -q '^F:(filesystem|disklabel)$'; then
	        log debug "$DEVNAME contains a filesystem or disklabel"

	        fstype="`/sbin/udev_volume_id -t \"$DEVNAME\"`"
	        log debug "$DEVNAME contains filesystem type $fstype"

	        # Test if the filesystem type is in the list of filesystem
	        # types to mount.
	        if in_list "$fstype" "$FILESYSTEMS"; then

		    # Search an available mountpoint.
		    for v in $MOUNTPOINTS; do
		        if test -d "$v" \
			     && ! grep -q "^[^ ][^ ]*  *$v " /proc/mounts; then
			    mountpoint="$v"
			    log debug "mountpoint $mountpoint is available for $DEVNAME"
			    break
		        fi
		    done
		    if test -n "$mountpoint"; then
		        # Determine mount options.
		        options=
		        for v in $FS_MOUNTOPTIONS; do
			    if expr "$v" : "-fstype=$fstype,."; then
			        options="`echo \"$v\" | sed 's/^[^,]*,//'`"
			        break
			    fi
		        done
		        if test -n "$MOUNTOPTIONS"; then
			    options="$MOUNTOPTIONS${options:+,$options}"
		        fi

		        # Mount the filesystem.
		        log info "executing command: mount -t$fstype ${options:+-o$options} $DEVNAME $mountpoint"
		        mount "-t$fstype" "${options:+-o$options}" "$DEVNAME" "$mountpoint"

		        # Determine vendor and model.
		        vendor=
		        if test -r "/sys$DEVPATH/device/vendor"; then
			    vendor="`cat \"/sys$DEVPATH/device/vendor\"`"
		        elif test -r "/sys$DEVPATH/../device/vendor"; then
			    vendor="`cat \"/sys$DEVPATH/../device/vendor\"`"
		        fi
		        vendor="`echo \"$vendor\" | sed 's/^ *//; s/ *$//'`"
		        model=
		        if test -r "/sys$DEVPATH/device/model"; then
			    model="`cat \"/sys$DEVPATH/device/model\"`"
		        elif test -r "/sys$DEVPATH/../device/model"; then
			    model="`cat \"/sys$DEVPATH/../device/model\"`"
		        fi
		        model="`echo \"$model\" | sed 's/^ *//; s/ *$//'`"

		        # Run hook scripts; ignore errors.
		        export UM_DEVICE="$DEVNAME"
		        export UM_MOUNTPOINT="$mountpoint"
		        export UM_FILESYSTEM="$fstype"
		        export UM_MOUNTOPTIONS="$options"
		        export UM_VENDOR="$vendor"
		        export UM_MODEL="$model"
		        log info "executing command: run-parts /etc/esatamount/mount.d"
		        run-parts /etc/esatamount/mount.d || :
		    else
		        # No suitable mount point found.
		        log warning "no mountpoint found for $DEVNAME"
		        exit 1
		    fi
	        fi
	     else
	        log debug "$DEVNAME does not contain a filesystem or disklabel"
	    fi
        fi
    fi

elif test "$ACTION" = remove; then

    # A block or partition device has been removed.
    # Test if it is mounted.
    while read device mountpoint fstype remainder; do
	if test "$DEVNAME" = "$device"; then
	    # If the mountpoint and filesystem type are maintained by
	    # this script, unmount the filesystem.
	    if in_list "$mountpoint" "$MOUNTPOINTS" \
		&& in_list "$fstype" "$FILESYSTEMS"; then
		log info "executing command: umount -l $mountpoint"
		umount -l "$mountpoint"

		# Run hook scripts; ignore errors.
		export UM_DEVICE="$DEVNAME"
		export UM_MOUNTPOINT="$mountpoint"
		export UM_FILESYSTEM="$fstype"
		log info "executing command: run-parts /etc/esatamount/umount.d"
		run-parts /etc/esatamount/umount.d || :
	    fi
	    break
	fi
    done < /proc/mounts

fi

exit 0
