Annotation of coherent/b/kernel/tools/kbmain.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * driver routine for loadable keyboard tables.
        !             3:  *
        !             4:  * prior to firing off the ioctl() which loads the new keyboard tables,
        !             5:  * permform some simple validity checks on the table.
        !             6:  * if errors are found, bail out without setting the new table.
        !             7:  *
        !             8:  * this version removes all references to stdio since we need to put over
        !             9:  * a dozen cooked keyboard tables on the boot disk - space is at a premium.
        !            10:  *
        !            11:  * Version 1.1, 6/25/91
        !            12:  */
        !            13: 
        !            14: #include <sgtty.h>
        !            15: #include <sys/kb.h>
        !            16: #include <sys/kbscan.h>
        !            17: #include <errno.h>
        !            18: #include <sys/mdata.h>
        !            19: 
        !            20: #define        VERSION "1.1"
        !            21: #define        FALSE   (0 != 0)
        !            22: #define        TRUE    (0 == 0)
        !            23: #define NULL ((char *)0)
        !            24: #define putchar(c) { char b = c; write(1, &b, 1); }
        !            25: 
        !            26: /*
        !            27:  * globals
        !            28:  */
        !            29: char   *argv0;                         /* name of this executable */
        !            30: int    errors;                         /* for exit status */
        !            31: char   verbose;                        /* step-by-step details */
        !            32: char   debug;                          /* print out cooked table & exit */
        !            33: KBTBL  table[MAX_KEYS];                /* cooked table for ioctl() */
        !            34: FNKEY  *arena;                         /* function key arena */
        !            35: unsigned char  fnbuffer[(sizeof(FNKEY) + MAX_FCHAR)]; /* function key area */
        !            36: 
        !            37: /*
        !            38:  * The following table maps the specified key number to
        !            39:  * a scan code set 3 value.
        !            40:  * Note that K_14, K_65 through K_74 and K_107
        !            41:  * are provided for compatibility with
        !            42:  * the old XT layout AT keyboards.
        !            43:  */
        !            44: unsigned char  keyval[] = {            /* code set 3 mapped value */
        !            45: none, K_1, K_2, K_3, K_4, K_5, K_6, K_7,
        !            46: K_8, K_9, K_10, K_11, K_12, K_13, K_14, K_15,
        !            47: K_16, K_17, K_18, K_19, K_20, K_21, K_22, K_23,
        !            48: K_24, K_25, K_26, K_27, K_28, K_29, K_30, K_31,
        !            49: K_32, K_33, K_34, K_35, K_36, K_37, K_38, K_39,
        !            50: K_40, K_41, K_42, K_43, K_44, K_45, K_46, K_47,
        !            51: K_48, K_49, K_50, K_51, K_52, K_53, K_54, K_55,
        !            52: none, K_57, K_58, none, K_60, K_61, K_62, none,
        !            53: K_64, K_65, K_66, K_67, K_68, K_69, K_70, K_71,
        !            54: K_72, K_73, K_74, K_75, K_76, none, none, K_79,
        !            55: K_80, K_81, none, K_83, K_84, K_85, K_86, none,
        !            56: none, K_89, K_90, K_91, K_92, K_93, none, K_95,
        !            57: K_96, K_97, K_98, K_99, K_100, K_101, K_102, K_103,
        !            58: K_104, K_105, K_106, K_107, K_108, none, K_110, none,
        !            59: K_112, K_113, K_114, K_115, K_116, K_117, K_118, K_119,
        !            60: K_120, K_121, K_122, K_123, K_124, K_125, K_126, none
        !            61: };
        !            62: 
        !            63: /*
        !            64:  * externs from user-defined keyboard table
        !            65:  */
        !            66: extern KBTBL   kbtbl[];                        /* actual table */
        !            67: extern char    tbl_name[];                     /* name of table as text */
        !            68: extern unsigned char *funkey[];                /* function key definitions */
        !            69: extern int     numfun;                         /* # of function keys in tbl */
        !            70: extern int     numkey;                         /* number of keys in kbtbl[] */
        !            71: 
        !            72: main(argc, argv)
        !            73: char *argv[];
        !            74: {
        !            75:        unsigned char *cp, *ncp;
        !            76:        int i, j;
        !            77:        int fd;                                 /* console file descriptor */
        !            78: 
        !            79:        argv0 = argv[0];
        !            80:        arena = (FNKEY *) fnbuffer;
        !            81: 
        !            82:        if (argc > 1) {
        !            83:                if (strcmp(argv[1], "-V") == 0)
        !            84:                        printf("Version %s\n", VERSION);
        !            85:                else if (strcmp(argv[1], "-D") == 0)
        !            86:                        ++debug;
        !            87:                else
        !            88:                        usage();
        !            89:        }
        !            90: 
        !            91:        if ((fd = open("/dev/console", 2)) < 0) {
        !            92:                err("unable to access console");
        !            93:                exit(errors);
        !            94:        }
        !            95: 
        !            96:        /*
        !            97:         * loop through the user's keyboard table validating each entry.
        !            98:         * if the entry is good, copy it to the destination table.
        !            99:         */
        !           100:        for (i = 0; i < numkey; ++i) {          /* loop thru user's keys */
        !           101:                if (ok_entry(i)) {
        !           102:                        j = kbtbl[i].k_key;             /* map key */
        !           103:                        table[j] = kbtbl[i];            /* copy entry */
        !           104:                } else
        !           105:                        ++errors;
        !           106:        }
        !           107: 
        !           108:        if (errors)
        !           109:                exit(errors);
        !           110:        /*
        !           111:         * build a function key arena consisting of the user defined
        !           112:         * special and function keys.
        !           113:         */
        !           114:        ncp = arena->k_fnval;
        !           115:        for (i = 0; i < numfun; ++i) {
        !           116:                cp = funkey[i];
        !           117:                do {
        !           118:                        if (ncp >= &arena->k_fnval[MAX_FCHAR]) {
        !           119:                                err("function key table overflow");
        !           120:                                exit(errors);
        !           121:                        }
        !           122:                        *ncp++ = *cp;
        !           123:                } while (*cp++ != DELIM);
        !           124:        }
        !           125:        arena->k_nfkeys = numfun;
        !           126: 
        !           127:        if (debug) {
        !           128:                dump();                         /* print out cooked table */
        !           129:                exit(0);
        !           130:        }
        !           131: 
        !           132:        /*
        !           133:         * load the cooked keyboard table into the driver via a
        !           134:         * special ioctl() call.
        !           135:         */
        !           136:        ioctl(fd, TIOCSETKBT, table);
        !           137:        if (errno) {
        !           138:                err("keyboard table ioctl() failed, errno=%d", errno);
        !           139:                exit(errors);
        !           140:        }
        !           141: 
        !           142:        /*
        !           143:         * load the cooked function key table into the driver via a
        !           144:         * special ioctl() call.
        !           145:         */
        !           146:        ioctl(fd, TIOCSETF, arena);
        !           147:        if (errno) {
        !           148:                err("function key ioctl() failed, errno=%d", errno);
        !           149:                exit(errors);
        !           150:        }
        !           151: 
        !           152:        printf("Loaded %s\n", tbl_name);
        !           153:        close(fd);
        !           154:        exit(errors);
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * validate a table entry
        !           159:  */
        !           160: ok_entry(n)
        !           161: register int n;
        !           162: {
        !           163:        int i;
        !           164:        int key = lookup(kbtbl[n].k_key);
        !           165:        unsigned char kval;
        !           166: 
        !           167:        if (!key) {
        !           168:                err("invalid key #0x%x in kbtbl[%d]", kbtbl[n].k_key, n);
        !           169:                return FALSE;
        !           170:        }
        !           171:        if ((kbtbl[n].k_flags & (S|F)) == (S|F)) {
        !           172:                err("invalid flag field for key K_%d", key);
        !           173:                return FALSE;
        !           174:        }
        !           175:        if (kbtbl[n].k_flags & S) {
        !           176:                for (i = BASE; i <= ALT_GR; ++i) {
        !           177:                        kval = kbtbl[n].k_val[i];
        !           178:                        if (kval != kbtbl[n].k_val[BASE]) {
        !           179:                                err("inconsistent shift key entry for K_%d",
        !           180:                                    key);
        !           181:                                return FALSE;
        !           182:                        }
        !           183:                        if (kval < scroll || kval > altgr) {
        !           184:                                err("bad shift key entry for K_%d",
        !           185:                                    key);
        !           186:                                return FALSE;
        !           187:                        }
        !           188:                } /* for */
        !           189:        } else if (kbtbl[n].k_flags & F) {
        !           190:                for (i = BASE; i <= ALT_GR; ++i) {
        !           191:                        kval = kbtbl[n].k_val[i];
        !           192:                        if (kval != none)
        !           193:                                if (kval >= numfun
        !           194:                                  && !VTKEY(kval) /* && kval != fgk*/) {
        !           195:                                        printf("val=%d\n", kval);
        !           196:                                        err("bad function key entry K_%d",
        !           197:                                            key);
        !           198:                                        return FALSE;
        !           199:                                }
        !           200:                } /* for */
        !           201:        } /* flag key */
        !           202: 
        !           203:        if (table[kbtbl[n].k_key].k_key != 0) {
        !           204:                err("multiple entries for K_%d", key);
        !           205:                return FALSE;
        !           206:        }
        !           207:        return TRUE;
        !           208: }
        !           209: 
        !           210: /*
        !           211:  * lookup the physical key number associated with a given
        !           212:  * code set 3 scan code.
        !           213:  *
        !           214:  * return 0 if not found.
        !           215:  */
        !           216: lookup(sc)
        !           217: unsigned sc;
        !           218: {
        !           219:        register int i;
        !           220: 
        !           221:        if (sc == none)
        !           222:                return 0;
        !           223:        for (i = 0; i < sizeof(keyval)/sizeof(keyval[0]); ++i)
        !           224:                if (keyval[i] == (unsigned char)sc)
        !           225:                        return (i);
        !           226:        return 0;
        !           227: }
        !           228: 
        !           229: usage()
        !           230: {
        !           231:        printf("usage:\t%s [-V]\n", argv0);
        !           232:        exit(1);
        !           233: }
        !           234: 
        !           235: err(msg)
        !           236: char *msg;
        !           237: {
        !           238:        printf("%s: ERROR: %r\n", argv0, &msg);
        !           239:        ++errors;
        !           240: }
        !           241: 
        !           242: /*
        !           243:  * dump the cooked keyboard table to stdout
        !           244:  */
        !           245: dump()
        !           246: {
        !           247:        int i, j;
        !           248: 
        !           249:        for (i = 0; i < MAX_KEYS; ++i) {
        !           250:                printf("%02x: %02x ", i, table[i].k_key);
        !           251:                for (j = 0; j < 9; ++j)
        !           252:                        printf("%02x ", table[i].k_val[j]);
        !           253:                printf("(%02x)\n", table[i].k_flags);
        !           254:        }
        !           255: }
        !           256: 
        !           257: 
        !           258: /*
        !           259:  * Simple standard output printf() using single character writes to stdout.
        !           260:  *
        !           261:  * Non-portable things:
        !           262:  * 1) alignment of arguments is assumed to be completely contiguous.
        !           263:  * 2) the smallest number is assumed to negate to itself.
        !           264:  *    be held in an exact number of ints.
        !           265:  */
        !           266: union  alltypes {
        !           267:        char    c;
        !           268:        int     i;
        !           269:        unsigned u;
        !           270:        char    *s;
        !           271: };
        !           272: 
        !           273: #define        bump(p,s)       (p+=sizeof(s)/sizeof(int))
        !           274: 
        !           275: char   *printi();
        !           276: 
        !           277: static char    null[] = "{NULL}";
        !           278: 
        !           279: printf(args)
        !           280: union alltypes args;
        !           281: {
        !           282:        xprintf(&args);
        !           283: }
        !           284: xprintf(argp)
        !           285: union alltypes *argp;
        !           286: {
        !           287:        register char *cbp;
        !           288:        int *iap;
        !           289:        register c;
        !           290:        char *s;
        !           291:        char *cbs;
        !           292:        char adj, pad;
        !           293:        int prec;
        !           294:        int fwidth;
        !           295:        int pwidth;
        !           296:        register char *fmt;
        !           297:        union alltypes elem;
        !           298:        char cbuf[64];
        !           299: 
        !           300:        iap = (int *)argp;
        !           301:        fmt = *(char **)iap;
        !           302:        bump(iap, char*);
        !           303:        for (;;) {
        !           304:                while((c = *fmt++) != '%') {
        !           305:                        if(c == '\0') {
        !           306:                                return;
        !           307:                        }
        !           308:                        putchar(c);
        !           309:                }
        !           310:                pad = ' ';
        !           311:                fwidth = -1;
        !           312:                prec = -1;
        !           313:                c = *fmt++;
        !           314:                if (c == '-') {
        !           315:                        adj = 1;
        !           316:                        c = *fmt++;
        !           317:                } else
        !           318:                        adj = 0;
        !           319:                if (c == '0') {
        !           320:                        pad = '0';
        !           321:                        c = *fmt++;
        !           322:                }
        !           323:                if (c == '*') {
        !           324:                        fwidth = *iap++;
        !           325:                        c = *fmt++;
        !           326:                } else
        !           327:                        for (fwidth = 0; c>='0' && c<='9'; c = *fmt++)
        !           328:                                fwidth = fwidth*10 + c-'0';
        !           329:                if (c == '.') {
        !           330:                        c = *fmt++;
        !           331:                        if (c == '*') {
        !           332:                                prec = *iap++;
        !           333:                                c = *fmt++;
        !           334:                        } else
        !           335:                                for (prec=0; c >= '0' && c <= '9'; c = *fmt++)
        !           336:                                        prec = prec*10 + c-'0';
        !           337:                }
        !           338:                cbp = cbs = cbuf;
        !           339:                switch (c) {
        !           340: 
        !           341:                case 'd':
        !           342:                        elem.i = *iap++;
        !           343:                        if (elem.i < 0) {
        !           344:                                elem.i = -elem.i;
        !           345:                                *cbp++ = '-';
        !           346:                        }
        !           347:                        cbp = printi(cbp, elem.i, 10);
        !           348:                        break;
        !           349: 
        !           350:                case 'u':
        !           351:                        cbp = printi(cbp, *iap++, 10);
        !           352:                        break;
        !           353:        
        !           354:                case 'o':
        !           355:                        cbp = printi(cbp, *iap++, 8);
        !           356:                        break;
        !           357: 
        !           358:                case 'x':
        !           359:                        cbp = printi(cbp, *iap++, 16);
        !           360:                        break;
        !           361: 
        !           362:                case 's':
        !           363:                        if ((s = *(char **)iap) == NULL)
        !           364:                                s = null;
        !           365:                        bump(iap, char*);
        !           366:                        /*
        !           367:                         * Do %s specially so it can be longer.
        !           368:                         */
        !           369:                        cbp = cbs = s;
        !           370:                        while (*cbp++ != '\0')
        !           371:                                if (prec>=0 && cbp-s>prec)
        !           372:                                        break;
        !           373:                        cbp--;
        !           374:                        break;
        !           375:        
        !           376:                case 'c':
        !           377:                        elem.c = *iap++;
        !           378:                        *cbp++ = elem.c;
        !           379:                        break;
        !           380:        
        !           381:                case 'r':
        !           382:                        xprintf(*(char ***)iap);
        !           383:                        bump(iap, char**);
        !           384:                        break;
        !           385:        
        !           386:                default:
        !           387:                        putchar(c);
        !           388:                        continue;
        !           389:                }
        !           390:                if ((pwidth = fwidth + cbs-cbp) < 0)
        !           391:                        pwidth = 0;
        !           392:                if (!adj)
        !           393:                        while (pwidth-- != 0)
        !           394:                                putchar(pad);
        !           395:                while (cbs < cbp)
        !           396:                        putchar(*cbs++);
        !           397:                if (adj)
        !           398:                        while (pwidth-- != 0)
        !           399:                                putchar(pad);
        !           400:        }
        !           401: }
        !           402: 
        !           403: static char    digits[] = {
        !           404:        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        !           405:        'A', 'B', 'C', 'D', 'E', 'F'
        !           406: };
        !           407: 
        !           408: /*
        !           409:  * Print an unsigned integer in base b.
        !           410:  */
        !           411: static
        !           412: char *
        !           413: printi(cp, n, b)
        !           414: char *cp;
        !           415: register unsigned n;
        !           416: {
        !           417:        register a;
        !           418:        register char *ep;
        !           419:        char pbuf[10];
        !           420: 
        !           421:        ep = &pbuf[10];
        !           422:        *--ep = 0;
        !           423:        for ( ; a = n/b; n=a)
        !           424:                *--ep = digits[n%b];
        !           425:        *--ep = digits[n];
        !           426:        while (*ep)
        !           427:                *cp++ = *ep++;
        !           428:        return (cp);
        !           429: }
        !           430: 
        !           431: /* end of kbmain.c */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.