118480Sralph #ifndef lint 2*25962Sbloom static char sccsid[] = "@(#)acucntrl.c 5.7 (Berkeley) 01/24/86"; 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" 49*25962Sbloom #ifdef DIALINOUT 5018480Sralph #include <sys/buf.h> 5118614Sralph #include <signal.h> 5218480Sralph #include <sys/conf.h> 5318480Sralph #ifdef BSD4_2 5423583Sbloom #include <vaxuba/ubavar.h> 5518614Sralph #else 5618480Sralph #include <sys/ubavar.h> 5718614Sralph #endif 5818480Sralph #include <sys/stat.h> 5918480Sralph #include <nlist.h> 6018480Sralph #include <sgtty.h> 6118480Sralph #include <utmp.h> 6218480Sralph #include <pwd.h> 6318480Sralph #include <stdio.h> 6425123Sbloom #include <sys/file.h> 6518480Sralph 6618480Sralph #define NDZLINE 8 /* lines/dz */ 6718480Sralph #define NDHLINE 16 /* lines/dh */ 6818480Sralph #define NDMFLINE 8 /* lines/dmf */ 6918480Sralph 7018480Sralph #define DZ11 1 7118480Sralph #define DH11 2 7218480Sralph #define DMF 3 7318480Sralph 7418480Sralph #define NLVALUE(val) (nl[val].n_value) 7518480Sralph 7618480Sralph struct nlist nl[] = { 7718480Sralph #define CDEVSW 0 7818480Sralph { "_cdevsw" }, 7918480Sralph 8018480Sralph #define DZOPEN 1 8118480Sralph { "_dzopen" }, 8218480Sralph #define DZINFO 2 8318480Sralph { "_dzinfo" }, 8418480Sralph #define NDZ11 3 8518480Sralph { "_dz_cnt" }, 8618480Sralph #define DZSCAR 4 8718480Sralph { "_dzsoftCAR" }, 8818480Sralph 8918480Sralph #define DHOPEN 5 9018480Sralph { "_dhopen" }, 9118480Sralph #define DHINFO 6 9218480Sralph { "_dhinfo" }, 9318480Sralph #define NDH11 7 9418480Sralph { "_ndh11" }, 9518480Sralph #define DHSCAR 8 9618480Sralph { "_dhsoftCAR" }, 9718480Sralph 9818480Sralph #define DMFOPEN 9 9918480Sralph { "_dmfopen" }, 10018480Sralph #define DMFINFO 10 10118480Sralph { "_dmfinfo" }, 10218480Sralph #define NDMF 11 10318480Sralph { "_ndmf" }, 10418480Sralph #define DMFSCAR 12 10518480Sralph { "_dmfsoftCAR" }, 10618480Sralph 10718480Sralph { "\0" } 10818480Sralph }; 10918480Sralph 11018480Sralph #define ENABLE 1 11118480Sralph #define DISABLE 0 11218480Sralph 11318480Sralph char Etcutmp[] = "/etc/utmp"; 11418480Sralph char Etcttys[] = "/etc/ttys"; 11523723Sbloom #ifdef BSD4_3 11625123Sbloom FILE *ttysfile, *nttysfile; 11723723Sbloom char NEtcttys[] = "/etc/ttys.new"; 11823723Sbloom extern long ftell(); 11923723Sbloom #endif BSD4_3 12018480Sralph char Devhome[] = "/dev"; 12118480Sralph 12218480Sralph char usage[] = "Usage: acucntrl {dis|en}able ttydX\n"; 12318480Sralph 12418480Sralph struct utmp utmp; 12518480Sralph char resettty, resetmodem; 12618480Sralph int etcutmp; 12718614Sralph off_t utmploc; 12818614Sralph off_t ttyslnbeg; 12918480Sralph 13018480Sralph #define NAMSIZ sizeof(utmp.ut_name) 13118480Sralph #define LINSIZ sizeof(utmp.ut_line) 13218480Sralph 13318480Sralph main(argc, argv) 13418480Sralph int argc; char *argv[]; 13518480Sralph { 13618480Sralph register char *p; 13718480Sralph register int i; 13818480Sralph char uname[NAMSIZ], Uname[NAMSIZ]; 13918480Sralph int enable ; 14018480Sralph char *device; 14118480Sralph int devfile; 14218480Sralph int uid, gid; 14318614Sralph off_t lseek(); 14418480Sralph struct passwd *getpwuid(); 14518480Sralph char *rindex(); 14618480Sralph extern int errno; 14718480Sralph extern char *sys_errlist[]; 14818480Sralph 14918480Sralph /* check input arguments */ 15018480Sralph if (argc!=3) { 15118480Sralph fprintf(stderr, usage); 15218480Sralph exit(1); 15318480Sralph } 15418480Sralph 15518480Sralph /* interpret command type */ 15623723Sbloom if (prefix(argv[1], "disable") || strcmp(argv[1], "dialout")==0) 15718480Sralph enable = 0; 15823723Sbloom else if (prefix(argv[1], "enable") || strcmp(argv[1], "dialin")==0) 15918480Sralph enable = 1; 16018480Sralph else { 16118480Sralph fprintf(stderr, usage); 16218480Sralph exit(1); 16318480Sralph } 16418480Sralph 16523723Sbloom device = rindex(argv[2], '/'); 16618480Sralph device = (device == NULL) ? argv[2]: device+1; 16718480Sralph 16818480Sralph /* only recognize devices of the form ttydX */ 16923723Sbloom if (strncmp(device, "ttyd", 4)!=0) { 17023723Sbloom fprintf(stderr, "Bad Device Name %s", device); 17118480Sralph exit(1); 17218480Sralph } 17318480Sralph 17418480Sralph opnttys(device); 17518480Sralph 17618480Sralph /* Get nlist info */ 17723723Sbloom nlist("/vmunix", nl); 17818480Sralph 17918480Sralph /* Chdir to /dev */ 18018480Sralph if(chdir(Devhome) < 0) { 18118480Sralph fprintf(stderr, "Cannot chdir to %s: %s\r\n", 18218480Sralph Devhome, sys_errlist[errno]); 18318480Sralph exit(1); 18418480Sralph } 18518480Sralph 18618480Sralph /* Get uid information */ 18718480Sralph uid = getuid(); 18818480Sralph gid = getgid(); 18918480Sralph 19018480Sralph p = getpwuid(uid)->pw_name; 19118480Sralph if (p==NULL) { 19223723Sbloom fprintf(stderr, "cannot get uid name\n"); 19318480Sralph exit(1); 19418480Sralph } 19518480Sralph 19618480Sralph /* to upper case */ 19718480Sralph i = 0; 19818480Sralph do { 19918480Sralph uname[i] = *p; 20018480Sralph Uname[i] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p; 20118480Sralph i++; p++; 20218480Sralph } while (*p && i<NAMSIZ); 20318480Sralph 20418480Sralph 20518480Sralph /* check to see if line is being used */ 20618480Sralph if( (etcutmp = open(Etcutmp, 2)) < 0) { 20723723Sbloom fprintf(stderr, "On open %s open: %s\n", 20823723Sbloom Etcutmp, sys_errlist[errno]); 20918480Sralph exit(1); 21018480Sralph } 21118480Sralph 21223723Sbloom (void)lseek(etcutmp, utmploc, 0); 21318480Sralph 21423723Sbloom i = read(etcutmp, (char *)&utmp, sizeof(struct utmp)); 21518480Sralph 21618480Sralph if( 21718480Sralph i == sizeof(struct utmp) && 21818480Sralph utmp.ut_line[0] != '\0' && 21918480Sralph utmp.ut_name[0] != '\0' && 22018480Sralph ( 22123723Sbloom !upcase(utmp.ut_name, NAMSIZ) || 22218480Sralph ( 22318480Sralph uid != 0 && 22423723Sbloom strncmp(utmp.ut_name, Uname, NAMSIZ) != 0 22518480Sralph ) 22618480Sralph ) 22718480Sralph ) { 22818480Sralph fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name); 22918480Sralph exit(2); 23018480Sralph } 23118480Sralph 23218480Sralph /* Disable modem control */ 23323723Sbloom if (setmodem(device, DISABLE) < 0) { 23423723Sbloom fprintf(stderr, "Unable to disable modem control\n"); 23518480Sralph exit(1); 23618480Sralph } 23718480Sralph 23818480Sralph if (enable) { 23918480Sralph if((devfile = open(device, 1)) < 0) { 24023723Sbloom fprintf(stderr, "On open of %s: %s\n", 24118480Sralph device, sys_errlist[errno]); 24223723Sbloom (void)setmodem(device, resetmodem); 24318480Sralph exit(1); 24418480Sralph } 24518480Sralph /* Try one last time to hang up */ 24623723Sbloom if (ioctl(devfile, (int)TIOCCDTR, (char *)0) < 0) 24723723Sbloom fprintf(stderr, "On TIOCCDTR ioctl: %s\n", 24818480Sralph sys_errlist[errno]); 24918480Sralph 25023723Sbloom if (ioctl(devfile, (int)TIOCNXCL, (char *)0) < 0) 25118480Sralph fprintf(stderr, 25218480Sralph "Cannot clear Exclusive Use on %s: %s\n", 25318480Sralph device, sys_errlist[errno]); 25418480Sralph 25523723Sbloom if (ioctl(devfile, (int)TIOCHPCL, (char *)0) < 0) 25618480Sralph fprintf(stderr, 25718480Sralph "Cannot set hangup on close on %s: %s\n", 25818480Sralph device, sys_errlist[errno]); 25918480Sralph 26018480Sralph i = resetmodem; 26118480Sralph 26223723Sbloom if (setmodem(device, ENABLE) < 0) { 26323723Sbloom fprintf(stderr, "Cannot Enable modem control\n"); 26423723Sbloom (void)setmodem(device, i); 26518480Sralph exit(1); 26618480Sralph } 26718480Sralph resetmodem=i; 26818480Sralph 26918614Sralph if (settys(ENABLE)) { 27023723Sbloom fprintf(stderr, "%s already enabled\n", device); 27118614Sralph } else { 27223723Sbloom pokeinit(device, Uname, enable); 27318614Sralph } 27423723Sbloom post(device, ""); 27518480Sralph 27618480Sralph } else { 27718480Sralph #if defined(TIOCMGET) && defined(SENSECARRIER) 27818480Sralph if (uid!=0) { 27918480Sralph int linestat = 0; 28018480Sralph 28118480Sralph /* check for presence of carrier */ 28218480Sralph sleep(2); /* need time after modem control turnoff */ 28318480Sralph 28418480Sralph if((devfile = open(device, 1)) < 0) { 28523723Sbloom fprintf(stderr, "On open of %s: %s\n", 28618480Sralph device, sys_errlist[errno]); 28723723Sbloom (void)setmodem(device, resetmodem); 28818480Sralph exit(1); 28918480Sralph } 29018480Sralph 29123723Sbloom (void)ioctl(devfile, TIOCMGET, &linestat); 29218480Sralph 29318480Sralph if (linestat&TIOCM_CAR) { 29423723Sbloom fprintf(stderr, "%s is in use (Carrier On)\n", 29518480Sralph device); 29623723Sbloom (void)setmodem(device, resetmodem); 29718480Sralph exit(2); 29818480Sralph } 29918480Sralph (void)close(devfile); 30018480Sralph } 30118480Sralph #endif TIOCMGET 30218480Sralph /* chown device */ 30318480Sralph if(chown(device, uid, gid) < 0) 30418480Sralph fprintf(stderr, "Cannot chown %s: %s\n", 30518480Sralph device, sys_errlist[errno]); 30618480Sralph 30718480Sralph 30818480Sralph /* poke init */ 30918614Sralph if(settys(DISABLE)) { 31023723Sbloom fprintf(stderr, "%s already disabled\n", device); 31118614Sralph } else { 31223723Sbloom pokeinit(device, Uname, enable); 31318614Sralph } 31423723Sbloom post(device, Uname); 31525123Sbloom if((devfile = open(device, O_RDWR|O_NDELAY)) < 0) { 31618480Sralph fprintf(stderr, "On %s open: %s\n", 31718480Sralph device, sys_errlist[errno]); 31818480Sralph } else { 31918614Sralph if(ioctl(devfile, (int)TIOCSDTR, (char *)0) < 0) 32018480Sralph fprintf(stderr, 32118480Sralph "Cannot set DTR on %s: %s\n", 32218480Sralph device, sys_errlist[errno]); 32318480Sralph } 32418480Sralph } 32518480Sralph 32618480Sralph exit(0); 32718480Sralph } 32818480Sralph 32918480Sralph /* return true if no lower case */ 33023723Sbloom upcase(str, len) 33118480Sralph register char *str; 33218480Sralph register int len; 33318480Sralph { 33418480Sralph for (; *str, --len >= 0 ; str++) 33518480Sralph if (*str>='a' && *str<='z') 33618480Sralph return(0); 33718480Sralph return(1); 33818480Sralph } 33918480Sralph 34018480Sralph /* Post name to public */ 34123723Sbloom post(device, name) 34218480Sralph char *device, *name; 34318480Sralph { 34418614Sralph (void)time((time_t *)&utmp.ut_time); 34523583Sbloom strncpy(utmp.ut_line, device, LINSIZ); 34623583Sbloom strncpy(utmp.ut_name, name, NAMSIZ); 34725123Sbloom if (lseek(etcutmp, utmploc, 0) < 0) 34823723Sbloom fprintf(stderr, "on lseek in /etc/utmp: %s", 34918480Sralph sys_errlist[errno]); 35025123Sbloom if (write(etcutmp, (char *)&utmp, sizeof(utmp)) < 0) 35123723Sbloom fprintf(stderr, "on write in /etc/utmp: %s", 35218480Sralph sys_errlist[errno]); 35318480Sralph } 35418480Sralph 35518480Sralph /* poke process 1 and wait for it to do its thing */ 35623723Sbloom pokeinit(device, uname, enable) 35718480Sralph char *uname, *device; int enable; 35818480Sralph { 35918480Sralph struct utmp utmp; 36018614Sralph register int i; 36118480Sralph 36218480Sralph post(device, uname); 36318480Sralph 36418480Sralph /* poke init */ 36518480Sralph if (kill(1, SIGHUP)) { 36618480Sralph fprintf(stderr, 36718480Sralph "Cannot send hangup to init process: %s\n", 36818480Sralph sys_errlist[errno]); 36918614Sralph (void)settys(resettty); 37023723Sbloom (void)setmodem(device, resetmodem); 37118480Sralph exit(1); 37218480Sralph } 37318480Sralph 37418480Sralph if (enable) 37518480Sralph return; 37618480Sralph 37718480Sralph /* wait till init has responded, clearing the utmp entry */ 37825123Sbloom i = 100; 37918480Sralph do { 38018480Sralph sleep(1); 38125123Sbloom if (lseek(etcutmp, utmploc, 0) < 0) 38223723Sbloom fprintf(stderr, "On lseek in /etc/utmp: %s", 38318480Sralph sys_errlist[errno]); 38425123Sbloom if (read(etcutmp, (char *)&utmp, sizeof utmp) < 0) 38523723Sbloom fprintf(stderr, "On read from /etc/utmp: %s", 38618480Sralph sys_errlist[errno]); 38718614Sralph } while (utmp.ut_name[0] != '\0' && --i > 0); 38818480Sralph } 38918480Sralph 39023723Sbloom #ifdef BSD4_3 39118480Sralph /* identify terminal line in ttys */ 39218480Sralph opnttys(device) 39318480Sralph char *device; 39418480Sralph { 39523723Sbloom register int ndevice; 39623723Sbloom register char *p; 39723723Sbloom char *index(); 39823723Sbloom char linebuf[BUFSIZ]; 39923723Sbloom 40025123Sbloom ttysfile = NULL; 40125123Sbloom do { 40225123Sbloom if (ttysfile != NULL) { 40325123Sbloom fclose(ttysfile); 40425123Sbloom sleep(5); 40525123Sbloom } 40625123Sbloom ttysfile = fopen(Etcttys, "r"); 40725123Sbloom if(ttysfile == NULL) { 40825123Sbloom fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 40925123Sbloom sys_errlist[errno]); 41025123Sbloom exit(1); 41125123Sbloom } 41225123Sbloom } while (flock(fileno(ttysfile), LOCK_NB|LOCK_EX) < 0); 41323723Sbloom nttysfile = fopen(NEtcttys, "w"); 41423723Sbloom if(nttysfile == NULL) { 41523723Sbloom fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 41623723Sbloom sys_errlist[errno]); 41723723Sbloom exit(1); 41823723Sbloom } 41923723Sbloom 42023723Sbloom ndevice = strlen(device); 421*25962Sbloom #ifndef BRL4_2 42225123Sbloom utmploc = sizeof(utmp); 423*25962Sbloom #else BRL4_2 424*25962Sbloom utmploc = 0; 425*25962Sbloom #endif BRL4_2 42623723Sbloom 42723723Sbloom while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { 42825123Sbloom if(strncmp(device, linebuf, ndevice) == 0) 42925123Sbloom return; 43025123Sbloom ttyslnbeg += strlen(linebuf); 431*25962Sbloom if (linebuf[0] != '#' && linebuf[0] != '\0') 432*25962Sbloom utmploc += sizeof(utmp); 43323723Sbloom if (fputs(linebuf, nttysfile) == NULL) { 43423723Sbloom fprintf(stderr, "On %s write: %s\n", 43523723Sbloom Etcttys, sys_errlist[errno]); 43623723Sbloom exit(1); 43723723Sbloom } 43823723Sbloom 43923723Sbloom } 44023723Sbloom fprintf(stderr, "%s not found in %s\n", device, Etcttys); 44123723Sbloom exit(1); 44223723Sbloom } 44323723Sbloom 44423723Sbloom /* modify appropriate line in /etc/ttys to turn on/off the device */ 44523723Sbloom settys(enable) 44623723Sbloom int enable; 44723723Sbloom { 44823723Sbloom register char *cp, *cp2; 44923723Sbloom char lbuf[BUFSIZ]; 45023723Sbloom int i; 45123723Sbloom char c1, c2; 45223723Sbloom 45325123Sbloom (void) fseek(ttysfile, ttyslnbeg, 0); 45425123Sbloom if(fgets(lbuf, BUFSIZ, ttysfile) == NULL) { 45523723Sbloom fprintf(stderr, "On %s read: %s\n", 45623723Sbloom Etcttys, sys_errlist[errno]); 45723723Sbloom exit(1); 45823723Sbloom } 45923723Sbloom /* format is now */ 46023723Sbloom /* ttyd0 std.100 dialup on secure # comment */ 46125364Sbloom /* except, 2nd item may have embedded spaces inside quotes, Hubert */ 46223723Sbloom cp = lbuf; 46323723Sbloom for (i=0;*cp && i<3;i++) { 46425364Sbloom if (*cp == '"') { 46523723Sbloom cp++; 46625364Sbloom while (*cp && *cp != '"') 46725364Sbloom cp++; 46825364Sbloom if (*cp != '\0') 46925364Sbloom cp++; 47025364Sbloom }else { 47125364Sbloom while (*cp && *cp != ' ' && *cp != '\t') 47225364Sbloom cp++; 47325364Sbloom } 47423723Sbloom while (*cp && (*cp == ' ' || *cp == '\t')) 47523723Sbloom cp++; 47623723Sbloom } 47723723Sbloom if (*cp == '\0') { 47823723Sbloom fprintf(stderr,"Badly formatted line in /etc/ttys:\n%s", lbuf); 47923723Sbloom exit(1); 48023723Sbloom } 48123723Sbloom c1 = *--cp; 48223723Sbloom *cp++ = '\0'; 48323723Sbloom cp2 = cp; 48423723Sbloom while (*cp && *cp != ' ' && *cp != '\t' && *cp != '\n') 48523723Sbloom cp++; 48623723Sbloom if (*cp == '\0') { 48723723Sbloom fprintf(stderr,"Badly formatted line in /etc/ttys:\n%s", lbuf); 48823723Sbloom exit(1); 48923723Sbloom } 49023723Sbloom c2 = *cp; 49123723Sbloom *cp++ = '\0'; 49223723Sbloom while (*cp && (*cp == ' ' || *cp == '\t')) 49323723Sbloom cp++; 49423723Sbloom resettty = strcmp("on", cp2) != 0; 49525123Sbloom fprintf(nttysfile,"%s%c%s%c%s", lbuf, c1, enable ? "on" : "off", c2, cp); 49625123Sbloom if (ferror(nttysfile)) { 49723723Sbloom fprintf(stderr, "On %s fprintf: %s\n", 49823723Sbloom NEtcttys, sys_errlist[errno]); 49923723Sbloom exit(1); 50023723Sbloom } 50125123Sbloom while(fgets(lbuf, sizeof(lbuf) - 1, ttysfile) != NULL) { 50225123Sbloom if (fputs(lbuf, nttysfile) == NULL) { 50323723Sbloom fprintf(stderr, "On %s write: %s\n", 50423723Sbloom NEtcttys, sys_errlist[errno]); 50523723Sbloom exit(1); 50623723Sbloom } 50723723Sbloom } 50823723Sbloom 50923723Sbloom if (enable^resettty) 51023723Sbloom (void) unlink(NEtcttys); 51123723Sbloom else { 51223723Sbloom struct stat statb; 51323723Sbloom if (stat(Etcttys, &statb) == 0) { 51425123Sbloom fchmod(fileno(nttysfile) ,statb.st_mode); 51525123Sbloom fchown(fileno(nttysfile), statb.st_uid, statb.st_gid); 51623723Sbloom } 51723723Sbloom (void) rename(NEtcttys, Etcttys); 51823723Sbloom } 51925123Sbloom (void) fclose(nttysfile); 52025123Sbloom (void) fclose(ttysfile); 52123723Sbloom return enable^resettty; 52223723Sbloom } 52323723Sbloom 52423723Sbloom #else !BSD4_3 52523723Sbloom 52623723Sbloom /* identify terminal line in ttys */ 52723723Sbloom opnttys(device) 52823723Sbloom char *device; 52923723Sbloom { 53018480Sralph register FILE *ttysfile; 53118480Sralph register int ndevice, lnsiz; 53218480Sralph register char *p; 53318480Sralph char *index(); 53423723Sbloom char linebuf[BUFSIZ]; 53518480Sralph 53618480Sralph ttysfile = fopen(Etcttys, "r"); 53718480Sralph if(ttysfile == NULL) { 53818480Sralph fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 53918480Sralph sys_errlist[errno]); 54018480Sralph exit(1); 54118480Sralph } 54218480Sralph 54318480Sralph ndevice = strlen(device); 54418480Sralph ttyslnbeg = 0; 54518480Sralph utmploc = 0; 54618480Sralph 54718480Sralph while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { 54818480Sralph lnsiz = strlen(linebuf); 54923723Sbloom if ((p = index(linebuf, '\n')) != NULL) 55018480Sralph *p = '\0'; 55118480Sralph if(strncmp(device, &linebuf[2], ndevice) == 0) { 55218480Sralph (void)fclose(ttysfile); 55318480Sralph return; 55418480Sralph } 55518480Sralph ttyslnbeg += lnsiz; 55625123Sbloom utmploc += sizeof(utmp); 55718480Sralph } 55818480Sralph fprintf(stderr, "%s not found in %s\n", device, Etcttys); 55918480Sralph exit(1); 56018480Sralph } 56118480Sralph 56218480Sralph /* modify appropriate line in /etc/ttys to turn on/off the device */ 56318480Sralph settys(enable) 56418480Sralph int enable; 56518480Sralph { 56618480Sralph int ittysfil; 56723723Sbloom char out, in; 56818480Sralph 56918480Sralph ittysfil = open(Etcttys, 2); 57023723Sbloom if(ittysfil < 0) { 57118480Sralph fprintf(stderr, "Cannot open %s for output: %s\n", 57218480Sralph Etcttys, sys_errlist[errno]); 57318480Sralph exit(1); 57418480Sralph } 57523723Sbloom (void)lseek(ittysfil, ttyslnbeg, 0); 57623723Sbloom if(read(ittysfil, &in, 1)<0) { 57723723Sbloom fprintf(stderr, "On %s write: %s\n", 57818480Sralph Etcttys, sys_errlist[errno]); 57918480Sralph exit(1); 58018480Sralph } 58118480Sralph resettty = (in == '1'); 58218480Sralph out = enable ? '1' : '0'; 58323723Sbloom (void)lseek(ittysfil, ttyslnbeg, 0); 58423723Sbloom if(write(ittysfil, &out, 1)<0) { 58523723Sbloom fprintf(stderr, "On %s write: %s\n", 58618480Sralph Etcttys, sys_errlist[errno]); 58718480Sralph exit(1); 58818480Sralph } 58918480Sralph (void)close(ittysfil); 59018614Sralph return(in==out); 59118480Sralph } 59223723Sbloom #endif !BSD4_3 59318480Sralph 59418480Sralph /* 59523723Sbloom * Excerpted from (June 8, 1983 W.Sebok) 59618480Sralph * > ttymodem.c - enable/disable modem control for tty lines. 59718480Sralph * > 59818480Sralph * > Knows about DZ11s and DH11/DM11s. 59918480Sralph * > 23.3.83 - TS 60023723Sbloom * > modified to know about DMF's (hasn't been tested) Nov 8, 1984 - WLS 60118480Sralph */ 60218480Sralph 60318480Sralph 60423723Sbloom setmodem(ttyline, enable) 60518480Sralph char *ttyline; int enable; 60618480Sralph { 60718480Sralph dev_t dev; 60818480Sralph int kmem; 60923723Sbloom int unit, line, nlines, addr, tflags; 61018614Sralph int devtype=0; 61118614Sralph char cflags; short sflags; 61218614Sralph #ifdef BSD4_2 61318614Sralph int flags; 61418614Sralph #else 61518614Sralph short flags; 61618614Sralph #endif 61718480Sralph struct uba_device *ubinfo; 61818480Sralph struct stat statb; 61918480Sralph struct cdevsw cdevsw; 62018480Sralph 62118480Sralph if(nl[CDEVSW].n_type == 0) { 62223723Sbloom fprintf(stderr, "No namelist.\n"); 62318480Sralph return(-1); 62418480Sralph } 62518480Sralph 62618480Sralph if((kmem = open("/dev/kmem", 2)) < 0) { 62723723Sbloom fprintf(stderr, "/dev/kmem open: %s\n", sys_errlist[errno]); 62818480Sralph return(-1); 62918480Sralph } 63018480Sralph 63123723Sbloom if(stat(ttyline, &statb) < 0) { 63223723Sbloom fprintf(stderr, "%s stat: %s\n", ttyline, sys_errlist[errno]); 63318480Sralph return(-1); 63418480Sralph } 63518480Sralph 63618614Sralph if((statb.st_mode&S_IFMT) != S_IFCHR) { 63723723Sbloom fprintf(stderr, "%s is not a character device.\n",ttyline); 63818480Sralph return(-1); 63918480Sralph } 64018480Sralph 64118480Sralph dev = statb.st_rdev; 64218480Sralph (void)lseek(kmem, 64318614Sralph (off_t) &(((struct cdevsw *)NLVALUE(CDEVSW))[major(dev)]),0); 64423723Sbloom (void)read(kmem, (char *) &cdevsw, sizeof cdevsw); 64518480Sralph 64618480Sralph if((int)(cdevsw.d_open) == NLVALUE(DZOPEN)) { 64718480Sralph devtype = DZ11; 64818480Sralph unit = minor(dev) / NDZLINE; 64918480Sralph line = minor(dev) % NDZLINE; 65018480Sralph addr = (int) &(((int *)NLVALUE(DZINFO))[unit]); 65123723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDZ11), 0); 65218480Sralph } else if((int)(cdevsw.d_open) == NLVALUE(DHOPEN)) { 65318480Sralph devtype = DH11; 65418480Sralph unit = minor(dev) / NDHLINE; 65518480Sralph line = minor(dev) % NDHLINE; 65618480Sralph addr = (int) &(((int *)NLVALUE(DHINFO))[unit]); 65723723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDH11), 0); 65818480Sralph } else if((int)(cdevsw.d_open) == NLVALUE(DMFOPEN)) { 65918480Sralph devtype = DMF; 66018480Sralph unit = minor(dev) / NDMFLINE; 66118480Sralph line = minor(dev) % NDMFLINE; 66218480Sralph addr = (int) &(((int *)NLVALUE(DMFINFO))[unit]); 66323723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDMF), 0); 66418480Sralph } else { 66523723Sbloom fprintf(stderr, "Device %s (%d/%d) unknown.\n", ttyline, 66623723Sbloom major(dev), minor(dev)); 66718480Sralph return(-1); 66818480Sralph } 66918480Sralph 67023723Sbloom (void)read(kmem, (char *) &nlines, sizeof nlines); 67118480Sralph if(minor(dev) >= nlines) { 67223723Sbloom fprintf(stderr, "Sub-device %d does not exist (only %d).\n", 67323723Sbloom minor(dev), nlines); 67418480Sralph return(-1); 67518480Sralph } 67618480Sralph 67723723Sbloom (void)lseek(kmem, (off_t)addr, 0); 67823723Sbloom (void)read(kmem, (char *) &ubinfo, sizeof ubinfo); 67923723Sbloom (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0); 68023723Sbloom (void)read(kmem, (char *) &flags, sizeof flags); 68118480Sralph 68218480Sralph tflags = 1<<line; 68318480Sralph resetmodem = ((flags&tflags) == 0); 68418480Sralph flags = enable ? (flags & ~tflags) : (flags | tflags); 68523723Sbloom (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0); 68623723Sbloom (void)write(kmem, (char *) &flags, sizeof flags); 68718480Sralph switch(devtype) { 68818480Sralph case DZ11: 68918480Sralph if((addr = NLVALUE(DZSCAR)) == 0) { 69023723Sbloom fprintf(stderr, "No dzsoftCAR.\n"); 69118480Sralph return(-1); 69218480Sralph } 69318614Sralph cflags = flags; 69423723Sbloom (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); 69523723Sbloom (void)write(kmem, (char *) &cflags, sizeof cflags); 69618480Sralph break; 69718480Sralph case DH11: 69818480Sralph if((addr = NLVALUE(DHSCAR)) == 0) { 69923723Sbloom fprintf(stderr, "No dhsoftCAR.\n"); 70018480Sralph return(-1); 70118480Sralph } 70218614Sralph sflags = flags; 70323723Sbloom (void)lseek(kmem, (off_t) &(((short *)addr)[unit]), 0); 70423723Sbloom (void)write(kmem, (char *) &sflags, sizeof sflags); 70518480Sralph break; 70618480Sralph case DMF: 70718480Sralph if((addr = NLVALUE(DMFSCAR)) == 0) { 70823723Sbloom fprintf(stderr, "No dmfsoftCAR.\n"); 70918480Sralph return(-1); 71018480Sralph } 71118614Sralph cflags = flags; 71223723Sbloom (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); 71323723Sbloom (void)write(kmem, (char *) &flags, sizeof cflags); 71418480Sralph break; 71518480Sralph default: 71623723Sbloom fprintf(stderr, "Unknown device type\n"); 71718480Sralph return(-1); 71818480Sralph } 71918480Sralph return(0); 72018480Sralph } 72118480Sralph 72218480Sralph prefix(s1, s2) 72318480Sralph register char *s1, *s2; 72418480Sralph { 72518480Sralph register char c; 72618480Sralph 72718480Sralph while ((c = *s1++) == *s2++) 72818480Sralph if (c == '\0') 72918480Sralph return (1); 73018480Sralph return (c == '\0'); 73118480Sralph } 732*25962Sbloom #endif DIALINOUT 733