date and time created 88/12/12 20:54:51 by kfall
[unix-history] / usr / src / old / configttys / configttys.c
#ifndef lint
char sccsid[] = "@(#)configttys.c 4.4 (Berkeley) %G%";
#endif
/*
* configttys - configure "tty" ports
*
* David L. Wasley
* U.C.Berkeley
*/
#include <stdio.h>
#include <getty.h>
#include <signal.h>
#define exists(file) (access(file, 0) == 0)
char *etc_ttys = "/etc/ttys"; /* active port speed table */
char *etc_ttytype = "/etc/ttytype"; /* terminal type table */
char *etc_conf = "/etc/ttyconf"; /* master config file */
char *lockfile = "/etc/ttyconf.lock"; /* interlock file */
struct ttys {
char ty_active; /* active login port */
char ty_speed; /* speed table character */
char ty_port[32]; /* port name */
} ttys[256];
struct ttytype {
char tp_term[64]; /* terminal type name */
char tp_port[32]; /* port name */
} ttytype[256];
char conformat[] = "%s\t%s\t%s\t%s\n";
int error = 0;
int renamed = 0;
int debug = 0; /* debug mode */
int backup = 0; /* create backup copies of old data */
int interactive = 1; /* interactive mode */
char *speedname(); /* port speed code name */
char speedchar(); /* getty table name */
char *termname(); /* name of terminal on this port */
char *rindex();
struct ttytype *type(); /* find ttytype for port */
FILE *fopen();
main (argc, argv)
int argc;
char **argv;
{
int lineno;
int child;
int status;
char c;
struct ttys *ty;
struct ttytype *tp;
char port[32];
char active[16];
char speed[32];
char term[64];
FILE *tyf, *tpf, *conf;
char buf[1024];
char ans[32];
while (--argc > 0)
{
if (**++argv == '-') switch (*++*argv)
{
case 'd':
debug = 1;
break;
case 'n': /* non-interactive */
interactive = 0;
break;
case 'b': /* backup old databases */
backup = 1;
break;
default:
fprintf(stderr, "unknown option %c\n", **argv);
exit(1);
}
}
if (debug)
{
etc_ttys = rindex(etc_ttys, '/') + 1;
etc_ttytype = rindex(etc_ttytype, '/') + 1;
etc_conf = rindex(etc_conf, '/') + 1;
lockfile = rindex(lockfile, '/') + 1;
}
/*
* create backup copies of the databases?
*/
if (backup)
{
if (exists(etc_ttys))
{
sprintf(buf, "/bin/cp %s %s.bak", etc_ttys, etc_ttys);
system(buf);
}
if (exists(etc_ttys))
{
sprintf(buf, "/bin/cp %s %s.bak", etc_ttytype, etc_ttytype);
system(buf);
}
if (exists(etc_conf))
{
sprintf(buf, "/bin/cp %s %s.bak", etc_conf, etc_conf);
system(buf);
}
}
/*
* create interlock file
*/
getlockfile(lockfile);
/*
* always read ttys file for comparison
* It is afterall what really counts!
*/
if (readttys() != 0)
quit(1);
/*
* read old ttytypes if necessary
*/
if (! exists(etc_conf))
{
/*
* open old ttytype file
*/
if ((tpf = fopen(etc_ttytype, "r")) == NULL)
{
perror(etc_ttytype);
quit(1);
}
/*
* read ttytype file
*/
lineno = 0;
tp = ttytype;
while (fgets(buf, sizeof buf, tpf))
{
lineno++;
if (sscanf(buf, "%s %s", tp->tp_term, tp->tp_port) == 2)
tp++;
else
{
error++;
fprintf(stderr, "bad line %d in %s: %s",
lineno, etc_ttytype, buf);
}
}
fclose(tpf);
tp->tp_term[0] = '\0';
if (error > 0)
quit(1);
/*
* create master config file
*/
if ((conf = fopen(etc_conf, "w")) == NULL)
{
perror(etc_conf);
quit(1);
}
fprintf(conf, conformat, "port", "login", "speed\t", "terminal type");
fprintf(conf, conformat, "----", "-----", "-----\t", "-------------");
for (ty = ttys; ty->ty_active; ty++)
{
fprintf(conf, conformat, ty->ty_port,
ty->ty_active == '1'? "active":"-",
speedname(ty->ty_speed),
termname(ty->ty_port));
}
fclose(conf);
}
/*
* open master config file
*/
if ((conf = fopen(etc_conf, "r")) == NULL)
{
perror(etc_conf);
quit(1);
}
if (interactive)
edit();
/*
* read conf file
*/
re_read:
rewind(conf);
ty = ttys;
renamed = 0;
error = 0;
lineno = 0;
while (fgets(buf, sizeof buf, conf)) /* skip heading */
{
lineno++;
if (buf[0] == '-')
break;
}
while (fgets(buf, sizeof buf, conf))
{
lineno++;
if (sscanf(buf, "%s %s %s %s", port, active, speed, term) < 4)
{
fprintf(stderr, "line %d: field(s) missing: %s",
lineno, buf);
error++;
break;
}
if (strcmp(port, ty->ty_port) != 0)
{
if (! ty->ty_active || renamed)
strcpy(ty->ty_port, port);
else
{
fprintf(stderr, "line %d: port name changed! %s -> %s\n",
lineno, ty->ty_port, port);
fprintf(stderr, "Are you sure this is OK? ");
gets(ans);
if (ans[0] != 'y')
{
edit();
goto re_read;
}
renamed++;
strcpy(ty->ty_port, port);
}
}
if (strcmp(active, "active") == 0)
ty->ty_active = '1';
else
ty->ty_active = '0';
if (c = speedchar(speed))
ty->ty_speed = c;
else
{
fprintf(stderr, "line %d: speed name not known: %s\n",
lineno, speed);
error++;
}
if (tp = type(port))
strcpy(tp->tp_term, term);
/* else ?? */
ty++;
}
if (ty == ttys)
{
fprintf(stderr, "%s empty??\n", etc_conf);
error++;
}
if (error)
{
if (interactive)
{
fprintf(stderr, "re-edit? ");
gets(ans);
if (ans[0] == 'y')
{
edit();
goto re_read;
}
}
fprintf(stderr, "Files not modified.\n");
quit(1);
}
writettys();
quit(0);
}
/*
* read ttys file
*/
readttys()
{
FILE *tyf;
register struct ttys *ty;
char buf[1024];
int lineno;
int error = 0;
if ((tyf = fopen(etc_ttys, "r")) == NULL)
{
if (exists(etc_conf))
return (0); /* hope user has it together! */
perror(etc_ttys);
quit(1);
}
lineno = 0;
ty = ttys;
while (fgets(buf, sizeof buf, tyf))
{
lineno++;
if (sscanf(buf, "%c%c%s",
&ty->ty_active, &ty->ty_speed, ty->ty_port) == 3)
ty++;
else
{
error++;
fprintf(stderr, "bad line %d in %s: %s",
lineno, etc_ttys, buf);
}
}
fclose(tyf);
ty->ty_active = '\0';
return(error);
}
writettys()
{
int rtn = 0;
char temp[1024];
FILE *tyf, *tpf;
register struct ttys *ty;
sprintf(temp, "%s.tmp", etc_ttys);
if ((tyf = fopen(temp, "w")) == NULL)
{
perror(temp);
quit(1);
}
for (ty = ttys; ty->ty_active; ty++)
fprintf(tyf, "%c%c%s\n",
ty->ty_active, ty->ty_speed, ty->ty_port);
fclose(tyf);
if (rename(temp, etc_ttys) != 0)
{
fprintf(stderr, "Can't rename %s\n", temp);
rtn = 1;
}
sprintf(temp, "%s.tmp", etc_ttytype);
if ((tpf = fopen(temp, "w")) == NULL)
{
perror(temp);
quit(1);
}
for (ty = ttys; ty->ty_active; ty++) /* same ports! */
fprintf(tpf, "%s %s\n",
type(ty->ty_port)->tp_term, ty->ty_port);
fclose(tpf);
if (rename(temp, etc_ttytype) != 0)
{
fprintf(stderr, "Can't rename %s\n", temp);
rtn = 1;
}
return (rtn);
}
/*
* invoke editor
*/
edit()
{
int child;
int status;
if ((child = fork()) == 0)
{
execl("/usr/ucb/vi", "vi", etc_conf, 0);
execl("/bin/ed", "ed", etc_conf, 0);
exit(1);
}
if (child < 0)
{
perror("can't fork editor");
quit(1);
}
/*
* wait for editor
*/
while (wait(&status) >= 0)
;
return (status);
}
quit (n)
int n;
{
unlink (lockfile);
if (n > 1)
{
signal (n, SIG_DFL);
kill (getpid(), n);
}
exit (n);
}
getlockfile ()
{
char *p;
char locktmp[64];
int fd;
strcpy(locktmp, lockfile);
if (p = rindex(locktmp, '/'))
p++;
else
p = locktmp;
strcpy(p, "confttysXXXXXX");
mktemp(locktmp);
if ((fd = creat(locktmp, 0600)) < 0)
{
perror(locktmp);
exit(1);
}
if (link(locktmp, lockfile) < 0)
{
perror(lockfile);
unlink(locktmp);
exit(1);
}
signal(SIGINT, quit);
signal(SIGQUIT, quit);
unlink(locktmp);
return(0);
}
struct speeds {
char *sp_name; /* human readable name */
char sp_table; /* getty table name */
} speeds[] = {
{ "dialup", GT_DIALUP }, /* normal dialup rotation */
{ "selector", GT_SELECTOR }, /* port selector pseudo-table autobaud*/
{ "b110", GT_B110 }, /* 110 baud */
{ "b134", GT_B134 }, /* 134.5 baud selectric */
{ "b150", GT_B150 }, /* 150 baud */
{ "b300", GT_B300 }, /* 300 baud */
{ "b600", GT_B600 }, /* 600 baud */
{ "b1200", GT_B1200 }, /* 1200 baud */
{ "b2400", GT_B2400 }, /* 2400 baud */
{ "b4800", GT_B4800 }, /* 4800 baud */
{ "b9600", GT_B9600 }, /* 9600 baud */
{ "dw2console", GT_DW2CONSOLE },/* Decwriter Console - 300 baud */
{ "fastdialup", GT_FASTDIALUP },/* 1200-300 baud rotation for dialup */
{ "fastdialup1",GT_FASTDIALUP1},/* 300-1200 " " " " */
{ "crt", GT_CRT_HCPY }, /* 9600-300 CRT + hardcopy rotation */
{ "hardcopy", GT_HCPY_CRT }, /* 300-9600 " " " */
{ "plugboard", GT_PLUGBOARD }, /* 9600-300-1200 rotation */
{ "plugboard1", GT_PLUGBOARD2 },/* 300-1200-9600 rotation */
{ "plugboard2", GT_PLUGBOARD2 },/* 1200-9600-300 rotation */
{ "interdata", GT_INTERDATA }, /* Interdata Console */
{ "chess", GT_CHESS }, /* LSI Chess Terminal */
{ "tty33", GT_TTY33 }, /* 110 baud Model 33 TTY */
{ "network", GT_NETWORK }, /* network port */
{ "", 0 }
};
char *
speedname (c)
char c;
{
struct speeds *sp;
static char sbuf[32];
for (sp = speeds; sp->sp_table; sp++)
if (sp->sp_table == c)
break;
if (sp->sp_table)
strcpy(sbuf, sp->sp_name);
else
strcpy(sbuf, "-");
if (strlen(sbuf) < 8)
strcat(sbuf, "\t");
return (sbuf);
}
char *
termname (port)
char *port;
{
register struct ttytype *tp;
for (tp = ttytype; tp->tp_term[0]; tp++)
if (strcmp(port, tp->tp_port) == 0)
return (tp->tp_term);
if (tp < &ttytype[(sizeof ttytype / sizeof (struct ttytype)) -1])
{
strcpy(tp->tp_port, port);
strcpy(tp->tp_term, "unknown");
(++tp)->tp_term[0] = '\0';
}
return ("unknown");
}
char
speedchar (speed)
char *speed;
{
register struct speeds *sp;
for (sp = speeds; sp->sp_table; sp++)
if (strcmp(sp->sp_name, speed) == 0)
return (sp->sp_table);
return ('\0');
}
struct ttytype *
type (port)
char *port;
{
register struct ttytype *tp;
for (tp = ttytype; tp->tp_term[0]; tp++)
if (strcmp(tp->tp_port, port) == 0)
return (tp);
if (tp < &ttytype[(sizeof ttytype / sizeof (struct ttytype)) -1])
{
strcpy(tp->tp_port, port);
strcpy(tp->tp_term, "unknown");
return(tp);
}
return((struct ttytype *)0);
}