118480Sralph #ifndef lint 2*23723Sbloom static char sccsid[] = "@(#)acucntrl.c 5.4 (Berkeley) 06/24/85"; 318480Sralph #endif 418480Sralph 518480Sralph /* acucntrl - turn around tty line between dialin and dialout 618480Sralph * 718480Sralph * Usage: acucntrl {enable,disable} /dev/ttydX 818480Sralph * 918480Sralph * History: 1018480Sralph * First written by Allan Wilkes (fisher!allan) 1118480Sralph * 1218480Sralph * Modified June 8,1983 by W.Sebok (astrovax!wls) to poke kernel rather 1318480Sralph * than use kernel hack to turn on/off modem control, using subroutine 1418480Sralph * stolen from program written by Tsutomu Shimomura 1518480Sralph * {astrovax,escher}!tsutomu 1618480Sralph * 1718480Sralph * Worked over many times by W.Sebok (i.e. hacked to death) 1818480Sralph * 1918480Sralph * Operation: 2018480Sralph * disable (i.e. setup for dialing out) 2118480Sralph * (1) check input arguments 2218480Sralph * (2) look in /etc/utmp to check that the line is not in use by another 2318480Sralph * (3) disable modem control on terminal 2418480Sralph * (4) check for carrier on device 2518480Sralph * (5) change owner of device to real id 2618480Sralph * (6) edit /etc/ttys, changing the first character of the appropriate 2718480Sralph * line to 0 2818480Sralph * (7) send a hangup to process 1 to poke init to disable getty 2918480Sralph * (8) post uid name in capitals in /etc/utmp to let world know device has 3018480Sralph * been grabbed 3118480Sralph * (9) make sure that DTR is on 3218480Sralph * 3318480Sralph * enable (i.e.) restore for dialin 3418480Sralph * (1) check input arguments 3518480Sralph * (2) look in /etc/utmp to check that the line is not in use by another 3618480Sralph * (3) make sure modem control on terminal is disabled 3718480Sralph * (4) turn off DTR to make sure line is hung up 3818480Sralph * (5) condition line: clear exclusive use and set hangup on close modes 3918480Sralph * (6) turn on modem control 4018480Sralph * (7) edit /etc/ttys, changing the first character of the appropriate 4118480Sralph * line to 1 4218480Sralph * (8) send a hangup to process 1 to poke init to enable getty 4318480Sralph * (9) clear uid name for /etc/utmp 4418480Sralph */ 4518480Sralph 4618480Sralph /* #define SENSECARRIER */ 4718480Sralph 4818480Sralph #include "uucp.h" 4918480Sralph #include <sys/buf.h> 5018614Sralph #include <signal.h> 5118480Sralph #include <sys/conf.h> 5218480Sralph #ifdef BSD4_2 5323583Sbloom #include <vaxuba/ubavar.h> 5418614Sralph #else 5518480Sralph #include <sys/ubavar.h> 5618614Sralph #endif 5718480Sralph #include <sys/stat.h> 5818480Sralph #include <nlist.h> 5918480Sralph #include <sgtty.h> 6018480Sralph #include <utmp.h> 6118480Sralph #include <pwd.h> 6218480Sralph #include <stdio.h> 6318480Sralph 6418480Sralph #define NDZLINE 8 /* lines/dz */ 6518480Sralph #define NDHLINE 16 /* lines/dh */ 6618480Sralph #define NDMFLINE 8 /* lines/dmf */ 6718480Sralph 6818480Sralph #define DZ11 1 6918480Sralph #define DH11 2 7018480Sralph #define DMF 3 7118480Sralph 7218480Sralph #define NLVALUE(val) (nl[val].n_value) 7318480Sralph 7418480Sralph struct nlist nl[] = { 7518480Sralph #define CDEVSW 0 7618480Sralph { "_cdevsw" }, 7718480Sralph 7818480Sralph #define DZOPEN 1 7918480Sralph { "_dzopen" }, 8018480Sralph #define DZINFO 2 8118480Sralph { "_dzinfo" }, 8218480Sralph #define NDZ11 3 8318480Sralph { "_dz_cnt" }, 8418480Sralph #define DZSCAR 4 8518480Sralph { "_dzsoftCAR" }, 8618480Sralph 8718480Sralph #define DHOPEN 5 8818480Sralph { "_dhopen" }, 8918480Sralph #define DHINFO 6 9018480Sralph { "_dhinfo" }, 9118480Sralph #define NDH11 7 9218480Sralph { "_ndh11" }, 9318480Sralph #define DHSCAR 8 9418480Sralph { "_dhsoftCAR" }, 9518480Sralph 9618480Sralph #define DMFOPEN 9 9718480Sralph { "_dmfopen" }, 9818480Sralph #define DMFINFO 10 9918480Sralph { "_dmfinfo" }, 10018480Sralph #define NDMF 11 10118480Sralph { "_ndmf" }, 10218480Sralph #define DMFSCAR 12 10318480Sralph { "_dmfsoftCAR" }, 10418480Sralph 10518480Sralph { "\0" } 10618480Sralph }; 10718480Sralph 10818480Sralph #define ENABLE 1 10918480Sralph #define DISABLE 0 11018480Sralph 11118480Sralph char Etcutmp[] = "/etc/utmp"; 11218480Sralph char Etcttys[] = "/etc/ttys"; 113*23723Sbloom #ifdef BSD4_3 114*23723Sbloom char NEtcttys[] = "/etc/ttys.new"; 115*23723Sbloom extern long ftell(); 116*23723Sbloom #endif BSD4_3 11718480Sralph char Devhome[] = "/dev"; 11818480Sralph 11918480Sralph char usage[] = "Usage: acucntrl {dis|en}able ttydX\n"; 12018480Sralph 12118480Sralph struct utmp utmp; 12218480Sralph char resettty, resetmodem; 12318480Sralph int etcutmp; 12418614Sralph off_t utmploc; 12518614Sralph off_t ttyslnbeg; 12618480Sralph 12718480Sralph #define NAMSIZ sizeof(utmp.ut_name) 12818480Sralph #define LINSIZ sizeof(utmp.ut_line) 12918480Sralph 13018480Sralph main(argc, argv) 13118480Sralph int argc; char *argv[]; 13218480Sralph { 13318480Sralph register char *p; 13418480Sralph register int i; 13518480Sralph char uname[NAMSIZ], Uname[NAMSIZ]; 13618480Sralph int enable ; 13718480Sralph char *device; 13818480Sralph int devfile; 13918480Sralph int uid, gid; 14018614Sralph off_t lseek(); 14118480Sralph struct passwd *getpwuid(); 14218480Sralph char *rindex(); 14318480Sralph extern int errno; 14418480Sralph extern char *sys_errlist[]; 14518480Sralph 14618480Sralph /* check input arguments */ 14718480Sralph if (argc!=3) { 14818480Sralph fprintf(stderr, usage); 14918480Sralph exit(1); 15018480Sralph } 15118480Sralph 15218480Sralph /* interpret command type */ 153*23723Sbloom if (prefix(argv[1], "disable") || strcmp(argv[1], "dialout")==0) 15418480Sralph enable = 0; 155*23723Sbloom else if (prefix(argv[1], "enable") || strcmp(argv[1], "dialin")==0) 15618480Sralph enable = 1; 15718480Sralph else { 15818480Sralph fprintf(stderr, usage); 15918480Sralph exit(1); 16018480Sralph } 16118480Sralph 162*23723Sbloom device = rindex(argv[2], '/'); 16318480Sralph device = (device == NULL) ? argv[2]: device+1; 16418480Sralph 16518480Sralph /* only recognize devices of the form ttydX */ 166*23723Sbloom if (strncmp(device, "ttyd", 4)!=0) { 167*23723Sbloom fprintf(stderr, "Bad Device Name %s", device); 16818480Sralph exit(1); 16918480Sralph } 17018480Sralph 17118480Sralph opnttys(device); 17218480Sralph 17318480Sralph /* Get nlist info */ 174*23723Sbloom nlist("/vmunix", nl); 17518480Sralph 17618480Sralph /* Chdir to /dev */ 17718480Sralph if(chdir(Devhome) < 0) { 17818480Sralph fprintf(stderr, "Cannot chdir to %s: %s\r\n", 17918480Sralph Devhome, sys_errlist[errno]); 18018480Sralph exit(1); 18118480Sralph } 18218480Sralph 18318480Sralph /* Get uid information */ 18418480Sralph uid = getuid(); 18518480Sralph gid = getgid(); 18618480Sralph 18718480Sralph p = getpwuid(uid)->pw_name; 18818480Sralph if (p==NULL) { 189*23723Sbloom fprintf(stderr, "cannot get uid name\n"); 19018480Sralph exit(1); 19118480Sralph } 19218480Sralph 19318480Sralph /* to upper case */ 19418480Sralph i = 0; 19518480Sralph do { 19618480Sralph uname[i] = *p; 19718480Sralph Uname[i] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p; 19818480Sralph i++; p++; 19918480Sralph } while (*p && i<NAMSIZ); 20018480Sralph 20118480Sralph 20218480Sralph /* check to see if line is being used */ 20318480Sralph if( (etcutmp = open(Etcutmp, 2)) < 0) { 204*23723Sbloom fprintf(stderr, "On open %s open: %s\n", 205*23723Sbloom Etcutmp, sys_errlist[errno]); 20618480Sralph exit(1); 20718480Sralph } 20818480Sralph 209*23723Sbloom (void)lseek(etcutmp, utmploc, 0); 21018480Sralph 211*23723Sbloom i = read(etcutmp, (char *)&utmp, sizeof(struct utmp)); 21218480Sralph 21318480Sralph if( 21418480Sralph i == sizeof(struct utmp) && 21518480Sralph utmp.ut_line[0] != '\0' && 21618480Sralph utmp.ut_name[0] != '\0' && 21718480Sralph ( 218*23723Sbloom !upcase(utmp.ut_name, NAMSIZ) || 21918480Sralph ( 22018480Sralph uid != 0 && 221*23723Sbloom strncmp(utmp.ut_name, Uname, NAMSIZ) != 0 22218480Sralph ) 22318480Sralph ) 22418480Sralph ) { 22518480Sralph fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name); 22618480Sralph exit(2); 22718480Sralph } 22818480Sralph 22918480Sralph /* Disable modem control */ 230*23723Sbloom if (setmodem(device, DISABLE) < 0) { 231*23723Sbloom fprintf(stderr, "Unable to disable modem control\n"); 23218480Sralph exit(1); 23318480Sralph } 23418480Sralph 23518480Sralph if (enable) { 23618480Sralph if((devfile = open(device, 1)) < 0) { 237*23723Sbloom fprintf(stderr, "On open of %s: %s\n", 23818480Sralph device, sys_errlist[errno]); 239*23723Sbloom (void)setmodem(device, resetmodem); 24018480Sralph exit(1); 24118480Sralph } 24218480Sralph /* Try one last time to hang up */ 243*23723Sbloom if (ioctl(devfile, (int)TIOCCDTR, (char *)0) < 0) 244*23723Sbloom fprintf(stderr, "On TIOCCDTR ioctl: %s\n", 24518480Sralph sys_errlist[errno]); 24618480Sralph 247*23723Sbloom if (ioctl(devfile, (int)TIOCNXCL, (char *)0) < 0) 24818480Sralph fprintf(stderr, 24918480Sralph "Cannot clear Exclusive Use on %s: %s\n", 25018480Sralph device, sys_errlist[errno]); 25118480Sralph 252*23723Sbloom if (ioctl(devfile, (int)TIOCHPCL, (char *)0) < 0) 25318480Sralph fprintf(stderr, 25418480Sralph "Cannot set hangup on close on %s: %s\n", 25518480Sralph device, sys_errlist[errno]); 25618480Sralph 25718480Sralph i = resetmodem; 25818480Sralph 259*23723Sbloom if (setmodem(device, ENABLE) < 0) { 260*23723Sbloom fprintf(stderr, "Cannot Enable modem control\n"); 261*23723Sbloom (void)setmodem(device, i); 26218480Sralph exit(1); 26318480Sralph } 26418480Sralph resetmodem=i; 26518480Sralph 26618614Sralph if (settys(ENABLE)) { 267*23723Sbloom fprintf(stderr, "%s already enabled\n", device); 26818614Sralph } else { 269*23723Sbloom pokeinit(device, Uname, enable); 27018614Sralph } 271*23723Sbloom post(device, ""); 27218480Sralph 27318480Sralph } else { 27418480Sralph #if defined(TIOCMGET) && defined(SENSECARRIER) 27518480Sralph if (uid!=0) { 27618480Sralph int linestat = 0; 27718480Sralph 27818480Sralph /* check for presence of carrier */ 27918480Sralph sleep(2); /* need time after modem control turnoff */ 28018480Sralph 28118480Sralph if((devfile = open(device, 1)) < 0) { 282*23723Sbloom fprintf(stderr, "On open of %s: %s\n", 28318480Sralph device, sys_errlist[errno]); 284*23723Sbloom (void)setmodem(device, resetmodem); 28518480Sralph exit(1); 28618480Sralph } 28718480Sralph 288*23723Sbloom (void)ioctl(devfile, TIOCMGET, &linestat); 28918480Sralph 29018480Sralph if (linestat&TIOCM_CAR) { 291*23723Sbloom fprintf(stderr, "%s is in use (Carrier On)\n", 29218480Sralph device); 293*23723Sbloom (void)setmodem(device, resetmodem); 29418480Sralph exit(2); 29518480Sralph } 29618480Sralph (void)close(devfile); 29718480Sralph } 29818480Sralph #endif TIOCMGET 29918480Sralph /* chown device */ 30018480Sralph if(chown(device, uid, gid) < 0) 30118480Sralph fprintf(stderr, "Cannot chown %s: %s\n", 30218480Sralph device, sys_errlist[errno]); 30318480Sralph 30418480Sralph 30518480Sralph /* poke init */ 30618614Sralph if(settys(DISABLE)) { 307*23723Sbloom fprintf(stderr, "%s already disabled\n", device); 30818614Sralph } else { 309*23723Sbloom pokeinit(device, Uname, enable); 31018614Sralph } 311*23723Sbloom post(device, Uname); 31218480Sralph if((devfile = open(device, 1)) < 0) { 31318480Sralph fprintf(stderr, "On %s open: %s\n", 31418480Sralph device, sys_errlist[errno]); 31518480Sralph } else { 31618614Sralph if(ioctl(devfile, (int)TIOCSDTR, (char *)0) < 0) 31718480Sralph fprintf(stderr, 31818480Sralph "Cannot set DTR on %s: %s\n", 31918480Sralph device, sys_errlist[errno]); 32018480Sralph } 32118480Sralph } 32218480Sralph 32318480Sralph exit(0); 32418480Sralph } 32518480Sralph 32618480Sralph /* return true if no lower case */ 327*23723Sbloom upcase(str, len) 32818480Sralph register char *str; 32918480Sralph register int len; 33018480Sralph { 33118480Sralph for (; *str, --len >= 0 ; str++) 33218480Sralph if (*str>='a' && *str<='z') 33318480Sralph return(0); 33418480Sralph return(1); 33518480Sralph } 33618480Sralph 33718480Sralph /* Post name to public */ 338*23723Sbloom post(device, name) 33918480Sralph char *device, *name; 34018480Sralph { 34118614Sralph (void)time((time_t *)&utmp.ut_time); 34223583Sbloom strncpy(utmp.ut_line, device, LINSIZ); 34323583Sbloom strncpy(utmp.ut_name, name, NAMSIZ); 34418480Sralph if (lseek(etcutmp, utmploc, 0)<0) 345*23723Sbloom fprintf(stderr, "on lseek in /etc/utmp: %s", 34618480Sralph sys_errlist[errno]); 34718480Sralph if (write(etcutmp, (char *)&utmp, sizeof(utmp))<0) 348*23723Sbloom fprintf(stderr, "on write in /etc/utmp: %s", 34918480Sralph sys_errlist[errno]); 35018480Sralph } 35118480Sralph 35218480Sralph /* poke process 1 and wait for it to do its thing */ 353*23723Sbloom pokeinit(device, uname, enable) 35418480Sralph char *uname, *device; int enable; 35518480Sralph { 35618480Sralph struct utmp utmp; 35718614Sralph register int i; 35818480Sralph 35918480Sralph post(device, uname); 36018480Sralph 36118480Sralph /* poke init */ 36218480Sralph if (kill(1, SIGHUP)) { 36318480Sralph fprintf(stderr, 36418480Sralph "Cannot send hangup to init process: %s\n", 36518480Sralph sys_errlist[errno]); 36618614Sralph (void)settys(resettty); 367*23723Sbloom (void)setmodem(device, resetmodem); 36818480Sralph exit(1); 36918480Sralph } 37018480Sralph 37118480Sralph if (enable) 37218480Sralph return; 37318480Sralph 37418480Sralph /* wait till init has responded, clearing the utmp entry */ 37518614Sralph i=100; 37618480Sralph do { 37718480Sralph sleep(1); 378*23723Sbloom if (lseek(etcutmp, utmploc, 0)<0) 379*23723Sbloom fprintf(stderr, "On lseek in /etc/utmp: %s", 38018480Sralph sys_errlist[errno]); 381*23723Sbloom if (read(etcutmp, (char *)&utmp, sizeof utmp)<0) 382*23723Sbloom fprintf(stderr, "On read from /etc/utmp: %s", 38318480Sralph sys_errlist[errno]); 38418614Sralph } while (utmp.ut_name[0] != '\0' && --i > 0); 38518480Sralph } 38618480Sralph 387*23723Sbloom #ifdef BSD4_3 38818480Sralph /* identify terminal line in ttys */ 38918480Sralph opnttys(device) 39018480Sralph char *device; 39118480Sralph { 392*23723Sbloom register FILE *ttysfile, *nttysfile; 393*23723Sbloom register int ndevice; 394*23723Sbloom register char *p; 395*23723Sbloom char *index(); 396*23723Sbloom char linebuf[BUFSIZ]; 397*23723Sbloom 398*23723Sbloom ttysfile = fopen(Etcttys, "r"); 399*23723Sbloom if(ttysfile == NULL) { 400*23723Sbloom fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 401*23723Sbloom sys_errlist[errno]); 402*23723Sbloom exit(1); 403*23723Sbloom } 404*23723Sbloom nttysfile = fopen(NEtcttys, "w"); 405*23723Sbloom if(nttysfile == NULL) { 406*23723Sbloom fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 407*23723Sbloom sys_errlist[errno]); 408*23723Sbloom exit(1); 409*23723Sbloom } 410*23723Sbloom 411*23723Sbloom ndevice = strlen(device); 412*23723Sbloom utmploc = 0; 413*23723Sbloom 414*23723Sbloom ttyslnbeg = 0; 415*23723Sbloom while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { 416*23723Sbloom utmploc += sizeof(utmp); 417*23723Sbloom if(strncmp(device, linebuf, ndevice) == 0) { 418*23723Sbloom fclose(ttysfile); 419*23723Sbloom fclose(nttysfile); 420*23723Sbloom return; 421*23723Sbloom } 422*23723Sbloom ttyslnbeg = ftell(ttysfile); 423*23723Sbloom if (fputs(linebuf, nttysfile) == NULL) { 424*23723Sbloom fprintf(stderr, "On %s write: %s\n", 425*23723Sbloom Etcttys, sys_errlist[errno]); 426*23723Sbloom exit(1); 427*23723Sbloom } 428*23723Sbloom 429*23723Sbloom } 430*23723Sbloom fprintf(stderr, "%s not found in %s\n", device, Etcttys); 431*23723Sbloom exit(1); 432*23723Sbloom } 433*23723Sbloom 434*23723Sbloom /* modify appropriate line in /etc/ttys to turn on/off the device */ 435*23723Sbloom settys(enable) 436*23723Sbloom int enable; 437*23723Sbloom { 438*23723Sbloom register char *cp, *cp2; 439*23723Sbloom FILE *ittysfil, *nttysfil; 440*23723Sbloom char lbuf[BUFSIZ]; 441*23723Sbloom int i; 442*23723Sbloom char c1, c2; 443*23723Sbloom 444*23723Sbloom ittysfil = fopen(Etcttys, "r"); 445*23723Sbloom if(ittysfil == NULL) { 446*23723Sbloom fprintf(stderr, "Cannot open %s for output: %s\n", 447*23723Sbloom Etcttys, sys_errlist[errno]); 448*23723Sbloom exit(1); 449*23723Sbloom } 450*23723Sbloom nttysfil = fopen(NEtcttys, "a"); 451*23723Sbloom if(nttysfil == NULL) { 452*23723Sbloom fprintf(stderr, "Cannot open %s for output: %s\n", 453*23723Sbloom NEtcttys, sys_errlist[errno]); 454*23723Sbloom exit(1); 455*23723Sbloom } 456*23723Sbloom (void)fseek(ittysfil, ttyslnbeg, 0); 457*23723Sbloom if(fgets(lbuf, BUFSIZ, ittysfil) == NULL) { 458*23723Sbloom fprintf(stderr, "On %s read: %s\n", 459*23723Sbloom Etcttys, sys_errlist[errno]); 460*23723Sbloom exit(1); 461*23723Sbloom } 462*23723Sbloom /* format is now */ 463*23723Sbloom /* ttyd0 std.100 dialup on secure # comment */ 464*23723Sbloom cp = lbuf; 465*23723Sbloom for (i=0;*cp && i<3;i++) { 466*23723Sbloom while (*cp && *cp != ' ' && *cp != '\t') 467*23723Sbloom cp++; 468*23723Sbloom while (*cp && (*cp == ' ' || *cp == '\t')) 469*23723Sbloom cp++; 470*23723Sbloom } 471*23723Sbloom if (*cp == '\0') { 472*23723Sbloom fprintf(stderr,"Badly formatted line in /etc/ttys:\n%s", lbuf); 473*23723Sbloom exit(1); 474*23723Sbloom } 475*23723Sbloom c1 = *--cp; 476*23723Sbloom *cp++ = '\0'; 477*23723Sbloom cp2 = cp; 478*23723Sbloom while (*cp && *cp != ' ' && *cp != '\t' && *cp != '\n') 479*23723Sbloom cp++; 480*23723Sbloom if (*cp == '\0') { 481*23723Sbloom fprintf(stderr,"Badly formatted line in /etc/ttys:\n%s", lbuf); 482*23723Sbloom exit(1); 483*23723Sbloom } 484*23723Sbloom c2 = *cp; 485*23723Sbloom *cp++ = '\0'; 486*23723Sbloom while (*cp && (*cp == ' ' || *cp == '\t')) 487*23723Sbloom cp++; 488*23723Sbloom resettty = strcmp("on", cp2) != 0; 489*23723Sbloom fprintf(nttysfil,"%s%c%s%c%s", lbuf, c1, enable ? "on" : "off", c2, cp); 490*23723Sbloom if (ferror(nttysfil)) { 491*23723Sbloom fprintf(stderr, "On %s fprintf: %s\n", 492*23723Sbloom NEtcttys, sys_errlist[errno]); 493*23723Sbloom exit(1); 494*23723Sbloom } 495*23723Sbloom while(fgets(lbuf, sizeof(lbuf) - 1, ittysfil) != NULL) { 496*23723Sbloom if (fputs(lbuf, nttysfil) == NULL) { 497*23723Sbloom fprintf(stderr, "On %s write: %s\n", 498*23723Sbloom NEtcttys, sys_errlist[errno]); 499*23723Sbloom exit(1); 500*23723Sbloom } 501*23723Sbloom } 502*23723Sbloom 503*23723Sbloom if (enable^resettty) 504*23723Sbloom (void) unlink(NEtcttys); 505*23723Sbloom else { 506*23723Sbloom struct stat statb; 507*23723Sbloom if (stat(Etcttys, &statb) == 0) { 508*23723Sbloom fchmod(fileno(nttysfil) ,statb.st_mode); 509*23723Sbloom fchown(fileno(nttysfil), statb.st_uid, statb.st_gid); 510*23723Sbloom } 511*23723Sbloom (void) rename(NEtcttys, Etcttys); 512*23723Sbloom } 513*23723Sbloom (void) fclose(ittysfil); 514*23723Sbloom (void) fclose(nttysfil); 515*23723Sbloom return enable^resettty; 516*23723Sbloom } 517*23723Sbloom 518*23723Sbloom #else !BSD4_3 519*23723Sbloom 520*23723Sbloom /* identify terminal line in ttys */ 521*23723Sbloom opnttys(device) 522*23723Sbloom char *device; 523*23723Sbloom { 52418480Sralph register FILE *ttysfile; 52518480Sralph register int ndevice, lnsiz; 52618480Sralph register char *p; 52718480Sralph char *index(); 528*23723Sbloom char linebuf[BUFSIZ]; 52918480Sralph 53018480Sralph ttysfile = fopen(Etcttys, "r"); 53118480Sralph if(ttysfile == NULL) { 53218480Sralph fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 53318480Sralph sys_errlist[errno]); 53418480Sralph exit(1); 53518480Sralph } 53618480Sralph 53718480Sralph ndevice = strlen(device); 53818480Sralph ttyslnbeg = 0; 53918480Sralph utmploc = 0; 54018480Sralph 54118480Sralph while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { 54218480Sralph utmploc += sizeof(utmp); 54318480Sralph lnsiz = strlen(linebuf); 544*23723Sbloom if ((p = index(linebuf, '\n')) != NULL) 54518480Sralph *p = '\0'; 54618480Sralph if(strncmp(device, &linebuf[2], ndevice) == 0) { 54718480Sralph (void)fclose(ttysfile); 54818480Sralph return; 54918480Sralph } 55018480Sralph ttyslnbeg += lnsiz; 55118480Sralph } 55218480Sralph fprintf(stderr, "%s not found in %s\n", device, Etcttys); 55318480Sralph exit(1); 55418480Sralph } 55518480Sralph 55618480Sralph /* modify appropriate line in /etc/ttys to turn on/off the device */ 55718480Sralph settys(enable) 55818480Sralph int enable; 55918480Sralph { 56018480Sralph int ittysfil; 561*23723Sbloom char out, in; 56218480Sralph 56318480Sralph ittysfil = open(Etcttys, 2); 564*23723Sbloom if(ittysfil < 0) { 56518480Sralph fprintf(stderr, "Cannot open %s for output: %s\n", 56618480Sralph Etcttys, sys_errlist[errno]); 56718480Sralph exit(1); 56818480Sralph } 569*23723Sbloom (void)lseek(ittysfil, ttyslnbeg, 0); 570*23723Sbloom if(read(ittysfil, &in, 1)<0) { 571*23723Sbloom fprintf(stderr, "On %s write: %s\n", 57218480Sralph Etcttys, sys_errlist[errno]); 57318480Sralph exit(1); 57418480Sralph } 57518480Sralph resettty = (in == '1'); 57618480Sralph out = enable ? '1' : '0'; 577*23723Sbloom (void)lseek(ittysfil, ttyslnbeg, 0); 578*23723Sbloom if(write(ittysfil, &out, 1)<0) { 579*23723Sbloom fprintf(stderr, "On %s write: %s\n", 58018480Sralph Etcttys, sys_errlist[errno]); 58118480Sralph exit(1); 58218480Sralph } 58318480Sralph (void)close(ittysfil); 58418614Sralph return(in==out); 58518480Sralph } 586*23723Sbloom #endif !BSD4_3 58718480Sralph 58818480Sralph /* 589*23723Sbloom * Excerpted from (June 8, 1983 W.Sebok) 59018480Sralph * > ttymodem.c - enable/disable modem control for tty lines. 59118480Sralph * > 59218480Sralph * > Knows about DZ11s and DH11/DM11s. 59318480Sralph * > 23.3.83 - TS 594*23723Sbloom * > modified to know about DMF's (hasn't been tested) Nov 8, 1984 - WLS 59518480Sralph */ 59618480Sralph 59718480Sralph 598*23723Sbloom setmodem(ttyline, enable) 59918480Sralph char *ttyline; int enable; 60018480Sralph { 60118480Sralph dev_t dev; 60218480Sralph int kmem; 603*23723Sbloom int unit, line, nlines, addr, tflags; 60418614Sralph int devtype=0; 60518614Sralph char cflags; short sflags; 60618614Sralph #ifdef BSD4_2 60718614Sralph int flags; 60818614Sralph #else 60918614Sralph short flags; 61018614Sralph #endif 61118480Sralph struct uba_device *ubinfo; 61218480Sralph struct stat statb; 61318480Sralph struct cdevsw cdevsw; 61418480Sralph 61518480Sralph if(nl[CDEVSW].n_type == 0) { 616*23723Sbloom fprintf(stderr, "No namelist.\n"); 61718480Sralph return(-1); 61818480Sralph } 61918480Sralph 62018480Sralph if((kmem = open("/dev/kmem", 2)) < 0) { 621*23723Sbloom fprintf(stderr, "/dev/kmem open: %s\n", sys_errlist[errno]); 62218480Sralph return(-1); 62318480Sralph } 62418480Sralph 625*23723Sbloom if(stat(ttyline, &statb) < 0) { 626*23723Sbloom fprintf(stderr, "%s stat: %s\n", ttyline, sys_errlist[errno]); 62718480Sralph return(-1); 62818480Sralph } 62918480Sralph 63018614Sralph if((statb.st_mode&S_IFMT) != S_IFCHR) { 631*23723Sbloom fprintf(stderr, "%s is not a character device.\n",ttyline); 63218480Sralph return(-1); 63318480Sralph } 63418480Sralph 63518480Sralph dev = statb.st_rdev; 63618480Sralph (void)lseek(kmem, 63718614Sralph (off_t) &(((struct cdevsw *)NLVALUE(CDEVSW))[major(dev)]),0); 638*23723Sbloom (void)read(kmem, (char *) &cdevsw, sizeof cdevsw); 63918480Sralph 64018480Sralph if((int)(cdevsw.d_open) == NLVALUE(DZOPEN)) { 64118480Sralph devtype = DZ11; 64218480Sralph unit = minor(dev) / NDZLINE; 64318480Sralph line = minor(dev) % NDZLINE; 64418480Sralph addr = (int) &(((int *)NLVALUE(DZINFO))[unit]); 645*23723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDZ11), 0); 64618480Sralph } else if((int)(cdevsw.d_open) == NLVALUE(DHOPEN)) { 64718480Sralph devtype = DH11; 64818480Sralph unit = minor(dev) / NDHLINE; 64918480Sralph line = minor(dev) % NDHLINE; 65018480Sralph addr = (int) &(((int *)NLVALUE(DHINFO))[unit]); 651*23723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDH11), 0); 65218480Sralph } else if((int)(cdevsw.d_open) == NLVALUE(DMFOPEN)) { 65318480Sralph devtype = DMF; 65418480Sralph unit = minor(dev) / NDMFLINE; 65518480Sralph line = minor(dev) % NDMFLINE; 65618480Sralph addr = (int) &(((int *)NLVALUE(DMFINFO))[unit]); 657*23723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDMF), 0); 65818480Sralph } else { 659*23723Sbloom fprintf(stderr, "Device %s (%d/%d) unknown.\n", ttyline, 660*23723Sbloom major(dev), minor(dev)); 66118480Sralph return(-1); 66218480Sralph } 66318480Sralph 664*23723Sbloom (void)read(kmem, (char *) &nlines, sizeof nlines); 66518480Sralph if(minor(dev) >= nlines) { 666*23723Sbloom fprintf(stderr, "Sub-device %d does not exist (only %d).\n", 667*23723Sbloom minor(dev), nlines); 66818480Sralph return(-1); 66918480Sralph } 67018480Sralph 671*23723Sbloom (void)lseek(kmem, (off_t)addr, 0); 672*23723Sbloom (void)read(kmem, (char *) &ubinfo, sizeof ubinfo); 673*23723Sbloom (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0); 674*23723Sbloom (void)read(kmem, (char *) &flags, sizeof flags); 67518480Sralph 67618480Sralph tflags = 1<<line; 67718480Sralph resetmodem = ((flags&tflags) == 0); 67818480Sralph flags = enable ? (flags & ~tflags) : (flags | tflags); 679*23723Sbloom (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0); 680*23723Sbloom (void)write(kmem, (char *) &flags, sizeof flags); 68118480Sralph switch(devtype) { 68218480Sralph case DZ11: 68318480Sralph if((addr = NLVALUE(DZSCAR)) == 0) { 684*23723Sbloom fprintf(stderr, "No dzsoftCAR.\n"); 68518480Sralph return(-1); 68618480Sralph } 68718614Sralph cflags = flags; 688*23723Sbloom (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); 689*23723Sbloom (void)write(kmem, (char *) &cflags, sizeof cflags); 69018480Sralph break; 69118480Sralph case DH11: 69218480Sralph if((addr = NLVALUE(DHSCAR)) == 0) { 693*23723Sbloom fprintf(stderr, "No dhsoftCAR.\n"); 69418480Sralph return(-1); 69518480Sralph } 69618614Sralph sflags = flags; 697*23723Sbloom (void)lseek(kmem, (off_t) &(((short *)addr)[unit]), 0); 698*23723Sbloom (void)write(kmem, (char *) &sflags, sizeof sflags); 69918480Sralph break; 70018480Sralph case DMF: 70118480Sralph if((addr = NLVALUE(DMFSCAR)) == 0) { 702*23723Sbloom fprintf(stderr, "No dmfsoftCAR.\n"); 70318480Sralph return(-1); 70418480Sralph } 70518614Sralph cflags = flags; 706*23723Sbloom (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); 707*23723Sbloom (void)write(kmem, (char *) &flags, sizeof cflags); 70818480Sralph break; 70918480Sralph default: 710*23723Sbloom fprintf(stderr, "Unknown device type\n"); 71118480Sralph return(-1); 71218480Sralph } 71318480Sralph return(0); 71418480Sralph } 71518480Sralph 71618480Sralph prefix(s1, s2) 71718480Sralph register char *s1, *s2; 71818480Sralph { 71918480Sralph register char c; 72018480Sralph 72118480Sralph while ((c = *s1++) == *s2++) 72218480Sralph if (c == '\0') 72318480Sralph return (1); 72418480Sralph return (c == '\0'); 72518480Sralph } 726