dragora-tools: Set LC_ALL=C for sort in dragora-keymap
[dragora.git] / archive / dragora-tools / dragora-keymap
blob65ad6988af2cda0575a976899d571c0396de87da
1 #! /bin/sh -
3 # A script to configure the keyboard map on console
5 # Copyright (c) 2019-2021 Matias Fonzo, <selk@dragora.org>.
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
11 # http://www.apache.org/licenses/LICENSE-2.0
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
19 # Exit immediately on any error
20 set -e
22 PROGRAM="${0##*/}"
23 TMPDIR="${TMPDIR:-$HOME}"
24 TMPFILE="${TMPDIR}/.${PROGRAM}.${RANDOM-0}$$"
25 OUTPUT="${TMPFILE}.data"
26 LOCKFILE=/var/lock/dragora-keymap.lockfile
27 KEYMAPS="${KEYMAPS:-/usr/share/keymaps/i386}"
29 chkstatus_or_exit()
31 status=$?
33 # Clean up temporary files
34 rm -f -- "$TMPFILE" "$LOCKFILE"
36 if test $status -ne 0
37 then
38 printf '%s\n' "" "Return status = $status" 1>&2
39 exit 2;
42 unset -v status
45 # Sanity checks
47 if test ! -d "$TMPDIR"
48 then
49 echo "${PROGRAM}: \`${TMPDIR}' is not a qualified temporary directory" 1>&2
50 exit 1;
52 if test ! -w "$TMPDIR"
53 then
54 echo "${PROGRAM}: \`${TMPDIR}' is not a writable temporary directory" 1>&2
55 exit 1;
57 if test ! -d "$KEYMAPS"
58 then
59 echo "${PROGRAM}: Directory \`${KEYMAPS}' for keyboard maps does not exist as such" 1>&2
60 exit 1;
63 trap 'chkstatus_or_exit' EXIT HUP INT QUIT ABRT TERM
65 umask 077; # Remove access for all but user.
67 # Unfortunately, loadkeys(1) is limited to the superuser;
68 # we set a lock to allow only one instance of the script.
70 if ( set -C ; echo ": $PROGRAM - locked" > $LOCKFILE ) 2> /dev/null
71 then
72 true
73 else
74 if test -e "$LOCKFILE"
75 then
76 echo "Only one instance of \`${PROGRAM}' is allowed." 1>&2
77 exit 1;
78 else
79 echo "${PROGRAM}: \`${LOCKFILE}' lock failed." 1>&2
80 exit 2;
84 ### Search for keyboard map files
86 search="$(find "$KEYMAPS" \( -type l -o -type f \) -name '*.map*' -print | LC_ALL=C sort 2> /dev/tty)"
88 if test -z "$search"
89 then
90 echo "No keyboard maps were found in \`${KEYMAPS}'." 1>&2
91 exit 1;
94 ### Compose output file to be shown
96 # Header
97 printf '%s\n' \
98 'dialog --colors \' \
99 ' --backtitle "\\Zb${PROGRAM} - Keyboard map selection" \' \
100 ' --title "MAIN MENU" --default-item "qwerty/us" --menu \' \
101 '"Welcome to \\Z3${PROGRAM}\\Zn!\\n\\n\' \
102 'The following menu list is organized as keyboard \\n\' \
103 '\"layout/language\". \\n\\n\' \
104 'Select a keyboard map for the console:" 20 56 6 \' \
105 > "$OUTPUT"
107 # Append 'search' to the body
109 for item in $search
111 level="${item%/*}" # Remove all except the last slash.
112 level="${level##*/}" # Starting-point under which it was found.
113 item="${item%.map*}" # Remove extension(s).
114 item="${item##*/}" # Get the base name.
116 # Ignore unwanted map directories
117 case $level in
118 include | fgGIod)
119 continue
122 echo "\"${level}/$item\" \"\" \\" >> "$OUTPUT"
124 esac
125 done
126 unset -v item level search
128 # End of
129 printf "2> \$TMPFILE\\n\\n" >> "$OUTPUT"
131 # Import menu
132 . "$OUTPUT"
134 # Read answer from 'TMPFILE'
136 echo "" >> "$TMPFILE"; # Append new line for reading.
137 IFS= read -r REPLY < "$TMPFILE" || exit 2;
139 # Compose values by layout/map to be set
141 layout="${REPLY%/*}"
142 map="${REPLY##*/}"
144 unset -v REPLY
146 # Temporary files are not needed anymore
147 rm -f -- "$TMPFILE" "$OUTPUT"
149 umask 022; # Remove write permission for group and other.
151 # Set keyboard map
152 loadkeys "${layout}/$map"
154 while true
156 testkeys="$(
157 dialog --colors \
158 --no-mouse --no-cancel --no-ok \
159 --backtitle "\\Zb${PROGRAM} - Keyboard map check" \
160 --title "SELECTED KEYMAP: ${layout}/$map" \
161 --inputbox \
162 "Try the chosen keyboard map by typing something. Once satisfied\\n\
163 type \\Zb\\Z71\\Zn (or \\Zb\\Z7y\\Zn) then hit \\Zb\\Z7ENTER\\Zn \
164 to continue. To choose a different keyboard map, type \\Zb\\Z72\\Zn (or \
165 \\Zb\\Z7n\\Zn) plus \\Zb\\Z7ENTER\\Zn." 10 68 2>&1 > /dev/tty
167 case $testkeys in
168 1 | Y | y)
169 break
171 2 | N | n)
172 rm -f -- "$LOCKFILE"
173 exec "$0"
175 esac
176 done
177 unset -v testkeys
179 dialog --colors \
180 --backtitle "\\Zb${PROGRAM} - Configuration file" \
181 --title "/etc/rc.conf" --yesno \
182 "Would do you like to save this change for the next reboot?" 5 62
183 echo ""
184 echo "Setting 'RC_KEYMAP=${layout}/$map' on /etc/rc.conf ..."
185 echo ",s/^\\(RC_KEYMAP\\)=.*/\\1=${layout}\\/${map}/"$'\nw' | \
186 ed /etc/rc.conf && echo Done.