#!/bin/sh # Menu to unmount drives and phones mounted with mounter (or anything else on a # /dev device, except /, /boot, /efi and /home), via udisks and gvfs. LUKS mappers # are locked again afterwards: automatically if udisks opened them (luks-), # else after asking. menu() { aurora-run -d -p "$1"; } notify() { notify-send -a unmounter "$@"; } die() { notify -u critical "💾 Unmount failed" "$1"; exit 1; } # kindtargetsourcefstype per mount; jq so paths with spaces survive. # Phones are gvfs mounts: target = their name, source = mtp:// uri. mounts="$( findmnt -Jo TARGET,SOURCE,FSTYPE | jq -r ' .. | objects | select(has("target")) | select(.source | startswith("/dev/")) | select(.target | test("^/(boot|efi|home)?$") | not) | ["drive", .target, (.source | sub("\\[.*"; "")), .fstype] | @tsv' gio mount -l 2>/dev/null | sed -n 's/^ *Mount([0-9]*): \(.*\) -> \(mtp:\/\/.*\)$/phone\t\1\t\2\tmtp/p' )" [ -z "$mounts" ] && { notify "💾 Unmounter" "Nothing to unmount."; exit 0; } i="$(echo "$mounts" | while IFS=" " read -r kind target src fstype; do case "$kind" in phone) icon="📱" ;; *) [ "$(lsblk -dno TYPE "$src" 2>/dev/null)" = "crypt" ] && icon="🔒" || icon="💾" ;; esac printf '%s %s %s (%s)\n' "$icon" "$target" "$src" "$fstype" done | aurora-run -d --index -p "Unmount")" || exit 1 [ "$i" -ge 0 ] 2>/dev/null || exit 1 IFS=" " read -r kind target src fstype <&1)" || die "$err" notify "📱 Unmounted" "$target" exit 0 fi err="$(udisksctl unmount -b "$src" 2>&1)" || { pids="$(fuser -m "$target" 2>/dev/null)" [ -n "$pids" ] && err="$err In use by: $(ps -o comm= -p "$(echo $pids | tr ' ' ',')" | sort -u | tr '\n' ' ')" die "$err" } notify "💾 Unmounted" "$target" # Lock the LUKS container behind a mapper, unless it's still mounted somewhere else. [ "$(lsblk -dno TYPE "$src" 2>/dev/null)" = "crypt" ] || exit 0 findmnt -n --source "$src" >/dev/null && exit 0 luks="$(lsblk -nprso NAME "$src" | sed -n 2p)" [ "$(lsblk -dno FSTYPE "$luks")" = "crypto_LUKS" ] || exit 0 case "$(basename "$src")" in luks-*) ;; *) [ "$(printf 'Yes\nNo' | menu "Also lock $luks ($(basename "$src"))?")" = "Yes" ] || exit 0 ;; esac err="$(udisksctl lock -b "$luks" 2>&1)" || die "Could not lock $luks: $err" notify "🔒 Locked" "$luks"