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