aboutsummaryrefslogtreecommitdiff
path: root/dotfiles/.local/bin/menublk
blob: 3b16f408556a5e88663fe4431c370456088e6989 (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
#!/bin/bash

# Script for mounting/unmounting drives (including encrypted ones)
# For encrypted drives, it works only if there's just one partition inside the
# crypt_LUKS volume
# It now also allows to power off devices so that you can safely disconnect
# them. It lists only USB devices.

# Yaroslav de la Peña Smirnov

. ~/.config/bemenurc

readarray -t blkdevs <<< "$(lsblk -r -o NAME,TYPE,FSTYPE,MOUNTPOINT | tail -n +2)"

notify_and_end() {
	notify-send "💽Drive management" "$1"
	exit $2
}

get_mountable() {
  for blkdev in "${blkdevs[@]}"; do
    name="$(cut -d " " -f1 <<< "${blkdev}")"
    btype="$(cut -d " " -f2 <<< "${blkdev}")"
    fstype="$(cut -d " " -f3 <<< "${blkdev}")"
    mountpoint="$(cut -d " " -f4 <<< "${blkdev}")"
    if [ "$btype" = "part" ]; then
      if [ -z "$mountpoint" ]; then
        if [ "$fstype" = "crypto_LUKS" ]; then
          if [ "$(lsblk -r -o FSTYPE "/dev/$name" | tail -n 1)" = "crypto_LUKS" ]; then
            echo "$name"
          fi
        else
          echo "$name"
        fi
      fi
    fi
  done
}

get_unmountable() {
  for blkdev in "${blkdevs[@]}"; do
    name="$(cut -d " " -f1 <<< "${blkdev}")"
    btype="$(cut -d " " -f2 <<< "${blkdev}")"
    fstype="$(cut -d " " -f3 <<< "${blkdev}")"
    mountpoint="$(cut -d " " -f4 <<< "${blkdev}")"
    if [ "$btype" = "part" ]; then
      if [ -z "$mountpoint" ] && [ "$fstype" = "crypto_LUKS" ]; then
        mountpoint="$(lsblk -r -o MOUNTPOINT "/dev/$name" | tail -n 1)"
      fi
      if [ -n "$mountpoint" ] && [ "$mountpoint" != "/" ] && [ "$mountpoint" != "/boot" ] && [ "$mountpoint" != "[SWAP]" ]
      then
        echo "$name"
      fi
    fi
  done
}

mount_dev() {
	fstype="$(lsblk -r -o FSTYPE "/dev/$1" | tail -n 1)"
	part="/dev/$1"
	if [ "$fstype" = "crypto_LUKS" ]; then
		password="$(echo "" | bemenu -p "Enter passphrase for encrypted drive:" --tf="$BEMENU_TF" --tb="$BEMENU_NB" --ff="$BEMENU_NB" --fb="$BEMENU_NB" --fn="$BEMENU_FN" --nb="$BEMENU_NB" --nf="$BEMENU_NF" --hf="$BEMENU_HF" --hb="$BEMENU_HB" --monitor="$BEMENU_MONITOR")"
		if [ -z "$password" ]; then
  	  	  exit 0
		fi
		printf "%s" "$password" > "$HOME/.cache/diskey"
		part="$(udisksctl unlock --key-file="$HOME/.cache/diskey" -b "/dev/$1" 2> $HOME/.cache/udiskerr | cut -d " " -f4 )"
		part="${part%?}"
		rm -f "$HOME/.cache/diskey"
		if [ $? -ne 0 ]; then
			notify_and_end "Error mounting: $(cat $HOME/.cache/udiskerr)" 1
		fi
	fi
	message="$(udisksctl mount -b "$part" 2> $HOME/.cache/udiskerr)"
	if [ $? -eq 0 ]; then
		notify_and_end "$message" 0
	else
		notify_and_end "Error mounting: $(cat $HOME/.cache/udiskerr)" 1
	fi
}

unmount_dev() {
  fstype="$(lsblk -r -o FSTYPE "/dev/$1" | sed "2q;d")"
  if [ "$fstype" = "crypto_LUKS" ]; then
    volume="/dev/mapper/$(lsblk -r -o NAME "/dev/$1" | tail -n 1)"
    if udisksctl unmount -b "$volume" 2> $HOME/.cache/udiskerr && udisksctl lock -b "/dev/$1" 2> $HOME/.cache/udiskerr; then
        notify_and_end "Device $1 has been unmounted and locked" 0
    else
		notify_and_end "Error unmounting: $(cat $HOME/.cache/udiskerr)" 1
    fi
  else
    if udisksctl unmount -b "/dev/$1" 2> $HOME/.cache/udiskerr; then
        notify_and_end "Device $0 has been unmounted" 0
    else
		notify_and_end "Error unmounting: $(cat $HOME/.cache/udiskerr)" 1
    fi
  fi
}

get_usb_storage() {
	for dev in /sys/block/*; do
		if udevadm info --query=property --path=$dev | grep -q ^ID_BUS=usb; then
			echo "$(cut -d "/" -f4 <<< ${dev})"
		fi
	done
}

poweroff_dev() {
	if udisksctl power-off -b "/dev/$1"; then
		notify_and_end "Device $1 has been powered off" 0
	else
		notify_and_end "An error occurred, could not power off device $1. Make sure that it's not in use." 1
	fi
}

action="$(printf "mount\nunmount\npoweroff\n" | bemenu -p "What to do?" --tf="$BEMENU_TF" --tb="$BEMENU_NB" --fb="$BEMENU_NB" --fn="$BEMENU_FN" --nb="$BEMENU_NB" --nf="$BEMENU_NF" --hf="$BEMENU_HF" --hb="$BEMENU_HB" --monitor="$BEMENU_MONITOR")"

case "$action" in
  mount)
    blkdev="$(get_mountable | bemenu -p "Choose device to mount:" --tf="$BEMENU_TF" --tb="$BEMENU_NB" --fb="$BEMENU_NB" --fn="$BEMENU_FN" --nb="$BEMENU_NB" --nf="$BEMENU_NF" --hf="$BEMENU_HF" --hb="$BEMENU_HB" --monitor="$BEMENU_MONITOR")"
    if [ -z "$blkdev" ]; then
      exit 0
    fi
    mount_dev "$blkdev";;
  unmount)
    blkdev="$(get_unmountable | bemenu -p "Choose device to umount:" --tf="$BEMENU_TF" --tb="$BEMENU_NB" --fb="$BEMENU_NB" --fn="$BEMENU_FN" --nb="$BEMENU_NB" --nf="$BEMENU_NF" --hf="$BEMENU_HF" --hb="$BEMENU_HB" --monitor="$BEMENU_MONITOR")"
    if [ -z "$blkdev" ]; then
      exit 0
    fi
    unmount_dev "$blkdev";;
  poweroff)
    blkdev="$(get_usb_storage | bemenu -p "Choose device to power off:" --tf="$BEMENU_TF" --tb="$BEMENU_NB" --fb="$BEMENU_NB" --fn="$BEMENU_FN" --nb="$BEMENU_NB" --nf="$BEMENU_NF" --hf="$BEMENU_HF" --hb="$BEMENU_HB" --monitor="$BEMENU_MONITOR")"
    if [ -z "$blkdev" ]; then
      exit 0
    fi
    poweroff_dev "$blkdev";;
  *)
    exit 0;;
esac