summaryrefslogtreecommitdiffstats
path: root/opensuse/tdebase/devmon-automounter.sh
diff options
context:
space:
mode:
Diffstat (limited to 'opensuse/tdebase/devmon-automounter.sh')
-rw-r--r--opensuse/tdebase/devmon-automounter.sh1086
1 files changed, 1086 insertions, 0 deletions
diff --git a/opensuse/tdebase/devmon-automounter.sh b/opensuse/tdebase/devmon-automounter.sh
new file mode 100644
index 000000000..ff2de18f1
--- /dev/null
+++ b/opensuse/tdebase/devmon-automounter.sh
@@ -0,0 +1,1086 @@
+#!/bin/bash
+# Script Name: devmon http://igurublog.wordpress.com/downloads/script-devmon/
+# Requires: udisks bash>=4
+# Recommended: consolekit zenity
+# License: GNU GENERAL PUBLIC LICENSE Version 3 http://www.gnu.org/licenses/gpl-3.0.txt
+# Thanks to Bernard Baeyens (berbae) for code from udisksvm script
+# https://bbs.archlinux.org/viewtopic.php?id=112397
+
+#=========================================================================
+
+defaultmountoptions="noexec,nosuid,noatime"
+
+#=========================================================================
+
+help()
+{
+ cat << EOF
+devmon version 1.0.5
+Automounts and unmounts optical and removable drives using udisks
+Requires: udisks bash>=4 Recommended: consolekit zenity
+Usage: devmon [AUTOMOUNT-OPTIONS] # Run as daemon to automount
+ devmon [MOUNT-OPTIONS] # Or run as client to manually un/mount
+AUTOMOUNT-OPTIONS: (these can be used only in daemon mode)
+--exec-on-device DEVICE "COMMAND" Execute COMMAND after mounting DEVICE
+--exec-on-label "LABEL" "COMMAND" Execute COMMAND after mounting LABEL
+--exec-on-video "COMMAND" Execute COMMAND after video DVD mount
+--exec-on-audio "COMMAND" Execute COMMAND after audio CD insertion
+--exec-on-disc "COMMAND" Execute COMMAND after data CD/DVD mount
+--exec-on-drive "COMMAND" Execute COMMAND after drive mount
+--exec-on-unmount "COMMAND" Execute COMMAND after unmount
+--exec-on-remove "COMMAND" Execute COMMAND after drive removal
+ Where the following in COMMAND will be replaced with:
+ %d mount point directory (eg /media/cd)
+ %f device name (eg /dev/sdd1)
+ %l label of mounted volume
+ Multiple --exec-on-XXX options may be used to execute multiple commands.
+ Other exec-on-XXX commands are ignored if exec-on-device or -label executed.
+--mount-options "OPTIONS" Default: $defaultmountoptions
+--info-on-mount Show mounted drive info in a zenity dialog
+--no-mount Don't mount anything, just exec (disables
+ --exec-on-video)
+--no-unmount Don't unmount all removable drives on exit
+
+MOUNT-OPTIONS: (these can be used only in client mode)
+--unmount-removable | -r Sync and unmount all removable drives and show
+ pop-up dialog (zenity installation required)
+--unmount-recent | -c Unmount most recently mounted removable drive
+--unmount-optical | -o Unmount all optical drives (error pop-up only)
+--unmount-all | -u Same as --unmount-removable --unmount-optical
+--unmount DIR|DEVICE Unmount DEVICE or mount point DIR
+--eject DIR|DEVICE Unmount and eject DEVICE or mount point DIR
+--mount-all | -a Mount all removable and optical drives
+--mount DEVICE Mount DEVICE
+--mount-options|--mount-fstype|--unmount-options|--eject-options "OPTIONS"
+ These options will be passed to udisks
+
+UNIVERSAL OPTIONS: (these can be used in both daemon and client modes)
+--ignore-device DEVICE Ignore DEVICE (eg /dev/sdd1)
+--ignore-label "LABEL" Ignore volume with LABEL
+--sync | -s Add sync mount option for ext2-4 ntfs ufs, or
+ flush for fat & vfat (slower writing but safer)
+--internal Also attempt to un/mount internal system drives
+ (this is mostly a fix for esata issues)
+--no-gui | -g Do not show zenity pop-up dialogs
+Instructions and updates:
+ http://igurublog.wordpress.com/downloads/script-devmon/
+EOF
+ exit
+}
+
+test2()
+{
+ if [ "${2:0:1}" = "-" ] || [ "$2" = "" ]; then
+ echo "devmon: Option $1 requires an argument" 1>&2
+ exit 1
+ fi
+}
+
+test3()
+{
+ if [ "${2:0:1}" = "-" ] || [ "$2" = "" ] || \
+ [ "${3:0:1}" = "-" ] || [ "$3" = "" ]; then
+ echo "devmon: Option $1 requires two arguments" 1>&2
+ exit 1
+ fi
+}
+
+unknown()
+{
+ echo "devmon: Unknown option $1" 1>&2
+ echo " For help use: devmon --help" 1>&2
+ exit 1
+}
+
+# parse command line
+execoix=0
+execomx=0
+execovx=0
+execoax=0
+execodx=0
+execolx=0
+execoux=0
+execorx=0
+umntx=0
+mntx=0
+ejx=0
+igdevx=0
+iglabx=0
+while [ "$1" != "" ]; do
+ if [ "${1:0:1}" = "-" ]; then
+ case "$1" in
+ --help )
+ help
+ exit
+ ;;
+ # don't use eval on these to preserve command strings
+ --exec-on-drive )
+ test2 "$1" "$2"
+ execoi[$execoix]="$2"
+ (( execoix++ ))
+ shift
+ ;;
+ --exec-on-disc )
+ test2 "$1" "$2"
+ execom[$execomx]="$2"
+ (( execomx++ ))
+ shift
+ ;;
+ --exec-on-video )
+ test2 "$1" "$2"
+ execov[$execovx]="$2"
+ (( execovx++ ))
+ shift
+ ;;
+ --exec-on-audio )
+ test2 "$1" "$2"
+ execoa[$execoax]="$2"
+ (( execoax++ ))
+ shift
+ ;;
+ --exec-on-device )
+ test3 "$1" "$2" "$3"
+ execod1[$execodx]="$2"
+ execod2[$execodx]="$3"
+ (( execodx++ ))
+ shift 2
+ ;;
+ --exec-on-label )
+ test3 "$1" "$2" "$3"
+ execol1[$execolx]="$2"
+ execol2[$execolx]="$3"
+ (( execolx++ ))
+ shift 2
+ ;;
+ --exec-on-unmount )
+ test2 "$1" "$2"
+ execou[$execoux]="$2"
+ (( execoux++ ))
+ shift
+ ;;
+ --exec-on-remove )
+ test2 "$1" "$2"
+ execor[$execorx]="$2"
+ (( execorx++ ))
+ shift
+ ;;
+ --info-on-mount )
+ infomount=1
+ ;;
+ --no-mount )
+ nomount=1
+ ;;
+ --sync )
+ syncopt=1
+ ;;
+ --unmount-on-exit )
+ # leave for usage compat with versions prior to 1.0.1
+ ;;
+ --no-unmount )
+ nounmount=1
+ ;;
+ --unmount-all )
+ unmountrem=1
+ unmountoptical=1
+ ;;
+ --unmount-removable )
+ unmountrem=1
+ ;;
+ --unmount-optical )
+ unmountoptical=1
+ ;;
+ --unmount-recent )
+ unmountrecent=1
+ ;;
+ --unmount )
+ test2 "$1" "$2"
+ umnt[$umntx]="$2"
+ (( umntx++ ))
+ shift
+ ;;
+ --mount-all )
+ mountall=1
+ ;;
+ --mount )
+ test2 "$1" "$2"
+ mnt[$mntx]="$2"
+ (( mntx++ ))
+ shift
+ ;;
+ --eject )
+ test2 "$1" "$2"
+ ej[$ejx]="$2"
+ (( ejx++ ))
+ shift
+ ;;
+ --mount-options )
+ test2 "$1" "$2"
+ mountoptions="$2"
+ shift
+ ;;
+ --mount-fstype )
+ test2 "$1" "$2"
+ mountfstype="$2"
+ shift
+ ;;
+ --unmount-options )
+ test2 "$1" "$2"
+ unmountoptions="$2"
+ shift
+ ;;
+ --eject-options )
+ test2 "$1" "$2"
+ ejectoptions="$2"
+ shift
+ ;;
+ --internal )
+ internal=1
+ ;;
+ --nogui | --no-gui )
+ nogui=1
+ ;;
+ --ignore-device )
+ test2 "$1" "$2"
+ igdev[$igdevx]="$2"
+ (( igdevx++ ))
+ shift
+ ;;
+ --ignore-label )
+ test2 "$1" "$2"
+ iglab[$iglabx]="$2"
+ (( iglabx++ ))
+ shift
+ ;;
+ --* )
+ unknown "$1";;
+ -* )
+ o="${1:1}"
+ while [ "$o" != "" ]; do
+ case "${o:0:1}" in
+ r )
+ unmountrem=1;;
+ o )
+ unmountoptical=1;;
+ u )
+ unmountrem=1
+ unmountoptical=1
+ ;;
+ a )
+ mountall=1;;
+ s )
+ syncopt=1;;
+ c )
+ unmountrecent=1;;
+ g )
+ nogui=1;;
+ h )
+ help
+ exit
+ ;;
+ * )
+ unknown "-${o:0:1}";;
+ esac
+ o="${o:1}"
+ done
+ ;;
+ esac
+ else
+ unknown "$1"
+ fi
+ shift
+done
+(( mountmode = umntx + mntx + ejx + unmountrem + unmountoptical + mountall + unmountrecent ))
+
+# Warnings
+if [ "$(whoami)" = "root" ]; then
+ echo "WARNING: running devmon as root is usually not required or recommended" 1>&2
+fi
+
+if (( execoix + execomx + execovx + execoax + execodx + execolx + execoux + execorx \
+ + nounmount + infomount != 0 )) && (( mountmode != 0 )); then
+ echo "WARNING: devmon automount options ignored in mount mode" 1>&2
+fi
+
+driveinfo() #$1=dev #Optional $2=quiet
+{
+ unset systeminternal usage ismounted presentationnopolicy hasmedia \
+ opticaldisc numaudiotracks type partition media blank label
+ uinfos=`udisks --show-info $1 2> /dev/null`
+ label=`echo "$uinfos" | grep -m 1 "^ label:" | sed 's/ *label: *\(.*\)/\1/'`
+ listinfos=`echo "$uinfos" | grep \
+ -e "^ system internal:" \
+ -e "^ usage:" \
+ -e "^ type:" \
+ -e "^ is mounted:" \
+ -e "^ presentation nopolicy:" \
+ -e "^ has media" \
+ -e "^ optical disc:" \
+ -e " blank:" \
+ -e " num audio tracks:" \
+ -e "^ partition:" \
+ -e " media:"`
+ # The change for type= is to take only its first value in listinfos
+ listinfos=$(echo "$listinfos" | sed 's/ //g
+ s/:/=/
+ s/opticaldisc=/&1/
+ s/type=\(.*\)/type=${type:-\1}/
+ s/[()]//g
+ s/partition=/&1/')
+ eval "$listinfos"
+ if (( internal == 1 )); then
+ systeminternal="ignored"
+ fi
+ # Take only the first character
+ hasmedia=${hasmedia:0:1}
+ # If "partition:" not find in listinfos, should mean it is not a partition
+ partition=${partition:-0}
+ nopolicy="$presentationnopolicy"
+ if (( mountmode == 0 )) && [ "$systeminternal" != "1" ] && [ "$2" != "quiet" ]; then
+ if [ "$usage" = "filesystem" ] || [ "$opticaldisc" = "1" ]; then
+ echo "device: [$1]"
+ echo " systeminternal: [$systeminternal]"
+ echo " usage: [$usage]"
+ echo " type: [$type]"
+ echo " label: [$label]"
+ echo " ismounted: [$ismounted]"
+ echo " nopolicy: [$nopolicy]"
+ echo " hasmedia: [$hasmedia]"
+ echo " opticaldisc: [$opticaldisc]"
+ echo " numaudiotracks: [$numaudiotracks]"
+ echo " blank: [$blank]"
+ echo " media: [$media]"
+ echo " partition: [$partition]"
+ fi
+ fi
+}
+
+ignoredevice()
+{
+ idx=0
+ while (( idx < igdevx )); do
+ if [ "$1" = "${igdev[$idx]}" ]; then
+ echo "devmon: ignored device $1"
+ return 0
+ fi
+ (( idx++ ))
+ done
+ return 1
+}
+
+ignorelabel()
+{
+ ilx=0
+ while (( ilx < iglabx )); do
+ if [ "$1" = "${iglab[$ilx]}" ]; then
+ echo "devmon: ignored label $1"
+ return 0
+ fi
+ (( ilx++ ))
+ done
+ return 1
+}
+
+execcommands() # $exectype "${exec[@]}"
+{
+ exectype="$1"
+ shift
+ while [ "$1" != "" ]; do
+ usercmd="$1"
+ usercmd="${usercmd//%f/$dv}"
+ usercmd="${usercmd//%l/'$lb'}"
+ usercmd="${usercmd//%d/'$point'}"
+ if [ "$usercmd" != "" ]; then
+ echo "devmon: [$exectype] eval $usercmd &"
+ eval $usercmd &
+ fi
+ shift
+ done
+}
+
+mountdev() # $1=device [$2=label] [$3=devtype or fstype]
+{
+ # set label comment
+ if [ "$2" = "" ]; then
+ lblcmt=""
+ else
+ lblcmt="($2)"
+ fi
+ # set mount-fstype option
+ if [ "$mountfstype" != "" ]; then
+ fst="--mount-fstype"
+ else
+ fst=""
+ fi
+ # set default mount options
+ if [ "$mountoptions" != "" ]; then
+ mopts="$mountoptions"
+ else
+ mopts="$defaultmountoptions"
+ fi
+ # set sync mount options
+ if (( syncopt == 1 )); then
+ case "$3" in
+ ext2 | ext3 | ext4 | ufs | ntfs )
+ mopts="$mopts,sync";;
+ fat | vfat )
+ mopts="$mopts,flush";;
+ esac
+ fi
+ # mount
+ mntmsg="devmon: mount $1 --mount-options $mopts $fst $mountfstype $lblcmt"
+ if [ "$3" != "nofs" ]; then
+ echo "$mntmsg"
+ fi
+ umsg=`udisks --mount $1 --mount-options "$mopts" $fst $mountfstype 2>&1`
+ mounterr="$?"
+ # get mount point
+ point=`echo "$umsg" | grep "^Mounted " | sed 's/^Mounted .* at \(.*\)/\1/'`
+ if [ "$mounterr" != "0" ] || [ "$point" = "" ]; then
+ # if $3=nofs then there was no apparent filesystem but we tried to mount it
+ # anyway in case it didn't report the filesystem accurately, so ignore the
+ # error
+ if [ "$3" != "nofs" ]; then
+ echo "$umsg" 1>&2
+ echo "devmon: error mounting $1 ($mounterr)" 1>&2
+ if (( mountmode == 0 )) && (( polkiterrgiven != 1 )) && \
+ [ "$(echo "$umsg" | grep "Not Authorized")" != "" ]; then
+ if (( nogui != 1 )); then
+ ( sleep 3 && WINDOWID="" zenity --error --no-wrap --title="devmon error" \
+ --text="udisks functions are not authorized through policykit,\nso devmon cannot automount drives.\nPlease see devmon's consolekit installation instructions:\n\nhttp://igurublog.wordpress.com/downloads/script-devmon/#install\n\n(To silence this pop-up add --no-gui to devmon's command line.)" &> /dev/null ) &
+ fi
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ echo "udisks functions are not authorized through policykit," 1>&2
+ echo "so devmon cannot automount drives." 1>&2
+ echo "Please see devmon's consolekit installation instructions:" 1>&2
+ echo "http://igurublog.wordpress.com/downloads/script-devmon/#install" 1>&2
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" 1>&2
+ polkiterrgiven=1
+ fi
+ fi
+ uerr=3
+ return 3
+ elif [ "$3" = "nofs" ]; then
+ # no filesystem reported but successful mount
+ echo "$mntmsg"
+ fi
+ echo "$umsg"
+}
+
+unmountdev() # $1=device
+{
+ if [ "$unmountoptions" != "" ]; then
+ echo "devmon: unmount $1 --unmount-options $unmountoptions"
+ uerrmsg=`udisks --unmount $1 --unmount-options "$unmountoptions" 2>&1`
+ else
+ echo "devmon: unmount $1"
+ uerrmsg=`udisks --unmount $1 2>&1`
+ fi
+ if [ "$uerrmsg" != "" ]; then
+ # bug: udisks returns $?==0 when unmount fails
+ echo "$uerrmsg"
+ uerr=3
+ return 3
+ fi
+}
+
+ejectdev()
+{
+ if [ "$ejectoptions" != "" ]; then
+ echo "devmon: eject $1 --eject-options $ejectoptions"
+ udisks --eject $1 --eject-options "$ejectoptions"
+ else
+ echo "devmon: eject $1"
+ udisks --eject $1
+ fi
+ if [ "$?" != "0" ]; then
+ uerr=3
+ return 3
+ fi
+}
+
+mountdrive() # $1=device $2=label [$3=devtype or fstype]
+{
+ dv="$1"
+ lb="$2"
+ tp="$3"
+ unset point
+
+ if ( ignoredevice "$dv" ) || ( ignorelabel "$lb" ); then
+ return
+ fi
+
+ # mount
+ if [ "$tp" != "audiocd" ] && (( nomount != 1 )); then
+ mountdev $dv "$lb" "$tp"
+ if [ "$?" != "0" ]; then
+ return
+ fi
+ fi
+
+ # exec on device
+ unset execdone
+ x=0
+ while (( x < execodx )); do
+ if [ "${execod1[$x]}" = "$dv" ]; then
+ usercmd="${execod2[$x]}"
+ usercmd="${usercmd//%f/$dv}"
+ usercmd="${usercmd//%l/'$lb'}"
+ usercmd="${usercmd//%d/'$point'}"
+ if [ "$usercmd" != "" ]; then
+ echo "devmon: [exec on device] eval $usercmd"
+ eval $usercmd &
+ execdone=1
+ fi
+ fi
+ (( x++ ))
+ done
+ if (( execdone == 1 )); then return; fi
+
+ # exec on label
+ x=0
+ while (( x < execolx )); do
+ if [ "${execol1[$x]}" = "$lb" ]; then
+ usercmd="${execol2[$x]}"
+ usercmd="${usercmd//%f/$dv}"
+ usercmd="${usercmd//%l/'$lb'}"
+ usercmd="${usercmd//%d/'$point'}"
+ if [ "$usercmd" != "" ]; then
+ echo "devmon: [exec on label] eval $usercmd"
+ eval $usercmd &
+ execdone=1
+ fi
+ fi
+ (( x++ ))
+ done
+ if (( execdone == 1 )); then return; fi
+
+ # exec on video
+ if [ "$tp" = "dvd" ] && [ "$point" != "" ] && [ -d "$point/VIDEO_TS" ]; then
+ echo "devmon: videodvd $dv ($lb) on $point"
+ if (( execovx != 0 )); then
+ execcommands "exec on video" "${execov[@]}"
+ fi
+ return
+ fi
+
+ # exec on audio
+ if [ "$tp" = "audiocd" ]; then
+ echo "devmon: audiocd $dv ($lb)"
+ if (( execoax != 0 )); then
+ execcommands "exec on audio" "${execoa[@]}"
+ fi
+ return
+ fi
+
+ # exec on disc
+ if [ "$tp" = "optical" ] || [ "$tp" = "dvd" ]; then
+ if [ "$point" != "" ] || (( nomount == 1 )); then
+ if (( execomx != 0 )); then
+ execcommands "exec on disc" "${execom[@]}"
+ fi
+ fi
+ return
+ fi
+
+ # exec on drive
+ if [ "$point" != "" ] || (( nomount == 1 )); then
+ if (( execoix != 0 )); then
+ execcommands "exec on drive" "${execoi[@]}"
+ fi
+ fi
+
+ # info on mount
+ if [ "$point" != "" ] && (( infomount == 1 )) && (( nomount != 1 )); then
+ sleep .5
+ echo "devmon: [info on mount] $dv"
+ if (( nogui != 1 )); then
+ WINDOWID="" zenity --info --text="The following device has been mounted:\n\n$(df -hT "$dv" \
+ | grep "$dv" | awk '{print "Device:\\t"$1"\x0AType:\\t"$2"\nSize:\\t\\t"$3"\nUsed:\\t"$4"\n""Avail:\\t"$5"\nUse%:\\t"$6"\nMount:\\t"$7,$8,$9,$10}')\nLabel:\\t$lb" --title="devmon mount" &
+ fi
+ df -hT "$dv"
+ fi
+}
+
+mountalldrives()
+{
+ # Mount all optical drives, no exec
+ x=0
+ while [ -e /dev/sr$x ]; do
+ driveinfo /dev/sr$x
+ if [ "$numaudiotracks" = "" ]; then
+ numaudiotracks=0
+ fi
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" != "1" ] && [ "$hasmedia" != "0" ] && \
+ [ "$blank" != "1" ] && (( numaudiotracks == 0 )) && \
+ [ "$nopolicy" != "1" ]; then
+ if ( ignoredevice "/dev/sr$x" ) || ( ignorelabel "$label" ); then
+ (( x++ ))
+ continue
+ fi
+ mountdev /dev/sr$x "$label"
+ eval notejectedsr$x=1
+ fi
+ (( x++ ))
+ done
+ # Mount removable drives, no exec
+ IFSOLD="$IFS"
+ IFS=$'\n'
+ partlist=`grep " sd[a-z0-9]*$" /proc/partitions | sed 's/.* \(sd[a-z0-9]*\)/\1/'`
+ for p in $partlist; do
+ if ( ignoredevice "/dev/$p" ); then
+ continue
+ fi
+ driveinfo /dev/$p
+ if ( ignorelabel "$label" ); then
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" != "1" ] && \
+ [ "$ismounted" = "0" ] && [ "$nopolicy" != "1" ]; then
+ if [ "$usage" = "filesystem" ]; then
+ echo "mountdev /dev/$p $label $type"
+ mountdev /dev/$p "$label" "$type"
+ else
+ mountdev /dev/$p "$label" nofs
+ fi
+ fi
+ fi
+ done
+ IFS="$IFSOLD"
+}
+
+trapexit()
+{
+ kill $COPROC_PID 2> /dev/null
+
+ # prevent trap code from executing multiple times on different signals
+ if (( trapdone != 1 )); then
+ trapdone=1
+ # Unmount All
+ if (( nounmount != 1 )); then
+ IFSOLD="$IFS"
+ IFS=$'\n'
+ uerr=0
+ partlist=`grep " sd[a-z0-9]*$" /proc/partitions | \
+ sed 's/.* \(sd[a-z0-9]*\)/\1/'`
+ for p in $partlist; do
+ if ( ignoredevice "/dev/$p" ); then
+ continue
+ fi
+ driveinfo /dev/$p
+ if ( ignorelabel "$label" ); then
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" != "1" ] && \
+ [ "$usage" = "filesystem" ] && [ "$ismounted" = "1" ]; then
+ echo "devmon: [on exit] unmount /dev/$p &"
+ udisks --unmount /dev/$p &
+ if [ "$?" != "0" ]; then
+ uerr=3
+ fi
+ fi
+ fi
+ done
+ IFS="$IFSOLD"
+ fi
+ echo 'devmon: stopped'
+ exit $uerr
+ fi
+}
+
+# Client Mode
+if (( mountmode != 0 )); then
+ uerr=0
+ if (( unmountrem == 1 )) || (( unmountrecent == 1 )); then
+ y=0
+ unset udrive zpid
+ IFSOLD="$IFS"
+ IFS=$'\n'
+ if (( unmountrem == 1 )); then
+ # Unmount All Removable Drives
+ partlist=`grep " sd[a-z0-9]*$" /proc/partitions | sed 's/.* \(sd[a-z0-9]*\)/\1/'`
+ msgtitle="devmon unmount"
+ else
+ # Unmount Recent
+ partlist=`mount | grep "^/dev/.* on " | sed 's/^\/dev\/\(.*\) on .*/\1/' \
+ | grep -v -e "null" -e "shm" -e "mapper" -e "snd" \
+ -e "video" -e "random" | tac`
+ msgtitle="devmon unmount recent"
+ fi
+ for p in $partlist; do
+ if ( ignoredevice "/dev/$p" ); then
+ continue
+ fi
+ driveinfo /dev/$p
+ if ( ignorelabel "$label" ); then
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" != "1" ] \
+ && [ "$ismounted" = "1" ]; then
+ udrive[$y]="/dev/$p"
+ (( y++ ))
+ if (( unmountrem != 1 )); then break; fi
+ fi
+ fi
+ done
+ IFS="$IFSOLD"
+ if (( y == 0 )); then
+ msg="No removable drives are mounted"
+ echo "$msg"
+ else
+ msg="Unmounting ${udrive[@]}...\n\n(This dialog will close when the devices are unmounted)"
+ echo "Preparing to unmount ${udrive[@]}"
+ fi
+ if (( nogui != 1 )); then
+ WINDOWID="" zenity --info --title="$msgtitle" --text="$msg" &> /dev/null &
+ zpid=$!
+ fi
+ if (( y > 0 )); then
+ echo "devmon: sync"
+ sync
+ for d in ${udrive[@]}; do
+ unmountdev $d
+ if [ "$?" != "0" ] && (( nogui != 1 )); then
+ driveinfo "$d" quiet
+ if [ "$label" = "" ]; then
+ lb=""
+ else
+ lb=" ($label)"
+ fi
+ msg="Unmount error on $d$lb:\n\n$uerrmsg"
+ WINDOWID="" zenity --error --title="$msgtitle" --text="$msg" &> /dev/null &
+ fi
+ done
+ echo "devmon: sync"
+ sync
+ fi
+ if [ "$zpid" != "" ]; then
+ sleep 2
+ kill $zpid 2> /dev/null
+ fi
+ fi
+
+ # Unmount Optical
+ if (( unmountoptical == 1 )); then
+ x=0
+ while [ -e "/dev/sr$x" ]; do
+ if ( ignoredevice "/dev/sr$x" ); then
+ (( x++ ))
+ continue
+ fi
+ driveinfo /dev/sr$x
+ if ( ignorelabel "$label" ); then
+ (( x++ ))
+ continue
+ else
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" = "1" ]; then
+ unmountdev /dev/sr$x
+ if [ "$?" != "0" ] && (( nogui != 1 )); then
+ if [ "$label" = "" ]; then
+ lb=""
+ else
+ lb=" ($label)"
+ fi
+ msg="Unmount error on /dev/sr$x$lb:\n\n$uerrmsg"
+ WINDOWID="" zenity --error --title="devmon unmount optical" \
+ --text="$msg" &> /dev/null &
+ fi
+ fi
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Unmount DIR|DEVICE
+ if (( umntx > 0 )); then
+ x=0
+ while (( x < umntx )); do
+ d="${umnt[$x]}"
+ # remove trailing slash
+ if [ "$d" != "/" ]; then
+ d="${d%/}"
+ fi
+ if [ "${d:0:5}" = "/dev/" ]; then
+ # Unmount DEVICE
+ unmountdev "$d"
+ else
+ # Unmount DIR
+ if [ "$(dirname "$d")" = "." ]; then
+ if [ -d "$(pwd)/$d" ]; then
+ d="$(pwd)/$d"
+ elif [ -d "/media/$d" ]; then
+ d="/media/$d"
+ elif [ -e "/dev/$d" ] && [ "$(mount | grep "^/dev/$d on ")" != "" ]; then
+ unmountdev "/dev/$d"
+ (( x++ ))
+ continue
+ fi
+ fi
+ if [ ! -d "$d" ]; then
+ echo "devmon: No such directory or mounted device $d" 1>&2
+ uerr=3
+ else
+ dv=`mount | grep -m 1 " on $d type " | awk '{print $1}'`
+ if [ "$dv" = "" ]; then
+ echo "devmon: Nothing mounted on $d (mtab)" 1>&2
+ uerr=3
+ else
+ unmountdev "$dv"
+ fi
+ fi
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Eject DIR|DEVICE
+ if (( ejx > 0 )); then
+ x=0
+ while (( x < ejx )); do
+ d="${ej[$x]}"
+ # remove trailing slash
+ if [ "$d" != "/" ]; then
+ d="${d%/}"
+ fi
+ dv=""
+ if [ "${d:0:5}" = "/dev/" ]; then
+ # Eject DEVICE
+ dv="$d"
+ else
+ # Eject DIR
+ if [ "$(dirname "$d")" = "." ]; then
+ if [ -d "$(pwd)/$d" ]; then
+ d="$(pwd)/$d"
+ elif [ -d "/media/$d" ]; then
+ d="/media/$d"
+ elif [ -e "/dev/$d" ] && [ "$(mount | grep "^/dev/$d on ")" != "" ]; then
+ dv="/dev/$d"
+ fi
+ fi
+ if [ "$dv" = "" ]; then
+ if [ ! -d "$d" ]; then
+ echo "devmon: No such directory or mounted device $d" 1>&2
+ uerr=3
+ else
+ dv=`mount | grep -m 1 " on $d type " | awk '{print $1}'`
+ if [ "$dv" = "" ]; then
+ echo "devmon: Nothing mounted on $d (mtab)" 1>&2
+ uerr=3
+ fi
+ fi
+ fi
+ fi
+ if [ "$dv" != "" ]; then
+ driveinfo "$dv"
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" = "1" ]; then
+ unmountdev "$dv"
+ fi
+ ejectdev "$dv"
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Mount DEVICE
+ if (( mntx > 0 )); then
+ x=0
+ while (( x < mntx )); do
+ d="${mnt[$x]}"
+ # remove trailing slash
+ if [ "$d" != "/" ]; then
+ d="${d%/}"
+ fi
+ if [ "$(dirname "$d")" = "." ] && [ "${d:0:5}" != "/dev/" ]; then
+ d="/dev/$d"
+ fi
+ driveinfo "$d" quiet
+ if [ "$opticaldisc" = "1" ]; then
+ mountdev $d "$label"
+ else
+ mountdev $d "$label" "$type"
+ fi
+ (( x++ ))
+ done
+ fi
+
+ # Mount All Unmounted
+ if (( mountall == 1 )); then
+ mountalldrives
+ fi
+
+ exit $uerr
+fi
+
+# Daemon Mode
+if [ "$mountfstype" != "" ]; then
+ echo "WARNING: --mount-fstype ignored in daemon mode" 1>&2
+ mountfstype=""
+fi
+if [ "$unmountoptions" != "" ]; then
+ echo "WARNING: --unmount-options ignored in daemon mode" 1>&2
+ unmountoptions=""
+fi
+if [ "$ejectoptions" != "" ]; then
+ echo "WARNING: --eject-options ignored in daemon mode" 1>&2
+ ejectoptions=""
+fi
+pidcount=`ps h -C ${0//*\//} -o pid | wc -l`
+if (( pidcount > 2 )); then
+ echo
+ echo "WARNING: multiple instances of devmon appear to be running"
+ echo
+fi
+
+# Trigger udisks daemon start two ways
+if [ -e /dev/sr0 ]; then
+ udisks --poll-for-media /dev/sr0
+fi
+udisks --show-info /dev/sda > /dev/null
+sleep 2 # helps successful sr0 startup mount on reboot
+
+
+# Startup Mounting
+if (( nomount != 1 )); then
+ mountalldrives
+fi
+
+# Start monitoring
+coproc udisks --monitor
+err=$?
+trap trapexit EXIT SIGINT SIGTERM SIGQUIT
+trap "echo devmon: ignored HUP" SIGHUP
+
+if [ $err != "0" ] || [ ! ps -p $COPROC_PID &>/dev/null ]; then
+ echo "devmon: unable to start udisks --monitor" 1>&2
+ echo " is udisks installed and dbus running?" 1>&2
+ exit 2
+fi
+
+
+# Monitoring Loop
+while ps -p $COPROC_PID &>/dev/null; do
+ read -u ${COPROC[0]}
+ echo "==========================================="
+ echo "$REPLY"
+ event="${REPLY%:*}"
+ devpath="${REPLY#*:}"
+ devpath="/dev/${devpath##*/}"
+ if [ "$event" != "" ] && [ "$devpath" != "/dev/" ] && [ -e "$devpath" ]; then
+ case $event in
+ added )
+ driveinfo $devpath
+ if [ "$systeminternal" != "1" ] && [ "$ismounted" = "0" ] && \
+ [ "$nopolicy" != "1" ]; then
+ if [ "$usage" = "filesystem" ]; then
+ mountdrive $devpath "$label" "$type"
+ else
+ mountdrive $devpath "$label" nofs
+ fi
+ fi
+ ;;
+ job-changed )
+ ;;
+ removed )
+ ;;
+ changed )
+ driveinfo $devpath
+ eval notejected=\$notejected${devpath#/dev/}
+ eval devmounted=\$devmounted${devpath#/dev/}
+ eval devmounted${devpath#/dev/}="$ismounted"
+ # If notejected==1 then cd has not been ejected and was probably
+ # manually unmounted, so don't automount it. Otherwise
+ # devmon will instantly mount any manual unmount.
+ if [ "$systeminternal" != "1" ] && [ "$opticaldisc" = "1" ] && \
+ [ "$ismounted" != "1" ] && [ "$hasmedia" != "0" ] && \
+ [ "$blank" != "1" ] && (( notejected != 1 )) && \
+ [ "$nopolicy" != "1" ]; then
+ if [ "$media" = "optical_dvd" ]; then
+ mountdrive $devpath "$label" dvd
+ elif (( numaudiotracks > 0 )); then
+ mountdrive $devpath "$label" audiocd
+ else
+ mountdrive $devpath "$label" optical
+ fi
+ eval notejected${devpath#/dev/}=1
+ else
+ if [ "$systeminternal" != "1" ] && \
+ [ "$ismounted" != "1" ] && [ "$hasmedia" = "0" ]; then
+ # disc ejected
+ echo "devmon: $devpath eject detected"
+ eval notejected${devpath#/dev/}=0
+ fi
+ if [ "$systeminternal" != "1" ] && [ "$ismounted" != "1" ] && \
+ [ "$nopolicy" != "1" ] && [ "$devmounted" = "1" ]; then
+ # exec-on-unmount
+ if (( execoux != 0 )); then
+ if ( ! ignoredevice "$devpath" ) && ( ! ignorelabel "$label" ); then
+ dv="$devpath"
+ execcommands "exec on unmount" "${execou[@]}"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ esac
+ elif [ "$event" = "removed" ]; then
+ eval unset devmounted${devpath#/dev/}
+ # exec-on-remove
+ if (( execorx != 0 )); then
+ if ( ! ignoredevice "$devpath" ); then
+ unset lb point
+ dv="$devpath"
+ execcommands "exec on remove" "${execor[@]}"
+ fi
+ fi
+ fi
+done
+
+exit
+
+# CHANGELOG
+# 1.0.5: --exec-on-unmount now executes only once per unmount
+# 1.0.4: added --exec-on-unmount, --exec-on-remove
+# added multiple instance warning
+# %f device spec no longer passed in quotes to commands
+# 1.0.3: help updated for sync
+# corrected exec-on-drive bug introduced in 1.0.1
+# 1.0.2: --sync adds sync for ntfs
+# 1.0.1: added --sync
+# added --no-unmount; unmount-on-exit is now default
+# obey UDISKS_PRESENTATION_NOPOLICY to inhibit automount
+# added unmount-all error pop-ups
+# 1.0.0: added --unmount-recent
+# improved udisks mount info to stdout
+# improved mount/unmount without apparent filesystem
+# 0.9.5: ignore trailing slash in un/mount dir/dev specs
+# attempt to mount no filesystem in case there is one
+# 0.9.4: polkit error more selective
+# 0.9.3: corrected problems with spaces in volume labels
+# corrected un/mounting of partitionless devices
+# corrected --ignore-devices problem
+# added not authorized pop-up error
+# 0.9.2: added --internal
+# 0.9.1: corrected --unmount-on-removable not recognized
+# 0.9.0: changed --unmount-all to --unmount-removable
+# added --unmount-all (now includes optical)
+# added --unmount-optical
+# added --unmount DIR|DEVICE
+# added --eject DIR|DEVICE
+# added --mount-all
+# added --mount DEVICE
+# added --info-on-mount
+# added pass options to udisks
+# better error msg from udisks
+# individual drive eject detection
+# no limit on number of optical drives
+# 0.8.2: more verbose errors
+# run as root changed to warning
+# 0.8.1: added --unmount-on-exit
+# adjusted start daemon trigger, timing
+# added 'do not run as root' catcher
+# added trap to ignore SIGHUP
+