#!/bin/sh # File: /usr/bin/myautomountd # Location: gitlab # Authors: beanpole135, bgstack15 # Startdate: 2020-09-23 # SPDX-License-Identifier: CC-BY-SA-4.0 # Title: Automount in Shell # Purpose: # History: # 2020-09-23 originally translated by bgstack15 to shell from Go version (reference 1) # 2020-09-25 diverged from original architecture # Usage: # Invoke this at X startup. This can be from the xdg autostart mechanism, or "exec myautomountd &" in ~/fluxbox.startup # This is the backend to myautomount-trayicon # Reference: # https://github.com/project-trident/trident-utilities/blob/master/src-go/automount/main.go # Improve: # Dependencies: # udevadm (from systemd-udev or eudev) # dep-devuan: eudev # FUNCTIONS clean_automount() { rm -f "${AUTOMOUNT_TMPFILE}" kill "${AUTOMOUNT_PID}" } reset_tmpfile() { cat /dev/null > "${AUTOMOUNT_TMPFILE}" } handleEvent() { # call: handleEvent "${STRING}" _line="${1}" test -n "${STACKTRACE}" && echo "handleEvent \"${_line}\"" 1>&2 echo "${_line}" | grep -qvE "^UDEV" && return # not a valid entry - possibly a startup message test $( echo "${_line}" | wc -w ) -ne 5 && return _deviceid= _eventType= for word in ${_line} ; do # no opportunity for the bash for statement to read a blank value here from unquoted variable if echo "${word}" | grep -qE '^(add|remove|change)$' ; then _eventType="${word}" elif echo "${word}" | grep -qE "^\/devices\/" ; then _deviceid="$( echo "${word}" | awk -F'/' '{print $NF}' )" fi done { test "${_deviceid}" = "" || test "${_eventType}" = "" ; } && return test -n "${VERBOSE}" || test -n "${DEBUG}" && echo "Got device event: ${_eventType} ${_deviceid}" 1>&2 _entry="${AUTOMOUNT_BASEDIR}/${_deviceid}.desktop" case "${_eventType}" in "add") createEntry "${_deviceid}" "${_entry}" ;; *) # anything else test -e "${_entry}" && { rm "${_entry}" || : ; } test "${_eventType}" = "change" && createEntry "${_deviceid}" "${_entry}" ;; esac } createEntry() { # call: createEntry "{device}" "${filepath}" _device="${1}" _filepath="${2}" test -n "${STACKTRACE}" && echo "STUB createEntry \"${_device}\" \"${_filepath}\"" 1>&2 _fs= _model= _vendor= _label= _atracks= _bytes="$( udevadm info "/dev/${_device}" 2>/dev/null )" _shortbytes="$( printf "%s\n" "${_bytes}" | sed -r -e 's/^E:\s*//;' | grep -E '^(ID_FS_TYPE|ID_MODEL|ID_VENDOR|ID_FS_LABEL|ID_CDROM_MEDIA_TRACK_COUNT_AUDIO)=' )" unset ID_FS_TYPE ID_MODEL ID_VENDOR ID_FS_LABEL ID_CDROM_MEDIA_TRACK_COUNT_AUDIO eval "${_shortbytes}" _fs="${ID_FS_TYPE}" _model="${ID_MODEL}" _vendor="${ID_VENDOR}" _label="${ID_FS_LABEL}" _atracks="${ID_CDROM_MEDIA_TRACK_COUNT_AUDIO}" test -n "${DEBUG}" && echo "fs=${_fs} model=${_model} vendor=${_vendor} label=${_label} atracks=${_atracks}" 1>&2 test "${_fs}" = "" && test "${_atracks}" = "" && return # if the fs cannot be detected touch "${_filepath}" ; chmod 0755 "${_filepath}" { echo "[Desktop Entry]" echo "Version=1.1" if test "${_fs}" = "udf" ; then echo "Type=Application" echo "Exec=xdg-open dvd:///dev/${_device}" elif test -n "${_atracks}" ; then test -n "${_label}" && _label="Audio CD" echo "Type=Application" echo "Exec=xdg-open cdda:///dev/${_device}" else echo "Type=Application" echo "Exec=xdg-open ${AUTOMOUNT_BROWSEDIR}/${_device}" echo "Path=${AUTOMOUNT_BROWSEDIR}/${_device}" fi if test -z "${_label}" ; then echo "Name=${_vendor} ${_model}" else echo "Name=${_label}" echo "GenericName=${_vendor} ${_model}" fi echo "Comment=${_device} (${_fs})" case "${_fs}" in "cd9600") echo "Icon=media-optical" ;; "udf") echo "Icon=media-optical-dvd" ;; "") echo "Icon=media-optical-audio" ;; *) echo "Icon=media-removable" ;; esac } > "${_filepath}" } # INITIALIZE test -z "${UID}" && export UID="$( $( which id ) -u "${USER}" )" . ${MYA_PREFIX}/etc/myautomount.conf trap '__ec=$? ; clean_automount ; trap "" 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 ; exit ${__ec} ;' 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 18 19 20 mkdir -p "${AUTOMOUNT_BASEDIR}" # run initialization script as root $( which sudo 2>/dev/null ) AUTOMOUNT_USER="${USER}" /usr/libexec/myautomount/myautomount-initialize.sh _response="${?}" ; test ${_response} -ne 0 && exit ${_response} # MAIN # start udevadm udevadm monitor -u -s block 1> "${AUTOMOUNT_TMPFILE}" & export AUTOMOUNT_PID="${!}" test -n "${DEBUG}" && env | grep -E '^AUTOMOUNT_' 1>&2 while ! test -e /tmp/kill-myautomount ; do tail -F "${AUTOMOUNT_TMPFILE}" 2>/dev/null | while read line ; do handleEvent "${line}" _length="$( wc -l < "${AUTOMOUNT_TMPFILE}" 2>/dev/null )" ; test -z "${_length}" && _length=0 test "${line}" = "$( tail -n1 "${AUTOMOUNT_TMPFILE}" )" && test ${_length} -gt 200 && reset_tmpfile done # the tail finished for some reason, so clear the file reset_tmpfile done