mv as from usr.bin to pgrm
[unix-history] / usr / src / old / configttys / configttys.c
CommitLineData
6880f830
SL
1
2#ifndef lint
3char sccsid[] = "@(#)configttys.c 4.4 (Berkeley) %G%";
4#endif
5
10c529ad
DW
6/*
7 * configttys - configure "tty" ports
8 *
9 * David L. Wasley
10 * U.C.Berkeley
11 */
12
10c529ad
DW
13#include <stdio.h>
14#include <getty.h>
15#include <signal.h>
16
17#define exists(file) (access(file, 0) == 0)
18
19char *etc_ttys = "/etc/ttys"; /* active port speed table */
20char *etc_ttytype = "/etc/ttytype"; /* terminal type table */
21char *etc_conf = "/etc/ttyconf"; /* master config file */
22char *lockfile = "/etc/ttyconf.lock"; /* interlock file */
23
24struct 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
30struct ttytype {
31 char tp_term[64]; /* terminal type name */
32 char tp_port[32]; /* port name */
33} ttytype[256];
34
35char conformat[] = "%s\t%s\t%s\t%s\n";
36
37int error = 0;
38int renamed = 0;
39int debug = 0; /* debug mode */
40int backup = 0; /* create backup copies of old data */
41int interactive = 1; /* interactive mode */
42
43char *speedname(); /* port speed code name */
44char speedchar(); /* getty table name */
45char *termname(); /* name of terminal on this port */
46char *rindex();
47struct ttytype *type(); /* find ttytype for port */
48FILE *fopen();
49
50main (argc, argv)
6880f830
SL
51 int argc;
52 char **argv;
10c529ad
DW
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
06e8262d
DW
178 fprintf(conf, conformat, "port", "login", "speed\t", "terminal type");
179 fprintf(conf, conformat, "----", "-----", "-----\t", "-------------");
10c529ad
DW
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 */
205re_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
6880f830
SL
297/*
298 * read ttys file
299 */
10c529ad
DW
300readttys()
301{
10c529ad
DW
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 {
bce6612a
DW
310 if (exists(etc_conf))
311 return (0); /* hope user has it together! */
10c529ad
DW
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
336writettys()
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
6880f830
SL
382/*
383 * invoke editor
384 */
10c529ad
DW
385edit()
386{
10c529ad
DW
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}
10c529ad
DW
411
412quit (n)
413int 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
424getlockfile ()
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}
6880f830 457
10c529ad
DW
458struct 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 " " " " */
6880f830
SL
476 { "crt", GT_CRT_HCPY }, /* 9600-300 CRT + hardcopy rotation */
477 { "hardcopy", GT_HCPY_CRT }, /* 300-9600 " " " */
10c529ad
DW
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 */
6880f830 484 { "network", GT_NETWORK }, /* network port */
10c529ad
DW
485 { "", 0 }
486};
487
488char *
489speedname (c)
6880f830 490 char c;
10c529ad
DW
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
510char *
511termname (port)
6880f830 512 char *port;
10c529ad
DW
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
530char
531speedchar (speed)
6880f830 532 char *speed;
10c529ad
DW
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
542struct ttytype *
543type (port)
6880f830 544 char *port;
10c529ad
DW
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}