148664Sbostic /*-
2*62391Sbostic * Copyright (c) 1985, 1993
3*62391Sbostic * The Regents of the University of California. All rights reserved.
448664Sbostic *
548664Sbostic * %sccs.include.proprietary.c%
648664Sbostic */
748664Sbostic
813641Ssam #ifndef lint
9*62391Sbostic static char sccsid[] = "@(#)condevs.c 8.1 (Berkeley) 06/06/93";
1048664Sbostic #endif /* not lint */
1113641Ssam
1225704Sbloom extern int errno;
1360116Storek extern const char *const sys_errlist[];
1425704Sbloom
1513641Ssam /*
1613641Ssam * Here are various dialers to establish the machine-machine connection.
1713641Ssam * conn.c/condevs.c was glued together by Mike Mitchell.
1813641Ssam * The dialers were supplied by many people, to whom we are grateful.
1913641Ssam *
2013641Ssam * ---------------------------------------------------------------------
2113641Ssam * NOTE:
2213641Ssam * There is a bug that occurs at least on PDP11s due to a limitation of
2313641Ssam * setjmp/longjmp. If the routine that does a setjmp is interrupted
2413641Ssam * and longjmp-ed to, it loses its register variables (on a pdp11).
2513641Ssam * What works is if the routine that does the setjmp
2613641Ssam * calls a routine and it is the *subroutine* that is interrupted.
2717833Sralph *
2813641Ssam * Anyway, in conclusion, condevs.c is plagued with register variables
2913641Ssam * that are used inside
3013641Ssam * if (setjmp(...)) {
3113641Ssam * ....
3213641Ssam * }
3317833Sralph *
3417833Sralph * THE FIX: Don't declare variables to be register
3513641Ssam */
3613641Ssam
3717833Sralph #include "condevs.h"
3837932Sbostic #include "pathnames.h"
3913641Ssam
4013641Ssam struct condev condevs[] = {
4117833Sralph { "DIR", "direct", diropn, nulldev, dircls },
4213641Ssam #ifdef DATAKIT
4317833Sralph { "DK", "datakit", dkopn, nulldev, nulldev },
4417833Sralph #endif DATAKIT
4513641Ssam #ifdef PNET
4617833Sralph { "PNET", "pnet", pnetopn, nulldev, nulldev },
4717833Sralph #endif PNET
4817833Sralph #ifdef UNETTCP
4917833Sralph { "TCP", "TCP", unetopn, nulldev, unetcls },
5017833Sralph #endif UNETTCP
5117833Sralph #ifdef BSDTCP
5217833Sralph { "TCP", "TCP", bsdtcpopn, nulldev, bsdtcpcls },
5317833Sralph #endif BSDTCP
5413641Ssam #ifdef MICOM
5517833Sralph { "MICOM", "micom", micopn, nulldev, miccls },
5613641Ssam #endif MICOM
5713641Ssam #ifdef DN11
5817833Sralph { "ACU", "dn11", Acuopn, dnopn, dncls },
5917833Sralph #endif DN11
6013641Ssam #ifdef HAYES
6123594Sbloom { "ACU", "hayes", Acuopn, hyspopn, hyscls },
6223594Sbloom { "ACU", "hayespulse", Acuopn, hyspopn, hyscls },
6323594Sbloom { "ACU", "hayestone", Acuopn, hystopn, hyscls },
6425126Sbloom { "WATS", "hayestone", Acuopn, hystopn, hyscls },
6513641Ssam #endif HAYES
6625965Sbloom #ifdef HAYES2400
6725965Sbloom { "ACU", "hayes2400", Acuopn, hyspopn24, hyscls24 },
6825965Sbloom { "ACU", "hayes2400pulse", Acuopn, hyspopn24, hyscls24 },
6925965Sbloom { "ACU", "hayes2400tone", Acuopn, hystopn24, hyscls24 },
7025965Sbloom #endif HAYES2400
7113641Ssam #ifdef HAYESQ /* a version of hayes that doesn't use result codes */
7223594Sbloom { "ACU", "hayesq", Acuopn, hysqpopn, hysqcls },
7323594Sbloom { "ACU", "hayesqpulse", Acuopn, hysqpopn, hysqcls },
7423594Sbloom { "ACU", "hayesqtone", Acuopn, hysqtopn, hysqcls },
7523594Sbloom #endif HAYESQ
7625965Sbloom #ifdef CDS224
7725965Sbloom { "ACU", "cds224", Acuopn, cdsopn224, cdscls224},
7825965Sbloom #endif CDS224
7917833Sralph #ifdef NOVATION
8017833Sralph { "ACU", "novation", Acuopn, novopn, novcls},
8117833Sralph #endif NOVATION
8213641Ssam #ifdef DF02
8317833Sralph { "ACU", "DF02", Acuopn, df2opn, df2cls },
8417833Sralph #endif DF02
8518618Sralph #ifdef DF112
8618618Sralph { "ACU", "DF112P", Acuopn, df12popn, df12cls },
8718618Sralph { "ACU", "DF112T", Acuopn, df12topn, df12cls },
8818618Sralph #endif DF112
8913641Ssam #ifdef VENTEL
9017833Sralph { "ACU", "ventel", Acuopn, ventopn, ventcls },
9113641Ssam #endif VENTEL
9218618Sralph #ifdef PENRIL
9318618Sralph { "ACU", "penril", Acuopn, penopn, pencls },
9418618Sralph #endif PENRIL
9513641Ssam #ifdef VADIC
9617833Sralph { "ACU", "vadic", Acuopn, vadopn, vadcls },
9713641Ssam #endif VADIC
9817833Sralph #ifdef VA212
9917833Sralph { "ACU", "va212", Acuopn, va212opn, va212cls },
10017833Sralph #endif VA212
10117833Sralph #ifdef VA811S
10217833Sralph { "ACU", "va811s", Acuopn, va811opn, va811cls },
10317833Sralph #endif VA811S
10417833Sralph #ifdef VA820
10517833Sralph { "ACU", "va820", Acuopn, va820opn, va820cls },
10617833Sralph { "WATS", "va820", Acuopn, va820opn, va820cls },
10717833Sralph #endif VA820
10813641Ssam #ifdef RVMACS
10917833Sralph { "ACU", "rvmacs", Acuopn, rvmacsopn, rvmacscls },
11013641Ssam #endif RVMACS
11117833Sralph #ifdef VMACS
11217833Sralph { "ACU", "vmacs", Acuopn, vmacsopn, vmacscls },
11317833Sralph #endif VMACS
11417833Sralph #ifdef SYTEK
11517833Sralph { "SYTEK", "sytek", sykopn, nulldev, sykcls },
11617833Sralph #endif SYTEK
11726150Sbloom #ifdef ATT2224
11826150Sbloom { "ACU", "att", Acuopn, attopn, attcls },
11926150Sbloom #endif ATT2224
12013641Ssam
12126150Sbloom
12217833Sralph /* Insert new entries before this line */
12317833Sralph { NULL, NULL, NULL, NULL, NULL }
12417833Sralph };
12513641Ssam
12617833Sralph /*
12713641Ssam * nulldev a null device (returns CF_DIAL)
12813641Ssam */
nulldev()12917833Sralph nulldev()
13013641Ssam {
13117833Sralph return CF_DIAL;
13213641Ssam }
13313641Ssam
13417833Sralph /*
13513641Ssam * nodev a null device (returns CF_NODEV)
13613641Ssam */
nodev()13717833Sralph nodev()
13813641Ssam {
13917833Sralph return CF_NODEV;
14013641Ssam }
14113641Ssam
14213641Ssam /*
14313641Ssam * Generic devices look through L-devices and call the CU_open routines for
14417833Sralph * appropriate devices. Some things, like the tcp/ip interface, or direct
14517833Sralph * connect, do not use the CU_open entry. ACUs must search to find the
14613641Ssam * right routine to call.
14713641Ssam */
14813641Ssam
14917833Sralph /*
15013641Ssam * diropn(flds) connect to hardware line
15113641Ssam *
15213641Ssam * return codes:
15317833Sralph * > 0 - file number - ok
15413641Ssam * FAIL - failed
15513641Ssam */
diropn(flds)15613641Ssam diropn(flds)
15713641Ssam register char *flds[];
15813641Ssam {
15913641Ssam register int dcr, status;
16013641Ssam struct Devices dev;
16113641Ssam char dcname[20];
16213641Ssam FILE *dfp;
16317833Sralph #ifdef VMSDTR /* Modem control on vms(works dtr) */
16417833Sralph int modem_control;
16517833Sralph short iosb[4];
16617833Sralph int sys$qiow(); /* use this for long reads on vms */
16717833Sralph int ret;
16817833Sralph long mode[2];
16917833Sralph modem_control = 0;
17017833Sralph #endif
17113641Ssam dfp = fopen(DEVFILE, "r");
17233947Srick if (dfp == NULL) {
17333947Srick syslog(LOG_ERR, "fopen(%s) failed: %m", DEVFILE);
17433947Srick cleanup(FAIL);
17533947Srick }
17613641Ssam while ((status = rddev(dfp, &dev)) != FAIL) {
17717833Sralph #ifdef VMSDTR /* Modem control on vms(works dtr) */
17817833Sralph /* If we find MOD in the device type field we go into action */
17917833Sralph if (strcmp(dev.D_type, "MOD") == SAME) {
18017833Sralph modem_control = 1;
18117833Sralph DEBUG(7, "Setting Modem control to %d",modem_control);
18217833Sralph }
18313641Ssam if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
18417833Sralph continue;
18517833Sralph /*
18617833Sralph * Modem control on vms(works dtr) Take anything in MOD class.
18717833Sralph * It probably should work differently anyway so we can have
18817833Sralph * multiple hardwired lines.
18917833Sralph */
19017833Sralph if (!modem_control&&strcmp(flds[F_PHONE], dev.D_line) != SAME)
19117833Sralph #else !VMSDTR
19217833Sralph if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
19313641Ssam continue;
19413641Ssam if (strcmp(flds[F_PHONE], dev.D_line) != SAME)
19517833Sralph #endif !VMSDTR
19613641Ssam continue;
19713641Ssam if (mlock(dev.D_line) != FAIL)
19813641Ssam break;
19913641Ssam }
20013641Ssam fclose(dfp);
20113641Ssam if (status == FAIL) {
20213641Ssam logent("DEVICE", "NO");
20317833Sralph return CF_NODEV;
20413641Ssam }
20513641Ssam
20637932Sbostic sprintf(dcname, "%s/%s", _PATH_DEV, dev.D_line);
20713641Ssam if (setjmp(Sjbuf)) {
20825704Sbloom DEBUG(4, "Open timed out\n", CNULL);
20913641Ssam delock(dev.D_line);
21017833Sralph return CF_DIAL;
21113641Ssam }
21213641Ssam signal(SIGALRM, alarmtr);
21325704Sbloom /* For PC Pursuit, it could take a while to call back */
21425704Sbloom alarm( strcmp(flds[F_LINE], "PCP") ? 10 : MAXMSGTIME*4 );
21513641Ssam getnextfd();
21613641Ssam errno = 0;
21725704Sbloom DEBUG(4,"Opening %s\n",dcname);
21813641Ssam dcr = open(dcname, 2); /* read/write */
21917833Sralph #ifdef VMSDTR /* Modem control on vms(works dtr) */
22017833Sralph fflush(stdout);
22117833Sralph if (modem_control) { /* Did we have MOD in the device type field ? */
22217833Sralph /* Sense the current terminal setup and save it */
22317833Sralph if ((ret = sys$qiow(_$EFN,(fd_fab_pointer[dcr]->fab).fab$l_stv,
22417833Sralph IO$_SENSEMODE,iosb,0,0,mode,8,0,0,0,0))
22517833Sralph != SS$_NORMAL) {
22617833Sralph DEBUG(7, "ret status on sense failed on Modem sense=%x<", ret);
22717833Sralph return CF_DIAL;
22817833Sralph }
22917833Sralph mode[1] |= TT$M_MODEM; /* Or in modem control(DTR) */
23017833Sralph /* Now set the new terminal characteristics */
23117833Sralph /* This is temporary and will go away when we let go of it */
23217833Sralph if ((ret = sys$qiow(_$EFN,(fd_fab_pointer[dcr]->fab).fab$l_stv,
23317833Sralph IO$_SETMODE,iosb,0,0,mode,8,0,0,0,0))
23417833Sralph != SS$_NORMAL) {
23517833Sralph DEBUG(7, "ret status on sense failed on Modem setup=%x<", ret);
23617833Sralph return CF_DIAL;
23717833Sralph }
23817833Sralph }
23917833Sralph #endif VMSDTR
24013641Ssam next_fd = -1;
24113641Ssam alarm(0);
24213641Ssam if (dcr < 0) {
24325704Sbloom if (errno == EACCES)
24425704Sbloom logent(dev.D_line, "CANT OPEN");
24525704Sbloom DEBUG(4, "OPEN FAILED: errno %d\n", errno);
24613641Ssam delock(dev.D_line);
24717833Sralph return CF_DIAL;
24813641Ssam }
24913641Ssam fflush(stdout);
25025704Sbloom if (fixline(dcr, dev.D_speed) == FAIL) {
25125704Sbloom DEBUG(4, "FIXLINE FAILED\n", CNULL);
25223594Sbloom return CF_DIAL;
25325704Sbloom }
25413641Ssam strcpy(devSel, dev.D_line); /* for latter unlock */
25513641Ssam CU_end = dircls;
25617833Sralph return dcr;
25713641Ssam }
25813641Ssam
dircls(fd)25913641Ssam dircls(fd)
26013641Ssam register int fd;
26113641Ssam {
26213641Ssam if (fd > 0) {
26313641Ssam close(fd);
26413641Ssam delock(devSel);
26513641Ssam }
26613641Ssam }
26713641Ssam
26818618Sralph /*
26918618Sralph * open an ACU and dial the number. The condevs table
27018618Sralph * will be searched until a dialing unit is found that is free.
27113641Ssam *
27213641Ssam * return codes: >0 - file number - o.k.
27313641Ssam * FAIL - failed
27413641Ssam */
27513641Ssam char devSel[20]; /* used for later unlock() */
27613641Ssam
Acuopn(flds)27713641Ssam Acuopn(flds)
27813641Ssam register char *flds[];
27913641Ssam {
28018618Sralph char phone[MAXPH+1];
28118618Sralph register struct condev *cd;
28218618Sralph register int fd, acustatus;
28318618Sralph register FILE *dfp;
28418618Sralph struct Devices dev;
28518618Sralph int retval = CF_NODEV;
28625126Sbloom char nobrand[MAXPH], *line;
28713641Ssam
28818618Sralph exphone(flds[F_PHONE], phone);
28925126Sbloom if (snccmp(flds[F_LINE], "LOCAL") == SAME)
29025126Sbloom line = "ACU";
29125126Sbloom else
29225126Sbloom line = flds[F_LINE];
29318618Sralph devSel[0] = '\0';
29423726Sbloom nobrand[0] = '\0';
29518618Sralph DEBUG(4, "Dialing %s\n", phone);
29618618Sralph dfp = fopen(DEVFILE, "r");
29733947Srick if (dfp == NULL) {
29833947Srick syslog(LOG_ERR, "fopen(%s) failed: %m", DEVFILE);
29933947Srick cleanup(FAIL);
30033947Srick }
30113641Ssam
30218618Sralph acustatus = 0; /* none found, none locked */
30325126Sbloom while (rddev(dfp, &dev) != FAIL) {
30425126Sbloom /*
30525126Sbloom * for each ACU L.sys line, try at most twice
30625126Sbloom * (TRYCALLS) to establish carrier. The old way tried every
30725126Sbloom * available dialer, which on big sites takes forever!
30825126Sbloom * Sites with a single auto-dialer get one try.
30925126Sbloom * Sites with multiple dialers get a try on each of two
31025126Sbloom * different dialers.
31125126Sbloom * To try 'harder' to connect to a remote site,
31225126Sbloom * use multiple L.sys entries.
31325126Sbloom */
31425126Sbloom if (acustatus > TRYCALLS)
31525126Sbloom break;
31625126Sbloom if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
31725126Sbloom continue;
31825126Sbloom if (snccmp(line, dev.D_type) != SAME)
31925126Sbloom continue;
32025126Sbloom if (dev.D_brand[0] == '\0') {
32125126Sbloom logent("Acuopn","No 'brand' name on ACU");
32225126Sbloom continue;
32325126Sbloom }
32425126Sbloom for(cd = condevs; cd->CU_meth != NULL; cd++) {
32525126Sbloom if (snccmp(line, cd->CU_meth) == SAME) {
32633947Srick if (snccmp(dev.D_brand, cd->CU_brand) == SAME) {
32733947Srick nobrand[0] = '\0';
32825126Sbloom break;
32933947Srick }
33023726Sbloom strncpy(nobrand, dev.D_brand, sizeof nobrand);
33118618Sralph }
33225126Sbloom }
33313641Ssam
33433582Srick if (acustatus < 1)
33533582Srick acustatus = 1; /* has been found */
33633582Srick
33733561Srick if (mlock(dev.D_line) == FAIL)
33825126Sbloom continue;
33933561Srick
34018618Sralph #ifdef DIALINOUT
34123594Sbloom #ifdef ALLACUINOUT
34225126Sbloom if (1) {
34323594Sbloom #else !ALLACUINOUT
34425126Sbloom if (snccmp("inout", dev.D_calldev) == SAME) {
34523594Sbloom #endif !ALLACUINOUT
34625126Sbloom if (disable(dev.D_line) == FAIL) {
34725126Sbloom delock(dev.D_line);
34825126Sbloom continue;
34925126Sbloom }
35025126Sbloom } else
35125126Sbloom reenable();
35218618Sralph #endif DIALINOUT
35318618Sralph
35425126Sbloom DEBUG(4, "Using %s\n", cd->CU_brand);
35525126Sbloom acustatus++;
35625126Sbloom fd = (*(cd->CU_open))(phone, flds, &dev);
35725126Sbloom if (fd > 0) {
35825126Sbloom CU_end = cd->CU_clos; /* point CU_end at close func */
35925126Sbloom fclose(dfp);
36025126Sbloom strcpy(devSel, dev.D_line); /* save for later unlock() */
36125126Sbloom return fd;
36225126Sbloom } else
36325126Sbloom delock(dev.D_line);
36425126Sbloom retval = CF_DIAL;
36513641Ssam }
36618618Sralph fclose(dfp);
36723726Sbloom if (acustatus == 0) {
36823726Sbloom if (nobrand[0])
36923726Sbloom logent(nobrand, "unsupported ACU type");
37023726Sbloom else
37123726Sbloom logent("L-devices", "No appropriate ACU");
37223726Sbloom }
37318618Sralph if (acustatus == 1)
37418618Sralph logent("DEVICE", "NO");
37518618Sralph return retval;
37613641Ssam }
37713641Ssam
37813641Ssam /*
37923594Sbloom * intervaldelay: delay execution for numerator/denominator seconds.
38013641Ssam */
38113641Ssam
38213641Ssam #ifdef INTERVALTIMER
38313704Ssam #include <sys/time.h>
38423594Sbloom #define uucpdelay(num,denom) intervaldelay(num,denom)
intervaldelay(num,denom)38523594Sbloom intervaldelay(num,denom)
38623594Sbloom int num, denom;
38723594Sbloom {
38823594Sbloom struct timeval tv;
38923594Sbloom tv.tv_sec = num / denom;
39023594Sbloom tv.tv_usec = (num * 1000000L / denom ) % 1000000L;
39123594Sbloom (void) select (0, (int *)0, (int *)0, (int *)0, &tv);
39223594Sbloom }
39313641Ssam #endif INTERVALTIMER
39413641Ssam
39513641Ssam #ifdef FASTTIMER
39613641Ssam #define uucpdelay(num,denom) nap(60*num/denom)
39713641Ssam /* Sleep in increments of 60ths of second. */
nap(time)39813641Ssam nap (time)
39918618Sralph register int time;
40013641Ssam {
40113641Ssam static int fd;
40213641Ssam
40313641Ssam if (fd == 0)
40413641Ssam fd = open (FASTTIMER, 0);
40513641Ssam
40613641Ssam read (fd, 0, time);
40713641Ssam }
40813641Ssam #endif FASTTIMER
40913641Ssam
41013641Ssam #ifdef FTIME
41113641Ssam #define uucpdelay(num,denom) ftimedelay(1000*num/denom)
ftimedelay(n)41213641Ssam ftimedelay(n)
41313641Ssam {
41413641Ssam static struct timeb loctime;
41517833Sralph register i = loctime.millitm;
41617833Sralph
41713641Ssam ftime(&loctime);
41817833Sralph while (abs((int)(loctime.millitm - i))<n) ftime(&loctime)
41917833Sralph ;
42013641Ssam }
42113641Ssam #endif FTIME
42213641Ssam
42313641Ssam #ifdef BUSYLOOP
42413641Ssam #define uucpdelay(num,denom) busyloop(CPUSPEED*num/denom)
42513641Ssam #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */
42613641Ssam #define DELAY(n) { register long N = (n); while (--N > 0); }
busyloop(n)42713641Ssam busyloop(n)
42817833Sralph {
42913641Ssam DELAY(n);
43017833Sralph }
43113641Ssam #endif BUSYLOOP
43213641Ssam
slowrite(fd,str)43313641Ssam slowrite(fd, str)
43413641Ssam register char *str;
43513641Ssam {
43617833Sralph DEBUG(6, "slowrite ", CNULL);
43713641Ssam while (*str) {
43813641Ssam DEBUG(6, "%c", *str);
43925704Sbloom uucpdelay(1, 10); /* delay 1/10 second */
44013641Ssam write(fd, str, 1);
44113641Ssam str++;
44213641Ssam }
44317833Sralph DEBUG(6, "\n", CNULL);
44413641Ssam }
44518618Sralph
44625704Sbloom #define BSPEED B150
44725704Sbloom
44825704Sbloom /*
44925704Sbloom * send a break
45025704Sbloom */
genbrk(fn,bnulls)45125704Sbloom genbrk(fn, bnulls)
45225704Sbloom register int fn, bnulls;
45325704Sbloom {
45425704Sbloom #ifdef USG
45525704Sbloom if (ioctl(fn, TCSBRK, STBNULL) < 0)
45625704Sbloom DEBUG(5, "break TCSBRK %s\n", sys_errlist[errno]);
45725704Sbloom #else !USG
45825704Sbloom # ifdef TIOCSBRK
45925704Sbloom if (ioctl(fn, TIOCSBRK, STBNULL) < 0)
46025704Sbloom DEBUG(5, "break TIOCSBRK %s\n", sys_errlist[errno]);
46125704Sbloom # ifdef TIOCCBRK
46225704Sbloom uucpdelay(bnulls, 10);
46325704Sbloom if (ioctl(fn, TIOCCBRK, STBNULL) < 0)
46425704Sbloom DEBUG(5, "break TIOCCBRK %s\n", sys_errlist[errno]);
46525704Sbloom # endif TIOCCBRK
46625704Sbloom DEBUG(4, "ioctl %f second break\n", (float) bnulls/10 );
46725704Sbloom # else !TIOCSBRK
46825704Sbloom struct sgttyb ttbuf;
46925704Sbloom register int sospeed;
47025704Sbloom
47125704Sbloom if (ioctl(fn, TIOCGETP, &ttbuf) < 0)
47225704Sbloom DEBUG(5, "break TIOCGETP %s\n", sys_errlist[errno]);
47325704Sbloom sospeed = ttbuf.sg_ospeed;
47425704Sbloom ttbuf.sg_ospeed = BSPEED;
47525704Sbloom if (ioctl(fn, TIOCSETP, &ttbuf) < 0)
47625704Sbloom DEBUG(5, "break TIOCSETP %s\n", sys_errlist[errno]);
47725704Sbloom if (write(fn, "\0\0\0\0\0\0\0\0\0\0\0\0", bnulls) != bnulls) {
47825704Sbloom badbreak:
47925704Sbloom logent(sys_errlist[errno], "BAD WRITE genbrk");
48025704Sbloom alarm(0);
48125704Sbloom longjmp(Sjbuf, 3);
48225704Sbloom }
48325704Sbloom ttbuf.sg_ospeed = sospeed;
48425704Sbloom if (ioctl(fn, TIOCSETP, &ttbuf) < 0)
48525704Sbloom DEBUG(5, "break ioctl %s\n", sys_errlist[errno]);
48625704Sbloom if (write(fn, "@", 1) != 1)
48725704Sbloom goto badbreak;
48825704Sbloom DEBUG(4, "sent BREAK nulls - %d\n", bnulls);
48925704Sbloom #endif !TIOCSBRK
49025704Sbloom #endif !USG
49125704Sbloom }
49225704Sbloom
49325704Sbloom
49418618Sralph #ifdef DIALINOUT
49518618Sralph /* DIALIN/OUT CODE (WLS) */
49618618Sralph /*
49718618Sralph * disable and reenable: allow a single line to be use for dialin/dialout
49818618Sralph *
49918618Sralph */
50018618Sralph
50118618Sralph char enbdev[16];
50218618Sralph
disable(dev)50318618Sralph disable(dev)
50418618Sralph register char *dev;
50518618Sralph {
50618618Sralph register char *rdev;
50718618Sralph
50818618Sralph /* strip off directory prefixes */
50918618Sralph rdev = dev;
51018618Sralph while (*rdev)
51118618Sralph rdev++;
51218618Sralph while (--rdev >= dev && *rdev != '/')
51318618Sralph ;
51418618Sralph rdev++;
51518618Sralph
51618618Sralph if (enbdev[0]) {
51718618Sralph if (strcmp(enbdev, rdev) == SAME)
51818618Sralph return SUCCESS; /* already disabled */
51918618Sralph delock(enbdev);
52018618Sralph reenable(); /* else, reenable the old one */
52118618Sralph }
52218618Sralph DEBUG(4, "Disable %s\n", rdev);
52318618Sralph if (enbcall("disable", rdev) == FAIL)
52418618Sralph return FAIL;
52518618Sralph strcpy(enbdev, rdev);
52618618Sralph return SUCCESS;
52718618Sralph }
52818618Sralph
reenable()52918618Sralph reenable()
53018618Sralph {
53123726Sbloom if (enbdev[0] == '\0')
53218618Sralph return;
53318618Sralph DEBUG(4, "Reenable %s\n", enbdev);
53418618Sralph (void) enbcall("enable", enbdev);
53518618Sralph enbdev[0] = '\0';
53618618Sralph }
53718618Sralph
enbcall(type,dev)53818618Sralph enbcall(type, dev)
53918618Sralph char *type, *dev;
54018618Sralph {
54118618Sralph int pid;
54218618Sralph register char *p;
54318618Sralph int fildes[2];
54418618Sralph int status;
54518618Sralph FILE *fil;
54618618Sralph char buf[80];
54718618Sralph
54818618Sralph fflush(stderr);
54918618Sralph fflush(stdout);
55018618Sralph pipe(fildes);
55118618Sralph if ((pid = fork()) == 0) {
55218618Sralph DEBUG(4, DIALINOUT, CNULL);
55318618Sralph DEBUG(4, " %s", type);
55418618Sralph DEBUG(4, " %s\n", dev);
55518618Sralph close(fildes[0]);
55618618Sralph close(0); close(1); close(2);
55737932Sbostic open(_PATH_DEVNULL,0);
55818618Sralph dup(fildes[1]); dup(fildes[1]);
55918618Sralph setuid(geteuid()); /* for chown(uid()) in acu program */
56034166Srick execl(DIALINOUT, "acu", type, dev, Rmtname, (char *)0);
56118618Sralph exit(-1);
56218618Sralph }
56318618Sralph if (pid<0)
56418618Sralph return FAIL;
56518618Sralph
56618618Sralph close(fildes[1]);
56718618Sralph fil = fdopen(fildes[0],"r");
56818618Sralph if (fil!=NULL) {
56923594Sbloom #ifdef BSD4_2
57018618Sralph setlinebuf(fil);
57123594Sbloom #endif BSD4_2
57218618Sralph while (fgets(buf, sizeof buf, fil) != NULL) {
57318618Sralph p = buf + strlen(buf) - 1;
57418618Sralph if (*p == '\n')
57518618Sralph *p = '\0';
57633561Srick DEBUG(4, "ACUCNTRL: %s\n", buf);
57718618Sralph }
57818618Sralph }
57918618Sralph while(wait(&status) != pid)
58018618Sralph ;
58118618Sralph fclose(fil);
58218618Sralph return status ? FAIL : SUCCESS;
58318618Sralph }
58418618Sralph #endif DIALINOUT
585