123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #! /bin/sh -
- #
- # A script to configure the keyboard map on console
- #
- # Copyright (c) 2019-2020 Matias Fonzo, <selk@dragora.org>.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- # Exit immediately on any error
- set -e
- PROGRAM="${0##*/}"
- TMPDIR="${TMPDIR:-$HOME}"
- TMPFILE="${TMPDIR}/.${PROGRAM}.${RANDOM-0}$$"
- OUTPUT="${TMPFILE}.data"
- LOCKFILE=/var/lock/dragora-keymap.lockfile
- KEYMAPS="${KEYMAPS:-/usr/share/keymaps/i386}"
- chkstatus_or_exit()
- {
- status=$?
- # Clean up temporary files
- rm -f -- "$TMPFILE" "$LOCKFILE"
- if test $status -ne 0
- then
- printf '%s\n' "" "Return status = $status" 1>&2
- exit 2;
- fi
- unset status
- }
- # Sanity checks
- if test ! -d "$TMPDIR"
- then
- echo "${PROGRAM}: \`${TMPDIR}' is not a qualified temporary directory" 1>&2
- exit 1;
- fi
- if test ! -w "$TMPDIR"
- then
- echo "${PROGRAM}: \`${TMPDIR}' is not a writable temporary directory" 1>&2
- exit 1;
- fi
- if test ! -d "$KEYMAPS"
- then
- echo "${PROGRAM}: Directory \`${KEYMAPS}' for keyboard maps does not exist as such" 1>&2
- exit 1;
- fi
- trap 'chkstatus_or_exit' EXIT HUP INT QUIT ABRT TERM
- umask 077; # Remove access for all but user.
- # Unfortunately, loadkeys(1) is limited to the superuser;
- # we set a lock to allow only one instance of the script.
- if ( set -C ; echo ": $PROGRAM - locked" > $LOCKFILE ) 2> /dev/null
- then
- true
- else
- if test -e "$LOCKFILE"
- then
- echo "Only one instance of \`${PROGRAM}' is allowed." 1>&2
- exit 1;
- else
- echo "${PROGRAM}: \`${LOCKFILE}' lock failed." 1>&2
- exit 2;
- fi
- fi
- ### Search for keyboard map files
- search="$(find "$KEYMAPS" \( -type l -o -type f \) -name '*.map*' -print | LANG=C sort 2> /dev/tty)"
- if test -z "$search"
- then
- echo "No keyboard maps were found in \`${KEYMAPS}'." 1>&2
- exit 1;
- fi
- ### Compose output file to be shown
- # Header
- printf '%s\n' \
- 'dialog --colors \' \
- ' --backtitle "\\Zb${PROGRAM} - Keyboard map selection" \' \
- ' --title "MAIN MENU" --default-item "qwerty/us" --menu \' \
- '"Welcome to \\Z3${PROGRAM}\\Zn!\\n\\n\' \
- 'The following menu list is organized as keyboard \\n\' \
- '\"layout/language\". \\n\\n\' \
- 'Select a keyboard map for the console:" 20 56 6 \' \
- > "$OUTPUT"
- # Append 'search' to the body
- for item in $search
- do
- level="${item%/*}" # Remove all except the last slash.
- level="${level##*/}" # Starting-point under which it was found.
- item="${item%.map*}" # Remove extension(s).
- item="${item##*/}" # Get the base name.
- # Ignore unwanted map directories
- case $level in
- include | fgGIod)
- continue
- ;;
- *)
- echo "\"${level}/$item\" \"\" \\" >> "$OUTPUT"
- ;;
- esac
- done
- unset item level search
- # End of
- printf "2> \$TMPFILE\\n\\n" >> "$OUTPUT"
- # Import menu
- . "$OUTPUT"
- # Read answer from 'TMPFILE'
- echo "" >> "$TMPFILE"; # Append new line for reading.
- IFS= read -r REPLY < "$TMPFILE" || exit 2;
- # Compose values by layout/map to be set
- layout="${REPLY%/*}"
- map="${REPLY##*/}"
- unset REPLY
- # Temporary files are not needed anymore
- rm -f -- "$TMPFILE" "$OUTPUT"
- umask 022; # Remove write permission for group and other.
- # Set keyboard map
- loadkeys "${layout}/$map"
- while true
- do
- testkeys="$(
- dialog --colors \
- --no-mouse --no-cancel --no-ok \
- --backtitle "\\Zb${PROGRAM} - Keyboard map check" \
- --title "SELECTED KEYMAP: ${layout}/$map" \
- --inputbox \
- "Try the chosen keyboard map by typing something. Once satisfied\\n\
- type \\Zb\\Z71\\Zn (or \\Zb\\Z7y\\Zn) then hit \\Zb\\Z7ENTER\\Zn \
- to continue. To choose a different keyboard map, type \\Zb\\Z72\\Zn (or \
- \\Zb\\Z7n\\Zn) plus \\Zb\\Z7ENTER\\Zn." 10 68 2>&1 > /dev/tty
- )"
- case $testkeys in
- 1 | Y | y)
- break
- ;;
- 2 | N | n)
- rm -f -- "$LOCKFILE"
- exec "$0"
- ;;
- esac
- done
- unset testkeys
- dialog --colors \
- --backtitle "\\Zb${PROGRAM} - Configuration file" \
- --title "/etc/rc.conf" --yesno \
- "Would do you like to save this change for the next reboot?" 5 62
- echo ""
- echo "Setting 'RC_KEYMAP=${layout}/$map' on /etc/rc.conf ..."
- echo ",s/^\\(RC_KEYMAP\\)=.*/\\1=${layout}\\/${map}/"$'\nw' | \
- ed /etc/rc.conf && echo Done.
|