diff options
-rwxr-xr-x | .local/bin/dmenumount | 41 | ||||
-rwxr-xr-x | .local/bin/dmenuunmount | 27 | ||||
-rwxr-xr-x | .local/bin/mounter | 94 | ||||
-rwxr-xr-x | .local/bin/umounter | 28 |
4 files changed, 122 insertions, 68 deletions
diff --git a/.local/bin/dmenumount b/.local/bin/dmenumount deleted file mode 100755 index 7314374..0000000 --- a/.local/bin/dmenumount +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -# Gives a dmenu prompt to mount unmounted drives and Android phones. If -# they're in /etc/fstab, they'll be mounted automatically. Otherwise, you'll -# be prompted to give a mountpoint from already existsing directories. If you -# input a novel directory, it will prompt you to create that directory. - -getmount() { \ - [ -z "$chosen" ] && exit 1 - # shellcheck disable=SC2086 - mp="$(find $1 2>/dev/null | dmenu -i -p "Type in mount point.")" || exit 1 - test -z "$mp" && exit 1 - if [ ! -d "$mp" ]; then - mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") || exit 1 - [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || doas mkdir -p "$mp") - fi - } - -mountusb() { \ - chosen="$(echo "$usbdrives" | dmenu -i -p "Mount which drive?")" || exit 1 - chosen="$(echo "$chosen" | awk '{print $1}')" - doas -A mount "$chosen" 2>/dev/null && notify-send "💻 USB mounting" "$chosen mounted." && exit 0 - alreadymounted=$(lsblk -nrpo "name,type,mountpoint" | awk '$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not ( -path *%s -prune ) ",$3}') - getmount "/mnt /media /mount /home -maxdepth 5 -type d $alreadymounted" - partitiontype="$(lsblk -no "fstype" "$chosen")" - case "$partitiontype" in - "vfat") doas mount -t vfat "$chosen" "$mp" -o rw,umask=0000;; - "exfat") doas mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)";; - *) doas mount "$chosen" "$mp"; user="$(whoami)"; ug="$(groups | awk '{print $1}')"; doas chown "$user":"$ug" "$mp";; - esac - notify-send "💻 USB mounting" "$chosen mounted to $mp." - } - -usbdrives="$(lsblk -rpo "name,type,size,label,mountpoint,fstype" | grep -v crypto_LUKS | grep 'part\|rom' | sed 's/ /:/g' | awk -F':' '$5==""{printf "%s (%s) %s\n",$1,$3,$4}')" - -if [ -z "$usbdrives" ]; then - echo "No USB drive detected" && exit -else - echo "USB drive(s) detected." - mountusb -fi diff --git a/.local/bin/dmenuunmount b/.local/bin/dmenuunmount deleted file mode 100755 index 9018419..0000000 --- a/.local/bin/dmenuunmount +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - -# A dmenu prompt to unmount drives. -# Provides you with mounted partitions, select one to unmount. -# Drives mounted at /, /boot and /home will not be options to unmount. - -unmountusb() { - [ -z "$drives" ] && exit - chosen="$(echo "$drives" | dmenu -i -p "Unmount which drive?")" || exit 1 - chosen="$(echo "$chosen" | awk '{print $1}')" - [ -z "$chosen" ] && exit - doas umount "$chosen" && notify-send "💻 USB unmounting" "$chosen unmounted." - } - -drives=$(lsblk -nrpo "name,type,size,mountpoint,label" | awk -F':' '{gsub(/ /,":")}$4!~/\/boot|\/efi|\/home$|SWAP/&&length($4)>1{printf "%s (%s) %s\n",$4,$3,$5}') - -if ! grep simple-mtpfs /etc/mtab; then - [ -z "$drives" ] && echo "No drives to unmount." && exit - echo "Unmountable USB drive detected." - unmountusb -else - if [ -n "$drives" ] - then - echo "Unmountable USB drive(s) detected." - unmountusb - fi -fi diff --git a/.local/bin/mounter b/.local/bin/mounter new file mode 100755 index 0000000..9e3c6a5 --- /dev/null +++ b/.local/bin/mounter @@ -0,0 +1,94 @@ +#!/bin/bash + +# Mounts Android Phones and USB drives (encrypted or not). This script will +# replace the older `dmenumount` which had extra steps and couldn't handle +# encrypted drives. +# TODO: Try decrypt for drives in crtypttab +# TODO: Add some support for connecting iPhones (although they are annoying). + +IFS=' +' +# Function for escaping cell-phone names. +escape() { echo "$@" | iconv -cf UTF-8 -t ASCII//TRANSLIT | tr -d '[:punct:]' | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | sed "s/-\+/-/g;s/\(^-\|-\$\)//g"; } + +# Check for drives. +lsblkoutput="$(lsblk -rpo "uuid,name,type,size,label,mountpoint,fstype")" +# Get all LUKS drives +allluks="$(echo "$lsblkoutput" | grep crypto_LUKS)" +# Get a list of the LUKS drive UUIDs already decrypted. +decrypted="$(find /dev/disk/by-id/dm-uuid-CRYPT-LUKS2-* | sed "s|.*LUKS2-||;s|-.*||")" +# Functioning for formatting drives correctly for dmenu: +filter() { sed "s/ /:/g" | awk -F':' '$7==""{printf "%s%s (%s) %s\n",$1,$3,$5,$6}'; } + +# Get only LUKS drives that are not decrypted. +unopenedluks="$(for drive in "${allluks[@]}"; do + uuid="${drive%% *}" + uuid="${uuid//-/}" # This is a bashism. + if [ "$decrypted" != "" ]; then + for open in "${decrypted[@]}"; do + [ "$uuid" = "$open" ] && break 1 + done && continue 1 + fi + echo "🔒 $drive" +done | filter)" + +# Get all normal, non-encrypted or decrypted partitions that are not mounted. +normalparts="$(echo "$lsblkoutput" | grep -v crypto_LUKS | grep 'part\|rom\|crypt' | sed "s/^/💾 /" | filter)" + +# Add all to one variable. If no mountable drives found, exit. +alldrives="$(echo "$unopenedluks +$normalparts" | sed "/^$/d;s/ *$//")" + +# Quit the script if a sequential command fails. +set -e + +test "$alldrives" != "" + +# Feed all found drives to dmenu and get user choice. +chosen="$(echo "$alldrives" | dmenu -p "Mount which drive?" -i)" + +# Function for prompting user for a mountpoint. +getmount() { + mp="$(find /mnt /media /mount /home -maxdepth 1 -type d 2>/dev/null | dmenu -i -p "Mount this drive where?")" + test "$mp" != "" + if [ ! -d "$mp" ]; then + mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") + [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || doas mkdir -p "$mp") + fi +} + +attemptmount() { + # Attempt to mount without a mountpoint, to see if drive is in fstab. + doas mount "$chosen" || return 1 + notify-send "💾Drive Mounted." "$chosen mounted." + exit +} + +case "$chosen" in +💾*) + chosen="${chosen%% *}" + chosen="${chosen:1}" # This is a bashism. + attemptmount || getmount + doas mount "$chosen" "$mp" # -o uid="$(id -u)",gid="$(id -g)" + notify-send "💾Drive Mounted." "$chosen mounted to $mp." + ;; + +🔒*) + chosen="${chosen%% *}" + chosen="${chosen:1}" # This is a bashism. + # Number the drive. + while true; do + [ -f "/dev/mapper/usb$num" ] || break + num="$(printf "%02d" "$((num + 1))")" + done + + # Decrypt in a terminal window + "${TERMINAL:-st}" -n floatterm -g 60x1 -e doas cryptsetup open "$chosen" "usb$num" + # Check if now decrypted. + test -b "/dev/mapper/usb$num" + + attemptmount || getmount + doas mount "/dev/mapper/usb$num" "$mp" # -o uid="$(id -u)",gid="$(id -g)" + notify-send "🔓Decrypted drive Mounted." "$chosen decrypted and mounted to $mp." + ;; +esac diff --git a/.local/bin/umounter b/.local/bin/umounter new file mode 100755 index 0000000..126f1b8 --- /dev/null +++ b/.local/bin/umounter @@ -0,0 +1,28 @@ +#!/bin/sh + +# Unmount USB drives or Android phones. Replaces the older `dmenuumount`. Fewer +# prompt and also de-decrypts LUKS drives that are unmounted. + +set -e + +mounteddroids="$(grep simple-mtpfs /etc/mtab | awk '{print "📱" $2}')" +lsblkoutput="$(lsblk -nrpo "name,type,size,mountpoint")" +mounteddrives="$(echo "$lsblkoutput" | awk '($2=="part"||$2="crypt")&&$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "💾%s (%s)\n",$4,$3}')" + +allunmountable="$(echo "$mounteddroids +$mounteddrives" | sed "/^$/d;s/ *$//")" +test -n "$allunmountable" + +chosen="$(echo "$allunmountable" | dmenu -i -p "Unmount which drive?")" +chosen="${chosen%% *}" +test -n "$chosen" + +doas umount -l "/${chosen#*/}" +notify-send "Device unmounted." "$chosen has been unmounted." + +# Close the chosen drive if decrypted. +cryptid="$(echo "$lsblkoutput" | grep "/${chosen#*/}$")" +cryptid="${cryptid%% *}" +test -b /dev/mapper/"${cryptid##*/}" +doas cryptsetup close "$cryptid" +notify-send "🔒Device dencryption closed." "Drive is now securely locked again." |