|
|
1.1 ! root 1: #define TEST 0 ! 2: ! 3: /* ! 4: * kbdinstall.c - 386 only! ! 5: * ! 6: * Revised: Thu Jul 29 05:02:49 1993 CDT ! 7: * Keyboard support installation, including virtual console questions. ! 8: * ! 9: * cc kbdinstall.c -lcurses [-lterm] ! 10: * Usage: kbdinstall [ -bu ] ! 11: * Options: ! 12: * -b invoked from build ! 13: * -u invoked from update install, don't patch running system ! 14: */ ! 15: ! 16: #include <stdio.h> ! 17: #include <string.h> ! 18: #include <ctype.h> ! 19: #include <curses.h> ! 20: #include <sys/kb.h> ! 21: ! 22: #include "build0.h" ! 23: ! 24: extern char *fgets(); ! 25: extern char *malloc(); ! 26: ! 27: #define VERSION "4.2" /* Version number. */ ! 28: #define KBDDIR "/conf/kbd" /* Keyboard directory. */ ! 29: ! 30: #if TEST ! 31: #define KBDLIST "kblist" /* List of keyboards. */ ! 32: #define TTYFILE "ttys" ! 33: #define DRVLDFILE "drvld.all" ! 34: #else ! 35: #define KBDLIST "/conf/kbd/kblist" /* List of keyboards. */ ! 36: #define TTYFILE "/tmp/ttys" ! 37: #define DRVLDFILE "/tmp/drvld.all" ! 38: #endif ! 39: ! 40: #define KB_LANG_VAR "kb_lang" ! 41: #define MONO_SESSION_VAR "MONO_COUNT" /* Number of monochrome sessions. */ ! 42: #define COLOR_SESSION_VAR "VGA_COUNT" /* Number of color sessions. */ ! 43: #define KBDY 4 /* y-coordinate of keyboard list. */ ! 44: #define NLINE 512 /* Line length. */ ! 45: #define NKBDS (24-KBDY) /* Max number of keyboards */ ! 46: #define USAGE "Usage: /etc/kbdinstall [-bu]\n" ! 47: #define MAX_NUM_SESSIONS 8 ! 48: ! 49: /* Language specifiers for nonloadable kb's. */ ! 50: #define DE_LANG_STR "DE" ! 51: #define FR_LANG_STR "FR" ! 52: #define US_LANG_STR "-" ! 53: ! 54: /* Keyboard list file entries. */ ! 55: typedef struct kline { ! 56: int k_loadable; /* True: loadable tables supported */ ! 57: int k_lang; /* Used only for nonloadable kb. */ ! 58: char *k_driver; /* Name of keyboard driver object */ ! 59: char *k_table; /* Keyboard table name */ ! 60: char *k_desc; /* Keyboard description */ ! 61: } KLINE; ! 62: ! 63: /* Forward */ ! 64: char *copystr(); ! 65: void display_line(); ! 66: void display_rev(); ! 67: int blank_line(); ! 68: void get_sessions(); ! 69: void fatal(); ! 70: void my_fatal(); /* handles window cleanup */ ! 71: void format_error(); ! 72: void nonfatal(); ! 73: void my_nonfatal(); /* handles window cleanup */ ! 74: void read_klist(); ! 75: ! 76: /* Globals. */ ! 77: int bflag; /* Invoked from build. */ ! 78: char buf[NBUF]; /* Input buffer. */ ! 79: KLINE klist[NKBDS]; /* Keyboard list. */ ! 80: int nkbds; /* Number of keyboards. */ ! 81: int initflag; /* Curses initialized. */ ! 82: int uflag; /* Invoked from update. */ ! 83: int virtual; /* Virtual consoles wanted */ ! 84: int default_entry = -1; /* Which entry to default to */ ! 85: ! 86: main(argc, argv) int argc; char *argv[]; ! 87: { ! 88: register int n, c; ! 89: char *s; ! 90: ! 91: #if TEST ! 92: printf("TEST version - recompile with TEST disabled for production.\n" ! 93: "Press enter: "); ! 94: getchar(); ! 95: #endif ! 96: ! 97: /* Process command line options. */ ! 98: while (argc > 1 && argv[1][0] == '-') { ! 99: for (s = &argv[1][1]; *s != '\0'; s++) { ! 100: switch (*s) { ! 101: case 'b': ++bflag; break; ! 102: case 'u': ++uflag; break; ! 103: case 'V': nonfatal("V%s", VERSION); break; ! 104: default: ! 105: fprintf(stderr, USAGE); ! 106: exit(1); ! 107: } ! 108: } ! 109: --argc; ! 110: ++argv; ! 111: } ! 112: ! 113: if (bflag && uflag) { ! 114: fprintf(stderr, USAGE); ! 115: exit(1); ! 116: } ! 117: ! 118: /* Initialize screen and terminal modes. */ ! 119: initscr(); ! 120: initflag = 1; ! 121: noecho(); ! 122: raw(); ! 123: clear(); ! 124: ! 125: if (bflag || uflag) { ! 126: /* ! 127: * If invoked from "build" or "install", output some ! 128: * info about virtual consoles. Prompt the user if he/she ! 129: * wants V.C. support and set variable "virtual" as needed. ! 130: */ ! 131: mvaddstr(0, 0, ! 132: "This release of COHERENT supports multiple simultaneous sessions on the"); ! 133: mvaddstr(1, 0, ! 134: "system console. This feature, known as virtual consoles, supports both"); ! 135: mvaddstr(2, 0, ! 136: "monochrome and color video cards (text mode only) with multiple \"login\""); ! 137: mvaddstr(3, 0, ! 138: "sessions on each, depending upon your hardware configuration. If you have"); ! 139: mvaddstr(4, 0, ! 140: "both color and monochrome adapters on your system, you can run multiple"); ! 141: mvaddstr(5, 0, ! 142: "sessions on each of them at the same time."); ! 143: mvaddstr(7, 0, ! 144: "Virtual console support only works with systems which have at least one"); ! 145: mvaddstr(8, 0, ! 146: "megabyte of usable system memory. You may choose a loadable keyboard table"); ! 147: mvaddstr(9, 0, ! 148: "or a non-loadable keyboard table. Loadable keyboard tables will give you the"); ! 149: mvaddstr(10, 0, ! 150: "flexibility of remapping your keys and to load new tables at any time while"); ! 151: mvaddstr(11, 0, ! 152: "your system is active. This requires keyboards that are 100% IBM AT compliant."); ! 153: mvaddstr(12, 0, ! 154: "If you chose a non-loadable keyboard, you will not have this flexibility."); ! 155: mvaddstr(14,0, ! 156: "Not all keyboards are 100% IBM AT compliant and will not work with loadable"); ! 157: mvaddstr(15,0, ! 158: "keyboard tables. If your keyboard is not 100% IBM AT compliant, it may result"); ! 159: mvaddstr(16,0, ! 160: "in COHERENT not booting properly after the installation process is completed,"); ! 161: mvaddstr(17,0, ! 162: "or you may find that your keyboard keys are not mapped as they are labeled and"); ! 163: mvaddstr(18,0, ! 164: "that some keys cease to function at all. For this reason, the default selection"); ! 165: mvaddstr(19,0, ! 166: "is the non-loadable keyboard."); ! 167: mvaddstr(21, 0, ! 168: "Do you wish to include support for virtual consoles? [y or n] "); ! 169: refresh(); ! 170: echo(); ! 171: for (;;) { ! 172: c = getch(); ! 173: switch (c) { ! 174: case 'Y': ! 175: case 'y': ! 176: ++virtual; ! 177: break; ! 178: case 'N': ! 179: case 'n': ! 180: break; ! 181: default: ! 182: continue; ! 183: } ! 184: noecho(); ! 185: refresh(); ! 186: mvaddstr(23, 0, "Please hit <Enter> ..."); ! 187: refresh(); ! 188: while ((c = getch()) != '\r' && c != '\n') ! 189: ; ! 190: mvaddstr(23, 0, "One moment, please ...."); ! 191: refresh(); ! 192: break; ! 193: } ! 194: clear(); ! 195: } ! 196: ! 197: /* Read the keyboard list file. */ ! 198: read_klist(); ! 199: ! 200: /* Display instructions at top of screen. */ ! 201: mvaddstr(0, 0, ! 202: "Select the entry below which indentifies your keyboard type. Hit <Enter> to"); ! 203: mvaddstr(1, 0, ! 204: "select the highlighted entry. Hit <space> to move to the next entry."); ! 205: ! 206: /* Display choices. */ ! 207: for (n = 0; n < nkbds; n++) ! 208: display_line(n); ! 209: ! 210: /* Interactive input loop: display choice n highlighted. */ ! 211: for (n = (default_entry >= 0) ? default_entry : 0; ; ) { ! 212: display_rev(n); /* display default choice in reverse */ ! 213: refresh(); ! 214: switch (c = getch()) { ! 215: case 'A': /* n.b.: ESC [ A is Up Arrow key */ ! 216: if (--n < 0) ! 217: n = nkbds - 1; ! 218: continue; ! 219: case ' ': /* space/Down Arrow: try next choice */ ! 220: case 'B': /* n.b.: ESC [ B is Down Arrow key */ ! 221: if (++n >= nkbds) ! 222: n = 0; ! 223: continue; ! 224: case '\n': ! 225: case '\r': /* enter: take default value */ ! 226: break; ! 227: default: ! 228: continue; /* ignore */ ! 229: } ! 230: break; /* done, choice is in n */ ! 231: } ! 232: ! 233: /* ! 234: * Execute the keyboard table file only if invoked by the user ! 235: * (i.e., not Build nor Update). ! 236: */ ! 237: if (!uflag && !bflag) { ! 238: #if! TEST ! 239: /* Omit this during testing! */ ! 240: if (klist[n].k_loadable) { ! 241: sprintf(buf, "%s/%s", KBDDIR, klist[n].k_table); ! 242: if (system(buf) != 0) ! 243: fatal("Loadable keyboard tables not supported by this kernel", buf); ! 244: } else { ! 245: fatal("Selected entry is not a loadable keyboard table"); ! 246: } ! 247: #endif ! 248: exit(0); ! 249: } ! 250: ! 251: /* ! 252: * Must be in Build or Update mode now. ! 253: */ ! 254: ! 255: /* Write idenable line to IDCMDFILE. */ ! 256: buf[0] = '\0'; ! 257: if (virtual) ! 258: strcpy(buf, "vt"); ! 259: strcat(buf, klist[n].k_driver); ! 260: idenable_dev(buf); ! 261: ! 262: if (klist[n].k_loadable) { ! 263: ! 264: /* ! 265: * Loadable keyboard table selected. ! 266: * Store name of keyboard executable into ! 267: * drvld.all. ! 268: */ ! 269: sprintf(buf,"/bin/echo %s/%s >> %s", ! 270: KBDDIR, klist[n].k_table, DRVLDFILE); ! 271: sys(buf,S_FATAL); ! 272: ! 273: } else { ! 274: ! 275: char * kb_lang_val; ! 276: char line[80]; ! 277: ! 278: /* ! 279: * Non-loadable keyboard table selected. ! 280: * If Language is German (DE) or French (FR), ! 281: * write cohtune line. ! 282: */ ! 283: switch(klist[n].k_lang) { ! 284: case kb_lang_us: ! 285: kb_lang_val = "kb_lang_us"; ! 286: break; ! 287: case kb_lang_de: ! 288: kb_lang_val = "kb_lang_de"; ! 289: break; ! 290: case kb_lang_fr: ! 291: kb_lang_val = "kb_lang_fr"; ! 292: break; ! 293: } ! 294: sprintf(line, "int %s = %s;", KB_LANG_VAR, kb_lang_val); ! 295: cohtune_ent("console", KB_LANG_VAR, line); ! 296: } ! 297: ! 298: ! 299: clear(); ! 300: mvaddstr(0,0,"Your keyboard selection will not take effect until after"); ! 301: move(1,0); ! 302: printw("your system %s has completed and the system has rebooted!\n", ! 303: bflag ? "installation" : "update"); ! 304: ! 305: ! 306: mvaddstr(3,0,"Press <Enter> to continue..."); ! 307: refresh(); ! 308: ! 309: while ((c = getch()) != '\r' && c != '\n') ! 310: ; ! 311: ! 312: #if 0 ! 313: clear(); ! 314: refresh(); ! 315: #endif ! 316: ! 317: /* Back to non-curses output. */ ! 318: endwin(); ! 319: ! 320: /* ! 321: * During installation, if V.C.'s are in use, ! 322: * don't enable the console device. ! 323: */ ! 324: if (bflag) { ! 325: sprintf(cmd, "/bin/echo \"%dlPconsole\" > %s", ! 326: virtual ? 0 : 1, TTYFILE); ! 327: sys(cmd, S_FATAL); ! 328: } ! 329: ! 330: /* For virtual consoles, ask how many sessions. */ ! 331: if (virtual) { ! 332: clear(); ! 333: get_sessions(); ! 334: } ! 335: ! 336: /* Done. */ ! 337: exit(0); ! 338: } ! 339: ! 340: /* ! 341: * Allocate a copy of a string and return a pointer to it. ! 342: */ ! 343: char * ! 344: copystr(s) register char *s; ! 345: { ! 346: register char *cp; ! 347: ! 348: if ((cp = malloc(strlen(s) + 1)) == NULL) ! 349: my_fatal("no space for string \"%s\""); ! 350: strcpy(cp, s); ! 351: return cp; ! 352: } ! 353: ! 354: /* ! 355: * Display choice n. ! 356: */ ! 357: void ! 358: display_line(n) register int n; ! 359: { ! 360: mvaddstr(KBDY+n, 12, klist[n].k_desc); ! 361: } ! 362: ! 363: /* ! 364: * Display choice n in reverse video. ! 365: */ ! 366: void ! 367: display_rev(n) int n; ! 368: { ! 369: static int last = -1; ! 370: ! 371: if (last != -1) ! 372: display_line(last); /* redisplay last in normal */ ! 373: standout(); ! 374: display_line(n); /* display n in reverse */ ! 375: standend(); ! 376: last = n; ! 377: } ! 378: ! 379: /* ! 380: * Cry and die. ! 381: */ ! 382: /* VARARGS */ ! 383: void ! 384: my_fatal(s) char *s; ! 385: { ! 386: if (initflag) ! 387: endwin(); ! 388: fprintf(stderr, "kbdinstall: %r\n", &s); ! 389: exit(1); ! 390: } ! 391: ! 392: /* ! 393: * Issue nonfatal informative message. ! 394: */ ! 395: /* VARARGS */ ! 396: void ! 397: my_nonfatal(s) char *s; ! 398: { ! 399: if (initflag) ! 400: endwin(); ! 401: fprintf(stderr, "kbdinstall: %r\n", &s); ! 402: } ! 403: ! 404: /* ! 405: * Read a file containing keyboard file names and descriptions, ! 406: * build a keyboard list. ! 407: * ! 408: * Format of input is: ! 409: * # Comment line ! 410: * blank line ! 411: * or ! 412: * Default <tab> Loadable <tab> Driver <tab> Table <tab> Descr. ! 413: */ ! 414: void ! 415: read_klist() ! 416: { ! 417: register FILE *fp; ! 418: register unsigned char *s, *s1; ! 419: ! 420: if ((fp = fopen(KBDLIST, "r")) == NULL) ! 421: my_fatal("cannot open \"%s\"", KBDLIST); ! 422: while (fgets(buf, sizeof buf, fp) != NULL) { ! 423: if (buf[0] == '#' || blank_line(buf)) ! 424: continue; /* ignore comments */ ! 425: if (nkbds == NKBDS) { ! 426: my_nonfatal("more than %d keyboard entries", NKBDS-1); ! 427: continue; ! 428: } ! 429: ! 430: /* ! 431: * Parse input lines and emit error messages if input bad. ! 432: */ ! 433: if (buf[0] == 'Y' || buf[0] == 'y') ! 434: default_entry = nkbds; ! 435: if ((s = strchr(buf, '\t')) == NULL) { ! 436: format_error(buf); ! 437: continue; ! 438: } ! 439: ! 440: switch (*++s) { ! 441: case 'Y': case 'y': ! 442: klist[nkbds].k_loadable = TRUE; ! 443: break; ! 444: case 'N': case 'n': ! 445: klist[nkbds].k_loadable = FALSE; ! 446: break; /* ... or if VC's desired */ ! 447: default: ! 448: format_error(buf); ! 449: continue; ! 450: } ! 451: if ((s = strchr(++s, '\t')) == NULL) { ! 452: format_error(buf); ! 453: continue; ! 454: } ! 455: if ((s1 = strchr(++s, '\t')) == NULL) { ! 456: format_error(buf); ! 457: continue; ! 458: } ! 459: *s1++ = '\0'; ! 460: klist[nkbds].k_driver = copystr(s); /* keyboard driver */ ! 461: if ((s = strchr(s1, '\t')) == NULL) { ! 462: format_error(s1); ! 463: continue; ! 464: } ! 465: *s++ = '\0'; ! 466: klist[nkbds].k_table = copystr(s1); /* keyboard table */ ! 467: ! 468: /* k_table must contain DE/FR/- for non-loadable driver. */ ! 469: if (!klist[nkbds].k_loadable) { ! 470: if (strcmp(klist[nkbds].k_table, DE_LANG_STR) == 0) ! 471: klist[nkbds].k_lang = kb_lang_de; ! 472: else if (strcmp(klist[nkbds].k_table, FR_LANG_STR) == 0) ! 473: klist[nkbds].k_lang = kb_lang_fr; ! 474: else if (strcmp(klist[nkbds].k_table, US_LANG_STR) == 0) ! 475: klist[nkbds].k_lang = kb_lang_us; ! 476: else { ! 477: format_error(s1); ! 478: continue; ! 479: } ! 480: } ! 481: ! 482: if ((s1 = strchr(s, '\n')) == NULL) { ! 483: my_nonfatal("no newline in \"%s\"", s); ! 484: continue; ! 485: } ! 486: ! 487: *s1 = '\0'; ! 488: klist[nkbds].k_desc = copystr(s); /* kbd description */ ! 489: ! 490: nkbds++; ! 491: } ! 492: fclose(fp); ! 493: } ! 494: ! 495: /* ! 496: * Input error found: display an error message and continue. ! 497: */ ! 498: void ! 499: format_error(line) ! 500: char *line; ! 501: { ! 502: my_nonfatal("Input format error found in \"%s\" -- ignored.", line); ! 503: } ! 504: ! 505: /* ! 506: * Return TRUE if line consists only of whitespace. ! 507: */ ! 508: int ! 509: blank_line(str) ! 510: char * str; ! 511: { ! 512: int is_blank = TRUE; ! 513: ! 514: while(*str) { ! 515: if (isspace(*str)) ! 516: str++; ! 517: else { ! 518: is_blank = FALSE; ! 519: break; ! 520: } ! 521: } ! 522: ! 523: return is_blank; ! 524: } ! 525: ! 526: /* ! 527: * For virtual console users only, ask how may mono/color sessions. ! 528: */ ! 529: void ! 530: get_sessions() ! 531: { ! 532: int color_sessions; /* number of color sessions */ ! 533: int mono_sessions; /* number of mono sessions */ ! 534: int mono_display; /* 1 if mono display is present */ ! 535: int color_display; /* 1 if color display is present */ ! 536: int high_prompt; ! 537: int i; ! 538: ! 539: for (;;) { ! 540: mono_sessions = 0; ! 541: color_sessions = 0; ! 542: mono_display = ! 543: yes_no("\nDoes this system have a monochrome " ! 544: "(i.e., MDA) video adapter"); ! 545: color_display = ! 546: yes_no("\nDoes this system have a color " ! 547: "(i.e., CGA/EGA/VGA) video adapter"); ! 548: printf("\nYou may select a total of up to %d virtual " ! 549: "console sessions.\n", MAX_NUM_SESSIONS); ! 550: ! 551: high_prompt = MAX_NUM_SESSIONS; ! 552: ! 553: if (color_display) { ! 554: sprintf(buf, "\nHow many active virtual console sessions " ! 555: "would you like on your\ncolor video display " ! 556: "[1-%d]?", high_prompt); ! 557: color_sessions = get_int(1, high_prompt, buf); ! 558: high_prompt = MAX_NUM_SESSIONS - color_sessions; ! 559: } ! 560: ! 561: if (mono_display) { ! 562: sprintf(buf, "\nHow many active virtual console sessions " ! 563: "would you like on your\nmonchrome video display " ! 564: "[1-%d]?", high_prompt); ! 565: mono_sessions = get_int(1, high_prompt, buf); ! 566: } ! 567: ! 568: if (mono_sessions + color_sessions > 0) ! 569: break; ! 570: ! 571: /* else - try again - no sessions enabled! */ ! 572: printf("\nYou must select either a monochrome or a color video " ! 573: "adapter!\n"); ! 574: } ! 575: ! 576: /* Write device entries to ttys file. */ ! 577: for (i = 0; i < color_sessions; ++i) { ! 578: sprintf(cmd, "/bin/echo \"1lPcolor%d\" >> %s", ! 579: i, TTYFILE); ! 580: sys(cmd, S_FATAL); ! 581: } ! 582: ! 583: for (i = 0; i < mono_sessions; ++i) { ! 584: sprintf(cmd, "/bin/echo \"1lPmono%d\" >> %s", ! 585: i, TTYFILE); ! 586: sys(cmd, S_FATAL); ! 587: } ! 588: ! 589: /* ! 590: * After linking new kernel, will patch it for number of mono ! 591: * and color sessions. Do the patch even if number of sessions ! 592: * for the given type is zero. ! 593: */ ! 594: idtune_var(MONO_SESSION_VAR, mono_sessions); ! 595: idtune_var(COLOR_SESSION_VAR, color_sessions); ! 596: } ! 597: ! 598: /* end of kbdinstall.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.