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