diff --git a/plugins/README.md b/plugins/README.md index f2a3c4e6..167676a1 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -45,7 +45,7 @@ Plugins extend the capabilities of `nnn`. They are _executable_ scripts (or bina | [mp3conv](mp3conv) | Extract audio from multimedia as mp3 | sh | ffmpeg | | [mtpmount](mtpmount) | Toggle mount of MTP device (eg. Android) | sh | gvfs-mtp | | [nbak](nbak) | Backs up `nnn` config | sh | tar, awk, mktemp | -| [nmount](nmount) | Toggle mount status of a device as normal user | sh | pmount, udisks2 | +| [nmount](nmount) | Toggle mount status of a device as normal user | sh | pmount (optional), udisks2 | | [nuke](nuke) | Sample file opener (CLI-only by default) | sh | _see in-file docs_ | | [oldbigfile](oldbigfile) | List large files by access time | sh | find, sort | | [openall](openall) | Open selected files together or one by one [✓] | bash | - | diff --git a/plugins/nmount b/plugins/nmount index c30efb4a..e05453f2 100755 --- a/plugins/nmount +++ b/plugins/nmount @@ -4,7 +4,7 @@ # If the device is not mounted, it will be mounted. # If the device is mounted, it will be unmounted and powered down. # -# Dependencies: lsblk, pmount +# Dependencies: lsblk, pmount (optional), udisks2 # # Usage: Runs `lsblk` on 'l', exits on 'Return`. # @@ -13,7 +13,7 @@ # macOS: "diskutil list" # BSD: "geom disk list" # - The script uses udisksctl (from udisks2) to power down devices. This is also Linux-specific. -# Users on non-Linux platforms can comment it and use an alterntive to power-down disks. +# Users on non-Linux platforms can comment it and use an alternative to power-down disks. # # Shell: POSIX compliant # Author: Arun Prakash Jana @@ -32,16 +32,48 @@ while [ -n "$dev" ]; do elif [ "$dev" = "q" ]; then exit else - if grep -qs "$dev " /proc/mounts; then + # LUKS volumes mounted with udisksctl appear differently than with pmount + if grep -qs "$dev " /proc/mounts || [ -n "$(lsblk -n "/dev/$dev" -o MOUNTPOINT)" ]; then sync "$(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")" - if pumount "/dev/$dev"; then + if type pumount >/dev/null 2>&1; then + pumount "/dev/$dev" + exit_code="$?" + else + # Unlike pmount, udisksctl does not transparently handle LUKS volumes + # We need to manually get the unlocked device, unmount it, and then lock the volume + if lsblk -n "/dev/$dev" -o FSTYPE | grep "crypto_LUKS" >/dev/null; then + dev_map="$(udisksctl info -b /dev/"$dev" | grep "CleartextDevice" | grep -o "dm_2d[[:digit:]]*" | sed "s/_2d/-/")" + udisksctl unmount -b "/dev/$dev_map" --no-user-interaction >/dev/null + exit_code="$?" + udisksctl lock -b "/dev/$dev" --no-user-interaction >/dev/null + else + udisksctl unmount -b "/dev/$dev" --no-user-interaction >/dev/null + exit_code="$?" + fi + fi + if [ $exit_code -eq 0 ]; then echo "/dev/$dev unmounted." if udisksctl power-off -b "/dev/$dev" --no-user-interaction; then echo "/dev/$dev ejected." fi fi elif [ -b "/dev/$dev" ]; then - if pmount "/dev/$dev"; then + if type pmount >/dev/null 2>&1; then + pmount "/dev/$dev" + exit_code="$?" + else + # Unlike pmount, udisksctl does not transparently handle LUKS volumes + # We need to manually get the unlocked device and mount that instead of the volume itself + if [ "$(lsblk "/dev/$dev" -n -o FSTYPE)" = "crypto_LUKS" ]; then + dev_map=$(udisksctl unlock -b "/dev/$dev" --no-user-interaction | grep -o "dm-[[:digit:]]*") + udisksctl mount -b "/dev/$dev_map" --no-user-interaction >/dev/null + exit_code="$?" + else + udisksctl mount -b "/dev/$dev" --no-user-interaction >/dev/null + exit_code="$?" + fi + fi + if [ $exit_code -eq 0 ]; then sleep 1 echo "/dev/$dev mounted to $(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")." fi