xref: /csrg-svn/usr.bin/uucp/uucico/condevs.c (revision 62391)
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