From: pcg@aber.ac.uk (Piercarlo Grandi)
Newsgroups: comp.unix.sysv386,alt.sources
Subject: A mapkey(1) clone that works!
Date: 25 Jul 92 13:26:05 GMT
Reply-To: pcg@aber.ac.uk (Piercarlo Grandi)
Organization: Coleg Prifysgol Cymru
X-Old-Subject: Re: DELL UNIX SysVr4 and ttydefs

On 24 Jul 92 19:24:12 GMT, davidsen@ariel.crd.GE.COM (william E Davidsen) said:

davidsen> To change what keys generate you use a map??? program.

Unfortunately most mapkey programs for SVR4 and SVR3 are creepy.
Here follows a shar archive with my own mapkbd(1) program.

It is a drop in replacement for mapkey(1), but with several bug fixes
and extensions. Among these:

* it allows to set keys to generate "meta" (high bit turned on)
  characters, and indeed with option '-m' will automatically set up the
  keyboard to do so;

* with option '-i' it can load incrementally several key definition
  files, and the last key definition encounted for a given key code
  prevails.

I have enclosed sample keyboard mapping files; in particular for the US
keyboard with meta keys (and some extra keys to switch VTs), and key
redefinitions for the UK and IT keyboards.

Copyright notice: this program is copyrighted by me and can be copied
in accordance with the GNU public license, version 2 or later.

This programs comes with NO WARRANTY implied or otherwise; it is not
error free, and there is no promise of corrections or support.

Finally, the usual disclaimer:

  This program has been written entirely by me, with the use of my own
  resources, money and time. It is in no way related or supported by the
  the University of Wales, Aberystwyth, and its activities and research
  in Computer Science or otherwise. I thank them profusely for allowing
  me to post such materials to this net.

-------------------------cut here-------------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 1)."
# Contents:  ita-meta.kbd mapkbd.1 mapkbd.c ukd-meta.kbd usa-meta.kbd
# Wrapped by pcg@aberdb on Sat Jul 25 13:19:16 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'ita-meta.kbd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ita-meta.kbd'\"
else
echo shar: Extracting \"'ita-meta.kbd'\" \(841 characters\)
sed "s/^X//" >'ita-meta.kbd' <<'END_OF_FILE'
X# Italian keyboard
X
X3	'2'	'"'	nop	nop	0xb2	0xa2	nop	nop	O
X# simbolo di lira
X4	'3'	0x9c	nop	nop	0xb3	'#'	nop	nop	O
X7	'6'	'&'	nop	nop	0xb6	0xa6	rs	rs	O
X8	'7'	'/'	nop	ns	0xb7	0xaf	nop	0x9f	O
X9	'8'	'('	nop	nop	0xb8	0xa8	nop	nop	O
X10	'9'	')'	nop	nop	0xb9	0xa9	nop	nop	O
X11	'0'	'='	nop	nop	0xb0	0xbd	nop	nop	O
X12	'\''	'?'	del	del	0xa7	0xbf	0xff	0xff	O
X# u accentata
X13	0x8d	'^'	rs	rs	'~'	0xde	0x9e	0x9e	O
X# e accentata lunga e breve
X26	0x8a	0x82	nop	nop	'['	'{'	esc	esc	O
X27	'+'	'*'	nop	nop	']'	'}'	gs	gs	O
X# o accentata
X39	0x95	'@'	nul	nul	'@'	0xc0	0x80	0x80	O
X# a accentata
X40	0x85	'#'	nop	nop	'#'	0xa3	nop	nop	O
X41	'<'	'>'	nop	nop	0xbc	0xbe	nop	nop	O
X# u accentata e simbolo di paragrafo
X43	0x97	0xb2	nop	nop	'`'	'~'	nul	nul	O
X51	','	';'	nop	nop	0xac	0xbb	nop	nop	O
X52	'.'	':'	nop	nop	0xae	0xba	nop	nop	O
X53	'-'	'_'	ns	ns	0xad	0xdf	0x9f	0x9f	O
END_OF_FILE
if test 841 -ne `wc -c <'ita-meta.kbd'`; then
    echo shar: \"'ita-meta.kbd'\" unpacked with wrong size!
fi
# end of 'ita-meta.kbd'
fi
if test -f 'mapkbd.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mapkbd.1'\"
else
echo shar: Extracting \"'mapkbd.1'\" \(6529 characters\)
sed "s/^X//" >'mapkbd.1' <<'END_OF_FILE'
X.TH MAPKBD 1M
X.ad b
X.SH NAME
Xmapkbd \- remap the keyboard under System V
X.SH SYNOPSYS
X.B mapkbd
X.BR \- [ mcivdox ]
X.BR \-t " path"
X.BR \-T " fd"
X.RB [ \- ]
X[ file ... ]
X.SH DESCRIPTION
XThis program remaps the keyboard under System V. It is an extended
Xclone of
X.IR mapkey (1M).
X.LP
XIt has some additional facilities, the most important of which is that it
Xactually works and does not make a mess of the keyboard mappings like the
XSVR4 supplied one. Among the others are the ability to make the
X.B alt
Xkey into a
X.B meta
Xkey, reading in one go multiple input files, setting the keyboard map
Xassociated to a specified device file or a file descriptor (thus being
Xto read the keymap file from the standard input), and doing a dry run.
X.LP
XThe
X.IR mapkey (1M)
Xcompatible options are:
X.TP
X.BR \- [ dox ]
XDump the now current keymap table to standard output, scancodes in decimal,
Xoctal or hexdecimal respectively.
X.TP
X.B \-m
XIf a non
X.B alt
Xkey combination generates an ASCII character code, the corresponding
X.B alt
Xcombination will generate the same character code with the eight bit set.
XIn other words it makes
X.B alt
Xbecome a
X.B meta
Xkey.
X.TP
X.B \-c
XDon't install the new keymap table into the system; use this option to
Xcheck the syntax of a keymap file.
X.TP
X.B \-i
XDon't clear the current keymap; fetch it first, modify it and then
Xload the modified one. Useful for incremental keymap modification,
Xfor example to modify a single key.
X.TP
X.B \-v
XBe verbose and print a list of the steps being performed by the program.
XMainly useful to understand the complex interplay of the various options.
X.TP
X.BI \-t " path"
XUpdate the keymap table associated with the given device. The device must
Xbe a (virtual) console, and the user must be the superuser.
X.TP
X.BI \-T " fd"
XUpdate the keymap table associated with the given file descriptor.
XThe device accessed via that file descriptor must
Xbe a (virtual) console, and the use must be the superuser. The default
Xis standard input, or file descriptor 0.
X.TP
X.I "file ..."
XThese are the pathnames of the files that contain the scancode tables.
XThe files are read sequentially, and this means that scancode lines in
Xlater files override those in earlier files. If
X.B "\-"
Xis used as pathname, the standard input is used instead. If no name is
Xgiven, the default is the system key table file.
X.SH "INPUT SYNTAX"
XEach line of an input file has ten columns; the first, numeric, is the
Xscancode, (in hex, octal or decimal),
Xthe next eight are for the character codes to generate for the modifier
Xcombinations
X.IR (NONE) ,
X.IR "SHIFT" ,
X.IR "CTRL" ,
X.IR "CTRL-SHIFT" ,
X.IR "ALT" ,
X.IR "ALT-SHIFT" ,
X.IR "ALT-CTRL" ,
X.IR "ALT-CTRL-SHIFT" ,
Xin the given order, and the last column is a single character,
X.I O
Xfor no special casing,
X.I N
Xif the key is affected by the
X.I "NumLock"
Xkey,
X.I "C"
Xif by the
X.I "CapsLock"
Xkey,
Xand
X.I "B"
Xif by both.
X.LP
XThe character code to be generated can be specified as a:
X.TP
X.I number
Xin hex, octal or decimal.
X.TP
X.BI "'" x "'"
Xa literal character .
X.TP
X.BR nul - gs
Xan ascii control character with the names given in
X.I /usr/pub/ascii
Xor some variations like
X.I nl
Xfor line feed,
X.I np
Xfor form feed,
X.I ns
Xfor unit separator.
X.TP
X.I special
Xthe name of an action or effect, with no character code generated. The names
Xare:
X.nf
X.ce 3
Xagr alt break btab clock ctl debug
Xfnscrn fpscrn lalt lctrl lshift nlock nop
Xnscr pscr ralt rctrl reboot rshift slock sysreq
X.fi
X.TP
X.B "fN fO f["
XOne of these keys means to generate the base character code preceded
Xby the escape character and then either
X.B N
Xor
X.B O
Xor
X.BR [ .
XThis is useful for defining function key sequences.
X.TP
X.BI scr number
Xswitch the to the virtual console whose one or two digit
X.I number
Xis given (the main console has number 0).
X.TP
X.BI fkey number
Xreturn the function key string with that
X.IR number .
X.TP
X.BI "^" x
Xan ascii control character.
X.TP
X.BI "C-" x
Xan ascii control character.
X.TP
X.BI "M-" x
Xa meta character.
X.TP
X.BI "M-C-" x
Xa meta control character.
X.SH EXAMPLES
X.LP
XThe first three examples are the same as for
X.I mapkey (1M).
XThe others illustrate new functionality.
X.TP
X.B mapkbd
XIt reads the
Xsystem key table file and sets the standard input keymap table to it.
X.TP
X.B "mapkbd /usr/local/etc/keys.lumbard"
X.br
XIt reads the given symbolic keymap file and sets the standard input
Xkeymap table to it.
X.TP
X.B "mapkbd \-d"
X.br
XDump symbolically to the standard output, in a format suitable for
Xrereading it, the currently installed keymap.
X.TP
X.B "mapkbd \-m file1 file2 file3"
X.br
XInstalls the indicated keymap files, but with the
X.B alt
Xkey as a
X.B meta
Xkey.
X.TP
X.BI "mapkbd \-c \-d " files...
X.br
XRead anch check the given files, and dump the resulting keymap
Xsymbolically to standard output. This can be used to merge several
Xkeymap files. If none given, the default system keymap file is checked
Xand dumped.
X.TP
X.BI "mapkbd \-c \-m \-d" " file"
X.br
XRead and check the given file,
X.I metaize
Xit and dump the resulting keymap
Xsymbolically to standard output. This can be used to add
X.B meta
Xlike bindings to an existing keymap file. If no file name were
Xspecified, the system default file would be used.
X.TP
X.BI "mapkbd \-i keypad-emacs.kb"
X.br
XOverlay the current keymap with the entries contained in the named file,
Xfor example one that redefines only the scancodes belonging to the keypad
Xto values more suitable with
X.IR emacs (1).
X.TP
X.BI "mapkbd \-m"
X.br
XModify the currently installed keymap file so that the
X.B alt
Xkey becomes a
X.B meta
Xkey. Note that this does not load the system default keymap file, it
Xmodifies the currently installed keymap, without reading any file.
X.TP
X.BI "/usr/local/sbin/mapkbd \-m </dev/console >/dev/sysmsg 2>&1"
X.br
XThis is a possible
X.I init.base
Xline to make sure that the default installed keymap is
X.I metaized
Xas it should be... I also add the path of my own map file that contains
Xless convoluted bindings for screen switching.
X.SH AUTHOR
XCopyright 1992 Piercarlo Grandi.
X.SH BUGS
XBecause of compatibility with
X.IR mapkey (1M)
Xthe rules concerning the case where no keymap file name is given are
Xfairly irregular. Basically when
X.B \-c
Xis specified the system default file is loaded, when
X.B \-m
Xis specified the currently installed keymap is read, and so on.
X.LP
XThe input format is (or should be) completely
X.IR mapkey (1M)
Xcompatible, but the output format is not. I have taken the liberty to
Xuse more traditional names for certain ASCII control characters, and for
Xsome specials. This can be easily changed by editing the source.
END_OF_FILE
if test 6529 -ne `wc -c <'mapkbd.1'`; then
    echo shar: \"'mapkbd.1'\" unpacked with wrong size!
fi
# end of 'mapkbd.1'
fi
if test -f 'mapkbd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mapkbd.c'\"
else
echo shar: Extracting \"'mapkbd.c'\" \(18179 characters\)
sed "s/^X//" >'mapkbd.c' <<'END_OF_FILE'
X#include <string.h>
X#include <stdlib.h>
X#include <search.h>
X#include <ctype.h>
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/at_ansi.h>
X#include <sys/kd.h>
X
X#define until(pred)	while(!(pred))
X
Xtypedef struct
X{
X  int			  value;
X  char			  *symbol;
X}
X			assoc_t;
X
Xtypedef enum
X{
X  sort_none,
X  sort_value,
X  sort_symbol,
X}
X			assoc_sort_t;
X
Xstatic int		assoc_value_cmp(elem,table)
X  register assoc_t	  *elem,*table;
X{
X  return elem->value - table->value;
X}
X
Xstatic assoc_t		*assoc_find_value(value,assocs,n,sorted)
X  int			  value;
X  assoc_t		  *assocs;
X  unsigned		  n;
X  assoc_sort_t		  sorted;
X{
X# if (!DONTSORT)
X   if (sorted == sort_value)
X   {
X     assoc_t		      assoc;
X
X     assoc.value = value;
X
X     return
X       (assoc_t *) bsearch
X	 (
X	   (void *) &assoc,(void *) assocs,n,
X	   sizeof (assoc_t),assoc_value_cmp
X	 );
X   }
X   else
X# endif
X  {
X    register assoc_t	      *assoc;
X
X    for (assoc = assocs; assoc < assocs+n; assoc++)
X      if (assoc->value == value)
X	return assoc;
X
X    return 0;
X  }
X}
X
Xstatic int		assoc_symbol_cmp(elem,table)
X  register assoc_t	  *elem,*table;
X{
X  return strcmp(elem->symbol,table->symbol);
X}
X
Xstatic assoc_t		*assoc_find_symbol(symbol,assocs,n,sorted)
X  char			  *symbol;
X  assoc_t		  *assocs;
X  unsigned		  n;
X  assoc_sort_t		  sorted;
X{
X# if (!DONTSORT)
X    if (sorted == sort_symbol)
X    {
X      assoc_t		      assoc;
X
X      assoc.symbol = symbol;
X
X      return
X	(assoc_t *) bsearch
X	  (
X	    (void *) &assoc,(void *) assocs,n,
X	    sizeof (assoc_t),assoc_symbol_cmp
X	  );
X    }
X  else
X# endif
X  {
X    register assoc_t	      *assoc;
X
X    for (assoc = assocs; assoc < assocs+n; assoc++)
X      if (strcmp(assoc->symbol,symbol) == 0)
X	return assoc;
X
X    return 0;
X  }
X}
X
Xstatic assoc_t		states[] =
X{
X  {	NORMAL,		"normal"	},
X  {	SHIFT,		"shift"		},
X  {	CNTRL,		"cntrl"		},
X  {	SHFCTL,		"shfctl"	},
X  {	ALT,		"alt"		},
X  {	ALTSHF,		"altshf"	},
X  {	ALTCTL,		"altctl"	},
X  {	ALTSHFCTL,	"altshfctl"	},
X};
X
Xstatic unsigned		n_states = sizeof states / sizeof *states;
X
Xstatic assoc_t		flags[] =
X{
X  {	L_O,	"O"	},
X  {	L_C,	"C"	},
X  {	L_N,	"N"	},
X  {	L_B,	"B"	},
X};
X
Xstatic unsigned		n_flags = sizeof flags / sizeof *flags;
X
Xstatic assoc_t		controls[] =
X{
X  {	0x00,	"nul"	},
X  {	0x01,	"soh"	},
X  {	0x02,	"stx"	},
X  {	0x03,	"etx"	},
X  {	0x04,	"eot"	},
X  {	0x05,	"enq"	},
X  {	0x06,	"ack"	},
X  {	0x07,	"bel"	},
X  {	0x08,	"bs"	},
X  {	0x09,	"ht"	},
X  {	0x0a,	"nl"	},
X  {	0x0a,	"lf"	},
X  {	0x0b,	"vt"	},
X  {	0x0c,	"ff"	},
X  {	0x0c,	"np"	},
X  {	0x0d,	"cr"	},
X  {	0x0e,	"so"	},
X  {	0x0f,	"si"	},
X  {	0x10,	"dle"	},
X  {	0x11,	"dc1"	},
X  {	0x12,	"dc2"	},
X  {	0x13,	"dc3"	},
X  {	0x14,	"dc4"	},
X  {	0x15,	"nak"	},
X  {	0x16,	"syn"	},
X  {	0x17,	"etb"	},
X  {	0x18,	"can"	},
X  {	0x19,	"em"	},
X  {	0x1a,	"sub"	},
X  {	0x1b,	"esc"	},
X  {	0x1c,	"fs"	},
X  {	0x1d,	"gs"	},
X  {	0x1e,	"rs"	}, 
X  {	0x1f,	"us"	},
X  {	0x1f,	"ns"	},
X  {	0x20,	"0x20"	},
X  {	0x20,	"sp"	},
X};
X
Xstatic unsigned		n_controls = sizeof controls / sizeof *controls;
Xstatic assoc_sort_t	s_controls = sort_value;
X
Xstatic assoc_t			specials[] =
X{
X  {	K_NOP,	"nop"		},
X  {	K_LSH,	"lshift"	},
X  {	K_RSH,	"rshift"	},
X  {	K_CLK,	"clock"		},
X  {	K_NLK,	"nlock"		},
X  {	K_SLK,	"slock"		},
X  {	K_ALT,	"alt"		},
X  {	K_BTAB,	"btab"		},
X  {	K_CTL,	"ctrl"		},
X  {	K_LAL,	"lalt"		},
X  {	K_RAL,	"ralt"		},
X  {	K_LCT,	"lctrl"		},
X  {	K_RCT,	"rctrl"		},
X  {	K_AGR,	"agr"		},
X  {	K_SRQ,	"sysreq"	},
X  {	K_BRK,	"brk"		},
X  {	K_BRK,	"break"		},
X  {	K_ESN,	"fN"		},
X  {	K_ESN,	"escn"		},
X  {	K_ESO,	"fO"		},
X  {	K_ESO,	"esco"		},
X  {	K_ESL,	"f["		},
X  {	K_ESL,	"escl"		},
X  {	K_RBT,	"reboot"	},
X  {	K_RBT,	"rboot"		},
X  {	K_DBG,	"debug"		},
X  {	K_NEXT,	"nscr"		},
X  {	K_PREV,	"pscr"		},
X  {	K_FRCNEXT, "fnscrn"	},
X  {	K_FRCPREV, "fpscrn"	},
X};
X
Xstatic unsigned		n_specials = sizeof specials / sizeof *specials;
Xstatic assoc_sort_t	s_specials = sort_value;
X
Xtypedef struct
X{
X  int			  first,last;
X  char			  *symbol;
X}
X			range_t;
X
Xstatic range_t		*range_find_value(value,ranges,n)
X  int			  value;
X  range_t		  *ranges;
X  unsigned		  n;
X{
X  register range_t	  *range;
X
X  for (range = ranges; range < ranges+n; range++)
X    if (range->first <= value && value <= range->last)
X      return range;
X
X  return 0;
X}
X
Xstatic range_t		*range_find_symbol(symbol,ranges,n)
X  char			  *symbol;
X  range_t		  *ranges;
X  unsigned		  n;
X{
X  register range_t	  *range;
X
X  for (range = ranges; range < ranges+n; range++)
X    if (strncmp(range->symbol,symbol,strlen(range->symbol)) == 0)
X      return range;
X
X  return 0;
X}
X
Xstatic range_t		ranges[] =
X{
X  {	K_FUNF,K_FUNL,	"fkey"	},
X  {	K_VTF,K_VTL,	"scr"	},
X  {	K_MGRF,K_MGRL,	"mgr"	},
X  {	K_MGRF,K_MGRL,	"MGR"	},
X  {	K_VTF,K_MGRL,	"vt"	},
X  {	K_VTF,K_MGRL,	"VT"	},
X  {	K_PFXF,K_PFXL,	"pfx"	},
X  {	K_PFXF,K_PFXL,	"PFX"	},
X};
X
Xstatic unsigned		n_ranges = sizeof ranges / sizeof *ranges;
X
Xstatic void		kmap_clear(kmap)
X  keymap_t		  *kmap;
X{
X  register unsigned	  code;
X  register struct key_t	  *key;
X
X  for
X  (
X    code = 0, key = &kmap->key[0];
X    code < NUM_KEYS;
X    code++, key++
X  )
X  {
X    register unsigned	    state;
X
X    for (state = 0; state < NUM_STATES; state++)
X      key->map[state] = K_NOP;
X    key->spcl = 0xFF;
X    key->flgs = L_O;
X  }
X
X  kmap->n_keys = 0;
X}
X
Xtypedef char	        symbol_t[12];
X
Xstatic void		skipoverwhite(file)
X  register FILE		  *file;
X{
X  register int		  ch;
X
X  do ch = getc(file);
X  until (ch == EOF || ch == '\n' || !isspace(ch));
X
X  if (ch != EOF) ungetc(ch,file);
X}
X
Xstatic void		skipovereol(file)
X  register FILE		  *file;
X{
X  register int		  ch;
X
X  do ch = getc(file);
X  until (ch == '\n' || ch == EOF);
X}
X  
Xstatic unsigned		getsymbol(file,symbol)
X  register FILE		  *file;
X  register char		  *symbol;
X{
X  register int		  ch;
X  register char		  *last = symbol + sizeof (symbol_t) - 1;
X
X  ch = getc(file);
X  if (ch == EOF)
X  {
X    *symbol = '\0';  
X    return 0;
X  }
X
X  /*
X    Here we spend some effort to special case ' '...
X  */
X
X  if (ch == '\'')
X  {
X    if (symbol < last)
X      *symbol++ = ch;
X    ch = getc(file);
X    if (ch != EOF && ch == ' ')
X    {
X      if (symbol < last)
X	*symbol++ = ch;
X      ch = getc(file);
X    }
X  }
X
X  until (ch == EOF || ch == '\n' || isspace(ch))
X  {
X    if (symbol < last)
X      *symbol++ = ch;
X    ch = getc(file);
X  }
X
X  *symbol = '\0';
X
X  ungetc(ch,file);
X
X  return symbol < last;
X}
X
Xstatic unsigned		tonumber(symbol,valuep)
X  register char		  *symbol;
X  unsigned		  *valuep;
X{
X  unsigned		  value;
X  char			  *tail = symbol;
X
X  value =
X    (symbol[0] == '0')
X      ? (symbol[1] == 'x' || symbol[1] == 'X')
X        ? strtoul(symbol+2,&tail,16) : strtoul(symbol+1,&tail,8)
X    : (strchr("123456789",symbol[0]))
X	? strtoul(symbol,&tail,10) : (tail = symbol, 0);
X
X  if (tail > symbol)
X    *valuep = value;
X
X  return tail > symbol;
X}
X
Xstatic unsigned		getstate(file,code,valuep,specp)
X  FILE			  *file;
X  unsigned		  code;
X  unsigned char		  *valuep;
X  unsigned		  *specp;
X{
X  symbol_t		  symbol;
X  unsigned		  value;
X  register assoc_t	  *assoc;
X  register range_t	  *range;
X
X  if (!getsymbol(file,symbol))
X  {
X    fprintf(stderr,"scancode %d: badly formed symbol '%s'\n",code,symbol);
X    return 0;
X  }
X
X  if (isdigit(symbol[0]) && tonumber(symbol,&value))
X    /*skip*/;
X  else if (symbol[0] == '\'')
X  {
X    value = symbol[(symbol[1] != '\\') ? 1 : 2];
X    if (!(' ' <= value && value <= '~'))
X      return 0;
X  }
X  else if (assoc = assoc_find_symbol(symbol,controls,n_controls,s_controls))
X    value = assoc->value;
X  else if (assoc = assoc_find_symbol(symbol,specials,n_specials,s_specials))
X  {
X    value = assoc->value;
X    *specp = 1;
X  }
X  else if (range = range_find_symbol(symbol,ranges,n_ranges))
X  {
X    value = range->first
X	+ strtoul(symbol+strlen(range->symbol),(char **) 0,10);
X    *specp = 1;
X  }
X  else if (strcmp(symbol,"del") == 0)
X    value = 0x7F;
X  else if
X  (
X    (symbol[0] == '^' && symbol[2] == '\0') 
X    || (symbol[0] == 'C' && symbol[1] == '-' && symbol[3] == '\0')
X    || (symbol[5] == '0' && strncmp(symbol,"M-C-",4))
X  )
X  {
X    value = symbol[(symbol[0] == '^') ? 1 : (symbol[1] == 'C') ? 2 : 4];
X    if ((value < '@' || value > '_') && value != '?')
X      return 0;
X    value = (value != '?') ? value & 0x1F : 0x7F;
X    if (symbol[0] == 'M')
X      value |= 0x80;
X  }
X  else if (symbol[0] == 'M' && symbol[1] == '-' && symbol[3] == '\0')
X  {
X    value = symbol[2];
X    if (value < ' ' || value > '~')
X      return 0;
X    value |= 0x80;
X  }
X  else
X    return 0;
X
X  *valuep = (unsigned char) value;
X  return 1;
X}
X
Xstatic unsigned		loadkey(file,code,key)
X  FILE			  *file;
X  unsigned		  code;
X  register struct key_t   *key;
X{
X  symbol_t		  symbol;
X  register unsigned	  state;
X  unsigned char	      	  values[NUM_STATES];
X  unsigned		  spcl;
X  unsigned		  flgs;
X  register assoc_t	  *assoc;
X  unsigned		  failures;
X
X  spcl = 0;
X  flgs = 0;
X  failures = 0;
X
X  for (state = 0; state < NUM_STATES; state++)
X  {
X    unsigned		    spec = 0;
X
X    skipoverwhite(file);
X
X    if (getstate(file,code,&values[state],&spec))
X    {
X      if (spec)
X	spcl |= (0x80 >> state);
X    }
X    else
X    {
X      fprintf(stderr,"scancode %d: symbol unrecognized",code);
X      if (assoc = assoc_find_value(states,n_states,state,sort_none))
X	fprintf(stderr," for state %s\n",assoc->symbol);
X      else
X	fprintf(stderr," for state %d\n",state);
X      failures++;
X    }
X  }
X
X  skipoverwhite(file);
X
X  if
X  (
X    !getsymbol(file,symbol)
X    || (assoc = assoc_find_symbol(symbol,flags,n_flags,sort_none)) == 0)
X  {
X    fprintf(stderr,"scancode %d: bad flags '%s'\n",code,symbol);
X    failures++;
X  }
X  flgs = assoc->value;  
X
X  if (!failures)
X  {
X    for (state = 0; state < NUM_STATES; state++)
X      key->map[state] = values[state];
X    key->spcl = spcl;
X    key->flgs = flgs;
X  }
X
X  return failures;
X}
X
Xstatic unsigned		kmap_load(lowest,kmap,file,path)
X  unsigned		  lowest;
X  keymap_t		  *kmap;
X  FILE			  *file;
X  char			  *path;
X{
X  register int		  ch;
X  int			  hcode;
X  unsigned		  failures;
X
X# if (DONTSORT)
X  {
X    s_controls = sort_none;
X    s_specials = sort_none;
X  }
X# else
X  {
X    if (s_controls != sort_symbol)
X    {
X      qsort(&controls, n_controls, sizeof (assoc_t), assoc_symbol_cmp);
X      s_controls = sort_symbol;
X    }
X
X    if (s_specials != sort_symbol)
X    {
X      qsort(&specials, n_specials, sizeof (assoc_t), assoc_symbol_cmp);
X      s_specials = sort_symbol;
X    }
X  }
X# endif
X
X  hcode = -1;
X  failures = 0;
X
X  while ((ch = getc(file)) != EOF)
X  {
X    ungetc(ch,file);
X
X    if (ch == '#')		skipovereol(file);
X    else if (ch == '\n')	ch = getc(file);
X    else if (isspace(ch))	skipoverwhite(file);
X    else /* A scancode line */
X    {
X      symbol_t		      symbol;
X      unsigned		      code;
X
X      if (!getsymbol(file,symbol) || !tonumber(symbol,&code)
X	|| code >= NUM_KEYS)
X      {
X	fprintf(stderr,"scancode '%s' in file '%s' is illegal\n",symbol,path);
X	failures++;
X      }
X      else
X      {
X	if (hcode < (int) code)
X	  hcode = code;
X
X	failures += loadkey(file,code,&kmap->key[code]);
X      }
X
X      skipovereol(file);
X    }
X  }
X
X  if (failures)
X    fprintf(stderr,"%d items in file '%s' could not be recognized\n",
X      failures,path);
X  else if (kmap->n_keys <= hcode)
X    kmap->n_keys = hcode+1;
X
X  return failures == 0 && hcode >= lowest;
X}
X
Xstatic void		kmap_dump(kmap,base)
X  keymap_t		  *kmap;
X  unsigned		  base;
X{
X  register unsigned	  code;
X  register struct key_t	  *key;
X
X# if (DONTSORT)
X  {
X    s_controls = sort_none;
X    s_specials = sort_none;
X  }
X# else
X  {
X    if (s_controls != sort_value)
X    {
X      qsort(&controls, n_controls, sizeof (assoc_t), assoc_value_cmp);
X      s_controls = sort_value;
X    }
X
X    if (s_specials != sort_value)
X    {
X      qsort(&specials, n_specials, sizeof (assoc_t), assoc_value_cmp);
X      s_specials = sort_value;
X    }
X  }
X# endif
X
X  for
X  (
X    code = 0, key = &kmap->key[0];
X    code < kmap->n_keys;
X    code++, key++
X  )
X  {
X    register unsigned	      state;
X
X    printf((base == 10) ? "%d" : (base == 16) ? "0x%02x" : "0%o",code);
X    for (state = 0; state < NUM_STATES; state++)
X    {
X      register unsigned char	value = key->map[state];
X
X
X      putchar('\t');
X
X      if (key->spcl & (0x80 >> state))
X      {
X        register assoc_t	  *assoc;
X	register range_t	  *range;
X
X	if (assoc = assoc_find_value(value,specials,n_specials,s_specials))
X	  fputs(assoc->symbol,stdout);
X	else if (range = range_find_value(value,ranges,n_ranges))
X	  printf("%s%02d",range->symbol,value-range->first);
X        else
X	  fputs("SPEC?",stdout);
X      }
X      else
X      {
X        if (value > ' ' && value <= '~')
X	  printf((value == '\'' || value == '\\') ? "'\\%c'" : "'%c'",value);
X        else if (value <= ' ')
X        {
X	  register assoc_t	  *assoc;
X
X	  if (assoc = assoc_find_value(value,controls,n_controls,s_controls))
X	    fputs(assoc->symbol,stdout);
X        }
X        else if (value == 0x7F)
X	  fputs("del",stdout);
X        else
X	  printf("0x%02x",value);
X      }
X    }
X
X    printf("\t%c\n","OCNB"[key->flgs&0x03]);
X  }
X}
X
Xstatic void		metaize(kmap)
X  keymap_t		  *kmap;
X{
X  register short	  code;
X  register struct key_t	  *key;
X
X  for
X  (
X    code = 0, key = &kmap->key[0];
X    code < kmap->n_keys;
X    code++, key++
X  )
X  {
X    register unsigned	    state;
X    register unsigned char  *map = key->map;
X    register unsigned	    spcl = key->spcl;
X
X    for (state = ALT; state <= ALTSHFCTL; state++)
X    {
X      if ((spcl & (0x80 >> state)) == 0)
X	 map[state] = map[state-(ALT-NORMAL)] | 0x80;
X    }
X  }
X}
X
X#if (defined KDDFLTKEYMAP)
X  static struct key_dflt  kdflt;
X# define kmap		  kdflt.key_map
X#else
X  static keymap_t	  kmap;
X#endif
X
Xextern int	main(argc,argv,envp)
X  int		  argc;
X  char		  **argv;
X  char		  **envp;
X{
X  int		  opt;
X
X  char		  *ttypath = 0;
X  int		  ttyfd = -1;
X
X  char		  **keypaths = 0;
X  unsigned	  keycount = 0;
X
X  enum
X  {
X    opt_DUMP	  = 0x003F,
X    opt_META	  = 0x0040,
X    opt_INCR	  = 0x0080,
X    opt_CHECK	  = 0x0100,
X    opt_VERBOSE	  = 0x0200,
X    opt_FILES	  = 0x0400,
X  };
X
X  enum
X  {
X    do_GET	  = 0x0001,
X    do_CLEAR	  = 0x0002,
X    do_LOAD	  = 0x0004,
X    do_META	  = 0x0008,
X    do_PUT	  = 0x0010,
X    do_DUMP	  = 0x0020,
X  };
X
X  unsigned	  opts = 0;
X  unsigned	  dos = 0;
X
X  unsigned	  failed = 0;
X
X  /*
X    These are for compatibility with SVR4 mapkey(1M):
X
X     <empty>			load default, put
X     -[dox] <empty>		get, dump
X     <files>			load files, put
X
X    These are new combinations:
X
X     -[dox] <files>		load files, put, dump
X
X     -c <empty>			load default
X     -c <files>			load files
X     -[dox] -c <files>		load files, dump
X     -m -[dox] -c <files>	load files, metaize, dump
X
X     -m <empty>			get, metaize, put
X     -m -[dox] <empty>		get, metaize, put, dump
X
X     -m <files>			load files, metaize, put
X     -m -[dox] <files>		load files, metaize, put, dump
X  */
X
X  while ((opt = getopt(argc,argv,"odxcmivt:T:")) != EOF)
X  switch (opt)
X  {
X  case 'o':	opts = (opts&~opt_DUMP) | 8; break;
X  case 'd':	opts = (opts&~opt_DUMP) | 10; break;
X  case 'x':	opts = (opts&~opt_DUMP) | 16; break;
X
X  case 'c':	opts |= opt_CHECK; break;
X  case 'm':	opts |= opt_META; break;
X  case 'i':	opts |= opt_INCR; break;
X  case 'v':	opts |= opt_VERBOSE; break;
X
X  case 't':	ttypath = optarg; break;
X  case 'T':	ttyfd = atoi(optarg); break;
X  }
X
X  if (optind < argc)
X  {
X    keypaths = &argv[optind];
X    keycount = argc-optind;
X    opts |= opt_FILES;
X  }
X
X  if ((opts & (opt_DUMP|opt_FILES|opt_META)) == (opt_DUMP))
X    opts |= opt_CHECK;
X
X  if ((!(opts & opt_FILES) && (opts & (opt_META|opt_DUMP)))
X    || (opts & opt_INCR))
X    dos |= do_GET;
X
X  if (!(dos & do_GET) && !(opts & opt_INCR))
X    dos |= do_CLEAR;
X
X  if (opts & opt_META)
X    dos |= do_META;
X
X  if ((opts & opt_FILES) || !(opts & (opt_META|opt_DUMP)))
X    dos |= do_LOAD;
X
X  if (((opts & opt_META) || (dos & do_LOAD)) && !(opts & opt_CHECK))
X    dos |= do_PUT;
X
X  if (opts & opt_DUMP)
X    dos |= do_DUMP;
X
X  if (opts & opt_VERBOSE)
X    fprintf(stderr,"opts 0x%04x, dos 0x%04x\n",opts,dos);
X
X  if (!(opts & opt_FILES) && (dos & do_LOAD))
X  {
X    static char		*(libpaths[]) = { "/usr/lib/keyboard/keys", 0 };
X
X    if (opts & opt_VERBOSE)
X      fprintf(stderr,"defaulting file to '%s'\n",libpaths[0]);
X
X    keypaths = &libpaths[0];
X    keycount = 1;
X  }
X
X  if ((dos & (do_GET|do_LOAD)) == 0)
X  {
X    fputs("no action requested!?\n",stderr);
X    exit(1);
X  }
X
X  if (ttyfd < 0)
X  {
X    if (ttypath == 0)
X      ttyfd = 0;
X    else
X    {
X      if (opts & opt_VERBOSE)
X      	fprintf(stderr,"opening tty '%s'\n",ttypath);
X
X      ttyfd = open(ttypath,0);
X      if (ttyfd < 0)
X      {
X	perror(ttypath);
X	exit(1);
X      }
X    }
X  }
X
X  if (dos & do_GET)
X  {
X    kmap_clear(&kmap);
X
X    if (opts & opt_VERBOSE)
X      fprintf(stderr,"getting map from fd %d\n",ttyfd);
X
X#   if (!defined KDDFLTKEYMAP)
X      if (ioctl(ttyfd,GIO_KEYMAP,&kmap) < 0)
X#   else
X      kdflt.key_direction = KD_DFLTGET;
X      if (ioctl(ttyfd,KDDFLTKEYMAP,&kdflt) < 0)
X#   endif
X    {
X      perror("get keymap");
X      exit(1);
X    }
X  }
X
X  if (dos & do_CLEAR)
X  {
X    if (opts & opt_VERBOSE)
X      fprintf(stderr,"clearing map\n");
X
X    kmap_clear(&kmap);
X  }
X
X  if (dos & do_LOAD)
X  {
X
X    for (keypaths, keycount; keycount != 0; keypaths++, --keycount)
X    {
X      FILE			*keys;
X      char			*keypath = *keypaths;
X
X      if (strcmp(keypath,"-") == 0)
X	keys = stdin, keypath = "<stdin>";
X      else if ((keys = fopen(keypath,"r")) == 0)
X      {
X	perror(keypath);
X        failed = 1; 
X      }
X      else
X      {
X        if (opts & opt_VERBOSE)
X	  fprintf(stderr,"loading from '%s'\n",keypath);
X
X	failed |= !kmap_load((dos&do_CLEAR) ? 'Z' : 0,&kmap,keys,keypath);
X
X	if (keys != stdin)
X	  fclose(keys);
X      }
X    }
X  }
X
X  if (dos & do_META)
X  {
X    if (opts & opt_VERBOSE)
X      fprintf(stderr,"metaizing\n");
X
X    metaize(&kmap);
X  }
X
X  if (!failed && (dos & do_PUT))
X  {
X    if (opts & opt_VERBOSE)
X      fprintf(stderr,"putting map to fd %d\n",ttyfd);
X
X#   if (!defined KDDFLTKEYMAP)
X      if (ioctl(ttyfd,PIO_KEYMAP,&kmap) < 0)
X#   else
X      kdflt.key_direction = KD_DFLTSET;
X      if (ioctl(ttyfd,KDDFLTKEYMAP,&kdflt) < 0)
X#   endif
X    {
X      perror("put keymap");
X      exit(1);
X    }
X  }
X
X  if (dos & do_DUMP)
X  {
X    if (opts & opt_VERBOSE)
X      fprintf(stderr,"dumping\n");
X
X    kmap_dump(&kmap,opts & opt_DUMP);
X  }
X
X  return failed;
X}
END_OF_FILE
if test 18179 -ne `wc -c <'mapkbd.c'`; then
    echo shar: \"'mapkbd.c'\" unpacked with wrong size!
fi
# end of 'mapkbd.c'
fi
if test -f 'ukd-meta.kbd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ukd-meta.kbd'\"
else
echo shar: Extracting \"'ukd-meta.kbd'\" \(271 characters\)
sed "s/^X//" >'ukd-meta.kbd' <<'END_OF_FILE'
X# Rebindings for UK keyboard
X
X3	'2'	'"'	nop	nop	0xb2	0xa2	nop	nop	O
X4	'3'	0x9c	nop	nop	0xb3	'#'	nop	nop	O
X40	'\''	'@'	nul	nul	0xa7	0xc0	0x80	0x80	O
X41	'`'	0xaa	nul	nul	0xe0	0xfe	0x80	0x80	O
X43	'#'	'~'	nul	nul	0xa3	0xfe	0x80	0x80	O
X86	'\\'	'|'	fs	fs	0xdc	0xfc	0x9c	0x9c	O
END_OF_FILE
if test 271 -ne `wc -c <'ukd-meta.kbd'`; then
    echo shar: \"'ukd-meta.kbd'\" unpacked with wrong size!
fi
# end of 'ukd-meta.kbd'
fi
if test -f 'usa-meta.kbd' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'usa-meta.kbd'\"
else
echo shar: Extracting \"'usa-meta.kbd'\" \(5742 characters\)
sed "s/^X//" >'usa-meta.kbd' <<'END_OF_FILE'
X# USA keys. ALT is used as a META key (code|0x80) and CTRL as a
X# CTL key (code&0x1f). We tend to leave undefine CTRL version of keys
X# that don't have a reasonable interpretation, but purely for
X# convenience we often have that SHIFT is allowed and gives the same
X# code a without the SHIFT.
X#
X#code	key	S	C	CS	M	MS	MC	MCS	LCK
X#
X0	nop	nop	nop	nop	nop	nop	nop	nop	O
X1	esc	esc	sysreq	nop	0x9b	0x9b	nop	nop	O
X2	'1'	'!'	nop	nop	0xb1	0xa1	nop	nop	O
X3	'2'	'@'	nul	nul	0xb2	0xc0	0x80	0x80	O
X4	'3'	'#'	nop	nop	0xb3	0xa3	nop	nop	O
X5	'4'	'$'	nop	nop	0xb4	0xa4	nop	nop	O
X6	'5'	'%'	nop	nop	0xb5	0xa5	nop	nop	O
X7	'6'	'^'	rs	rs	0xb6	0xde	0x9e	0x9e	O
X8	'7'	'&'	nop	nop	0xb7	0xa6	nop	nop	O
X9	'8'	'*'	nop	nop	0xb8	0xaa	nop	nop	O
X10	'9'	'('	nop	nop	0xb9	0xa8	nop	nop	O
X11	'0'	')'	nop	nop	0xb0	0xa9	nop	nop	O
X12	'-'	'_'	ns	ns	0xad	0xdf	0x9f	0x9f	O
X13	'='	'+'	nop	nop	0xbd	0xab	nop	nop	O
X14	bs	bs	nop	nop	0x88	0x88	nop	nop	O
X15	ht	gs	nop	nop	0x89	0x9d	nop	nop	O
X16	'q'	'Q'	dc1	dc1	0xf1	0xd1	0x91	0x91	C
X17	'w'	'W'	etb	etb	0xf7	0xd7	0x97	0x97	C
X18	'e'	'E'	enq	enq	0xe5	0xc5	0x85	0x85	C
X19	'r'	'R'	dc2	dc2	0xf2	0xd2	0x92	0x92	C
X20	't'	'T'	dc4	dc4	0xf4	0xd4	0x94	0x94	C
X21	'y'	'Y'	em	em	0xf9	0xd9	0x99	0x99	C
X22	'u'	'U'	nak	nak	0xf5	0xd5	0x95	0x95	C
X23	'i'	'I'	ht	ht	0xe9	0xc9	0x89	0x89	C
X24	'o'	'O'	si	si	0xef	0xcf	0x8f	0x8f	C
X25	'p'	'P'	dle	dle	0xf0	0xd0	0x90	0x90	C
X26	'['	'{'	esc	esc	0xdb	0xfb	0x9b	0x9b	O
X27	']'	'}'	gs	gs	0xdd	0xfd	0x9d	0x9d	O
X28	cr	cr	nop	nop	0x8d	0x8d	nop	nop	O
X29	lctrl	lctrl	lctrl	lctrl	lctrl	lctrl	lctrl	lctrl	O
X30	'a'	'A'	soh	soh	0xe1	0xc1	0x81	0x81	C
X31	's'	'S'	dc3	dc3	0xf3	0xd3	0x93	0x93	C
X32	'd'	'D'	eot	eot	0xe4	0xc4	debug	0x84	C
X33	'f'	'F'	ack	ack	0xe6	0xc6	0x86	0x87	C
X34	'g'	'G'	bel	bel	0xe7	0xc7	0x87	0x87	C
X35	'h'	'H'	bs	bs	0xe8	0xc8	0x88	0x88	C
X36	'j'	'J'	nl	nl	0xea	0xca	0x8a	0x8a	C
X37	'k'	'K'	vt	vt	0xeb	0xcb	0x8b	0x8b	C
X38	'l'	'L'	np	np	0xec	0xcc	0x8c	0x8c	C
X39	';'	':'	nop	nop	0xbb	0xba	nop	nop	O
X40	'\''	'"'	nop	nop	0xa7	0xa2	nop	nop	O
X41	'`'	'~'	nul	nul	0xe0	0xfe	0x80	0x80	O
X42	lshift	lshift	lshift	lshift	lshift	lshift	lshift	lshift	O
X43	'\\'	'|'	fs	fs	0xdc	0xfc	0x9c	0x9c	O
X44	'z'	'Z'	sub	sub	0xfa	0xda	0x9a	0x9a	C
X45	'x'	'X'	can	can	0xf8	0xd8	0x98	0x98	C
X46	'c'	'C'	etx	etx	0xe3	0xc3	0x83	0x83	C
X47	'v'	'V'	syn	syn	0xf6	0xd6	0x96	0x96	C
X48	'b'	'B'	stx	stx	0xe2	0xc2	0x82	0x82	C
X49	'n'	'N'	so	so	0xee	0xce	0x8e	0x8e	C
X50	'm'	'M'	cr	cr	0xed	0xcd	0x8d	0x8d	C
X51	','	'<'	nop	nop	0xac	0xbc	nop	nop	O
X52	'.'	'>'	nop	nop	0xae	0xbe	nop	nop	O
X53	'/'	'?'	ns	del	0xaf	0xbf	0x9f	0xff	O
X54	rshift	rshift	rshift	rshift	rshift	rshift	rshift	rshift	O
X55	'*'	'*'	nop	nop	0xaa	0xaa	nop	nop	O
X56	lalt	lalt	lalt	lalt	lalt	lalt	lalt	lalt	O
X57	0x20	0x20	nul	nul	0xa0	0xa0	0x80	0x80	O
X58	clock	clock	clock	clock	clock	clock	clock	clock	O
X59	fkey00	fkey12	fkey24	fkey36	nop	nop	nop	nop	O
X60	fkey01	fkey13	fkey25	fkey37	nop	nop	nop	nop	O
X61	fkey02	fkey14	fkey26	fkey38	nop	nop	nop	nop	O
X62	fkey03	fkey15	fkey27	fkey39	nop	nop	nop	nop	O
X63	fkey04	fkey16	fkey28	fkey40	nop	nop	nop	nop	O
X64	fkey05	fkey17	fkey29	fkey41	nop	nop	nop	nop	O
X65	fkey06	fkey18	fkey30	fkey42	nop	nop	nop	nop	O
X66	fkey07	fkey19	fkey31	fkey43	nop	nop	nop	nop	O
X67	fkey08	fkey20	fkey32	fkey44	nop	nop	nop	nop	O
X68	fkey09	fkey21	fkey33	fkey45	nop	nop	nop	nop	O
X69	nlock	nlock	nlock	nlock	nlock	nlock	nlock	nlock	O
X70	slock	slock	break	break	break	break	nop	nop	O
X71	fkey48	'7'	nop	nop	scr07	0xb7	scr17	nop	N
X72	fkey49	'8'	nop	nop	scr08	0xb8	scr18	nop	N
X73	fkey50	'9'	nop	nop	scr09	0xb9	scr19	nop	N
X74	fkey51	'-'	nop	nop	nop	0xad	nop	nop	N
X75	fkey52	'4'	nop	nop	scr04	0xb4	scr14	nop	N
X76	fkey53	'5'	nop	nop	scr05	0xb5	scr15	nop	N
X77	fkey54	'6'	nop	nop	scr06	0xb6	scr16	nop	N
X78	fkey55	'+'	nop	nop	nop	0xab	nop	nop	N
X79	fkey56	'1'	nop	nop	scr01	0xb1	scr11	nop	N
X80	fkey57	'2'	nop	nop	scr02	0xb2	scr12	nop	N
X81	fkey58	'3'	nop	nop	scr03	0xb3	scr13	nop	N
X82	fkey59	'0'	nop	nop	scr00	0xb0	scr10	nop	N
X83	del	'.'	nop	nop	0xff	0xae	reboot	nop	N
X84	fkey59	fkey25	sysreq	sysreq	sysreq	sysreq	nop	nop	O
X85	fkey57	fkey57	nop	nop	scr00	scr00	nop	nop	O
X86	fkey52	fkey52	nop	nop	nop	nop	nop	nop	O
X87	fkey10	fkey22	fkey34	fkey46	scr10	scr22	scr34	scr46	O
X88	fkey11	fkey23	fkey35	fkey47	scr11	scr23	scr35	scr47	O
X89	nop	nop	nop	nop	nop	nop	nop	nop	O
X90	nop	nop	nop	nop	nop	nop	nop	nop	O
X91	nop	nop	nop	nop	nop	nop	nop	nop	O
X92	nop	nop	nop	nop	nop	nop	nop	nop	O
X93	nop	nop	nop	nop	nop	nop	nop	nop	O
X94	nop	nop	nop	nop	nop	nop	nop	nop	O
X95	nop	nop	nop	nop	nop	nop	nop	nop	O
X96	nop	nop	nop	nop	nop	nop	nop	nop	O
X97	nop	nop	nop	nop	nop	nop	nop	nop	O
X98	nop	nop	nop	nop	nop	nop	nop	nop	O
X99	nop	nop	nop	nop	nop	nop	nop	nop	O
X100	nop	nop	nop	nop	nop	nop	nop	nop	O
X101	nop	nop	nop	nop	nop	nop	nop	nop	O
X102	nop	nop	nop	nop	nop	nop	nop	nop	O
X103	nop	nop	nop	nop	nop	nop	nop	nop	O
X104	nop	nop	nop	nop	nop	nop	nop	nop	O
X105	nop	nop	nop	nop	nop	nop	nop	nop	O
X106	nop	nop	nop	nop	nop	nop	nop	nop	O
X107	fkey52	fkey52	nop	nop	pscr	fpscrn	nop	nop	O
X108	nop	nop	nop	nop	nop	nop	nop	nop	O
X109	nop	nop	nop	nop	nop	nop	nop	nop	O
X110	nop	nop	nop	nop	nop	nop	nop	nop	O
X111	fkey50	fkey50	nop	nop	nop	nop	nop	nop	O
X112	nop	nop	nop	nop	nop	nop	nop	nop	O
X113	nop	nop	nop	nop	nop	nop	nop	nop	O
X114	ralt	ralt	ralt	ralt	ralt	ralt	ralt	ralt	O
X115	rctrl	rctrl	rctrl	rctrl	rctrl	rctrl	rctrl	rctrl	O
X116	nl	nl	nop	nop	0x8a	0x8a	nop	nop	O
X117	'/'	'/'	nop	nop	0xaf	0xaf	nop	nop	O
X118	nop	nop	nop	nop	nop	nop	nop	nop	O
X119	break	break	break	break	break	break	break	break	O
X120	fkey49	fkey49	nop	nop	scr00	scr00	nop	nop	O
X121	del	del	nop	nop	0xff	0xff	nop	nop	O
X122	fkey56	fkey56	nop	nop	nop	nop	nop	nop	O
X123	fkey59	fkey59	nop	nop	nop	nop	nop	nop	O
X124	nop	nop	nop	nop	nop	nop	nop	nop	O
X125	fkey54	fkey54	nop	nop	nscr	fnscrn	nop	nop	O
X126	fkey58	fkey58	nop	nop	nop	nop	nop	nop	O
X127	fkey48	fkey48	nop	nop	nop	nop	nop	nop	O
END_OF_FILE
if test 5742 -ne `wc -c <'usa-meta.kbd'`; then
    echo shar: \"'usa-meta.kbd'\" unpacked with wrong size!
fi
# end of 'usa-meta.kbd'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
--
Piercarlo Grandi                   | ARPA: pcg%uk.ac.aber@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@aber.ac.uk