|
|
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.