#!/bin/sh do_font=yes # configure font do_kbd=yes # configure keyboard do_check=yes # test whether we are on the console do_verbose='' # explain what is being doing do_save='' # save the required files in /etc/console-setup savekbdfile='' # save the keyboard map in $savekbdfile setupdir='' # directory for --setup-dir SETUP='' which () { local IFS IFS=: for i in $PATH; do if [ -f "$i/$1" -a -x "$i/$1" ]; then echo "$i/$1" return 0 fi done return 1 } tempfiles='' trap 'rm -f $tempfiles >/dev/null 2>&1' 0 trap "exit 2" 1 2 3 13 15 tempfile () { if \ TMPFILE=`mktemp /tmp/tmpkbd.XXXXXX 2>/dev/null` \ || TMPFILE=`mktemp /run/tmpkbd.XXXXXX 2>/dev/null` \ || TMPFILE=`mktemp /dev/.tmpkbd.XXXXXX 2>/dev/null` \ || TMPFILE=`mktemp /lib/init/rw/tmpkbd.XXXXXX 2>/dev/null` \ || TMPFILE=`mktemp 2>/dev/null` then tempfiles="$tempfiles $TMPFILE" return 0 else TMPFILE='' return 1 fi } report () { local nl case "$1" in -n) shift nl='' ;; *) nl=' ' ;; esac if [ "$do_verbose" ]; then echo -n "$@" "$nl" >&2 fi } run () { local ttyarg cmd verbose tty x ttyarg="$1" verbose="$2" cmd="$3" shift; shift; shift if [ -z "$ACTIVE_CONSOLES" ]; then ttyarg=plain fi case "$ttyarg" in plain) if [ "$setupdir" ]; then SETUP="$SETUP$cmd $@ " elif [ "$do_verbose" ]; then case "$verbose" in NONE) report executing $cmd "$@". $cmd "$@" ;; FORK) report executing $cmd. $cmd "$@" & ;; *) report executing $cmd "$@". $cmd "$@" $verbose ;; esac else case "$verbose" in NONE) report executing $cmd "$@". $cmd "$@" >/dev/null 2>&1 ;; FORK) report executing $cmd. $cmd "$@" & ;; *) report executing $cmd "$@". $cmd "$@" ;; esac fi ;; in) for tty in $ACTIVE_CONSOLES; do if [ "$setupdir" ]; then SETUP="$SETUP$cmd $@ < $tty " elif [ -r $tty ]; then report -n on $tty '' run plain "$verbose" "$cmd" "$@" <$tty else report No read access from $tty. Can not execute $cmd. fi done ;; out) for tty in $ACTIVE_CONSOLES; do if [ "$setupdir" ]; then SETUP="$SETUP$cmd $@ > $tty " elif [ -w $tty ]; then report -n on $tty '' run plain "$verbose" "$cmd" "$@" >$tty else report No write access to $tty. Can not execute $cmd. fi done ;; *) for tty in $ACTIVE_CONSOLES; do x="${ttyarg}$tty" run plain "$verbose" "$cmd" $x "$@" done ;; esac } findfile () { local x case "$2" in /*) if [ -f "$2" ]; then echo "$2" return 0 fi ;; esac x=`(ls "$installdir"/$1/$2 \ /usr/local/$1/$2 \ /usr/$1/$2 \ /etc/console-setup/cached_$2 \ /etc/console-setup/$2 \ "$installdir"/etc/console-setup/cached_$2 \ "$installdir"/etc/console-setup/$2) 2>/dev/null` x=`echo $x` [ "${x%% *}" ] || report Unable to find "$2". echo "${x%% *}" } test_console () { local ok ok=0 if which tty >/dev/null; then case "`tty`" in /dev/tty[1-9]*|/dev/vc/[0-9]*|/dev/console|/dev/ttyv[0-9]*) return 0 ;; esac ok=1 fi if which kbd_mode >/dev/null; then mode="`(LC_ALL=C; export LC_ALL; kbd_mode) 2>&1`" mode=${mode#The keyboard is in } case "$mode" in Unicode*|default*|xlate*) return 0 ;; esac ok=1 fi if which vidcontrol >/dev/null; then if vidcontrol -i adapter >&- 2>&-; then return 0 fi ok=1 fi return $ok } while [ "$1" ]; do case "$1" in -k|--keyboard-only) do_font='' ;; -f|--font-only) do_kbd='' ;; -v|--verbose) do_verbose=yes ;; --force) do_check='' ;; --save) do_save=yes ;; --save-only) do_save=yes do_kbd='' do_font='' do_check='' ;; --save-keyboard) shift savekbdfile="$1" do_kbd='' do_font='' do_check='' ;; --setup-dir) shift setupdir="$1" do_check='' ;; -h|--help) cat >&2 <&2 exit 1 ;; *) if [ -z "$VARIANT" ]; then VARIANT="$1" else echo "setupcon: Two variants specified: $VARIANT and $1" >&2 exit 1 fi ;; esac shift done installdir=${0%/*} case "$installdir" in */bin) installdir=${installdir%/bin} ;; *) installdir=$installdir/.. ;; esac [ -n "$installdir" -a -d "$installdir"/bin ] || installdir=/usr case "$installdir" in /*) ;; *) installdir="`pwd`\$installdir" ;; esac if [ "$VARIANT" ]; then VARIANT=".$VARIANT" fi USER_CONFIG=${HOME}/.console-setup"$VARIANT" USER_CONFIG2=${HOME}/.keyboard"$VARIANT" MAIN_CONFIG=/etc/default/keyboard"$VARIANT" [ -f "$MAIN_CONFIG" ] \ || [ ! -f "$installdir"/etc/default/keyboard"$VARIANT" ] \ || MAIN_CONFIG="$installdir"/etc/default/keyboard"$VARIANT" MAIN_CONFIG2=/etc/default/console-setup"$VARIANT" [ -f "$MAIN_CONFIG2" ] \ || [ ! -f "$installdir"/etc/default/console-setup"$VARIANT" ] \ || MAIN_CONFIG2="$installdir"/etc/default/console-setup"$VARIANT" if [ -f "$USER_CONFIG" -o -f "$USER_CONFIG2" ]; then CONFIG="$USER_CONFIG" CONFIG2="$USER_CONFIG2" elif [ -f "$MAIN_CONFIG" -o -f "$MAIN_CONFIG2" ]; then CONFIG="$MAIN_CONFIG" CONFIG2="$MAIN_CONFIG2" else echo "setupcon: None of $MAIN_CONFIG, $MAIN_CONFIG2, $USER_CONFIG, $USER_CONFIG2 exists." >&2 exit 1 fi if [ -f "$CONFIG2" ]; then . "$CONFIG2" else CONFIG2="$CONFIG" fi if [ -f "$CONFIG" ]; then . "$CONFIG" fi if [ "$VERBOSE_OUTPUT" = yes ]; then do_verbose=yes fi kernel=unknown if which uname >/dev/null; then case "`uname`" in *Linux*) kernel=linux ;; *FreeBSD*) kernel=freebsd ;; *) echo 'Unknown kernel (only Linux and FreeBSD are supported).' >&2 exit 1 ;; esac fi if [ -n "$do_save" ]; then if [ ! -d /usr/share ]; then echo It seems /usr is not mounted. Will not save files in /etc. >&2 do_save='' fi fi ACTIVE_CONSOLES=$( for tty in $ACTIVE_CONSOLES; do if [ -e $tty ]; then echo $tty fi done ) if [ -z "$ACTIVE_CONSOLES" ]; then for tty in \ $(cat /etc/inittab /etc/init/* /etc/ttys 2>/dev/null \ | grep getty \ | egrep '([[:blank:]]|^)tty([1-9][0-9]*|v[0-9a-f])([[:blank:]]|$)' \ | sed -e '/^ *#/d' \ -e 's/.*[[:blank:]]\(tty[1-9][0-9]*\).*/\1/' \ -e 's/.*[[:blank:]]\(ttyv[0-9a-f]\).*/\1/') do if [ -e /dev/$tty ]; then ACTIVE_CONSOLES="$ACTIVE_CONSOLES /dev/$tty" fi done fi if [ -z "$ACTIVE_CONSOLES" ]; then case "$kernel" in linux) ACTIVE_CONSOLES=$(ls /dev/tty[1-6] 2>/dev/null) ;; freebsd) ACTIVE_CONSOLES=$(ls /dev/ttyv[0-3] 2>/dev/null) ;; esac report Can not find the active virtual consoles, \ assuming ACTIVE_CONSOLES=\"$ACTIVE_CONSOLES\" >&2 else report Configuring $ACTIVE_CONSOLES fi if [ "$CHARMAP" = guess -o -z "$CHARMAP" ]; then CHARMAP='' if which locale >/dev/null; then CHARMAP=`locale charmap` fi fi CHARMAP=${CHARMAP:-UTF-8} case "$CHARMAP" in ISO8859-*) CHARMAP="ISO-8859-${CHARMAP#ISO8859-}" ;; US-ASCII|ANSI*) CHARMAP=ISO-8859-1 ;; esac report The charmap is $CHARMAP if \ [ "$CHARMAP" = UTF-8 ] then unicode=yes else unicode='' fi if [ "$do_font" ]; then case "$kernel" in linux) if which consolechars >/dev/null ; then do_font=linuxct elif which setfont >/dev/null ; then do_font=linuxkbd else echo "Neither setfont nor consolechars is accessible. No font will be configured." >&2 do_font='' fi ;; freebsd) if which vidcontrol >/dev/null ; then do_font=freebsd else echo "vidcontrol is not accessible. No font will be configured." >&2 do_font='' fi ;; esac fi if which pidof >/dev/null; then if pidof splashy > /dev/null || pidof usplash > /dev/null; then do_font='' fi fi [ "$CODESET" != guess ] || CODESET='' if [ -z "$CODESET" ]; then case "$CHARMAP" in UTF-8) CODESET=Uni2;; ARMSCII-8) CODESET=Armenian ;; CP1251) CODESET=CyrSlav ;; CP1255) CODESET=Hebrew ;; CP1256) CODESET=Arabic ;; GEORGIAN-ACADEMY) CODESET=Georgian ;; GEORGIAN-PS) CODESET=Georgian ;; IBM1133) CODESET=Lao ;; ISIRI-3342) CODESET=Arabic ;; ISO-8859-1) CODESET=Lat15 ;; ISO-8859-2) CODESET=Lat2 ;; ISO-8859-3) CODESET=Lat38 ;; ISO-8859-4) CODESET=Lat7 ;; # sometimes Lat15 ISO-8859-5) CODESET=CyrSlav ;; ISO-8859-6) CODESET=Arabic ;; ISO-8859-7) CODESET=Greek ;; ISO-8859-8) CODESET=Hebrew ;; ISO-8859-9) CODESET=Lat15 ;; ISO-8859-10) CODESET=Lat15 ;; ISO-8859-11) CODESET=Thai ;; ISO-8859-13) CODESET=Lat7 ;; ISO-8859-14) CODESET=Lat38 ;; ISO-8859-15) CODESET=Lat15 ;; ISO-8859-16) CODESET=Lat2 ;; KOI8-R) CODESET=CyrKoi ;; KOI8-U) CODESET=CyrKoi ;; TIS-620) CODESET=Thai ;; VISCII) CODESET=Vietnamese ;; *) if [ "$do_font" ]; then echo Unsupported charmap $CHARMAP >&2 exit 1 fi ;; esac if [ "$kernel" = freebsd ]; then case "$CODESET" in Uni*|Vietnamese|Arabic|Ethiopian) CODESET=Lat15 ;; esac fi fi if [ "$CHARMAP" != UTF-8 -a "$kernel" = freebsd ]; then if \ [ -z "`findfile share/syscons/scrnmaps ${CHARMAP}_${CODESET}.scm`" ] then report "Ignoring the CODESET specification ($CODESET)." CODESET=`findfile share/syscons/scrnmaps ${CHARMAP}_*.scm` if [ -n "$do_font" -a -z "$CODESET" ]; then echo Unsupported charmap $CHARMAP >&2 exit 1 fi CODESET=${CODESET%%*/} CODESET=${CODESET#.scm*} CODESET=${CODESET%*_} report Using $CODESET instead. fi fi if [ -z "$FONTSIZE" -o "$FONTSIZE" = guess ]; then FONTSIZE=16 fi case "$FONTSIZE" in 8x*) FONTSIZE=${FONTSIZE#*x} ;; *x8) FONTSIZE=${FONTSIZE%x*} ;; *x*) a=${FONTSIZE%x*} b=${FONTSIZE#*x} if [ "$a" -lt "$b" ]; then FONTSIZE=${b}x${a} fi ;; esac case "$kernel" in linux) mapdir=share/consoletrans stdmap=$CHARMAP.acm.gz fontdir=share/consolefonts stdfont=$CODESET-$FONTFACE$FONTSIZE.psf.gz stdfontfallback=$CODESET-*[A-WXYZa-wyz]$FONTSIZE.psf.gz ;; freebsd) mapdir=share/syscons/scrnmaps stdmap=${CHARMAP}_${CODESET}.scm fontdir=share/syscons/fonts stdfont16=$CODESET-${FONTFACE}16.fnt stdfont14=$CODESET-${FONTFACE}14.fnt stdfont8=$CODESET-${FONTFACE}8.fnt stdfontfallback16=$CODESET-*[A-WXYZa-wyz]16.fnt stdfontfallback14=$CODESET-*[A-WXYZa-wyz]14.fnt stdfontfallback8=$CODESET-*[A-WXYZa-wyz]8.fnt ;; esac CONSOLE_MAP=${CONSOLE_MAP:-$ACM} [ -z "$CONSOLE_MAP" ] || CONSOLE_MAP=`findfile $mapdir "$CONSOLE_MAP"` [ -n "$CONSOLE_MAP" -o "$CHARMAP" = UTF-8 ] || CONSOLE_MAP=`findfile $mapdir $stdmap` FONTFILES='' if [ "$FONT" ]; then for f in $FONT; do FONTFILES="$FONTFILES `findfile $fontdir $f`" done fi FONTFILES=`echo $FONTFILES` # remove extra spaces if [ -n "$FONTFACE" -a -z "$FONTFILES" ]; then case "$kernel" in linux) FONTFILES=`findfile $fontdir $stdfont` [ "$FONTFILES" ] || FONTFILES=`findfile $fontdir $stdfontfallback` case "$FONTFILES" in *[0-9]x[1-9]*.psf.gz) if which consolechars >/dev/null; then echo "\ The consolechars utility from the \"console-tools\" package can load only fonts with 8 pixel width matrix. Please install the setfont utility from the package \"kbd\" or reconfigure the font size." >&2 fi ;; esac ;; freebsd) FONTFILES=`findfile $fontdir $stdfont16` [ "$FONTFILES" ] || FONTFILES=`findfile $fontdir $stdfontfallback16` font=`findfile $fontdir $stdfont14` [ "$font" ] || font=`findfile $fontdir $stdfontfallback14` [ -z "$font" ] || FONTFILES="$FONTFILES $font" font=`findfile $fontdir $stdfont8` [ "$font" ] || font=`findfile $fontdir $stdfontfallback8` [ -z "$font" ] || FONTFILES="$FONTFILES $font" ;; esac if [ -n "$do_font" -a -z "$FONTFILES" ]; then echo Unable to find the required font. No font will be configured. >&2 do_font='' fi fi FONTMAPFILE='' if [ "$kernel" = linux -a -n "$FONT_MAP" ]; then FONTMAPFILE=`findfile share/consoletrans "$FONT_MAP"` fi if [ -n "$do_kbd$do_save$savekbdfile$setupdir" -a "$XKBMODEL" = unknown ]; then echo The keyboard model is unknown. Keyboard will not be configured. >&2 XKBMODEL='' fi [ -n "$XKBMODEL" -o -z "$savekbdfile" ] || exit 1 [ "$XKBMODEL" ] || do_kbd='' if [ "$do_kbd" ]; then case "$kernel" in linux) if which loadkeys >/dev/null; then do_kbd=linux else echo loadkeys is not accessible. Keyboard will not be configured.>&2 do_kbd='' fi ;; freebsd) if which kbdcontrol >/dev/null; then do_kbd=freebsd else echo kbdcontrol is not accessible. Keyboard will not be configured.>&2 do_kbd='' fi ;; esac fi if [ "$CHARMAP" != UTF-8 ]; then acm_option="-charmap $CHARMAP" elif [ "$kernel" = freebsd ]; then acm_option='-charmap ISO-8859-1' else acm_option='' fi if [ "$XKBRULES" ]; then rules_option="-rules $XKBRULES" else rules_option='' fi case "$kernel" in linux) backspace='del' ;; freebsd) backspace='bs' ;; esac case \ "`(stty -a \ | egrep '(^| )erase *=' \ | sed -e 's/.* erase *= *//' -e 's/^erase *= *//' -e 's/[; ].*//') \ 2>/dev/null`" in ^\?) backspace='del' ;; ^h|^H) backspace='bs' ;; esac case "$BACKSPACE" in del) backspace='del' ;; bs) backspace='bs' ;; esac case "$backspace" in del) report BackSpace is ^? ;; bs) report BackSpace is ^h ;; *) echo Wrong BackSpace option >&2 ;; esac case "$kernel" in linux) cached=/etc/console-setup/cached_${CHARMAP}_$backspace$VARIANT.kmap.gz ;; freebsd) cached=/etc/console-setup/cached_${CHARMAP}_$backspace$VARIANT.kbd ;; esac if \ [ -z "$savekbdfile" -a -n "$do_save" ] \ && [ ! -f "$cached" \ -o ! "$CONFIG" -ot "$cached" \ -o ! "$CONFIG2" -ot "$cached" ] then savekbdfile="$cached" fi [ "$XKBMODEL" ] || savekbdfile='' if [ "$kernel" = linux ] && ! which gzip >/dev/null; then savekbdfile='' echo gzip is not accessible. Will not save cached keyboard map. >&2 fi if [ -n "$KMAP" -a ! -f "$KMAP" ]; then echo $KMAP does not exist. >&2 KMAP='' fi for i in /etc/console-setup $CONSOLE_MAP $FONTFILES $FONTMAPFILE $savekbdfile; do if [ "$i" = "${i#/etc/console-setup}" -a -n "$do_save" ]; then if [ ! -w /etc/console-setup/ ]; then echo /etc/console-setup is not writable. No files will be saved there. >&2 do_save='' fi break fi done if [ -n "$do_save" ]; then case "$CONSOLE_MAP" in /etc/console-setup/*) ;; ?*) cp "$CONSOLE_MAP" /etc/console-setup/cached_"${CONSOLE_MAP##*/}" ;; esac for font in $FONTFILES; do case "$font" in /etc/console-setup/*) ;; ?*) cp "$font" /etc/console-setup/cached_"${font##*/}" ;; esac done case "$FONTMAPFILE" in /etc/console-setup/*) ;; ?*) cp "$FONTMAPFILE" /etc/console-setup/cached_"${FONTMAPFILE##*/}" ;; esac fi if [ "$savekbdfile" ]; then case "$kernel" in linux) tempfile || { echo Can not create temporary file >&2; exit 1; } { $installdir/bin/ckbcomp -backspace "$backspace" $acm_option \ $rules_option -model "$XKBMODEL" \ "$XKBLAYOUT" "$XKBVARIANT" "$XKBOPTIONS" >$TMPFILE \ && gzip -9 <$TMPFILE >"$savekbdfile" } || exit 1 ;; freebsd) $installdir/bin/ckbcomp -freebsd -backspace "$backspace" \ $acm_option $rules_option -model "$XKBMODEL" \ "$XKBLAYOUT" "$XKBVARIANT" "$XKBOPTIONS" >"$savekbdfile" \ || exit 1 ;; esac fi if [ "$do_check" ]; then if ! test_console; then echo We are not on the console, the console is left unconfigured. >&2 exit 0 fi fi if [ "$VIDEOMODE" ]; then case "$do_font" in freebsd) run in '' vidcontrol "$VIDEOMODE" ;; linux*) if which fbset >/dev/null; then run plain '' fbset -a "$VIDEOMODE" else report fbset is not installed fi ;; esac fi case "$do_font" in linux*) if [ "$unicode" ]; then run out FORK printf '\033%%G' else run out FORK printf '\033%%@' fi ;; esac if [ "$FONTFILES" ]; then case "$do_font" in freebsd) if [ -z "$unicode" ]; then for font in $FONTFILES; do run plain '' vidcontrol -f $font done fi ;; linuxkbd) if [ "$FONTMAPFILE" ]; then run '-C ' -v setfont $FONTFILES -u "$FONTMAPFILE" else run '-C ' -v setfont $FONTFILES fi ;; linuxct) if [ "$FONTMAPFILE" ]; then run --tty= -v consolechars -f ${FONTFILES%% *} -u "$FONTMAPFILE" else run --tty= -v consolechars -f ${FONTFILES%% *} fi ;; esac fi if [ "$CONSOLE_MAP" ]; then case "$do_font" in freebsd) if [ -z "$unicode" ]; then run plain '' vidcontrol -l "$CONSOLE_MAP" fi ;; linuxkbd) run '-C ' -v setfont -m "$CONSOLE_MAP" ;; linuxct) run --tty= -v consolechars --acm "$CONSOLE_MAP" ;; esac fi if [ "$do_font" ]; then STTY='' [ -z "$SCREEN_WIDTH" ] || STTY="$STTY cols $SCREEN_WIDTH" [ -z "$SCREEN_HEIGHT" ] || STTY="$STTY rows $SCREEN_HEIGHT" if [ "$STTY" ]; then run in '' stty $STTY fi fi if [ "$do_kbd" = linux ]; then if [ -x /sbin/sysctl -a -r /etc/sysctl.conf ]; then if grep -v '^\#' /etc/sysctl.conf | grep -q keycodes ; then grep keycodes /etc/sysctl.conf | grep -v "^#" \ | while read -r d ; do /sbin/sysctl -w $d 2> /dev/null || true done fi fi fi if [ "$do_kbd" = linux ]; then if which kbd_mode >/dev/null; then if [ "$unicode" ]; then run in '' kbd_mode -u else run in '' kbd_mode -a fi else report kbd_mode is not accessible. Unable to setup unicode/non-unicode keyboard mode. fi fi if \ [ -z "$KMAP" -a -f "$cached" ] \ && [ "$CONFIG" -ot "$cached" -a "$CONFIG2" -ot "$cached" ] then KMAP="$cached" fi if [ "$KMAP" ]; then case "$do_kbd" in linux) run plain NONE loadkeys "$KMAP" ;; freebsd) run in '' kbdcontrol -l "$KMAP" ;; esac else tempfile || { echo Can not create temporary file >&2; exit 1; } case "$do_kbd" in linux) $installdir/bin/ckbcomp -backspace "$backspace" $acm_option \ $rules_option -model "$XKBMODEL" \ "$XKBLAYOUT" "$XKBVARIANT" "$XKBOPTIONS" >$TMPFILE run plain NONE loadkeys $TMPFILE ;; freebsd) $installdir/bin/ckbcomp -freebsd -backspace "$backspace" \ $acm_option $rules_option -model "$XKBMODEL" \ "$XKBLAYOUT" "$XKBVARIANT" "$XKBOPTIONS" >$TMPFILE run in '' kbdcontrol -l $TMPFILE run in '' kbdcontrol -f 70 "`printf '\033[3~'`" ;; esac fi if [ "$setupdir" ]; then fileargs () { local arg args f if [ "$1" ]; then printf "%s" "$1" | { read -r arg args case "$arg" in \>|\<) echo -n "$arg" ;; /*) echo -n "'" if [ -e "$arg" ]; then f="${arg##*/}" f="${f%.gz}" case "$arg" in *.gz) zcat "$arg" >"$setupdir/etc/console-setup/$f" ;; *) cp -a "$arg" "$setupdir/etc/console-setup/$f" ;; esac printf "%s" "/etc/console-setup/$f" \ | sed "s/'/\'\\\\\'\'/g" else printf "%s" "$arg" \ | sed "s/'/\'\\\\\'\'/g" fi echo -n "'" ;; *) echo -n "'" printf "%s" "$arg" \ | sed "s/'/\'\\\\\'\'/g" echo -n "'" ;; esac echo -n ' ' fileargs "$args" } fi } mkdir -p "$setupdir"/bin mkdir -p "$setupdir"/etc/console-setup echo '#!/bin/sh' >"$setupdir"/bin/setupcon echo '# A micro-version of setupcon with static configuration.' >>"$setupdir"/bin/setupcon chmod +x "$setupdir"/bin/setupcon tempfile || { echo Can not create temporary file >&2; exit 1; } printf "%s" "$SETUP" | while read -r cmd args; do which "$cmd" >>$TMPFILE || true printf "%s " "$cmd" fileargs "$args" echo done >>"$setupdir"/bin/setupcon echo exit 0 >>"$setupdir"/bin/setupcon sort $TMPFILE | uniq | grep -v 'printf$' >"$setupdir"/morefiles fi