Print this page
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    9259 libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Revert "NEX-16819 loader UEFI support"
This reverts commit ec06b9fc617b99234e538bf2e7e4d02a24993e0c.
Reverting due to failures in the zfs-tests and the sharefs-tests
NEX-16819 loader UEFI support
Includes work by Toomas Soome <tsoome@me.com>
Upstream commits:
    loader: pxe receive cleanup
    9475 libefi: Do not return only if ReceiveFilter
    installboot: should support efi system partition
    8931 boot1.efi: scan all display modes rather than
    loader: spinconsole updates
    loader: gfx experiment to try GOP Blt() function.
    sha1 build test
    loader: add sha1 hash calculation
    common/sha1: update for loader build
    loader: biosdisk rework
    uts: 32-bit kernel FB needs mapping in low memory
    uts: add diag-device
    uts: boot console mirror with diag-device
    uts: enable very early console on ttya
    kmdb: add diag-device as input/output device
    uts: test VGA memory exclusion from mapping
    uts: clear boot mapping and protect boot pages test
    uts: add dboot map debug printf
    uts: need to release FB pages in release_bootstrap()
    uts: add screenmap ioctl
    uts: update sys/queue.h
    loader: add illumos uts/common to include path
    loader: tem/gfx font cleanup
    loader: vbe checks
    uts: gfx_private set KD_TEXT when KD_RESETTEXT is
    uts: gfx 8-bit update
    loader: gfx 8-bit fix
    loader: always set media size from partition.
    uts: MB2 support for 32-bit kernel
    loader: x86 should have tem 80x25
    uts: x86 should have tem 80x25
    uts: font update
    loader: font update
    uts: tem attributes
    loader: tem.c comment added
    uts: use font module
    loader: add font module
    loader: build rules for new font setup
    uts: gfx_private update for new font structure
    uts: early boot update for new font structure
    uts: font update
    uts: font build rules update for new fonts
    uts: tem update to new font structure
    loader: module.c needs to include tem_impl.h
    uts: gfx_private 8x16 font rework
    uts: make font_lookup public
    loader: font rework
    uts: font rework
    libefi: efi_alloc_and_read should check for PMBR
    uts: tem utf-8 support
    loader: implement tem utf-8 support
    loader: tem should be able to display UTF-8
    7784 uts: console input should support utf-8
    7796 uts: ldterm default to utf-8
    uts: do not reset serial console
    uts: set up colors even if tem is not console
    uts: add type for early boot properties
    uts: gfx_private experiment with drm and vga
    uts: gfx_private should use setmode drm callback.
    uts: identify FB types and set up gfx_private based
    loader: replace gop and vesa with framebuffer
    uts: boot needs simple tem to support mdb
    uts: boot_keyboard should emit esc sequences for
    uts: gfx_private FB showuld be written by line
    kmdb: set terminal window size
    uts: gfx_private needs to keep track of early boot FB
    pnglite: move pnglite to usr/src/common
    loader: gfx_fb
    ficl-sys: add gfx primitives
    loader: add illumos.png logo
    ficl: add fb-putimage
    loader: add png support
    loader: add alpha blending for gfx_fb
    loader: use term-drawrect for menu frame
    ficl: add simple gfx words
    uts: provide fb_info via fbgattr dev_specific array.
    uts: gfx_private add alpha blending
    uts: update sys/ascii.h
    uts: tem OSC support (incomplete)
    uts: implement env module support and use data from
    uts: tem get colors from early boot data
    loader: use crc32 from libstand (libz)
    loader: optimize for size
    loader: pass tem info to the environment
    loader: import tem for loader console
    loader: UEFI loader needs to set ISADIR based on
    loader: need UEFI32 support
    8918 loader.efi: add vesa edid support
    uts: tem_safe_pix_clear_prom_output() should only
    uts: tem_safe_pix_clear_entire_screen() should use
    uts: tem_safe_check_first_time() should query cursor
    uts: tem implement cls callback & visual_io v4
    uts: gfx_vgatext use block cursor for vgatext
    uts: gfx_private implement cls callback & visual_io
    uts: gfx_private bitmap framebuffer implementation
    uts: early start frame buffer console support
    uts: font functions should check the input char
    uts: font rendering should support 16/24/32bit depths
    uts: use smallest font as fallback default.
    uts: update terminal dimensions based on selected
    7834 uts: vgatext should use gfx_private
    uts: add spacing property to 8859-1.bdf
    terminfo: add underline for sun-color
    terminfo: sun-color has 16 colors
    uts: add font load callback type
    loader: do not repeat int13 calls with error 0x20 and
    8905 loader: add skein/edonr support
    8904 common/crypto: make skein and edonr loader
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>


   4  *
   5  * The contents of this file are subject to the terms of the
   6  * Common Development and Distribution License, Version 1.0 only
   7  * (the "License").  You may not use this file except in compliance
   8  * with the License.
   9  *
  10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  11  * or http://www.opensolaris.org/os/licensing.
  12  * See the License for the specific language governing permissions
  13  * and limitations under the License.
  14  *
  15  * When distributing Covered Code, include this CDDL HEADER in each
  16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  17  * If applicable, add the following below this CDDL HEADER, with the
  18  * fields enclosed by brackets "[]" replaced with your own identifying
  19  * information: Portions Copyright [yyyy] [name of copyright owner]
  20  *
  21  * CDDL HEADER END
  22  */
  23 
  24 #ifndef lint
  25 #pragma ident   "%Z%%M% %I%     %E% SMI"
  26 #endif
  27 
  28 /*
  29  * Copyright (c) 1999 by Sun Microsystems, Inc.
  30  * All rights reserved.
  31  */
  32 
  33 #include <sys/param.h>
  34 #include <ctype.h>
  35 #include <stdio.h>
  36 #include <search.h>
  37 #include <string.h>
  38 #include <malloc.h>
  39 #include <fcntl.h>
  40 #include <stdlib.h>
  41 #include <errno.h>
  42 #include <unistd.h>
  43 #include <sys/kbd.h>
  44 #include <sys/kbio.h>
  45 
  46 #define ALL     -1      /* special symbol for all tables */
  47 
  48 /*
  49  * SunOS 4.x and Solaris 2.[1234] put Type 4 key tables into
  50  * the keytables directory with no type qualification.
  51  * If we're a SPARC, we might be using an NFS server that
  52  * doesn't have the new type-qualified directories.
  53  * (loadkeys wasn't used on non-SPARCs in 2.[1234].)
  54  */
  55 #ifdef  sparc
  56 #define COMPATIBILITY_DIR
  57 #endif
  58 
  59 static char     keytable_dir[] = "/usr/share/lib/keytables/type_%d/";
  60 #ifdef  COMPATIBILITY_DIR
  61 static char     keytable_dir2[] = "/usr/share/lib/keytables/";
  62 #endif
  63 static char     layout_prefix[] = "layout_";
  64 
  65 struct keyentry {
  66         struct keyentry *ke_next;
  67         struct kiockeymap ke_entry;
  68 };
  69 
  70 typedef struct keyentry keyentry;
  71 
  72 static keyentry *firstentry;
  73 static keyentry *lastentry;
  74 
  75 struct dupentry {
  76         struct dupentry *de_next;
  77         int     de_station;
  78         int     de_otherstation;
  79 };
  80 
  81 typedef struct dupentry dupentry;
  82 


 115 
 116 static  smentry_t shiftmasks[] = {
 117         { 0,            SM_NORMAL },
 118         { SHIFTMASK,    SM_NORMAL },
 119         { CAPSMASK,     SM_NORMAL },
 120         { CTRLMASK,     SM_NORMAL },
 121         { ALTGRAPHMASK, SM_NORMAL },
 122         { NUMLOCKMASK,  SM_NUMLOCK },
 123         { UPMASK,       SM_UP },
 124 };
 125 
 126 
 127 #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0]))
 128 
 129 static void     enter_mapentry(int station, keyentry *entrylistp);
 130 static keyentry *makeentry(int tablemask, int entry);
 131 static int      loadkey(int kbdfd, keyentry *kep);
 132 static int      dupkey(int kbdfd, dupentry *dep, int shiftmask);
 133 static int      swapkey(int kbdfd, dupentry *dep, int shiftmask);
 134 static int      yylex();

 135 static int      readesc(FILE *stream, int delim, int single_char);
 136 static int      wordcmp(const void *w1, const void *w2);
 137 static int      yyerror(char *msg);
 138 static void     usage(void);
 139 static void     set_layout(char *arg);
 140 static FILE     *open_mapping_file(char *pathbuf, char *name,
 141                         boolean_t explicit_name, int type);
 142 
 143 int
 144 main(argc, argv)
 145         int argc;
 146         char **argv;
 147 {
 148         register int kbdfd;
 149         int type;
 150         int layout;
 151         /* maxint is 8 hex digits. */
 152         char layout_filename[sizeof(layout_prefix)+8];
 153         char pathbuf[MAXPATHLEN];
 154         register int shift;
 155         struct kiockeymap mapentry;
 156         register keyentry *kep;
 157         register dupentry *dep;
 158         boolean_t explicit_name;
 159 
 160         while(++argv, --argc) {
 161                 if(argv[0][0] != '-') break;
 162                 switch(argv[0][1]) {
 163                 case 'e':
 164                         /* -e obsolete, silently ignore */
 165                         break;
 166                 case 's':
 167                         if (argc != 2) {
 168                                 usage();
 169                                 /* NOTREACHED */
 170                         }
 171                         set_layout(argv[1]);
 172                         exit(0);
 173                 default:
 174                         usage();
 175                         /* NOTREACHED */
 176                 }
 177         }


 316         }
 317 
 318         if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
 319                 perror("/dev/kbd");
 320                 exit(1);
 321         }
 322 
 323         ret = ioctl(kbdfd, KIOCSLAYOUT, layout);
 324         if (ret == -1) {
 325                 perror("KIOCSLAYOUT");
 326         }
 327 
 328         close(kbdfd);
 329 }
 330 
 331 /*
 332  * Attempt to find the specified mapping file.  Return a FILE * if found,
 333  * else print a message on stderr and return NULL.
 334  */
 335 FILE *
 336 open_mapping_file(
 337         char *pathbuf,
 338         char *name,
 339         boolean_t explicit_name,
 340         int type
 341 ) {
 342         /* If the user specified the name, try it "raw". */
 343         if (explicit_name) {
 344                 strcpy(pathbuf, name);
 345                 infile = fopen(pathbuf, "r");
 346                 if (infile) return (infile);
 347                 if (errno != ENOENT) goto fopen_fail;
 348         }
 349 
 350         /* Everything after this point applies only to relative names. */
 351         if (*name == '/') goto fopen_fail;
 352 
 353         /* Try the type-qualified directory name. */
 354         sprintf(pathbuf, keytable_dir, type);
 355         if ((int)(strlen(pathbuf) + strlen(name) + 1) >= MAXPATHLEN) {
 356                 (void) fprintf(stderr, "loadkeys: Name %s is too long\n",
 357                                 name);
 358                 return (NULL);
 359         }
 360         (void) strcat(pathbuf, name);
 361         infile = fopen(pathbuf, "r");
 362         if (infile) return (infile);
 363         if (errno != ENOENT) goto fopen_fail;
 364 
 365 #ifdef  COMPATIBILITY_DIR
 366         /* If not, and either the name was specified explicitly */
 367         /*     or this is a type 4... */
 368         if (explicit_name || type == KB_SUN4) {
 369                 /* Try the compatibility name. */
 370                 /* No need to check len here, it's shorter. */
 371                 (void) strcpy(pathbuf, keytable_dir2);
 372                 (void) strcat(pathbuf, infilename);
 373                 infile = fopen(pathbuf, "r");
 374                 if (infile) return (infile);
 375                 if (errno != ENOENT) goto fopen_fail;
 376         }
 377 #endif
 378 
 379 fopen_fail:
 380         (void) fprintf(stderr, "loadkeys: ");
 381         perror(name);
 382         return (NULL);
 383 }
 384 
 385 /*
 386  * We have a list of entries for a given keystation, and the keystation number
 387  * for that keystation; put that keystation number into all the entries in that
 388  * list, and chain that list to the end of the main list of entries.
 389  */
 390 static void
 391 enter_mapentry(station, entrylistp)
 392         int station;
 393         keyentry *entrylistp;
 394 {
 395         register keyentry *kep;
 396 
 397         if (lastentry == NULL)
 398                 firstentry = entrylistp;


 408                 kep = kep->ke_next;
 409         }
 410 }
 411 
 412 /*
 413  * Allocate and fill in a new entry.
 414  */
 415 static keyentry *
 416 makeentry(tablemask, entry)
 417         int tablemask;
 418         int entry;
 419 {
 420         register keyentry *kep;
 421         register int index;
 422 
 423         if ((kep = (keyentry *) malloc((unsigned)sizeof (keyentry))) == NULL)
 424                 yyerror("out of memory for entries");
 425         kep->ke_next = NULL;
 426         kep->ke_entry.kio_tablemask = tablemask;
 427         kep->ke_entry.kio_station = 0;
 428         kep->ke_entry.kio_entry = (u_short)entry;
 429         index = entry - STRING;
 430         if (index >= 0 && index <= 15)
 431                 (void) strncpy(kep->ke_entry.kio_string, strings[index],
 432                     KTAB_STRLEN);
 433         return (kep);
 434 }
 435 
 436 /*
 437  * Make a set of entries for a keystation that indicate that that keystation's
 438  * settings should be copied from another keystation's settings.
 439  */
 440 static void
 441 duplicate_mapentry(station, otherstation)
 442         int station;
 443         int otherstation;
 444 {
 445         register dupentry *dep;
 446 
 447         if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL)
 448                 yyerror("out of memory for entries");


 607                 $$ = $1;
 608                 }
 609 ;
 610 
 611 entry:
 612         TABLENAME code
 613                 {
 614                 $$ = makeentry($1, $2);
 615                 }
 616 ;
 617 
 618 code:
 619         CHARSTRING
 620                 {
 621                 $$ = $1;
 622                 }
 623 |       CHAR
 624                 {
 625                 $$ = $1;
 626                 }




 627 |       '('
 628                 {
 629                 $$ = '(';
 630                 }
 631 |       ')'
 632                 {
 633                 $$ = ')';
 634                 }
 635 |       '+'
 636                 {
 637                 $$ = '+';
 638                 }
 639 |       expr
 640                 {
 641                 $$ = $1;
 642                 }
 643 ;
 644 
 645 expr:
 646         term


 690 
 691 /*
 692  * Table must be in alphabetical order.
 693  */
 694 word_t  wordtab[] = {
 695         { "all",        TABLENAME,      ALL },
 696         { "alt",        CONSTANT,       ALT },
 697         { "altg",       TABLENAME,      ALTGRAPHMASK },
 698         { "altgraph",   CONSTANT,       ALTGRAPH },
 699         { "as",         AS,             0 },
 700         { "base",       TABLENAME,      0 },
 701         { "bf",         FKEY,           BOTTOMFUNC },
 702         { "buckybits",  CONSTANT,       BUCKYBITS },
 703         { "caps",       TABLENAME,      CAPSMASK },
 704         { "capslock",   CONSTANT,       CAPSLOCK },
 705         { "compose",    CONSTANT,       COMPOSE },
 706         { "ctrl",       TABLENAME,      CTRLMASK },
 707         { "downarrow",  CONSTANT,       DOWNARROW },
 708         { "error",      CONSTANT,       ERROR },
 709         { "fa_acute",   CONSTANT,       FA_ACUTE },



 710         { "fa_cedilla", CONSTANT,       FA_CEDILLA },
 711         { "fa_cflex",   CONSTANT,       FA_CFLEX },


 712         { "fa_grave",   CONSTANT,       FA_GRAVE },




 713         { "fa_tilde",   CONSTANT,       FA_TILDE },
 714         { "fa_umlaut",  CONSTANT,       FA_UMLAUT },
 715         { "hole",       CONSTANT,       HOLE },
 716         { "homearrow",  CONSTANT,       HOMEARROW },
 717         { "idle",       CONSTANT,       IDLE },
 718         { "key",        KEY,            0 },
 719         { "leftarrow",  CONSTANT,       LEFTARROW },
 720         { "leftctrl",   CONSTANT,       LEFTCTRL },
 721         { "leftshift",  CONSTANT,       LEFTSHIFT },
 722         { "lf",         FKEY,           LEFTFUNC },
 723         { "metabit",    CONSTANT,       METABIT },
 724         { "nonl",       CONSTANT,       NONL },
 725         { "nop",        CONSTANT,       NOP },
 726         { "numl",       TABLENAME,      NUMLOCKMASK },
 727         { "numlock",    CONSTANT,       NUMLOCK },
 728         { "oops",       CONSTANT,       OOPS },
 729         { "pad0",       CONSTANT,       PAD0 },
 730         { "pad1",       CONSTANT,       PAD1 },
 731         { "pad2",       CONSTANT,       PAD2 },
 732         { "pad3",       CONSTANT,       PAD3 },


 893                 } else if (strlen(tokbuf) == 2 && tokbuf[0] == '^') {
 894                         tokentype = CHAR;
 895                         yylval.number = (unsigned char)(tokbuf[1] & 037);
 896                 } else {
 897                         word_t word;
 898                         register word_t *wptr;
 899                         char *ptr;
 900 
 901                         for (cp = &tokbuf[0]; (c = *cp) != '\0'; cp++) {
 902                                 if (isupper(c))
 903                                         *cp = tolower(c);
 904                         }
 905                         word.w_string = tokbuf;
 906                         wptr = (word_t *)bsearch((char *)&word,
 907                             (char *)wordtab, NWORDS, sizeof (word_t),
 908                             wordcmp);
 909                         if (wptr != NULL) {
 910                                 yylval.number = wptr->w_lval;
 911                                 tokentype = wptr->w_type;
 912                         } else {
 913                                 yylval.number = strtol(tokbuf, &ptr, 10);
 914                                 if (ptr == tokbuf)
 915                                         yyerror("syntax error");
 916                                 else
 917                                         tokentype = INT;
 918                         }
 919                         break;
 920                 }
 921         }
 922 
 923         return (tokentype);
 924 }
 925 
 926 static int
 927 readesc(stream, delim, single_char)
 928         FILE *stream;
 929         int delim;
 930         int single_char;
 931 {
 932         register int c;
 933         register int val;




   4  *
   5  * The contents of this file are subject to the terms of the
   6  * Common Development and Distribution License, Version 1.0 only
   7  * (the "License").  You may not use this file except in compliance
   8  * with the License.
   9  *
  10  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  11  * or http://www.opensolaris.org/os/licensing.
  12  * See the License for the specific language governing permissions
  13  * and limitations under the License.
  14  *
  15  * When distributing Covered Code, include this CDDL HEADER in each
  16  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  17  * If applicable, add the following below this CDDL HEADER, with the
  18  * fields enclosed by brackets "[]" replaced with your own identifying
  19  * information: Portions Copyright [yyyy] [name of copyright owner]
  20  *
  21  * CDDL HEADER END
  22  */
  23 




  24 /*
  25  * Copyright (c) 1999 by Sun Microsystems, Inc.
  26  * All rights reserved.
  27  */
  28 
  29 #include <sys/param.h>
  30 #include <ctype.h>
  31 #include <stdio.h>
  32 #include <search.h>
  33 #include <string.h>
  34 #include <malloc.h>
  35 #include <fcntl.h>
  36 #include <stdlib.h>
  37 #include <errno.h>
  38 #include <unistd.h>
  39 #include <sys/kbd.h>
  40 #include <sys/kbio.h>
  41 
  42 #define ALL     -1      /* special symbol for all tables */
  43 











  44 static char     keytable_dir[] = "/usr/share/lib/keytables/type_%d/";



  45 static char     layout_prefix[] = "layout_";
  46 
  47 struct keyentry {
  48         struct keyentry *ke_next;
  49         struct kiockeymap ke_entry;
  50 };
  51 
  52 typedef struct keyentry keyentry;
  53 
  54 static keyentry *firstentry;
  55 static keyentry *lastentry;
  56 
  57 struct dupentry {
  58         struct dupentry *de_next;
  59         int     de_station;
  60         int     de_otherstation;
  61 };
  62 
  63 typedef struct dupentry dupentry;
  64 


  97 
  98 static  smentry_t shiftmasks[] = {
  99         { 0,            SM_NORMAL },
 100         { SHIFTMASK,    SM_NORMAL },
 101         { CAPSMASK,     SM_NORMAL },
 102         { CTRLMASK,     SM_NORMAL },
 103         { ALTGRAPHMASK, SM_NORMAL },
 104         { NUMLOCKMASK,  SM_NUMLOCK },
 105         { UPMASK,       SM_UP },
 106 };
 107 
 108 
 109 #define NSHIFTS (sizeof (shiftmasks) / sizeof (shiftmasks[0]))
 110 
 111 static void     enter_mapentry(int station, keyentry *entrylistp);
 112 static keyentry *makeentry(int tablemask, int entry);
 113 static int      loadkey(int kbdfd, keyentry *kep);
 114 static int      dupkey(int kbdfd, dupentry *dep, int shiftmask);
 115 static int      swapkey(int kbdfd, dupentry *dep, int shiftmask);
 116 static int      yylex();
 117 extern int      yyparse(void);
 118 static int      readesc(FILE *stream, int delim, int single_char);
 119 static int      wordcmp(const void *w1, const void *w2);
 120 static int      yyerror(char *msg);
 121 static void     usage(void);
 122 static void     set_layout(char *arg);
 123 static FILE     *open_mapping_file(char *pathbuf, char *name,
 124                         boolean_t explicit_name, int type);
 125 
 126 int
 127 main(int argc, char **argv)


 128 {
 129         int kbdfd;
 130         int type;
 131         int layout;
 132         /* maxint is 8 hex digits. */
 133         char layout_filename[sizeof(layout_prefix)+8];
 134         char pathbuf[MAXPATHLEN];
 135         int shift;
 136         struct kiockeymap mapentry;
 137         keyentry *kep;
 138         dupentry *dep;
 139         boolean_t explicit_name;
 140 
 141         while(++argv, --argc) {
 142                 if(argv[0][0] != '-') break;
 143                 switch(argv[0][1]) {
 144                 case 'e':
 145                         /* -e obsolete, silently ignore */
 146                         break;
 147                 case 's':
 148                         if (argc != 2) {
 149                                 usage();
 150                                 /* NOTREACHED */
 151                         }
 152                         set_layout(argv[1]);
 153                         exit(0);
 154                 default:
 155                         usage();
 156                         /* NOTREACHED */
 157                 }
 158         }


 297         }
 298 
 299         if ((kbdfd = open("/dev/kbd", O_WRONLY)) < 0) {
 300                 perror("/dev/kbd");
 301                 exit(1);
 302         }
 303 
 304         ret = ioctl(kbdfd, KIOCSLAYOUT, layout);
 305         if (ret == -1) {
 306                 perror("KIOCSLAYOUT");
 307         }
 308 
 309         close(kbdfd);
 310 }
 311 
 312 /*
 313  * Attempt to find the specified mapping file.  Return a FILE * if found,
 314  * else print a message on stderr and return NULL.
 315  */
 316 FILE *
 317 open_mapping_file(char *pathbuf, char *name, boolean_t explicit_name, int type)
 318 {




 319         /* If the user specified the name, try it "raw". */
 320         if (explicit_name) {
 321                 strcpy(pathbuf, name);
 322                 infile = fopen(pathbuf, "r");
 323                 if (infile) return (infile);
 324                 if (errno != ENOENT) goto fopen_fail;
 325         }
 326 
 327         /* Everything after this point applies only to relative names. */
 328         if (*name == '/') goto fopen_fail;
 329 
 330         /* Try the type-qualified directory name. */
 331         sprintf(pathbuf, keytable_dir, type);
 332         if ((int)(strlen(pathbuf) + strlen(name) + 1) >= MAXPATHLEN) {
 333                 (void) fprintf(stderr, "loadkeys: Name %s is too long\n",
 334                                 name);
 335                 return (NULL);
 336         }
 337         (void) strcat(pathbuf, name);
 338         if ((infile = fopen(pathbuf, "r")) != NULL)
 339                 return (infile);

 340 














 341 fopen_fail:
 342         (void) fprintf(stderr, "loadkeys: ");
 343         perror(name);
 344         return (NULL);
 345 }
 346 
 347 /*
 348  * We have a list of entries for a given keystation, and the keystation number
 349  * for that keystation; put that keystation number into all the entries in that
 350  * list, and chain that list to the end of the main list of entries.
 351  */
 352 static void
 353 enter_mapentry(station, entrylistp)
 354         int station;
 355         keyentry *entrylistp;
 356 {
 357         register keyentry *kep;
 358 
 359         if (lastentry == NULL)
 360                 firstentry = entrylistp;


 370                 kep = kep->ke_next;
 371         }
 372 }
 373 
 374 /*
 375  * Allocate and fill in a new entry.
 376  */
 377 static keyentry *
 378 makeentry(tablemask, entry)
 379         int tablemask;
 380         int entry;
 381 {
 382         register keyentry *kep;
 383         register int index;
 384 
 385         if ((kep = (keyentry *) malloc((unsigned)sizeof (keyentry))) == NULL)
 386                 yyerror("out of memory for entries");
 387         kep->ke_next = NULL;
 388         kep->ke_entry.kio_tablemask = tablemask;
 389         kep->ke_entry.kio_station = 0;
 390         kep->ke_entry.kio_entry = entry;
 391         index = entry - STRING;
 392         if (index >= 0 && index <= 15)
 393                 (void) strncpy(kep->ke_entry.kio_string, strings[index],
 394                     KTAB_STRLEN);
 395         return (kep);
 396 }
 397 
 398 /*
 399  * Make a set of entries for a keystation that indicate that that keystation's
 400  * settings should be copied from another keystation's settings.
 401  */
 402 static void
 403 duplicate_mapentry(station, otherstation)
 404         int station;
 405         int otherstation;
 406 {
 407         register dupentry *dep;
 408 
 409         if ((dep = (dupentry *) malloc((unsigned)sizeof (dupentry))) == NULL)
 410                 yyerror("out of memory for entries");


 569                 $$ = $1;
 570                 }
 571 ;
 572 
 573 entry:
 574         TABLENAME code
 575                 {
 576                 $$ = makeentry($1, $2);
 577                 }
 578 ;
 579 
 580 code:
 581         CHARSTRING
 582                 {
 583                 $$ = $1;
 584                 }
 585 |       CHAR
 586                 {
 587                 $$ = $1;
 588                 }
 589 |       INT
 590                 {
 591                 $$ = $1;
 592                 }
 593 |       '('
 594                 {
 595                 $$ = '(';
 596                 }
 597 |       ')'
 598                 {
 599                 $$ = ')';
 600                 }
 601 |       '+'
 602                 {
 603                 $$ = '+';
 604                 }
 605 |       expr
 606                 {
 607                 $$ = $1;
 608                 }
 609 ;
 610 
 611 expr:
 612         term


 656 
 657 /*
 658  * Table must be in alphabetical order.
 659  */
 660 word_t  wordtab[] = {
 661         { "all",        TABLENAME,      ALL },
 662         { "alt",        CONSTANT,       ALT },
 663         { "altg",       TABLENAME,      ALTGRAPHMASK },
 664         { "altgraph",   CONSTANT,       ALTGRAPH },
 665         { "as",         AS,             0 },
 666         { "base",       TABLENAME,      0 },
 667         { "bf",         FKEY,           BOTTOMFUNC },
 668         { "buckybits",  CONSTANT,       BUCKYBITS },
 669         { "caps",       TABLENAME,      CAPSMASK },
 670         { "capslock",   CONSTANT,       CAPSLOCK },
 671         { "compose",    CONSTANT,       COMPOSE },
 672         { "ctrl",       TABLENAME,      CTRLMASK },
 673         { "downarrow",  CONSTANT,       DOWNARROW },
 674         { "error",      CONSTANT,       ERROR },
 675         { "fa_acute",   CONSTANT,       FA_ACUTE },
 676         { "fa_apostrophe", CONSTANT,    FA_APOSTROPHE },
 677         { "fa_breve",   CONSTANT,       FA_BREVE },
 678         { "fa_caron",   CONSTANT,       FA_CARON },
 679         { "fa_cedilla", CONSTANT,       FA_CEDILLA },
 680         { "fa_cflex",   CONSTANT,       FA_CFLEX },
 681         { "fa_dacute",  CONSTANT,       FA_DACUTE },
 682         { "fa_dot",     CONSTANT,       FA_DOT },
 683         { "fa_grave",   CONSTANT,       FA_GRAVE },
 684         { "fa_macron",  CONSTANT,       FA_MACRON },
 685         { "fa_ogonek",  CONSTANT,       FA_OGONEK },
 686         { "fa_ring",    CONSTANT,       FA_RING },
 687         { "fa_slash",   CONSTANT,       FA_SLASH },
 688         { "fa_tilde",   CONSTANT,       FA_TILDE },
 689         { "fa_umlaut",  CONSTANT,       FA_UMLAUT },
 690         { "hole",       CONSTANT,       HOLE },
 691         { "homearrow",  CONSTANT,       HOMEARROW },
 692         { "idle",       CONSTANT,       IDLE },
 693         { "key",        KEY,            0 },
 694         { "leftarrow",  CONSTANT,       LEFTARROW },
 695         { "leftctrl",   CONSTANT,       LEFTCTRL },
 696         { "leftshift",  CONSTANT,       LEFTSHIFT },
 697         { "lf",         FKEY,           LEFTFUNC },
 698         { "metabit",    CONSTANT,       METABIT },
 699         { "nonl",       CONSTANT,       NONL },
 700         { "nop",        CONSTANT,       NOP },
 701         { "numl",       TABLENAME,      NUMLOCKMASK },
 702         { "numlock",    CONSTANT,       NUMLOCK },
 703         { "oops",       CONSTANT,       OOPS },
 704         { "pad0",       CONSTANT,       PAD0 },
 705         { "pad1",       CONSTANT,       PAD1 },
 706         { "pad2",       CONSTANT,       PAD2 },
 707         { "pad3",       CONSTANT,       PAD3 },


 868                 } else if (strlen(tokbuf) == 2 && tokbuf[0] == '^') {
 869                         tokentype = CHAR;
 870                         yylval.number = (unsigned char)(tokbuf[1] & 037);
 871                 } else {
 872                         word_t word;
 873                         register word_t *wptr;
 874                         char *ptr;
 875 
 876                         for (cp = &tokbuf[0]; (c = *cp) != '\0'; cp++) {
 877                                 if (isupper(c))
 878                                         *cp = tolower(c);
 879                         }
 880                         word.w_string = tokbuf;
 881                         wptr = (word_t *)bsearch((char *)&word,
 882                             (char *)wordtab, NWORDS, sizeof (word_t),
 883                             wordcmp);
 884                         if (wptr != NULL) {
 885                                 yylval.number = wptr->w_lval;
 886                                 tokentype = wptr->w_type;
 887                         } else {
 888                                 yylval.number = strtol(tokbuf, &ptr, 0);
 889                                 if (ptr == tokbuf)
 890                                         yyerror("syntax error");
 891                                 else
 892                                         tokentype = INT;
 893                         }
 894                         break;
 895                 }
 896         }
 897 
 898         return (tokentype);
 899 }
 900 
 901 static int
 902 readesc(stream, delim, single_char)
 903         FILE *stream;
 904         int delim;
 905         int single_char;
 906 {
 907         register int c;
 908         register int val;