mdisk: Remove color from "Already mounted" message
[sunny256-utils.git] / mdisk
blob6f39b2e2b2cc32b0ae07c95249685ab0f22274ee
1 #!/bin/sh
3 #==============================================================================
4 # mdisk
5 # File ID: 0548a2d2-ea04-11ed-b5e0-83850402c3ce
7 # Mount a LUKS-encrypted disk under /media/
9 # Author: Øyvind A. Holm <sunny@sunbase.org>
10 # License: GNU General Public License version 2 or later.
11 #==============================================================================
13 progname=mdisk
14 VERSION=0.2.3
16 opt_help=0
17 opt_quiet=0
18 opt_umount=0
19 opt_verbose=0
20 while test -n "$1"; do
21 case "$1" in
22 -a|--all) opt_all=1; shift ;;
23 -h|--help) opt_help=1; shift ;;
24 -q|--quiet) opt_quiet=$(($opt_quiet + 1)); shift ;;
25 -u|--umount) opt_umount=1; shift ;;
26 -v|--verbose) opt_verbose=$(($opt_verbose + 1)); shift ;;
27 --version) echo $progname $VERSION; exit 0 ;;
28 --) shift; break ;;
30 if printf '%s\n' "$1" | grep -q ^-; then
31 echo "$progname: $1: Unknown option" >&2
32 exit 1
33 else
34 break
36 break ;;
37 esac
38 done
39 opt_verbose=$(($opt_verbose - $opt_quiet))
41 [ -e "$HOME/.mdiskrc" ] && . "$HOME/.mdiskrc"
43 T_BOLD=$(tput bold)
44 T_GREEN=$(tput setaf 2)
45 T_RED=$(tput setaf 1)
46 T_RESET=$(tput sgr0)
48 if test "$opt_help" = "1"; then
49 test $opt_verbose -gt 0 && { echo; echo $progname $VERSION; }
50 cat <<END
52 Mount a LUKS-encrypted disk under /media/.
54 Usage: $progname [options] DISKNAME
56 Options:
58 -a, --all
59 Loop through all directory names under /media/ and mount or unmount
60 all corresponding disks.
61 -h, --help
62 Show this help.
63 -q, --quiet
64 Be more quiet. Can be repeated to increase silence.
65 -v, --verbose
66 Increase level of verbosity. Can be repeated.
67 -u, --umount
68 Unmount the disk.
69 --version
70 Print version information.
72 Environment variables
74 MDISK_KEY_FILE
75 Full path to text file with passphrase for encrypted drives.
77 Files and directories
79 \$HOME/.mdiskrc
80 Init file. A regular shell script that can be used to initialize
81 environment variables and run commands before normal program
82 execution.
83 .dontsleep/
84 If this directory exists at the top of the disk, the disk is
85 prevented from sleeping. When a disk with this directory is mounted,
86 a background process is started that writes 512 random bytes to a
87 file in this directory every two minutes. The current user must have
88 write permission in this directory, otherwise sleeping is not
89 prevented. When the disk is unmounted with -u/--umount, the process
90 is killed.
92 END
93 exit 0
96 msg() {
97 test $1 -gt $opt_verbose && return;
98 shift
99 echo "$progname: $*" >&2
102 err() {
103 echo "$progname: $T_BOLD$T_RED$*$T_RESET" >&2
104 exit 1
107 is_active() {
108 sudo cryptsetup status $disk | grep -q "/dev/mapper/$disk is active"
111 is_in_blkid() {
112 sudo blkid | grep -q "LABEL=\"$1\"" && return 0
113 return 1
116 is_mounted() {
117 df | grep -q "/media/$disk\$" && return 0
118 return 1
121 strip_diskname() {
122 echo $(echo "$1" | sed 's.^/media/..; s./$..')
125 create_ds_script() {
126 echo >$ds_script || err $ds_dir/: Cannot write to directory, \
127 disk sleep is not prevented
128 cat <<'END' >$ds_script
129 #!/bin/sh
131 outfile=.dontsleep.bin
133 rm -f $outfile
134 echo $$ >pid || {
135 echo -n "$T_BOLD$T_RED$0: Cannot write pid file to $ds_dir," >&2
136 echo " unable to prevent sleep$T_RESET" >&2
137 exit 1
139 while :; do
140 head -c 512 /dev/urandom >>$outfile
141 (cd; sleep 120)
142 done
146 prevent_sleep() {
147 local disk=$1
149 msg 0 Preventing $disk from sleeping
150 cd "$ds_dir" || err $ds_dir: chdir error
151 create_ds_script
152 sh $ds_script $disk &
155 kill_prevent() {
156 local disk=$1
158 pidfile="$ds_dir/pid"
159 if [ ! -f "$pidfile" ]; then
160 echo $progname: PID file $pidfile not found >&2
161 return
163 kill $(cat $pidfile)
164 rm $pidfile
167 if [ "$opt_all" = "1" ]; then
168 for f in /media/*; do
169 is_in_blkid $(strip_diskname $f) || continue
170 if [ "$opt_umount" = "1" ]; then
171 $0 -u $f
172 else
173 $0 $f
175 done
176 exit
179 disk=$(strip_diskname $1)
180 [ -z "$disk" ] && err No disk specified
182 is_in_blkid $disk || err $disk: Disk not found in blkid
184 ds_dir="/media/$disk/.dontsleep"
185 ds_script=dontsleep
187 if [ "$opt_umount" != "1" ]; then
188 is_mounted $disk && {
189 msg 0 $disk: Already mounted
190 exit 0
192 device=$(blkid -L $disk)
193 msg 1 device = \"$device\"
194 [ -z "$device" ] && err Cannot get device for $disk
195 echo "$device" | grep -q ^/dev/ || err $device: Malformed device name
196 is_active $disk \
197 || sudo cryptsetup luksOpen \
198 $([ -n "$MDISK_KEY_FILE" ] && echo "--key-file $MDISK_KEY_FILE") \
199 $device $disk && mount /media/$disk
200 is_mounted $disk \
201 && msg 0 $T_BOLD$T_GREEN$disk mounted on /media/$disk$T_RESET \
202 || err $disk: mount failed
203 [ -d "$ds_dir" ] && prevent_sleep $disk
204 else
205 [ -d "$ds_dir" ] && kill_prevent $disk
206 is_mounted $disk && umount /media/$disk
207 [ -d "$ds_dir" ] && prevent_sleep $disk
208 is_mounted $disk && err /media/$disk: umount failed
209 sudo cryptsetup luksClose $disk
210 sync
211 is_active $disk && err $disk is still active
212 msg 0 $T_BOLD$T_GREEN$disk is unmounted and closed$T_RESET
215 # vim: set ts=8 sw=8 sts=8 noet fo+=w tw=79 fenc=UTF-8 :