#ifndef lint char sccsid[] = "@(#)configttys.c 4.4 (Berkeley) 06/19/83"; #endif /* * configttys - configure "tty" ports * * David L. Wasley * U.C.Berkeley */ #include #include #include #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); }