|
|
1.1 root 1: /*
2: * kbdinstall.c
3: * 10/24/91
4: * Keyboard support installation.
5: *
6: * cc kbdinstall.c -lcurses -lterm
7: * Usage: kbdinstall [ -bu ]
8: * Options:
9: * -b invoked from build
10: * -u invoked from update install, don't patch running system
11: */
12:
13: #include <stdio.h>
14: #include <string.h>
15: #include <curses.h>
16:
17: extern char *fgets();
18: extern char *malloc();
19:
20: #define VERSION "2.2" /* Version number. */
21: #define KBDDIR "/conf/kbd" /* Keyboard directory. */
22: #define KBDLIST "/conf/kbd/.list" /* List of keyboards. */
23: #define KBDFILE "/tmp/kbd" /* File containing driver object name */
24: #define KBDY 4 /* y-coordinate of keyboard list. */
25: #define NLINE 512 /* Line length. */
26: #define NKBDS (24-KBDY) /* Max number of keyboards */
27: #define USAGE "Usage: /etc/kbdinstall [-bu]\n"
28:
29: /* Keyboard list file entries. */
30: typedef struct kline {
31: int k_loadable; /* True: loadable tables supported */
32: char *k_driver; /* Name of keyboard driver object */
33: char *k_table; /* Keyboard table name */
34: char *k_desc; /* Keyboard description */
35: } KLINE;
36:
37: /* Forward. */
38: char *copystr();
39: void display_line();
40: void display_rev();
41: void fatal();
42: void format_error();
43: void nonfatal();
44: void read_klist();
45:
46: /* Globals. */
47: int bflag; /* Invoked from build. */
48: char buf[NLINE]; /* Input buffer. */
49: KLINE klist[NKBDS]; /* Keyboard list. */
50: int nkbds; /* Number of keyboards. */
51: int initflag; /* Curses initialized. */
52: int uflag; /* Invoked from update. */
53: int default_entry = -1; /* Which entry to default to */
54:
55: main(argc, argv) int argc; char *argv[];
56: {
57: register int n, c;
58: char *s;
59:
60: /* Process command line options. */
61: while (argc > 1 && argv[1][0] == '-') {
62: for (s = &argv[1][1]; *s != '\0'; s++) {
63: switch (*s) {
64: case 'b': ++bflag; break;
65: case 'u': ++uflag; break;
66: case 'V': nonfatal("V%s", VERSION); break;
67: default:
68: fprintf(stderr, USAGE);
69: exit(1);
70: }
71: }
72: --argc;
73: ++argv;
74: }
75:
76: if (bflag && uflag) {
77: fprintf(stderr, USAGE);
78: exit(1);
79: }
80:
81: /* Read the keyboard list file. */
82: read_klist();
83:
84: /* Initialize screen and terminal modes. */
85: initscr();
86: initflag = 1;
87: noecho();
88: raw();
89: clear();
90:
91: /* Display instructions at top of screen. */
92: mvaddstr(0, 0, "Select the entry below which indentifies your keyboard type.");
93: mvaddstr(1, 0, "Hit <Enter> to select the highlighted entry.");
94: mvaddstr(2, 0, "Hit <space> or use arrow keys to move to the next entry.");
95:
96: /* Display choices. */
97: for (n = 0; n < nkbds; n++)
98: display_line(n);
99:
100: /* Interactive input loop: display choice n highlighted. */
101: for (n = (default_entry >= 0) ? default_entry : 0; ; ) {
102: display_rev(n); /* display default choice in reverse */
103: refresh();
104: switch (c = getch()) {
105: case 'A': /* n.b.: ESC [ A is Up Arrow key */
106: if (--n < 0)
107: n = nkbds - 1;
108: continue;
109: case ' ': /* space/Down Arrow: try next choice */
110: case 'B': /* n.b.: ESC [ B is Down Arrow key */
111: if (++n >= nkbds)
112: n = 0;
113: continue;
114: case '\n':
115: case '\r': /* enter: take default value */
116: break;
117: default:
118: continue; /* ignore */
119: }
120: break; /* done, choice is in n */
121: }
122: endwin();
123:
124: /*
125: * Execute the keyboard table file only if invoked by the user
126: * (i.e., not Build nor Update).
127: */
128: if (!uflag && !bflag) {
129: if (klist[n].k_loadable) {
130: sprintf(buf, "%s/%s", KBDDIR, klist[n].k_table);
131: if (system(buf) != 0)
132: fatal("Loadable keyboard tables not supported by this kernel", buf);
133: } else {
134: fatal("Selected entry is not a loadable keyboard table");
135: }
136: exit(0);
137: }
138:
139: /*
140: * Build or Update:
141: * Store keyboard driver name in file specified by KBDFILE.
142: * If loadable keyboard table selected, store name of keyboard
143: * table into /tmp/drvld.all if invoked from build,
144: * or to /etc/drvld.all if an update.
145: */
146: if (klist[n].k_loadable) {
147: sprintf(buf,
148: "/bin/echo %s >%s ; /bin/echo %s/%s >>%s/drvld.all",
149: klist[n].k_driver, KBDFILE,
150: KBDDIR, klist[n].k_table,
151: (bflag) ? "/tmp" : "/etc");
152: } else {
153: sprintf(buf, "/bin/echo %s >%s",
154: klist[n].k_driver, KBDFILE);
155: }
156: if (system(buf) != 0)
157: fatal("command \"%s\" failed", buf);
158:
159: printf( "Your keyboard selection will not take effect until after\n"
160: "your system %s has completed and the system has rebooted!\n",
161: bflag ? "installation" : "update");
162: /* Done. */
163: exit(0);
164: }
165:
166: /*
167: * Allocate a copy of a string and return a pointer to it.
168: */
169: char *
170: copystr(s) register char *s;
171: {
172: register char *cp;
173:
174: if ((cp = malloc(strlen(s) + 1)) == NULL)
175: fatal("no space for string \"%s\"");
176: strcpy(cp, s);
177: return cp;
178: }
179:
180: /*
181: * Display choice n.
182: */
183: void
184: display_line(n) register int n;
185: {
186: mvaddstr(KBDY+n, 12, klist[n].k_desc);
187: }
188:
189: /*
190: * Display choice n in reverse video.
191: */
192: void
193: display_rev(n) int n;
194: {
195: static int last = -1;
196:
197: if (last != -1)
198: display_line(last); /* redisplay last in normal */
199: standout();
200: display_line(n); /* display n in reverse */
201: standend();
202: last = n;
203: }
204:
205: /*
206: * Cry and die.
207: */
208: /* VARARGS */
209: void
210: fatal(s) char *s;
211: {
212: if (initflag)
213: endwin();
214: fprintf(stderr, "kbdinstall: %r\n", &s);
215: exit(1);
216: }
217:
218: /*
219: * Issue nonfatal informative message.
220: */
221: /* VARARGS */
222: void
223: nonfatal(s) char *s;
224: {
225: fprintf(stderr, "kbdinstall: %r\n", &s);
226: }
227:
228: /*
229: * Read a file containing keyboard file names and descriptions,
230: * build a keyboard list.
231: *
232: * Format of input is:
233: * # Comment line
234: * or
235: * Default <tab> Loadable <tab> Driver <tab> Table <tab> Descr.
236: */
237: void
238: read_klist()
239: {
240: register FILE *fp;
241: register unsigned char *s, *s1;
242:
243: if ((fp = fopen(KBDLIST, "r")) == NULL)
244: fatal("cannot open \"%s\"", KBDLIST);
245: while (fgets(buf, sizeof buf, fp) != NULL) {
246: if (buf[0] == '#')
247: continue; /* ignore comments */
248: if (nkbds == NKBDS) {
249: nonfatal("more than %d keyboard entries", NKBDS-1);
250: continue;
251: }
252:
253: /*
254: * Parse input lines and emit error messages if input bad.
255: */
256: if (buf[0] == 'Y' || buf[0] == 'y')
257: default_entry = nkbds;
258: if ((s = strchr(buf, '\t')) == NULL) {
259: format_error(buf);
260: continue;
261: }
262:
263: switch (*++s) {
264: case 'Y': case 'y':
265: klist[nkbds].k_loadable = TRUE;
266: break;
267: case 'N': case 'n':
268: if (!bflag && !uflag)
269: continue; /* ignore if interactive */
270: break;
271: default:
272: format_error(buf);
273: continue;
274: }
275: if ((s = strchr(++s, '\t')) == NULL) {
276: format_error(buf);
277: continue;
278: }
279: if ((s1 = strchr(++s, '\t')) == NULL) {
280: format_error(buf);
281: continue;
282: }
283: *s1++ = '\0';
284: klist[nkbds].k_driver = copystr(s); /* keyboard driver */
285: if ((s = strchr(s1, '\t')) == NULL) {
286: format_error(s1);
287: continue;
288: }
289: *s++ = '\0';
290: klist[nkbds].k_table = copystr(s1); /* keyboard table */
291: if ((s1 = strchr(s, '\n')) == NULL) {
292: nonfatal("no newline in \"%s\"", s);
293: continue;
294: }
295: *s1 = '\0';
296: klist[nkbds].k_desc = copystr(s); /* kbd description */
297:
298: nkbds++;
299: }
300: fclose(fp);
301: }
302:
303: /*
304: * Input error found: display an error message and continue.
305: */
306: void
307: format_error(line)
308: char *line;
309: {
310: nonfatal("Input format error found in \"%s\" -- ignored.", line);
311: }
312:
313: /* end of kbdinstall.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.