1*13206Ssam
2*13206Ssam #ifndef lint
3*13206Ssam char sccsid[] = "@(#)configttys.c 4.4 (Berkeley) 06/19/83";
4*13206Ssam #endif
5*13206Ssam
612530Sdlw /*
712530Sdlw * configttys - configure "tty" ports
812530Sdlw *
912530Sdlw * David L. Wasley
1012530Sdlw * U.C.Berkeley
1112530Sdlw */
1212530Sdlw
1312530Sdlw #include <stdio.h>
1412530Sdlw #include <getty.h>
1512530Sdlw #include <signal.h>
1612530Sdlw
1712530Sdlw #define exists(file) (access(file, 0) == 0)
1812530Sdlw
1912530Sdlw char *etc_ttys = "/etc/ttys"; /* active port speed table */
2012530Sdlw char *etc_ttytype = "/etc/ttytype"; /* terminal type table */
2112530Sdlw char *etc_conf = "/etc/ttyconf"; /* master config file */
2212530Sdlw char *lockfile = "/etc/ttyconf.lock"; /* interlock file */
2312530Sdlw
2412530Sdlw struct ttys {
2512530Sdlw char ty_active; /* active login port */
2612530Sdlw char ty_speed; /* speed table character */
2712530Sdlw char ty_port[32]; /* port name */
2812530Sdlw } ttys[256];
2912530Sdlw
3012530Sdlw struct ttytype {
3112530Sdlw char tp_term[64]; /* terminal type name */
3212530Sdlw char tp_port[32]; /* port name */
3312530Sdlw } ttytype[256];
3412530Sdlw
3512530Sdlw char conformat[] = "%s\t%s\t%s\t%s\n";
3612530Sdlw
3712530Sdlw int error = 0;
3812530Sdlw int renamed = 0;
3912530Sdlw int debug = 0; /* debug mode */
4012530Sdlw int backup = 0; /* create backup copies of old data */
4112530Sdlw int interactive = 1; /* interactive mode */
4212530Sdlw
4312530Sdlw char *speedname(); /* port speed code name */
4412530Sdlw char speedchar(); /* getty table name */
4512530Sdlw char *termname(); /* name of terminal on this port */
4612530Sdlw char *rindex();
4712530Sdlw struct ttytype *type(); /* find ttytype for port */
4812530Sdlw FILE *fopen();
4912530Sdlw
main(argc,argv)5012530Sdlw main (argc, argv)
51*13206Ssam int argc;
52*13206Ssam char **argv;
5312530Sdlw {
5412530Sdlw int lineno;
5512530Sdlw int child;
5612530Sdlw int status;
5712530Sdlw char c;
5812530Sdlw struct ttys *ty;
5912530Sdlw struct ttytype *tp;
6012530Sdlw char port[32];
6112530Sdlw char active[16];
6212530Sdlw char speed[32];
6312530Sdlw char term[64];
6412530Sdlw FILE *tyf, *tpf, *conf;
6512530Sdlw char buf[1024];
6612530Sdlw char ans[32];
6712530Sdlw
6812530Sdlw while (--argc > 0)
6912530Sdlw {
7012530Sdlw if (**++argv == '-') switch (*++*argv)
7112530Sdlw {
7212530Sdlw case 'd':
7312530Sdlw debug = 1;
7412530Sdlw break;
7512530Sdlw
7612530Sdlw case 'n': /* non-interactive */
7712530Sdlw interactive = 0;
7812530Sdlw break;
7912530Sdlw
8012530Sdlw case 'b': /* backup old databases */
8112530Sdlw backup = 1;
8212530Sdlw break;
8312530Sdlw
8412530Sdlw default:
8512530Sdlw fprintf(stderr, "unknown option %c\n", **argv);
8612530Sdlw exit(1);
8712530Sdlw }
8812530Sdlw }
8912530Sdlw
9012530Sdlw if (debug)
9112530Sdlw {
9212530Sdlw etc_ttys = rindex(etc_ttys, '/') + 1;
9312530Sdlw etc_ttytype = rindex(etc_ttytype, '/') + 1;
9412530Sdlw etc_conf = rindex(etc_conf, '/') + 1;
9512530Sdlw lockfile = rindex(lockfile, '/') + 1;
9612530Sdlw }
9712530Sdlw
9812530Sdlw /*
9912530Sdlw * create backup copies of the databases?
10012530Sdlw */
10112530Sdlw if (backup)
10212530Sdlw {
10312530Sdlw if (exists(etc_ttys))
10412530Sdlw {
10512530Sdlw sprintf(buf, "/bin/cp %s %s.bak", etc_ttys, etc_ttys);
10612530Sdlw system(buf);
10712530Sdlw }
10812530Sdlw if (exists(etc_ttys))
10912530Sdlw {
11012530Sdlw sprintf(buf, "/bin/cp %s %s.bak", etc_ttytype, etc_ttytype);
11112530Sdlw system(buf);
11212530Sdlw }
11312530Sdlw if (exists(etc_conf))
11412530Sdlw {
11512530Sdlw sprintf(buf, "/bin/cp %s %s.bak", etc_conf, etc_conf);
11612530Sdlw system(buf);
11712530Sdlw }
11812530Sdlw }
11912530Sdlw
12012530Sdlw /*
12112530Sdlw * create interlock file
12212530Sdlw */
12312530Sdlw getlockfile(lockfile);
12412530Sdlw
12512530Sdlw /*
12612530Sdlw * always read ttys file for comparison
12712530Sdlw * It is afterall what really counts!
12812530Sdlw */
12912530Sdlw if (readttys() != 0)
13012530Sdlw quit(1);
13112530Sdlw
13212530Sdlw /*
13312530Sdlw * read old ttytypes if necessary
13412530Sdlw */
13512530Sdlw if (! exists(etc_conf))
13612530Sdlw {
13712530Sdlw /*
13812530Sdlw * open old ttytype file
13912530Sdlw */
14012530Sdlw if ((tpf = fopen(etc_ttytype, "r")) == NULL)
14112530Sdlw {
14212530Sdlw perror(etc_ttytype);
14312530Sdlw quit(1);
14412530Sdlw }
14512530Sdlw
14612530Sdlw /*
14712530Sdlw * read ttytype file
14812530Sdlw */
14912530Sdlw lineno = 0;
15012530Sdlw tp = ttytype;
15112530Sdlw while (fgets(buf, sizeof buf, tpf))
15212530Sdlw {
15312530Sdlw lineno++;
15412530Sdlw if (sscanf(buf, "%s %s", tp->tp_term, tp->tp_port) == 2)
15512530Sdlw tp++;
15612530Sdlw else
15712530Sdlw {
15812530Sdlw error++;
15912530Sdlw fprintf(stderr, "bad line %d in %s: %s",
16012530Sdlw lineno, etc_ttytype, buf);
16112530Sdlw }
16212530Sdlw }
16312530Sdlw fclose(tpf);
16412530Sdlw tp->tp_term[0] = '\0';
16512530Sdlw
16612530Sdlw if (error > 0)
16712530Sdlw quit(1);
16812530Sdlw
16912530Sdlw /*
17012530Sdlw * create master config file
17112530Sdlw */
17212530Sdlw if ((conf = fopen(etc_conf, "w")) == NULL)
17312530Sdlw {
17412530Sdlw perror(etc_conf);
17512530Sdlw quit(1);
17612530Sdlw }
17712530Sdlw
17812537Sdlw fprintf(conf, conformat, "port", "login", "speed\t", "terminal type");
17912537Sdlw fprintf(conf, conformat, "----", "-----", "-----\t", "-------------");
18012530Sdlw for (ty = ttys; ty->ty_active; ty++)
18112530Sdlw {
18212530Sdlw fprintf(conf, conformat, ty->ty_port,
18312530Sdlw ty->ty_active == '1'? "active":"-",
18412530Sdlw speedname(ty->ty_speed),
18512530Sdlw termname(ty->ty_port));
18612530Sdlw }
18712530Sdlw fclose(conf);
18812530Sdlw }
18912530Sdlw
19012530Sdlw /*
19112530Sdlw * open master config file
19212530Sdlw */
19312530Sdlw if ((conf = fopen(etc_conf, "r")) == NULL)
19412530Sdlw {
19512530Sdlw perror(etc_conf);
19612530Sdlw quit(1);
19712530Sdlw }
19812530Sdlw
19912530Sdlw if (interactive)
20012530Sdlw edit();
20112530Sdlw
20212530Sdlw /*
20312530Sdlw * read conf file
20412530Sdlw */
20512530Sdlw re_read:
20612530Sdlw rewind(conf);
20712530Sdlw ty = ttys;
20812530Sdlw renamed = 0;
20912530Sdlw error = 0;
21012530Sdlw lineno = 0;
21112530Sdlw
21212530Sdlw while (fgets(buf, sizeof buf, conf)) /* skip heading */
21312530Sdlw {
21412530Sdlw lineno++;
21512530Sdlw if (buf[0] == '-')
21612530Sdlw break;
21712530Sdlw }
21812530Sdlw
21912530Sdlw while (fgets(buf, sizeof buf, conf))
22012530Sdlw {
22112530Sdlw lineno++;
22212530Sdlw if (sscanf(buf, "%s %s %s %s", port, active, speed, term) < 4)
22312530Sdlw {
22412530Sdlw fprintf(stderr, "line %d: field(s) missing: %s",
22512530Sdlw lineno, buf);
22612530Sdlw error++;
22712530Sdlw break;
22812530Sdlw }
22912530Sdlw
23012530Sdlw if (strcmp(port, ty->ty_port) != 0)
23112530Sdlw {
23212530Sdlw if (! ty->ty_active || renamed)
23312530Sdlw strcpy(ty->ty_port, port);
23412530Sdlw else
23512530Sdlw {
23612530Sdlw fprintf(stderr, "line %d: port name changed! %s -> %s\n",
23712530Sdlw lineno, ty->ty_port, port);
23812530Sdlw fprintf(stderr, "Are you sure this is OK? ");
23912530Sdlw gets(ans);
24012530Sdlw if (ans[0] != 'y')
24112530Sdlw {
24212530Sdlw edit();
24312530Sdlw goto re_read;
24412530Sdlw }
24512530Sdlw renamed++;
24612530Sdlw strcpy(ty->ty_port, port);
24712530Sdlw }
24812530Sdlw }
24912530Sdlw
25012530Sdlw if (strcmp(active, "active") == 0)
25112530Sdlw ty->ty_active = '1';
25212530Sdlw else
25312530Sdlw ty->ty_active = '0';
25412530Sdlw
25512530Sdlw if (c = speedchar(speed))
25612530Sdlw ty->ty_speed = c;
25712530Sdlw else
25812530Sdlw {
25912530Sdlw fprintf(stderr, "line %d: speed name not known: %s\n",
26012530Sdlw lineno, speed);
26112530Sdlw error++;
26212530Sdlw }
26312530Sdlw
26412530Sdlw if (tp = type(port))
26512530Sdlw strcpy(tp->tp_term, term);
26612530Sdlw /* else ?? */
26712530Sdlw
26812530Sdlw ty++;
26912530Sdlw }
27012530Sdlw
27112530Sdlw if (ty == ttys)
27212530Sdlw {
27312530Sdlw fprintf(stderr, "%s empty??\n", etc_conf);
27412530Sdlw error++;
27512530Sdlw }
27612530Sdlw
27712530Sdlw if (error)
27812530Sdlw {
27912530Sdlw if (interactive)
28012530Sdlw {
28112530Sdlw fprintf(stderr, "re-edit? ");
28212530Sdlw gets(ans);
28312530Sdlw if (ans[0] == 'y')
28412530Sdlw {
28512530Sdlw edit();
28612530Sdlw goto re_read;
28712530Sdlw }
28812530Sdlw }
28912530Sdlw fprintf(stderr, "Files not modified.\n");
29012530Sdlw quit(1);
29112530Sdlw }
29212530Sdlw
29312530Sdlw writettys();
29412530Sdlw quit(0);
29512530Sdlw }
29612530Sdlw
297*13206Ssam /*
298*13206Ssam * read ttys file
299*13206Ssam */
readttys()30012530Sdlw readttys()
30112530Sdlw {
30212530Sdlw FILE *tyf;
30312530Sdlw register struct ttys *ty;
30412530Sdlw char buf[1024];
30512530Sdlw int lineno;
30612530Sdlw int error = 0;
30712530Sdlw
30812530Sdlw if ((tyf = fopen(etc_ttys, "r")) == NULL)
30912530Sdlw {
31012566Sdlw if (exists(etc_conf))
31112566Sdlw return (0); /* hope user has it together! */
31212530Sdlw perror(etc_ttys);
31312530Sdlw quit(1);
31412530Sdlw }
31512530Sdlw
31612530Sdlw lineno = 0;
31712530Sdlw ty = ttys;
31812530Sdlw while (fgets(buf, sizeof buf, tyf))
31912530Sdlw {
32012530Sdlw lineno++;
32112530Sdlw if (sscanf(buf, "%c%c%s",
32212530Sdlw &ty->ty_active, &ty->ty_speed, ty->ty_port) == 3)
32312530Sdlw ty++;
32412530Sdlw else
32512530Sdlw {
32612530Sdlw error++;
32712530Sdlw fprintf(stderr, "bad line %d in %s: %s",
32812530Sdlw lineno, etc_ttys, buf);
32912530Sdlw }
33012530Sdlw }
33112530Sdlw fclose(tyf);
33212530Sdlw ty->ty_active = '\0';
33312530Sdlw return(error);
33412530Sdlw }
33512530Sdlw
writettys()33612530Sdlw writettys()
33712530Sdlw {
33812530Sdlw int rtn = 0;
33912530Sdlw char temp[1024];
34012530Sdlw FILE *tyf, *tpf;
34112530Sdlw register struct ttys *ty;
34212530Sdlw
34312530Sdlw sprintf(temp, "%s.tmp", etc_ttys);
34412530Sdlw if ((tyf = fopen(temp, "w")) == NULL)
34512530Sdlw {
34612530Sdlw perror(temp);
34712530Sdlw quit(1);
34812530Sdlw }
34912530Sdlw
35012530Sdlw for (ty = ttys; ty->ty_active; ty++)
35112530Sdlw fprintf(tyf, "%c%c%s\n",
35212530Sdlw ty->ty_active, ty->ty_speed, ty->ty_port);
35312530Sdlw fclose(tyf);
35412530Sdlw
35512530Sdlw if (rename(temp, etc_ttys) != 0)
35612530Sdlw {
35712530Sdlw fprintf(stderr, "Can't rename %s\n", temp);
35812530Sdlw rtn = 1;
35912530Sdlw }
36012530Sdlw
36112530Sdlw sprintf(temp, "%s.tmp", etc_ttytype);
36212530Sdlw if ((tpf = fopen(temp, "w")) == NULL)
36312530Sdlw {
36412530Sdlw perror(temp);
36512530Sdlw quit(1);
36612530Sdlw }
36712530Sdlw
36812530Sdlw for (ty = ttys; ty->ty_active; ty++) /* same ports! */
36912530Sdlw fprintf(tpf, "%s %s\n",
37012530Sdlw type(ty->ty_port)->tp_term, ty->ty_port);
37112530Sdlw fclose(tpf);
37212530Sdlw
37312530Sdlw if (rename(temp, etc_ttytype) != 0)
37412530Sdlw {
37512530Sdlw fprintf(stderr, "Can't rename %s\n", temp);
37612530Sdlw rtn = 1;
37712530Sdlw }
37812530Sdlw
37912530Sdlw return (rtn);
38012530Sdlw }
38112530Sdlw
382*13206Ssam /*
383*13206Ssam * invoke editor
384*13206Ssam */
edit()38512530Sdlw edit()
38612530Sdlw {
38712530Sdlw int child;
38812530Sdlw int status;
38912530Sdlw
39012530Sdlw if ((child = fork()) == 0)
39112530Sdlw {
39212530Sdlw execl("/usr/ucb/vi", "vi", etc_conf, 0);
39312530Sdlw execl("/bin/ed", "ed", etc_conf, 0);
39412530Sdlw exit(1);
39512530Sdlw }
39612530Sdlw
39712530Sdlw if (child < 0)
39812530Sdlw {
39912530Sdlw perror("can't fork editor");
40012530Sdlw quit(1);
40112530Sdlw }
40212530Sdlw
40312530Sdlw /*
40412530Sdlw * wait for editor
40512530Sdlw */
40612530Sdlw while (wait(&status) >= 0)
40712530Sdlw ;
40812530Sdlw
40912530Sdlw return (status);
41012530Sdlw }
41112530Sdlw
quit(n)41212530Sdlw quit (n)
41312530Sdlw int n;
41412530Sdlw {
41512530Sdlw unlink (lockfile);
41612530Sdlw if (n > 1)
41712530Sdlw {
41812530Sdlw signal (n, SIG_DFL);
41912530Sdlw kill (getpid(), n);
42012530Sdlw }
42112530Sdlw exit (n);
42212530Sdlw }
42312530Sdlw
getlockfile()42412530Sdlw getlockfile ()
42512530Sdlw {
42612530Sdlw char *p;
42712530Sdlw char locktmp[64];
42812530Sdlw int fd;
42912530Sdlw
43012530Sdlw strcpy(locktmp, lockfile);
43112530Sdlw if (p = rindex(locktmp, '/'))
43212530Sdlw p++;
43312530Sdlw else
43412530Sdlw p = locktmp;
43512530Sdlw strcpy(p, "confttysXXXXXX");
43612530Sdlw mktemp(locktmp);
43712530Sdlw
43812530Sdlw if ((fd = creat(locktmp, 0600)) < 0)
43912530Sdlw {
44012530Sdlw perror(locktmp);
44112530Sdlw exit(1);
44212530Sdlw }
44312530Sdlw
44412530Sdlw if (link(locktmp, lockfile) < 0)
44512530Sdlw {
44612530Sdlw perror(lockfile);
44712530Sdlw unlink(locktmp);
44812530Sdlw exit(1);
44912530Sdlw }
45012530Sdlw
45112530Sdlw signal(SIGINT, quit);
45212530Sdlw signal(SIGQUIT, quit);
45312530Sdlw
45412530Sdlw unlink(locktmp);
45512530Sdlw return(0);
45612530Sdlw }
457*13206Ssam
45812530Sdlw struct speeds {
45912530Sdlw char *sp_name; /* human readable name */
46012530Sdlw char sp_table; /* getty table name */
46112530Sdlw } speeds[] = {
46212530Sdlw { "dialup", GT_DIALUP }, /* normal dialup rotation */
46312530Sdlw { "selector", GT_SELECTOR }, /* port selector pseudo-table autobaud*/
46412530Sdlw { "b110", GT_B110 }, /* 110 baud */
46512530Sdlw { "b134", GT_B134 }, /* 134.5 baud selectric */
46612530Sdlw { "b150", GT_B150 }, /* 150 baud */
46712530Sdlw { "b300", GT_B300 }, /* 300 baud */
46812530Sdlw { "b600", GT_B600 }, /* 600 baud */
46912530Sdlw { "b1200", GT_B1200 }, /* 1200 baud */
47012530Sdlw { "b2400", GT_B2400 }, /* 2400 baud */
47112530Sdlw { "b4800", GT_B4800 }, /* 4800 baud */
47212530Sdlw { "b9600", GT_B9600 }, /* 9600 baud */
47312530Sdlw { "dw2console", GT_DW2CONSOLE },/* Decwriter Console - 300 baud */
47412530Sdlw { "fastdialup", GT_FASTDIALUP },/* 1200-300 baud rotation for dialup */
47512530Sdlw { "fastdialup1",GT_FASTDIALUP1},/* 300-1200 " " " " */
476*13206Ssam { "crt", GT_CRT_HCPY }, /* 9600-300 CRT + hardcopy rotation */
477*13206Ssam { "hardcopy", GT_HCPY_CRT }, /* 300-9600 " " " */
47812530Sdlw { "plugboard", GT_PLUGBOARD }, /* 9600-300-1200 rotation */
47912530Sdlw { "plugboard1", GT_PLUGBOARD2 },/* 300-1200-9600 rotation */
48012530Sdlw { "plugboard2", GT_PLUGBOARD2 },/* 1200-9600-300 rotation */
48112530Sdlw { "interdata", GT_INTERDATA }, /* Interdata Console */
48212530Sdlw { "chess", GT_CHESS }, /* LSI Chess Terminal */
48312530Sdlw { "tty33", GT_TTY33 }, /* 110 baud Model 33 TTY */
484*13206Ssam { "network", GT_NETWORK }, /* network port */
48512530Sdlw { "", 0 }
48612530Sdlw };
48712530Sdlw
48812530Sdlw char *
speedname(c)48912530Sdlw speedname (c)
490*13206Ssam char c;
49112530Sdlw {
49212530Sdlw struct speeds *sp;
49312530Sdlw static char sbuf[32];
49412530Sdlw
49512530Sdlw for (sp = speeds; sp->sp_table; sp++)
49612530Sdlw if (sp->sp_table == c)
49712530Sdlw break;
49812530Sdlw
49912530Sdlw if (sp->sp_table)
50012530Sdlw strcpy(sbuf, sp->sp_name);
50112530Sdlw else
50212530Sdlw strcpy(sbuf, "-");
50312530Sdlw
50412530Sdlw if (strlen(sbuf) < 8)
50512530Sdlw strcat(sbuf, "\t");
50612530Sdlw
50712530Sdlw return (sbuf);
50812530Sdlw }
50912530Sdlw
51012530Sdlw char *
termname(port)51112530Sdlw termname (port)
512*13206Ssam char *port;
51312530Sdlw {
51412530Sdlw register struct ttytype *tp;
51512530Sdlw
51612530Sdlw for (tp = ttytype; tp->tp_term[0]; tp++)
51712530Sdlw if (strcmp(port, tp->tp_port) == 0)
51812530Sdlw return (tp->tp_term);
51912530Sdlw
52012530Sdlw if (tp < &ttytype[(sizeof ttytype / sizeof (struct ttytype)) -1])
52112530Sdlw {
52212530Sdlw strcpy(tp->tp_port, port);
52312530Sdlw strcpy(tp->tp_term, "unknown");
52412530Sdlw (++tp)->tp_term[0] = '\0';
52512530Sdlw }
52612530Sdlw
52712530Sdlw return ("unknown");
52812530Sdlw }
52912530Sdlw
53012530Sdlw char
speedchar(speed)53112530Sdlw speedchar (speed)
532*13206Ssam char *speed;
53312530Sdlw {
53412530Sdlw register struct speeds *sp;
53512530Sdlw
53612530Sdlw for (sp = speeds; sp->sp_table; sp++)
53712530Sdlw if (strcmp(sp->sp_name, speed) == 0)
53812530Sdlw return (sp->sp_table);
53912530Sdlw return ('\0');
54012530Sdlw }
54112530Sdlw
54212530Sdlw struct ttytype *
type(port)54312530Sdlw type (port)
544*13206Ssam char *port;
54512530Sdlw {
54612530Sdlw register struct ttytype *tp;
54712530Sdlw
54812530Sdlw for (tp = ttytype; tp->tp_term[0]; tp++)
54912530Sdlw if (strcmp(tp->tp_port, port) == 0)
55012530Sdlw return (tp);
55112530Sdlw
55212530Sdlw if (tp < &ttytype[(sizeof ttytype / sizeof (struct ttytype)) -1])
55312530Sdlw {
55412530Sdlw strcpy(tp->tp_port, port);
55512530Sdlw strcpy(tp->tp_term, "unknown");
55612530Sdlw return(tp);
55712530Sdlw }
55812530Sdlw
55912530Sdlw return((struct ttytype *)0);
56012530Sdlw }
561