123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #! /bin/sh -
- #
- # A script to configure the keyboard map on console
- #
- # Copyright (c) 2019 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=/tmp/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
- # Compose output file to be shown
- # Use a portable find(1) in terms of options, plus sort(1),
- # redirects the standard error to see any possible error
- search="$(find "$KEYMAPS" -name '*.map*' -print | sort 2> /dev/tty)"
- if test -z "$search"
- then
- echo "No keyboard maps were found in \`${KEYMAPS}'." 1>&2
- exit 1;
- fi
- # 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:" 24 56 12 \' \
- > $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
- # The 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
- dialog --clear
- echo ""
- echo "Setting 'RC_KEYMAP=${layout}/$map' on /etc/rc.conf ..."
- echo ",s/^\(RC_KEYMAP\)=.*/\1=${layout}\/${map}/"$'\nw' | \
- ed -s /etc/rc.conf && echo Done.
|