aboutsummaryrefslogtreecommitdiff
path: root/stackrpms-automount.sh
blob: 232a7f69c05dc82921f528f08f633eb8f063c481 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/bin/sh
# File: stackrpms-automount.sh
# Location: gitlab
# Authors: beanpole135, bgstack15
# Startdate: 2020-09-23
# Title: Automount in Shell
# Purpose: almost one-for-one translation of Go version 
# History:
#    2020-09-23 translated by bgstack15 to shell from Go version (reference 1)
#        Several translation notes: configuration split out into separate file
#           and given a Fedora flavor.
# Usage:
#    Run as root.
# Reference:
#    1: https://github.com/project-trident/trident-utilities/blob/master/src-go/automount/main.go
# Improve:
# Dependencies: udevadm (from systemd-udev or 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)=' )"
   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}"
}

setupSystem() {
   _needrestart=0
   mkdir -m0755 -p "${AUTOMOUNT_DIR}" || fail "Could not setup autofs rules! Check if this is being run as root?"
   ! test -f "${AUTOMOUNT_FILE}" && {
      { touch "${AUTOMOUNT_FILE}" && echo "* -fstype=auto,rw,nosuid,uid=${USER},gid=users  :/dev/& " > "${AUTOMOUNT_FILE}" ; } || fail "Could not setup autofs rules! Check if this is being run as root?"
      _needrestart=1
   }
   ! test -f "${AUTOMOUNT_DIR_FILE}" && {
      { touch "${AUTOMOUNT_DIR_FILE}" && echo "${AUTOMOUNT_BROWSEDIR}  ${AUTOMOUNT_FILE}       --timeout=5 " > "${AUTOMOUNT_DIR_FILE}" ; } || fail "Could not setup autofs rules! Check if this is being run as root?"
      _needrestart=1
   }
   test ${_needrestart} -eq 1 && eval "service autofs restart"
}

fail() {
   echo "${@}" 1>&2
   exit 1
}

# INITIALIZE
. ${0%%.sh}.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
setupSystem

# 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-automount ;
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
bgstack15