#!/usr/bin/sh
#$1 = <dev>

# Default options to use for mounting
AUTOMOUNT_OPTS='users,exec'
# Default type to use for mounting
AUTOMOUNT_TYPE='auto'

# Directory to look for type-specific settings
confdir=/etc/media-automount.d

# Directory to use as parent media dir for mountpoints
mediadir=/media

[ $(id -u) != 0 ] && {
    echo "This tool requires root permissions"
    exit 1
}

log() {
    echo "$*" | systemd-cat -p ${loglevel:-info} -t "media-automount"
}

alias debuglog="loglevel=debug log"
alias errorlog="loglevel=err log"

acquire_lock() {
    exec 3>/var/run/media-automount.lock
    flock -x 3
}

release_lock() {
    flock -u 3
    exec 3>&-
}

if ! [ "$1" ]
then
    errorlog "missing arguments! a device name must be provided"
    exit 1
else
    dev=/dev/${1##*/}
fi

if [ "$dev" = "$(findmnt -n -o SOURCE /)" ]
then
    log "$dev is used as rootfs, automount won't manage it"
    exit 0
fi

acquire_lock

# Check if the device exists, if not but mounted, umount it
if ! [ -b $dev ]
then
    if grep /etc/mtab -qe "^$dev"
    then
        log "$dev device removed, umounting and cleaning /media"
        if umount "$dev"
        then
            exitcode=0
        else
            exitcode=$?
            errorlog "Error umounting $dev errcode:$exitcode"
            errorlog "Command was: umount $dev"
        fi
    else
        # prevent it from failing on nonexistent devices and degrading systemctl boot
        exitcode=0
        errorlog "device doesn't exist anymore or is not a block device: $dev"
    fi

    # cleanup
    for dir in "$mediadir"/*
    do
        # Only clean non active mountpoints that have no /etc/fstab entry
        if [ -d "$dir" ] && ! mountpoint -q "$dir" && ! grep -q "^\s*[^#\s]\+\s\+${dir}" /etc/fstab; then
            rmdir "$dir"
        fi
    done
    release_lock; exit $exitcode
fi

# Load additional info for the block device
eval $(blkid -po export $dev)

# Devices with unknown type will be ignored
if [ -z "$TYPE" ]
then
    debuglog "$dev has no known filesystem type, ignoring mount request"
    release_lock; exit 0
fi

# Check /etc/fstab for an entry corresponding to the device
fstab=$([ ! "x${PART_ENTRY_UUID}" = "x" ] && grep /etc/fstab -e "^[^#]*PARTUUID=${PART_ENTRY_UUID}") || \
fstab=$([ ! "x${UUID}" = "x" ] && grep /etc/fstab -e "^[^#]*UUID=${UUID}") || \
fstab=$([ ! "x${LABEL}" = "x" ] && grep /etc/fstab -e "^[^# ]*LABEL=${LABEL}") || \
fstab=$(grep /etc/fstab -e "^[ \t]*$dev[ \t]")

# Don't manage devices that are already in fstab
if [ ! "x$fstab" = "x" ]
then
    debuglog "$dev already in /etc/fstab, automount won't manage it: ${fstab#\t}"
    release_lock; exit 0
fi

# directory name
AUTOMOUNT_DIR="${mediadir}/${LABEL:-${dev##*/}}.$TYPE"

# Avoid conflicts when multiple devices have the same label
if [ -e "$AUTOMOUNT_DIR" ] && mountpoint -q "$AUTOMOUNT_DIR"
then
    dups=$(find "${AUTOMOUNT_DIR}*" -maxdepth 0 -printf '.' | wc -c)
    AUTOMOUNT_DIR="${AUTOMOUNT_DIR}_$((dups+1))"
fi

# Load PARTUUID-specific configuration for mounting
if [ ! "x${PART_ENTRY_UUID}" = "x" ] && [ -e "$confdir/${PART_ENTRY_UUID}.partuuid" ]
then
    debuglog "loading configuration for PARTUUID $PART_ENTRY_UUID"
    . "${confdir}/${PART_ENTRY_UUID}.partuuid"
# Load UUID-specific configuration for mounting
elif [ ! "x${UUID}" = "x" ] && [ -e "${confdir}/${UUID}.uuid" ]
then
    debuglog "loading configuration for UUID $UUID"
    . "${confdir}/${UUID}.uuid"
# Load Filesystem-specific configuration for mounting
elif [ ! "x${TYPE}" = "x" ] && [ -e "${confdir}/${TYPE}.type" ]
then
    debuglog "loading configuration for fs type $TYPE"
    . "${confdir}/${TYPE}.type"
elif [ -e "$confdir/auto" ]
then
    . "$confdir/auto"
fi

log "mounting device $dev in $AUTOMOUNT_DIR"
mkdir -p "$AUTOMOUNT_DIR"
if mount -t "$AUTOMOUNT_TYPE" -o "$AUTOMOUNT_OPTS" "$dev" "$AUTOMOUNT_DIR"
then
    # Notify
    username="$(ps au | awk '$11 ~ /^xinit/ { print $1; exit }')"
    [ "$username" ] && DISPLAY=:0 runuser -u "$username" xdg-open "$AUTOMOUNT_DIR"
    log "Device successfully mounted: $AUTOMOUNT_DIR"
    release_lock; exit 0
else
    errorlog "Mount error: $?"
    errorlog "Command was : mount -t $AUTOMOUNT_TYPE -o $AUTOMOUNT_OPTS $dev $AUTOMOUNT_DIR"

    rmdir "$AUTOMOUNT_DIR"
    release_lock; exit 1
fi
