#! /bin/sh

PACKAGE=kbd

# kbdconfig - Configuration script for the `kbd' and `console-tools' packages
# Copyright (c) 1997, 1998  Yann Dirson
# Copyright (c) 1996  Dominik Kubla

KBDCONF_VERSION=1998.11.09

#set -e


CONFDIR=/etc/${PACKAGE}
LOCALLIBDIR=/usr/local/share

LIBDIR=/usr/share
#LIBDIR=.
KEYMAPSDIR=keymaps
#KEYMAPSDIR=keytables

if [ $# -gt 0 ]
then
    case $1 in
    --help)
	echo
	echo "Usage: kbdconfig [ --help | --version ]"
	echo
	echo "  --help      show this information and exit"
	echo "  --version   show version information and exit"
	echo
	exit 0
	;;		
    --version)	
	echo "This is \`kbdconfig' for Linux Console Tools version ${KBDCONF_VERSION%-*}, Debian release ${KBDCONF_VERSION##*-}"
	exit 0
	;;
    *)
	echo "kbdconfig: Unknown option or parameter $1."
	echo "Use \`kbdconfig --help' for further information."
	exit 1
	;;
    esac
fi

if [ -z "$ALLOWNOROOT" -a ! $(id -u) = 0 ]
then
    echo "You must be root to run \`$(basename $0)'."
    exit 1
fi

case ${PACKAGE} in
kbd)
    KMAPEXT=map
    ;;
console-tools)
    KMAPEXT=kmap
;;
esac

KERNEL_KEYMAP=/var/lib/${PACKAGE}/kernel.${EXT}

yesno() # message [default choice] [secure]
{
    local REPLY=x
    local DEFAULT=''
    local SECURE=''
  
    # default choice
    if [ $# -ge 2 ]
    then
	DEFAULT=$2
    else
	DEFAULT=y
    fi
  
    # default font fallback ?
    if [ $# -ge 3 ]
    then
	SECURE=$3
    else
	SECURE=n
    fi
  
    # get answer
    until [ $REPLY = y -o $REPLY = n ]
    do
	if [ $SECURE = y ]
	then
	    echo "  NOTE: Answering anything else than 'y', 'n', or RETURN"
	    echo "        will reload the kernel's default keymap."
	fi
	echo -n $1 " [${DEFAULT}] "
	read
	if [ x$REPLY = x ]
	then
	    REPLY=$DEFAULT
	fi
	if [ $SECURE = y -a ! x$REPLY = xy -a ! x$REPLY = xn ]
	then
	    if [ -r ${KERNEL_KEYMAP} ]
	    then
		/bin/loadkeys ${KERNEL_KEYMAP}
	    else
		/bin/loadkeys -d
	    fi
	fi
    done
    test x$REPLY = xy
}

do_preserving_keymap()
# execute shell command-line preserving the keymap
{
    # save keymap
    TMP=$(tempfile)
    echo "Saving keymap to ${TMP}"
    /usr/bin/dumpkeys >${TMP}

    eval "$*"

    # restore keymap
    /bin/loadkeys ${TMP}
    rm ${TMP}
}

test_and_install()
{
    if [ $keymap = NONE ]
    then
	# create an empty keymap so that no question is re-asked on upgrade
	touch ${CONFDIR}/default.${KMAPEXT}
    else
	echo "You selected keymap $keymap"
	# Maybe test the keymap before installing
	#
	if /usr/bin/showkey --keymap --timeout=1 >/dev/null 2>&1
	then
	    if yesno "Do you want to test the new keymap right now ?" y
	    then
		do_preserving_keymap "/bin/loadkeys ${keymap} ; /usr/bin/showkey --keymap"
	    else
		echo "WARNING: keymap was not tested... use it at your own risk !"
	    fi
	else
	    echo "Sorry, I can't make you test this keymap now (showkey does not accept --keymap)."
	fi
    fi
  
    # Maybe install the new keymap
    #
    if yesno "Do you accept the chosen map for installation ?" y y
    then
	MAP_ACCEPTED=1
      
	echo Removing $(rm -fv ${CONFDIR}/default.${KMAPEXT} ${CONFDIR}/default.${KMAPEXT}.gz)
      
	if [ "${keymap}" != "NONE" ] 
	then
	    echo -n "Generating include-less $keymap"
	    do_preserving_keymap "loadkeys $keymap ; dumpkeys > ${CONFDIR}/default.${KMAPEXT}"
	    echo -n "Compressing "
	    gzip -9fv ${CONFDIR}/default.${KMAPEXT}
	fi
    fi
}


BIGITEM=''
maxlength_old()
{
    for item in $*
    do
	if [ ${#item} -gt ${#BIGITEM} ]
	then
	    BIGITEM=$item
	fi
    done
}

maxlength()
{
    local BIG=''
    while read REPLY
    do
	if [ ${#REPLY} -gt ${#BIG} ]
	then
	    BIG=$REPLY
	fi
    done

    echo $BIG
}

# list all maps, compressed or not
listfiles()
{
    local DIR=$1
    local flist=$(tempfile)

    # NOTE: bash doesn't want to assign spaces to variable, so we first use '£'
    #  (or I can't figure out how :)
    {
	{ # the dirs
	if [ ! -e $LIBDIR/${DIR}/.top-level ]
	then
	    echo ".."
	fi
	find $LIBDIR/${DIR}/ $LOCALLIBDIR/${DIR}/ -mindepth 1 -maxdepth 1 -type d \
		-printf "%f/\n" 2>/dev/null |
	    sort
	} ; { # the files
	find  $LIBDIR/${DIR}/ $LOCALLIBDIR/${DIR}/ -maxdepth 1 -type f \
		\( -name *.${KMAPEXT} -o -name *.${KMAPEXT}.gz \) \
		-printf "%f\n" 2>/dev/null |
	    # keep basename only and remove .gz extension
	    sed -e 's+.*/++' -e 's/\.gz//g' -e "s/\.${KMAPEXT}//g" | 
	    sort 
	}
    # write to a file so that $SPACES is computed before the remaining of the pipeline
    } > $flist

    # compute column width - add 3 chars as column sep
    BIGITEM="$(maxlength < $flist)"
    BIGITEM=${BIGITEM%.gz}
    BIGITEM=${BIGITEM%.${KMAPEXT}}

    # a string of as many £ (for spaces) as an item, plus 3 more as column-separator
    SPACES="$(echo -n £££${BIGITEM} | tr -c £ £)"

    cat $flist |
	# pad with enough spaces
	sed -e "s/$/${SPACES}/g" -e 's/£/ /g' |    
 	# strip spaces to needed length
	fold -w ${#SPACES} | sed -e '/^ *$/d' |
	# remove newlines
	awk -v ORS='' '{print}' |
	# make columns
	fmt -w ${COLUMNS}

    rm $flist
}


# try to guess COLUMNS if not set
#
if [ "${COLUMNS}" = "" -a -x /usr/bin/X11/resize ]
then
    eval $(/usr/bin/X11/resize -u)
fi

# fallback to decent defaults if it failed
if [ "${COLUMNS}" = "" ]
then
    COLUMNS=80
fi

MAP_ACCEPTED=0
until [ $MAP_ACCEPTED = 1 ]
do
    # Security
    #
    echo -e "\nDo you want the kernel's default keymap to be reloaded ?"
    echo "If you can't press 'n' and hit RETURN, I will assume you need that."
    echo -n "Your choice: "
    read
    if [ x$REPLY != xn ]
    then
	/bin/loadkeys -d
    fi

    ITEM=${KEYMAPSDIR}
    while [ $MAP_ACCEPTED = 0 -a \( -d ${LIBDIR}/$ITEM -o -d ${LOCALLIBDIR}/$ITEM \) ]
    do
	if [ -r ${LIBDIR}/${ITEM}/.desc ]
	then
	    echo
	    cat ${LIBDIR}/${ITEM}/.desc
	    echo
	else
	    cat << EOT

Please choose one of the following keyboard tables,
or \`..' to return to parent directory:

EOT
	fi
	listfiles ${ITEM}
  
	cat <<EOF | fold -s -w ${COLUMNS}

Or answer NONE to skip the loading of a keytable.
Just pressing RETURN will abort the procedure.
EOF

	echo -n "What keytable to load? "; read keymap
	if [ -z "$keymap" ] 
	then
	    echo "Leaving configuration unchanged."
	    exit 0
	fi

	# if there is such a dir, do not look for a keymap
	if [ -d ${LIBDIR}/$ITEM/$keymap -o -d ${LOCALLIBDIR}/$ITEM/$keymap ]
	then
	    if [ $keymap = .. ]
	    then
		if [ -r ${ITEM}/.top-level ]
		then
		    echo -e "\n Already at top-level !"
		else
		    ITEM=${ITEM%/*}
		fi
	    else
		ITEM=${ITEM}/$keymap
	    fi
	    continue
	fi

	# Canonify name and check that wanted keymap exists
	#
	if [ $keymap = NONE ]
	then
	    test_and_install
	else
	    keymap=${keymap%.gz}
	    keymap=${keymap%.${KMAPEXT}}.${KMAPEXT}
	    if [ ! -z $(find ${LIBDIR}/${ITEM}/ -name ${keymap} 2>/dev/null) ]
	    then
		keymap=$(find ${LIBDIR}/${ITEM}/ -name ${keymap})
		test_and_install
	    elif [ ! -z $(find ${LIBDIR}/${ITEM}/ -name ${keymap}.gz 2>/dev/null) ]
	    then
		keymap=$(find ${LIBDIR}/${ITEM}/ -name ${keymap}.gz)
		test_and_install
	    elif [ ! -z $(find ${LOCALLIBDIR}/${ITEM}/ -name ${keymap} 2>/dev/null) ]
	    then
		keymap=$(find ${LOCALLIBDIR}/${ITEM}/ -name ${keymap})
		test_and_install
	    elif [ ! -z $(find ${LOCALLIBDIR}/${ITEM}/ -name ${keymap}.gz 2>/dev/null) ]
	    then
		keymap=$(find ${LOCALLIBDIR}/${ITEM}/ -name ${keymap}.gz)
		test_and_install
	    else
		echo "Sorry, cannot find directory or keymap \`${keymap%.${KMAPEXT}}'."
	    fi
	fi
    done

done

# Maybe load the last installed keymap
#
if yesno "Do you want changes to take effect right now ?" y
then
    if [ "$keymap" != NONE ]
    then
	/bin/loadkeys ${CONFDIR}/default.${KMAPEXT}
    else
	/bin/loadkeys -d
    fi
else
  echo "Any changes you made will take effect after the next boot."
fi
