|
|
1.1 root 1:
2: #ifndef lint
3: char sccsid[] = "@(#)configttys.c 4.4 (Berkeley) 6/19/83";
4: #endif
5:
6: /*
7: * configttys - configure "tty" ports
8: *
9: * David L. Wasley
10: * U.C.Berkeley
11: */
12:
13: #include <stdio.h>
14: #include <getty.h>
15: #include <signal.h>
16:
17: #define exists(file) (access(file, 0) == 0)
18:
19: char *etc_ttys = "/etc/ttys"; /* active port speed table */
20: char *etc_ttytype = "/etc/ttytype"; /* terminal type table */
21: char *etc_conf = "/etc/ttyconf"; /* master config file */
22: char *lockfile = "/etc/ttyconf.lock"; /* interlock file */
23:
24: struct ttys {
25: char ty_active; /* active login port */
26: char ty_speed; /* speed table character */
27: char ty_port[32]; /* port name */
28: } ttys[256];
29:
30: struct ttytype {
31: char tp_term[64]; /* terminal type name */
32: char tp_port[32]; /* port name */
33: } ttytype[256];
34:
35: char conformat[] = "%s\t%s\t%s\t%s\n";
36:
37: int error = 0;
38: int renamed = 0;
39: int debug = 0; /* debug mode */
40: int backup = 0; /* create backup copies of old data */
41: int interactive = 1; /* interactive mode */
42:
43: char *speedname(); /* port speed code name */
44: char speedchar(); /* getty table name */
45: char *termname(); /* name of terminal on this port */
46: char *rindex();
47: struct ttytype *type(); /* find ttytype for port */
48: FILE *fopen();
49:
50: main (argc, argv)
51: int argc;
52: char **argv;
53: {
54: int lineno;
55: int child;
56: int status;
57: char c;
58: struct ttys *ty;
59: struct ttytype *tp;
60: char port[32];
61: char active[16];
62: char speed[32];
63: char term[64];
64: FILE *tyf, *tpf, *conf;
65: char buf[1024];
66: char ans[32];
67:
68: while (--argc > 0)
69: {
70: if (**++argv == '-') switch (*++*argv)
71: {
72: case 'd':
73: debug = 1;
74: break;
75:
76: case 'n': /* non-interactive */
77: interactive = 0;
78: break;
79:
80: case 'b': /* backup old databases */
81: backup = 1;
82: break;
83:
84: default:
85: fprintf(stderr, "unknown option %c\n", **argv);
86: exit(1);
87: }
88: }
89:
90: if (debug)
91: {
92: etc_ttys = rindex(etc_ttys, '/') + 1;
93: etc_ttytype = rindex(etc_ttytype, '/') + 1;
94: etc_conf = rindex(etc_conf, '/') + 1;
95: lockfile = rindex(lockfile, '/') + 1;
96: }
97:
98: /*
99: * create backup copies of the databases?
100: */
101: if (backup)
102: {
103: if (exists(etc_ttys))
104: {
105: sprintf(buf, "/bin/cp %s %s.bak", etc_ttys, etc_ttys);
106: system(buf);
107: }
108: if (exists(etc_ttys))
109: {
110: sprintf(buf, "/bin/cp %s %s.bak", etc_ttytype, etc_ttytype);
111: system(buf);
112: }
113: if (exists(etc_conf))
114: {
115: sprintf(buf, "/bin/cp %s %s.bak", etc_conf, etc_conf);
116: system(buf);
117: }
118: }
119:
120: /*
121: * create interlock file
122: */
123: getlockfile(lockfile);
124:
125: /*
126: * always read ttys file for comparison
127: * It is afterall what really counts!
128: */
129: if (readttys() != 0)
130: quit(1);
131:
132: /*
133: * read old ttytypes if necessary
134: */
135: if (! exists(etc_conf))
136: {
137: /*
138: * open old ttytype file
139: */
140: if ((tpf = fopen(etc_ttytype, "r")) == NULL)
141: {
142: perror(etc_ttytype);
143: quit(1);
144: }
145:
146: /*
147: * read ttytype file
148: */
149: lineno = 0;
150: tp = ttytype;
151: while (fgets(buf, sizeof buf, tpf))
152: {
153: lineno++;
154: if (sscanf(buf, "%s %s", tp->tp_term, tp->tp_port) == 2)
155: tp++;
156: else
157: {
158: error++;
159: fprintf(stderr, "bad line %d in %s: %s",
160: lineno, etc_ttytype, buf);
161: }
162: }
163: fclose(tpf);
164: tp->tp_term[0] = '\0';
165:
166: if (error > 0)
167: quit(1);
168:
169: /*
170: * create master config file
171: */
172: if ((conf = fopen(etc_conf, "w")) == NULL)
173: {
174: perror(etc_conf);
175: quit(1);
176: }
177:
178: fprintf(conf, conformat, "port", "login", "speed\t", "terminal type");
179: fprintf(conf, conformat, "----", "-----", "-----\t", "-------------");
180: for (ty = ttys; ty->ty_active; ty++)
181: {
182: fprintf(conf, conformat, ty->ty_port,
183: ty->ty_active == '1'? "active":"-",
184: speedname(ty->ty_speed),
185: termname(ty->ty_port));
186: }
187: fclose(conf);
188: }
189:
190: /*
191: * open master config file
192: */
193: if ((conf = fopen(etc_conf, "r")) == NULL)
194: {
195: perror(etc_conf);
196: quit(1);
197: }
198:
199: if (interactive)
200: edit();
201:
202: /*
203: * read conf file
204: */
205: re_read:
206: rewind(conf);
207: ty = ttys;
208: renamed = 0;
209: error = 0;
210: lineno = 0;
211:
212: while (fgets(buf, sizeof buf, conf)) /* skip heading */
213: {
214: lineno++;
215: if (buf[0] == '-')
216: break;
217: }
218:
219: while (fgets(buf, sizeof buf, conf))
220: {
221: lineno++;
222: if (sscanf(buf, "%s %s %s %s", port, active, speed, term) < 4)
223: {
224: fprintf(stderr, "line %d: field(s) missing: %s",
225: lineno, buf);
226: error++;
227: break;
228: }
229:
230: if (strcmp(port, ty->ty_port) != 0)
231: {
232: if (! ty->ty_active || renamed)
233: strcpy(ty->ty_port, port);
234: else
235: {
236: fprintf(stderr, "line %d: port name changed! %s -> %s\n",
237: lineno, ty->ty_port, port);
238: fprintf(stderr, "Are you sure this is OK? ");
239: gets(ans);
240: if (ans[0] != 'y')
241: {
242: edit();
243: goto re_read;
244: }
245: renamed++;
246: strcpy(ty->ty_port, port);
247: }
248: }
249:
250: if (strcmp(active, "active") == 0)
251: ty->ty_active = '1';
252: else
253: ty->ty_active = '0';
254:
255: if (c = speedchar(speed))
256: ty->ty_speed = c;
257: else
258: {
259: fprintf(stderr, "line %d: speed name not known: %s\n",
260: lineno, speed);
261: error++;
262: }
263:
264: if (tp = type(port))
265: strcpy(tp->tp_term, term);
266: /* else ?? */
267:
268: ty++;
269: }
270:
271: if (ty == ttys)
272: {
273: fprintf(stderr, "%s empty??\n", etc_conf);
274: error++;
275: }
276:
277: if (error)
278: {
279: if (interactive)
280: {
281: fprintf(stderr, "re-edit? ");
282: gets(ans);
283: if (ans[0] == 'y')
284: {
285: edit();
286: goto re_read;
287: }
288: }
289: fprintf(stderr, "Files not modified.\n");
290: quit(1);
291: }
292:
293: writettys();
294: quit(0);
295: }
296:
297: /*
298: * read ttys file
299: */
300: readttys()
301: {
302: FILE *tyf;
303: register struct ttys *ty;
304: char buf[1024];
305: int lineno;
306: int error = 0;
307:
308: if ((tyf = fopen(etc_ttys, "r")) == NULL)
309: {
310: if (exists(etc_conf))
311: return (0); /* hope user has it together! */
312: perror(etc_ttys);
313: quit(1);
314: }
315:
316: lineno = 0;
317: ty = ttys;
318: while (fgets(buf, sizeof buf, tyf))
319: {
320: lineno++;
321: if (sscanf(buf, "%c%c%s",
322: &ty->ty_active, &ty->ty_speed, ty->ty_port) == 3)
323: ty++;
324: else
325: {
326: error++;
327: fprintf(stderr, "bad line %d in %s: %s",
328: lineno, etc_ttys, buf);
329: }
330: }
331: fclose(tyf);
332: ty->ty_active = '\0';
333: return(error);
334: }
335:
336: writettys()
337: {
338: int rtn = 0;
339: char temp[1024];
340: FILE *tyf, *tpf;
341: register struct ttys *ty;
342:
343: sprintf(temp, "%s.tmp", etc_ttys);
344: if ((tyf = fopen(temp, "w")) == NULL)
345: {
346: perror(temp);
347: quit(1);
348: }
349:
350: for (ty = ttys; ty->ty_active; ty++)
351: fprintf(tyf, "%c%c%s\n",
352: ty->ty_active, ty->ty_speed, ty->ty_port);
353: fclose(tyf);
354:
355: if (rename(temp, etc_ttys) != 0)
356: {
357: fprintf(stderr, "Can't rename %s\n", temp);
358: rtn = 1;
359: }
360:
361: sprintf(temp, "%s.tmp", etc_ttytype);
362: if ((tpf = fopen(temp, "w")) == NULL)
363: {
364: perror(temp);
365: quit(1);
366: }
367:
368: for (ty = ttys; ty->ty_active; ty++) /* same ports! */
369: fprintf(tpf, "%s %s\n",
370: type(ty->ty_port)->tp_term, ty->ty_port);
371: fclose(tpf);
372:
373: if (rename(temp, etc_ttytype) != 0)
374: {
375: fprintf(stderr, "Can't rename %s\n", temp);
376: rtn = 1;
377: }
378:
379: return (rtn);
380: }
381:
382: /*
383: * invoke editor
384: */
385: edit()
386: {
387: int child;
388: int status;
389:
390: if ((child = fork()) == 0)
391: {
392: execl("/usr/ucb/vi", "vi", etc_conf, 0);
393: execl("/bin/ed", "ed", etc_conf, 0);
394: exit(1);
395: }
396:
397: if (child < 0)
398: {
399: perror("can't fork editor");
400: quit(1);
401: }
402:
403: /*
404: * wait for editor
405: */
406: while (wait(&status) >= 0)
407: ;
408:
409: return (status);
410: }
411:
412: quit (n)
413: int n;
414: {
415: unlink (lockfile);
416: if (n > 1)
417: {
418: signal (n, SIG_DFL);
419: kill (getpid(), n);
420: }
421: exit (n);
422: }
423:
424: getlockfile ()
425: {
426: char *p;
427: char locktmp[64];
428: int fd;
429:
430: strcpy(locktmp, lockfile);
431: if (p = rindex(locktmp, '/'))
432: p++;
433: else
434: p = locktmp;
435: strcpy(p, "confttysXXXXXX");
436: mktemp(locktmp);
437:
438: if ((fd = creat(locktmp, 0600)) < 0)
439: {
440: perror(locktmp);
441: exit(1);
442: }
443:
444: if (link(locktmp, lockfile) < 0)
445: {
446: perror(lockfile);
447: unlink(locktmp);
448: exit(1);
449: }
450:
451: signal(SIGINT, quit);
452: signal(SIGQUIT, quit);
453:
454: unlink(locktmp);
455: return(0);
456: }
457:
458: struct speeds {
459: char *sp_name; /* human readable name */
460: char sp_table; /* getty table name */
461: } speeds[] = {
462: { "dialup", GT_DIALUP }, /* normal dialup rotation */
463: { "selector", GT_SELECTOR }, /* port selector pseudo-table autobaud*/
464: { "b110", GT_B110 }, /* 110 baud */
465: { "b134", GT_B134 }, /* 134.5 baud selectric */
466: { "b150", GT_B150 }, /* 150 baud */
467: { "b300", GT_B300 }, /* 300 baud */
468: { "b600", GT_B600 }, /* 600 baud */
469: { "b1200", GT_B1200 }, /* 1200 baud */
470: { "b2400", GT_B2400 }, /* 2400 baud */
471: { "b4800", GT_B4800 }, /* 4800 baud */
472: { "b9600", GT_B9600 }, /* 9600 baud */
473: { "dw2console", GT_DW2CONSOLE },/* Decwriter Console - 300 baud */
474: { "fastdialup", GT_FASTDIALUP },/* 1200-300 baud rotation for dialup */
475: { "fastdialup1",GT_FASTDIALUP1},/* 300-1200 " " " " */
476: { "crt", GT_CRT_HCPY }, /* 9600-300 CRT + hardcopy rotation */
477: { "hardcopy", GT_HCPY_CRT }, /* 300-9600 " " " */
478: { "plugboard", GT_PLUGBOARD }, /* 9600-300-1200 rotation */
479: { "plugboard1", GT_PLUGBOARD2 },/* 300-1200-9600 rotation */
480: { "plugboard2", GT_PLUGBOARD2 },/* 1200-9600-300 rotation */
481: { "interdata", GT_INTERDATA }, /* Interdata Console */
482: { "chess", GT_CHESS }, /* LSI Chess Terminal */
483: { "tty33", GT_TTY33 }, /* 110 baud Model 33 TTY */
484: { "network", GT_NETWORK }, /* network port */
485: { "", 0 }
486: };
487:
488: char *
489: speedname (c)
490: char c;
491: {
492: struct speeds *sp;
493: static char sbuf[32];
494:
495: for (sp = speeds; sp->sp_table; sp++)
496: if (sp->sp_table == c)
497: break;
498:
499: if (sp->sp_table)
500: strcpy(sbuf, sp->sp_name);
501: else
502: strcpy(sbuf, "-");
503:
504: if (strlen(sbuf) < 8)
505: strcat(sbuf, "\t");
506:
507: return (sbuf);
508: }
509:
510: char *
511: termname (port)
512: char *port;
513: {
514: register struct ttytype *tp;
515:
516: for (tp = ttytype; tp->tp_term[0]; tp++)
517: if (strcmp(port, tp->tp_port) == 0)
518: return (tp->tp_term);
519:
520: if (tp < &ttytype[(sizeof ttytype / sizeof (struct ttytype)) -1])
521: {
522: strcpy(tp->tp_port, port);
523: strcpy(tp->tp_term, "unknown");
524: (++tp)->tp_term[0] = '\0';
525: }
526:
527: return ("unknown");
528: }
529:
530: char
531: speedchar (speed)
532: char *speed;
533: {
534: register struct speeds *sp;
535:
536: for (sp = speeds; sp->sp_table; sp++)
537: if (strcmp(sp->sp_name, speed) == 0)
538: return (sp->sp_table);
539: return ('\0');
540: }
541:
542: struct ttytype *
543: type (port)
544: char *port;
545: {
546: register struct ttytype *tp;
547:
548: for (tp = ttytype; tp->tp_term[0]; tp++)
549: if (strcmp(tp->tp_port, port) == 0)
550: return (tp);
551:
552: if (tp < &ttytype[(sizeof ttytype / sizeof (struct ttytype)) -1])
553: {
554: strcpy(tp->tp_port, port);
555: strcpy(tp->tp_term, "unknown");
556: return(tp);
557: }
558:
559: return((struct ttytype *)0);
560: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.