1*48649Sbostic /*- 2*48649Sbostic * Copyright (c) 1985, 1986 The Regents of the University of California. 3*48649Sbostic * All rights reserved. 4*48649Sbostic * 5*48649Sbostic * %sccs.include.redist.c% 6*48649Sbostic */ 7*48649Sbostic 818480Sralph #ifndef lint 9*48649Sbostic char copyright[] = 10*48649Sbostic "@(#) Copyright (c) 1985, 1986 The Regents of the University of California.\n\ 11*48649Sbostic All rights reserved.\n"; 12*48649Sbostic #endif /* not lint */ 1318480Sralph 14*48649Sbostic #ifndef lint 15*48649Sbostic static char sccsid[] = "@(#)acucntrl.c 5.17 (Berkeley) 04/24/91"; 16*48649Sbostic #endif /* not lint */ 17*48649Sbostic 1818480Sralph /* acucntrl - turn around tty line between dialin and dialout 1918480Sralph * 2018480Sralph * Usage: acucntrl {enable,disable} /dev/ttydX 2118480Sralph * 2218480Sralph * History: 2318480Sralph * First written by Allan Wilkes (fisher!allan) 2418480Sralph * 2518480Sralph * Modified June 8,1983 by W.Sebok (astrovax!wls) to poke kernel rather 2618480Sralph * than use kernel hack to turn on/off modem control, using subroutine 2718480Sralph * stolen from program written by Tsutomu Shimomura 2818480Sralph * {astrovax,escher}!tsutomu 2918480Sralph * 3018480Sralph * Worked over many times by W.Sebok (i.e. hacked to death) 3118480Sralph * 3218480Sralph * Operation: 3318480Sralph * disable (i.e. setup for dialing out) 3418480Sralph * (1) check input arguments 3537930Sbostic * (2) look in _PATH_UTMP to check that the line is not in use by another 3618480Sralph * (3) disable modem control on terminal 3718480Sralph * (4) check for carrier on device 3818480Sralph * (5) change owner of device to real id 3937930Sbostic * (6) edit _PATH_TTYS, changing the first character of the appropriate 4018480Sralph * line to 0 4118480Sralph * (7) send a hangup to process 1 to poke init to disable getty 4237930Sbostic * (8) post uid name in capitals in _PATH_UTMP to let world know device 4337930Sbostic * has been grabbed 4418480Sralph * (9) make sure that DTR is on 4518480Sralph * 4618480Sralph * enable (i.e.) restore for dialin 4718480Sralph * (1) check input arguments 4837930Sbostic * (2) look in _PATH_UTMP to check that the line is not in use by another 4918480Sralph * (3) make sure modem control on terminal is disabled 5018480Sralph * (4) turn off DTR to make sure line is hung up 5118480Sralph * (5) condition line: clear exclusive use and set hangup on close modes 5218480Sralph * (6) turn on modem control 5337930Sbostic * (7) edit _PATH_TTYS, changing the first character of the appropriate 5418480Sralph * line to 1 5518480Sralph * (8) send a hangup to process 1 to poke init to enable getty 5637930Sbostic * (9) clear uid name for _PATH_UTMP 5718480Sralph */ 5818480Sralph 5918480Sralph /* #define SENSECARRIER */ 6018480Sralph 6118480Sralph #include "uucp.h" 6233557Srick #ifdef DIALINOUT 6318480Sralph #include <sys/buf.h> 6418614Sralph #include <signal.h> 6518480Sralph #include <sys/conf.h> 6633557Srick #ifdef vax 6733557Srick #ifdef BSD4_2 6833557Srick #include <vaxuba/ubavar.h> 6933557Srick #else 7033557Srick #include <sys/ubavar.h> 7133557Srick #endif 7233557Srick #endif /* vax */ 7318480Sralph #include <sys/stat.h> 7418480Sralph #include <nlist.h> 7518480Sralph #include <sgtty.h> 7618480Sralph #include <utmp.h> 7718480Sralph #include <pwd.h> 7818480Sralph #include <stdio.h> 7925123Sbloom #include <sys/file.h> 8037930Sbostic #include "pathnames.h" 8118480Sralph 8218480Sralph #define NDZLINE 8 /* lines/dz */ 8318480Sralph #define NDHLINE 16 /* lines/dh */ 8418480Sralph #define NDMFLINE 8 /* lines/dmf */ 8518480Sralph 8618480Sralph #define DZ11 1 8718480Sralph #define DH11 2 8818480Sralph #define DMF 3 8918480Sralph 9018480Sralph #define NLVALUE(val) (nl[val].n_value) 9118480Sralph 9218480Sralph struct nlist nl[] = { 9318480Sralph #define CDEVSW 0 9418480Sralph { "_cdevsw" }, 9518480Sralph 9618480Sralph #define DZOPEN 1 9718480Sralph { "_dzopen" }, 9818480Sralph #define DZINFO 2 9918480Sralph { "_dzinfo" }, 10018480Sralph #define NDZ11 3 10118480Sralph { "_dz_cnt" }, 10218480Sralph #define DZSCAR 4 10318480Sralph { "_dzsoftCAR" }, 10418480Sralph 10518480Sralph #define DHOPEN 5 10618480Sralph { "_dhopen" }, 10718480Sralph #define DHINFO 6 10818480Sralph { "_dhinfo" }, 10918480Sralph #define NDH11 7 11018480Sralph { "_ndh11" }, 11118480Sralph #define DHSCAR 8 11218480Sralph { "_dhsoftCAR" }, 11318480Sralph 11418480Sralph #define DMFOPEN 9 11518480Sralph { "_dmfopen" }, 11618480Sralph #define DMFINFO 10 11718480Sralph { "_dmfinfo" }, 11818480Sralph #define NDMF 11 11918480Sralph { "_ndmf" }, 12018480Sralph #define DMFSCAR 12 12118480Sralph { "_dmfsoftCAR" }, 12218480Sralph 12318480Sralph { "\0" } 12418480Sralph }; 12518480Sralph 12618480Sralph #define ENABLE 1 12718480Sralph #define DISABLE 0 12818480Sralph 12937930Sbostic char Etcttys[] = _PATH_TTYS; 13023723Sbloom #ifdef BSD4_3 13125123Sbloom FILE *ttysfile, *nttysfile; 13237930Sbostic char NEtcttys[] = _PATH_NEWTTYS; 13323723Sbloom extern long ftell(); 13423723Sbloom #endif BSD4_3 13537930Sbostic char Devhome[] = _PATH_DEV; 13618480Sralph 13718480Sralph char usage[] = "Usage: acucntrl {dis|en}able ttydX\n"; 13818480Sralph 13918480Sralph struct utmp utmp; 14018480Sralph char resettty, resetmodem; 14118480Sralph int etcutmp; 14234163Srick off_t utmploc; 14334163Srick off_t ttyslnbeg; 14434093Sbostic extern int errno; 14534093Sbostic extern char *sys_errlist[]; 14634093Sbostic off_t lseek(); 14718480Sralph 14818480Sralph #define NAMSIZ sizeof(utmp.ut_name) 14918480Sralph #define LINSIZ sizeof(utmp.ut_line) 15018480Sralph 15118480Sralph main(argc, argv) 15218480Sralph int argc; char *argv[]; 15318480Sralph { 15418480Sralph register char *p; 15518480Sralph register int i; 15618480Sralph char uname[NAMSIZ], Uname[NAMSIZ]; 15718480Sralph int enable ; 15818480Sralph char *device; 15918480Sralph int devfile; 16018480Sralph int uid, gid; 16118480Sralph struct passwd *getpwuid(); 16218480Sralph char *rindex(); 16318480Sralph 16418480Sralph /* check input arguments */ 16534163Srick if (argc!=3 && argc != 4) { 16618480Sralph fprintf(stderr, usage); 16718480Sralph exit(1); 16818480Sralph } 16918480Sralph 17018480Sralph /* interpret command type */ 17123723Sbloom if (prefix(argv[1], "disable") || strcmp(argv[1], "dialout")==0) 17218480Sralph enable = 0; 17323723Sbloom else if (prefix(argv[1], "enable") || strcmp(argv[1], "dialin")==0) 17418480Sralph enable = 1; 17518480Sralph else { 17618480Sralph fprintf(stderr, usage); 17718480Sralph exit(1); 17818480Sralph } 17918480Sralph 18023723Sbloom device = rindex(argv[2], '/'); 18118480Sralph device = (device == NULL) ? argv[2]: device+1; 18218480Sralph 18318480Sralph opnttys(device); 18418480Sralph 18533557Srick #ifdef vax 18618480Sralph /* Get nlist info */ 18737930Sbostic nlist(_PATH_UNIX, nl); 18833557Srick #endif vax 18918480Sralph 19018480Sralph /* Chdir to /dev */ 19118480Sralph if(chdir(Devhome) < 0) { 19218480Sralph fprintf(stderr, "Cannot chdir to %s: %s\r\n", 19318480Sralph Devhome, sys_errlist[errno]); 19418480Sralph exit(1); 19518480Sralph } 19618480Sralph 19718480Sralph /* Get uid information */ 19818480Sralph uid = getuid(); 19918480Sralph gid = getgid(); 20018480Sralph 20118480Sralph p = getpwuid(uid)->pw_name; 20218480Sralph if (p==NULL) { 20323723Sbloom fprintf(stderr, "cannot get uid name\n"); 20418480Sralph exit(1); 20518480Sralph } 20618480Sralph 20734163Srick if (strcmp(p, "uucp") == 0 && argc == 4) 20834163Srick p = argv[3]; 20934163Srick 21018480Sralph /* to upper case */ 21118480Sralph i = 0; 21218480Sralph do { 21318480Sralph uname[i] = *p; 21433968Srick Uname[i++] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p; 21533968Srick } while (*p++ && i<NAMSIZ); 21618480Sralph 21718480Sralph /* check to see if line is being used */ 21837930Sbostic if( (etcutmp = open(_PATH_UTMP, 2)) < 0) { 21923723Sbloom fprintf(stderr, "On open %s open: %s\n", 22037930Sbostic _PATH_UTMP, sys_errlist[errno]); 22118480Sralph exit(1); 22218480Sralph } 22318480Sralph 22423723Sbloom (void)lseek(etcutmp, utmploc, 0); 22518480Sralph 22623723Sbloom i = read(etcutmp, (char *)&utmp, sizeof(struct utmp)); 22718480Sralph 22818480Sralph if( 22918480Sralph i == sizeof(struct utmp) && 23018480Sralph utmp.ut_line[0] != '\0' && 23118480Sralph utmp.ut_name[0] != '\0' && 23218480Sralph ( 23323723Sbloom !upcase(utmp.ut_name, NAMSIZ) || 23418480Sralph ( 23518480Sralph uid != 0 && 23623723Sbloom strncmp(utmp.ut_name, Uname, NAMSIZ) != 0 23718480Sralph ) 23818480Sralph ) 23918480Sralph ) { 24018480Sralph fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name); 24118480Sralph exit(2); 24218480Sralph } 24318480Sralph 24433557Srick #ifndef sequent 24518480Sralph /* Disable modem control */ 24623723Sbloom if (setmodem(device, DISABLE) < 0) { 24723723Sbloom fprintf(stderr, "Unable to disable modem control\n"); 24818480Sralph exit(1); 24918480Sralph } 25033557Srick #endif !sequent 25118480Sralph 25218480Sralph if (enable) { 25333557Srick #ifdef sequent 25433557Srick if (setmodem(device, ENABLE) < 0) { 25533557Srick fprintf(stderr, "Cannot Enable modem control\n"); 25633557Srick (void)setmodem(device, i); 25733557Srick exit(1); 25833557Srick } 25933557Srick #endif sequent 26033557Srick #ifndef sequent 26118480Sralph if((devfile = open(device, 1)) < 0) { 26223723Sbloom fprintf(stderr, "On open of %s: %s\n", 26318480Sralph device, sys_errlist[errno]); 26423723Sbloom (void)setmodem(device, resetmodem); 26518480Sralph exit(1); 26618480Sralph } 26718480Sralph /* Try one last time to hang up */ 26823723Sbloom if (ioctl(devfile, (int)TIOCCDTR, (char *)0) < 0) 26923723Sbloom fprintf(stderr, "On TIOCCDTR ioctl: %s\n", 27018480Sralph sys_errlist[errno]); 27118480Sralph 27223723Sbloom if (ioctl(devfile, (int)TIOCNXCL, (char *)0) < 0) 27318480Sralph fprintf(stderr, 27418480Sralph "Cannot clear Exclusive Use on %s: %s\n", 27518480Sralph device, sys_errlist[errno]); 27618480Sralph 27723723Sbloom if (ioctl(devfile, (int)TIOCHPCL, (char *)0) < 0) 27818480Sralph fprintf(stderr, 27918480Sralph "Cannot set hangup on close on %s: %s\n", 28018480Sralph device, sys_errlist[errno]); 28118480Sralph 28233557Srick #endif !sequent 28318480Sralph i = resetmodem; 28418480Sralph 28533557Srick #ifndef sequent 28623723Sbloom if (setmodem(device, ENABLE) < 0) { 28723723Sbloom fprintf(stderr, "Cannot Enable modem control\n"); 28823723Sbloom (void)setmodem(device, i); 28918480Sralph exit(1); 29018480Sralph } 29133557Srick #endif sequent 29218480Sralph resetmodem=i; 29318480Sralph 29418614Sralph if (settys(ENABLE)) { 29523723Sbloom fprintf(stderr, "%s already enabled\n", device); 29618614Sralph } else { 29723723Sbloom pokeinit(device, Uname, enable); 29818614Sralph } 29923723Sbloom post(device, ""); 30018480Sralph 30118480Sralph } else { 30218480Sralph #if defined(TIOCMGET) && defined(SENSECARRIER) 30318480Sralph if (uid!=0) { 30418480Sralph int linestat = 0; 30518480Sralph 30618480Sralph /* check for presence of carrier */ 30718480Sralph sleep(2); /* need time after modem control turnoff */ 30818480Sralph 30918480Sralph if((devfile = open(device, 1)) < 0) { 31023723Sbloom fprintf(stderr, "On open of %s: %s\n", 31118480Sralph device, sys_errlist[errno]); 31223723Sbloom (void)setmodem(device, resetmodem); 31318480Sralph exit(1); 31418480Sralph } 31518480Sralph 31623723Sbloom (void)ioctl(devfile, TIOCMGET, &linestat); 31718480Sralph 31818480Sralph if (linestat&TIOCM_CAR) { 31923723Sbloom fprintf(stderr, "%s is in use (Carrier On)\n", 32018480Sralph device); 32123723Sbloom (void)setmodem(device, resetmodem); 32218480Sralph exit(2); 32318480Sralph } 32418480Sralph (void)close(devfile); 32518480Sralph } 32618480Sralph #endif TIOCMGET 32718480Sralph /* chown device */ 32818480Sralph if(chown(device, uid, gid) < 0) 32918480Sralph fprintf(stderr, "Cannot chown %s: %s\n", 33018480Sralph device, sys_errlist[errno]); 33118480Sralph 33218480Sralph 33318480Sralph /* poke init */ 33418614Sralph if(settys(DISABLE)) { 33523723Sbloom fprintf(stderr, "%s already disabled\n", device); 33618614Sralph } else { 33723723Sbloom pokeinit(device, Uname, enable); 33818614Sralph } 33923723Sbloom post(device, Uname); 34033557Srick #ifdef sequent 34133557Srick /* Disable modem control */ 34233557Srick if (setmodem(device, DISABLE) < 0) { 34333557Srick fprintf(stderr, "Unable to disable modem control\n"); 34433557Srick exit(1); 34533557Srick } 34633557Srick #endif sequent 34725123Sbloom if((devfile = open(device, O_RDWR|O_NDELAY)) < 0) { 34818480Sralph fprintf(stderr, "On %s open: %s\n", 34918480Sralph device, sys_errlist[errno]); 35018480Sralph } else { 35118614Sralph if(ioctl(devfile, (int)TIOCSDTR, (char *)0) < 0) 35218480Sralph fprintf(stderr, 35318480Sralph "Cannot set DTR on %s: %s\n", 35418480Sralph device, sys_errlist[errno]); 35518480Sralph } 35618480Sralph } 35718480Sralph 35818480Sralph exit(0); 35918480Sralph } 36018480Sralph 36118480Sralph /* return true if no lower case */ 36223723Sbloom upcase(str, len) 36318480Sralph register char *str; 36418480Sralph register int len; 36518480Sralph { 36618480Sralph for (; *str, --len >= 0 ; str++) 36718480Sralph if (*str>='a' && *str<='z') 36818480Sralph return(0); 36918480Sralph return(1); 37018480Sralph } 37118480Sralph 37218480Sralph /* Post name to public */ 37323723Sbloom post(device, name) 37418480Sralph char *device, *name; 37518480Sralph { 37618614Sralph (void)time((time_t *)&utmp.ut_time); 37723583Sbloom strncpy(utmp.ut_line, device, LINSIZ); 37823583Sbloom strncpy(utmp.ut_name, name, NAMSIZ); 37925123Sbloom if (lseek(etcutmp, utmploc, 0) < 0) 38037930Sbostic fprintf(stderr, "on lseek in %s: %s", 38137930Sbostic _PATH_UTMP, sys_errlist[errno]); 38225123Sbloom if (write(etcutmp, (char *)&utmp, sizeof(utmp)) < 0) 38337930Sbostic fprintf(stderr, "on write in %s: %s", 38437930Sbostic _PATH_UTMP, sys_errlist[errno]); 38518480Sralph } 38618480Sralph 38718480Sralph /* poke process 1 and wait for it to do its thing */ 38823723Sbloom pokeinit(device, uname, enable) 38918480Sralph char *uname, *device; int enable; 39018480Sralph { 39118480Sralph struct utmp utmp; 39218614Sralph register int i; 39318480Sralph 39418480Sralph post(device, uname); 39518480Sralph 39618480Sralph /* poke init */ 39718480Sralph if (kill(1, SIGHUP)) { 39818480Sralph fprintf(stderr, 39918480Sralph "Cannot send hangup to init process: %s\n", 40018480Sralph sys_errlist[errno]); 40118614Sralph (void)settys(resettty); 40223723Sbloom (void)setmodem(device, resetmodem); 40318480Sralph exit(1); 40418480Sralph } 40518480Sralph 40618480Sralph if (enable) 40718480Sralph return; 40818480Sralph 40918480Sralph /* wait till init has responded, clearing the utmp entry */ 41025123Sbloom i = 100; 41118480Sralph do { 41218480Sralph sleep(1); 41325123Sbloom if (lseek(etcutmp, utmploc, 0) < 0) 41437930Sbostic fprintf(stderr, "On lseek in %s: %s", 41537930Sbostic _PATH_UTMP, sys_errlist[errno]); 41625123Sbloom if (read(etcutmp, (char *)&utmp, sizeof utmp) < 0) 41737930Sbostic fprintf(stderr, "On read from %s: %s", 41837930Sbostic _PATH_UTMP, sys_errlist[errno]); 41918614Sralph } while (utmp.ut_name[0] != '\0' && --i > 0); 42018480Sralph } 42118480Sralph 42223723Sbloom #ifdef BSD4_3 42318480Sralph /* identify terminal line in ttys */ 42418480Sralph opnttys(device) 42518480Sralph char *device; 42618480Sralph { 42723723Sbloom register int ndevice; 42823723Sbloom register char *p; 42923723Sbloom char *index(); 43023723Sbloom char linebuf[BUFSIZ]; 43123723Sbloom 43225123Sbloom ttysfile = NULL; 43325123Sbloom do { 43425123Sbloom if (ttysfile != NULL) { 43525123Sbloom fclose(ttysfile); 43625123Sbloom sleep(5); 43725123Sbloom } 43825123Sbloom ttysfile = fopen(Etcttys, "r"); 43925123Sbloom if(ttysfile == NULL) { 44025123Sbloom fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 44125123Sbloom sys_errlist[errno]); 44225123Sbloom exit(1); 44325123Sbloom } 44425123Sbloom } while (flock(fileno(ttysfile), LOCK_NB|LOCK_EX) < 0); 44523723Sbloom nttysfile = fopen(NEtcttys, "w"); 44623723Sbloom if(nttysfile == NULL) { 44723723Sbloom fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 44823723Sbloom sys_errlist[errno]); 44923723Sbloom exit(1); 45023723Sbloom } 45123723Sbloom 45223723Sbloom ndevice = strlen(device); 45325962Sbloom #ifndef BRL4_2 45425123Sbloom utmploc = sizeof(utmp); 45525962Sbloom #else BRL4_2 45625962Sbloom utmploc = 0; 45725962Sbloom #endif BRL4_2 45823723Sbloom 45923723Sbloom while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { 46025123Sbloom if(strncmp(device, linebuf, ndevice) == 0) 46125123Sbloom return; 46225123Sbloom ttyslnbeg += strlen(linebuf); 46325962Sbloom if (linebuf[0] != '#' && linebuf[0] != '\0') 46425962Sbloom utmploc += sizeof(utmp); 46523723Sbloom if (fputs(linebuf, nttysfile) == NULL) { 46623723Sbloom fprintf(stderr, "On %s write: %s\n", 46723723Sbloom Etcttys, sys_errlist[errno]); 46823723Sbloom exit(1); 46923723Sbloom } 47023723Sbloom 47123723Sbloom } 47223723Sbloom fprintf(stderr, "%s not found in %s\n", device, Etcttys); 47323723Sbloom exit(1); 47423723Sbloom } 47523723Sbloom 47637930Sbostic /* modify appropriate line in _PATH_TTYS to turn on/off the device */ 47723723Sbloom settys(enable) 47823723Sbloom int enable; 47923723Sbloom { 48023723Sbloom register char *cp, *cp2; 48123723Sbloom char lbuf[BUFSIZ]; 48223723Sbloom int i; 48323723Sbloom char c1, c2; 48423723Sbloom 48525123Sbloom (void) fseek(ttysfile, ttyslnbeg, 0); 48625123Sbloom if(fgets(lbuf, BUFSIZ, ttysfile) == NULL) { 48723723Sbloom fprintf(stderr, "On %s read: %s\n", 48823723Sbloom Etcttys, sys_errlist[errno]); 48923723Sbloom exit(1); 49023723Sbloom } 49123723Sbloom /* format is now */ 49223723Sbloom /* ttyd0 std.100 dialup on secure # comment */ 49325364Sbloom /* except, 2nd item may have embedded spaces inside quotes, Hubert */ 49423723Sbloom cp = lbuf; 49523723Sbloom for (i=0;*cp && i<3;i++) { 49625364Sbloom if (*cp == '"') { 49723723Sbloom cp++; 49825364Sbloom while (*cp && *cp != '"') 49925364Sbloom cp++; 50025364Sbloom if (*cp != '\0') 50125364Sbloom cp++; 50225364Sbloom }else { 50325364Sbloom while (*cp && *cp != ' ' && *cp != '\t') 50425364Sbloom cp++; 50525364Sbloom } 50623723Sbloom while (*cp && (*cp == ' ' || *cp == '\t')) 50723723Sbloom cp++; 50823723Sbloom } 50923723Sbloom if (*cp == '\0') { 51037930Sbostic fprintf(stderr,"Badly formatted line in %s:\n%s", 51137930Sbostic _PATH_TTYS, lbuf); 51223723Sbloom exit(1); 51323723Sbloom } 51423723Sbloom c1 = *--cp; 51523723Sbloom *cp++ = '\0'; 51623723Sbloom cp2 = cp; 51723723Sbloom while (*cp && *cp != ' ' && *cp != '\t' && *cp != '\n') 51823723Sbloom cp++; 51923723Sbloom if (*cp == '\0') { 52037930Sbostic fprintf(stderr,"Badly formatted line in %s:\n%s", 52137930Sbostic _PATH_TTYS, lbuf); 52223723Sbloom exit(1); 52323723Sbloom } 52423723Sbloom c2 = *cp; 52523723Sbloom *cp++ = '\0'; 52623723Sbloom while (*cp && (*cp == ' ' || *cp == '\t')) 52723723Sbloom cp++; 52823723Sbloom resettty = strcmp("on", cp2) != 0; 52925123Sbloom fprintf(nttysfile,"%s%c%s%c%s", lbuf, c1, enable ? "on" : "off", c2, cp); 53025123Sbloom if (ferror(nttysfile)) { 53123723Sbloom fprintf(stderr, "On %s fprintf: %s\n", 53223723Sbloom NEtcttys, sys_errlist[errno]); 53323723Sbloom exit(1); 53423723Sbloom } 53525123Sbloom while(fgets(lbuf, sizeof(lbuf) - 1, ttysfile) != NULL) { 53625123Sbloom if (fputs(lbuf, nttysfile) == NULL) { 53723723Sbloom fprintf(stderr, "On %s write: %s\n", 53823723Sbloom NEtcttys, sys_errlist[errno]); 53923723Sbloom exit(1); 54023723Sbloom } 54123723Sbloom } 54223723Sbloom 54323723Sbloom if (enable^resettty) 54423723Sbloom (void) unlink(NEtcttys); 54523723Sbloom else { 54623723Sbloom struct stat statb; 54723723Sbloom if (stat(Etcttys, &statb) == 0) { 54825123Sbloom fchmod(fileno(nttysfile) ,statb.st_mode); 54925123Sbloom fchown(fileno(nttysfile), statb.st_uid, statb.st_gid); 55023723Sbloom } 55123723Sbloom (void) rename(NEtcttys, Etcttys); 55223723Sbloom } 55325123Sbloom (void) fclose(nttysfile); 55425123Sbloom (void) fclose(ttysfile); 55523723Sbloom return enable^resettty; 55623723Sbloom } 55723723Sbloom 55823723Sbloom #else !BSD4_3 55923723Sbloom 56023723Sbloom /* identify terminal line in ttys */ 56123723Sbloom opnttys(device) 56223723Sbloom char *device; 56323723Sbloom { 56418480Sralph register FILE *ttysfile; 56518480Sralph register int ndevice, lnsiz; 56618480Sralph register char *p; 56718480Sralph char *index(); 56823723Sbloom char linebuf[BUFSIZ]; 56918480Sralph 57018480Sralph ttysfile = fopen(Etcttys, "r"); 57118480Sralph if(ttysfile == NULL) { 57218480Sralph fprintf(stderr, "Cannot open %s: %s\n", Etcttys, 57318480Sralph sys_errlist[errno]); 57418480Sralph exit(1); 57518480Sralph } 57618480Sralph 57718480Sralph ndevice = strlen(device); 57818480Sralph ttyslnbeg = 0; 57918480Sralph utmploc = 0; 58018480Sralph 58118480Sralph while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { 58218480Sralph lnsiz = strlen(linebuf); 58323723Sbloom if ((p = index(linebuf, '\n')) != NULL) 58418480Sralph *p = '\0'; 58518480Sralph if(strncmp(device, &linebuf[2], ndevice) == 0) { 58618480Sralph (void)fclose(ttysfile); 58733557Srick #ifdef sequent 58833557Srick /* Why is the sequent off by one? */ 58933557Srick utmploc += sizeof(utmp); 59033557Srick #endif sequent 59118480Sralph return; 59218480Sralph } 59318480Sralph ttyslnbeg += lnsiz; 59425123Sbloom utmploc += sizeof(utmp); 59518480Sralph } 59618480Sralph fprintf(stderr, "%s not found in %s\n", device, Etcttys); 59718480Sralph exit(1); 59818480Sralph } 59918480Sralph 60037930Sbostic /* modify appropriate line in _PATH_TTYS to turn on/off the device */ 60118480Sralph settys(enable) 60218480Sralph int enable; 60318480Sralph { 60418480Sralph int ittysfil; 60523723Sbloom char out, in; 60618480Sralph 60718480Sralph ittysfil = open(Etcttys, 2); 60823723Sbloom if(ittysfil < 0) { 60918480Sralph fprintf(stderr, "Cannot open %s for output: %s\n", 61018480Sralph Etcttys, sys_errlist[errno]); 61118480Sralph exit(1); 61218480Sralph } 61323723Sbloom (void)lseek(ittysfil, ttyslnbeg, 0); 61423723Sbloom if(read(ittysfil, &in, 1)<0) { 61523723Sbloom fprintf(stderr, "On %s write: %s\n", 61618480Sralph Etcttys, sys_errlist[errno]); 61718480Sralph exit(1); 61818480Sralph } 61918480Sralph resettty = (in == '1'); 62018480Sralph out = enable ? '1' : '0'; 62123723Sbloom (void)lseek(ittysfil, ttyslnbeg, 0); 62223723Sbloom if(write(ittysfil, &out, 1)<0) { 62323723Sbloom fprintf(stderr, "On %s write: %s\n", 62418480Sralph Etcttys, sys_errlist[errno]); 62518480Sralph exit(1); 62618480Sralph } 62718480Sralph (void)close(ittysfil); 62818614Sralph return(in==out); 62918480Sralph } 63023723Sbloom #endif !BSD4_3 63118480Sralph 63233557Srick #ifdef sequent 63333557Srick setmodem(ttyline, enable) 63433557Srick char *ttyline; int enable; 63533557Srick { 63633557Srick char *sysbuf[BUFSIZ]; 63733557Srick sprintf(sysbuf,"/etc/ttyconfig /dev/%s -special %s", ttyline, 63833557Srick enable ? "-carrier" : "-nocarrier"); 63933557Srick system(sysbuf); 64033557Srick } 64133557Srick #endif /* sequent */ 64233557Srick #ifdef vax 64318480Sralph /* 64423723Sbloom * Excerpted from (June 8, 1983 W.Sebok) 64518480Sralph * > ttymodem.c - enable/disable modem control for tty lines. 64618480Sralph * > 64718480Sralph * > Knows about DZ11s and DH11/DM11s. 64818480Sralph * > 23.3.83 - TS 64923723Sbloom * > modified to know about DMF's (hasn't been tested) Nov 8, 1984 - WLS 65018480Sralph */ 65118480Sralph 65218480Sralph 65323723Sbloom setmodem(ttyline, enable) 65418480Sralph char *ttyline; int enable; 65518480Sralph { 65618480Sralph dev_t dev; 65718480Sralph int kmem; 65823723Sbloom int unit, line, nlines, addr, tflags; 65918614Sralph int devtype=0; 66018614Sralph char cflags; short sflags; 66118614Sralph #ifdef BSD4_2 66218614Sralph int flags; 66318614Sralph #else 66418614Sralph short flags; 66518614Sralph #endif 66618480Sralph struct uba_device *ubinfo; 66718480Sralph struct stat statb; 66818480Sralph struct cdevsw cdevsw; 66918480Sralph 67018480Sralph if(nl[CDEVSW].n_type == 0) { 67123723Sbloom fprintf(stderr, "No namelist.\n"); 67218480Sralph return(-1); 67318480Sralph } 67418480Sralph 67537930Sbostic if((kmem = open(_PATH_KMEM, 2)) < 0) { 67637930Sbostic fprintf(stderr, "%s open: %s\n", _PATH_KMEM, 67737930Sbostic sys_errlist[errno]); 67818480Sralph return(-1); 67918480Sralph } 68018480Sralph 68123723Sbloom if(stat(ttyline, &statb) < 0) { 68223723Sbloom fprintf(stderr, "%s stat: %s\n", ttyline, sys_errlist[errno]); 68318480Sralph return(-1); 68418480Sralph } 68518480Sralph 68618614Sralph if((statb.st_mode&S_IFMT) != S_IFCHR) { 68723723Sbloom fprintf(stderr, "%s is not a character device.\n",ttyline); 68818480Sralph return(-1); 68918480Sralph } 69018480Sralph 69118480Sralph dev = statb.st_rdev; 69218480Sralph (void)lseek(kmem, 69318614Sralph (off_t) &(((struct cdevsw *)NLVALUE(CDEVSW))[major(dev)]),0); 69423723Sbloom (void)read(kmem, (char *) &cdevsw, sizeof cdevsw); 69518480Sralph 69618480Sralph if((int)(cdevsw.d_open) == NLVALUE(DZOPEN)) { 69718480Sralph devtype = DZ11; 69818480Sralph unit = minor(dev) / NDZLINE; 69918480Sralph line = minor(dev) % NDZLINE; 70018480Sralph addr = (int) &(((int *)NLVALUE(DZINFO))[unit]); 70123723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDZ11), 0); 70218480Sralph } else if((int)(cdevsw.d_open) == NLVALUE(DHOPEN)) { 70318480Sralph devtype = DH11; 70418480Sralph unit = minor(dev) / NDHLINE; 70518480Sralph line = minor(dev) % NDHLINE; 70618480Sralph addr = (int) &(((int *)NLVALUE(DHINFO))[unit]); 70723723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDH11), 0); 70818480Sralph } else if((int)(cdevsw.d_open) == NLVALUE(DMFOPEN)) { 70918480Sralph devtype = DMF; 71018480Sralph unit = minor(dev) / NDMFLINE; 71118480Sralph line = minor(dev) % NDMFLINE; 71218480Sralph addr = (int) &(((int *)NLVALUE(DMFINFO))[unit]); 71323723Sbloom (void)lseek(kmem, (off_t) NLVALUE(NDMF), 0); 71418480Sralph } else { 71523723Sbloom fprintf(stderr, "Device %s (%d/%d) unknown.\n", ttyline, 71623723Sbloom major(dev), minor(dev)); 71718480Sralph return(-1); 71818480Sralph } 71918480Sralph 72023723Sbloom (void)read(kmem, (char *) &nlines, sizeof nlines); 72118480Sralph if(minor(dev) >= nlines) { 72223723Sbloom fprintf(stderr, "Sub-device %d does not exist (only %d).\n", 72323723Sbloom minor(dev), nlines); 72418480Sralph return(-1); 72518480Sralph } 72618480Sralph 72723723Sbloom (void)lseek(kmem, (off_t)addr, 0); 72823723Sbloom (void)read(kmem, (char *) &ubinfo, sizeof ubinfo); 72923723Sbloom (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0); 73023723Sbloom (void)read(kmem, (char *) &flags, sizeof flags); 73118480Sralph 73218480Sralph tflags = 1<<line; 73318480Sralph resetmodem = ((flags&tflags) == 0); 73418480Sralph flags = enable ? (flags & ~tflags) : (flags | tflags); 73523723Sbloom (void)lseek(kmem, (off_t) &(ubinfo->ui_flags), 0); 73623723Sbloom (void)write(kmem, (char *) &flags, sizeof flags); 73718480Sralph switch(devtype) { 73818480Sralph case DZ11: 73918480Sralph if((addr = NLVALUE(DZSCAR)) == 0) { 74023723Sbloom fprintf(stderr, "No dzsoftCAR.\n"); 74118480Sralph return(-1); 74218480Sralph } 74318614Sralph cflags = flags; 74423723Sbloom (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); 74523723Sbloom (void)write(kmem, (char *) &cflags, sizeof cflags); 74618480Sralph break; 74718480Sralph case DH11: 74818480Sralph if((addr = NLVALUE(DHSCAR)) == 0) { 74923723Sbloom fprintf(stderr, "No dhsoftCAR.\n"); 75018480Sralph return(-1); 75118480Sralph } 75218614Sralph sflags = flags; 75323723Sbloom (void)lseek(kmem, (off_t) &(((short *)addr)[unit]), 0); 75423723Sbloom (void)write(kmem, (char *) &sflags, sizeof sflags); 75518480Sralph break; 75618480Sralph case DMF: 75718480Sralph if((addr = NLVALUE(DMFSCAR)) == 0) { 75823723Sbloom fprintf(stderr, "No dmfsoftCAR.\n"); 75918480Sralph return(-1); 76018480Sralph } 76118614Sralph cflags = flags; 76223723Sbloom (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); 76334008Sbostic (void)write(kmem, (char *) &cflags, sizeof cflags); 76418480Sralph break; 76518480Sralph default: 76623723Sbloom fprintf(stderr, "Unknown device type\n"); 76718480Sralph return(-1); 76818480Sralph } 76918480Sralph return(0); 77018480Sralph } 77133557Srick #endif /* vax */ 77218480Sralph 77318480Sralph prefix(s1, s2) 77418480Sralph register char *s1, *s2; 77518480Sralph { 77618480Sralph register char c; 77718480Sralph 77818480Sralph while ((c = *s1++) == *s2++) 77918480Sralph if (c == '\0') 78018480Sralph return (1); 78118480Sralph return (c == '\0'); 78218480Sralph } 78333592Srick #else /* !DIALINOUT */ 78433592Srick main() 78533592Srick { 78633592Srick fprintf(stderr,"acucntrl is not supported on this system\n"); 78733592Srick } 78833592Srick #endif /* !DIALINOUT */ 789