xref: /original-bsd/usr.bin/uucp/uucico/condevs.c (revision 8251a00e)
1 #ifndef lint
2 static char sccsid[] = "@(#)condevs.c	5.6 (Berkeley) 08/12/83";
3 #endif
4 
5 /*
6  * Here are various dialers to establish the machine-machine connection.
7  * conn.c/condevs.c was glued together by Mike Mitchell.
8  * The dialers were supplied by many people, to whom we are grateful.
9  *
10  * ---------------------------------------------------------------------
11  * NOTE:
12  * There is a bug that occurs at least on PDP11s due to a limitation of
13  * setjmp/longjmp.   If the routine that does a setjmp is interrupted
14  * and longjmp-ed to,  it loses its register variables (on a pdp11).
15  * What works is if the routine that does the setjmp
16  * calls a routine and it is the *subroutine* that is interrupted.
17  *
18  * Anyway, in conclusion, condevs.c is plagued with register variables
19  * that are used inside
20  * 	if (setjmp(...)) {
21  * 		....
22  * 	}
23  *
24  * THE FIX: In dnopn(), for example, delete the 'register' Devices *dev.
25  * (That was causing a core dump; deleting register fixed it.)
26  * Also for dnopn delete 'register' int dnf... .
27  * In pkopn, delete 'register' flds... .
28  * There may be others, especially mcm's version of hysopen.
29  * You could just delete all references to register, that is safest.
30  * This problem might not occur on 4.1bsd, I am not sure.
31  * 	Tom Truscott
32  */
33 #include <sys/types.h>
34 #include <errno.h>
35 #include <setjmp.h>
36 #include <signal.h>
37 #include <sgtty.h>
38 #include "uucp.h"
39 
40 extern char devSel[];	/* name to pass to delock() in close */
41 extern int errno, next_fd;
42 extern jmp_buf Sjbuf;
43 extern int alarmtr();
44 int nulldev(), nodev(), Acuopn(), diropn(), dircls();
45 
46 #ifdef DATAKIT
47 int dkopn();
48 #endif
49 #ifdef DN11
50 int dnopn(), dncls();
51 #endif
52 #ifdef HAYES
53 int hysopn(), hyscls();
54 #endif
55 #ifdef HAYESQ
56 int hysqopn(), hysqcls();  /* a version of hayes that doesn't use ret codes */
57 #endif
58 #ifdef DF02
59 int df2opn(), df2cls();
60 #endif
61 #ifdef PNET
62 int pnetopn();
63 #endif
64 #ifdef VENTEL
65 int ventopn(), ventcls();
66 #endif
67 #ifdef	UNET
68 #include <UNET/unetio.h>
69 #include <UNET/tcp.h>
70 int unetopn(), unetcls();
71 #endif UNET
72 #ifdef VADIC
73 int vadopn(), vadcls();
74 #endif VADIC
75 #ifdef	RVMACS
76 int rvmacsopn(), rvmacscls();
77 #endif
78 #ifdef MICOM
79 int micopn(), miccls();
80 #endif MICOM
81 
82 struct condev condevs[] = {
83 { "DIR", "direct", diropn, nulldev, dircls },
84 #ifdef DATAKIT
85 { "DK", "datakit", dkopn, nulldev, nulldev },
86 #endif
87 #ifdef PNET
88 { "PNET", "pnet", pnetopn, nulldev, nulldev },
89 #endif
90 #ifdef	UNET
91 { "UNET", "UNET", unetopn, nulldev, unetcls },
92 #endif UNET
93 #ifdef MICOM
94 { "MICOM", "micom", micopn, nulldev, miccls },
95 #endif MICOM
96 #ifdef DN11
97 { "ACU", "dn11", Acuopn, dnopn, dncls },
98 #endif
99 #ifdef HAYES
100 { "ACU", "hayes", Acuopn, hysopn, hyscls },
101 #endif HAYES
102 #ifdef HAYESQ	/* a version of hayes that doesn't use result codes */
103 { "ACU", "hayesq", Acuopn, hysqopn, hysqcls },
104 #endif HATESQ
105 #ifdef DF02
106 { "ACU", "DF02", Acuopn, df2opn, df2cls },
107 #endif
108 #ifdef VENTEL
109 { "ACU", "ventel", Acuopn, ventopn, ventcls },
110 #endif VENTEL
111 #ifdef VADIC
112 { "ACU", "vadic", Acuopn, vadopn, vadcls },
113 #endif VADIC
114 #ifdef RVMACS
115 { "ACU", "rvmacs", Acuopn, rvmacsopn, rvmacscls },
116 #endif RVMACS
117 
118 /* Insert new entries before this line */
119 { NULL, NULL, NULL, NULL, NULL } };
120 
121 /***
122  *	nulldev		a null device (returns CF_DIAL)
123  */
124 int nulldev()
125 {
126 	return(CF_DIAL);
127 }
128 
129 /***
130  *	nodev		a null device (returns CF_NODEV)
131  */
132 int nodev()
133 {
134 	return(CF_NODEV);
135 }
136 
137 
138 /*
139  * The first things in this file are the generic devices.
140  * Generic devices look through L-devices and call the CU_open routines for
141  * appropriate devices.  Some things, like the Unet interface, or direct
142  * connect, do not use the CU_open entry.  ACUs must search to find the'
143  * right routine to call.
144  */
145 
146 /***
147  *	diropn(flds)	connect to hardware line
148  *	char *flds[];
149  *
150  *	return codes:
151  *		>0  -  file number  -  ok
152  *		FAIL  -  failed
153  */
154 
155 diropn(flds)
156 register char *flds[];
157 {
158 	register int dcr, status;
159 	struct Devices dev;
160 	char dcname[20];
161 	FILE *dfp;
162 	dfp = fopen(DEVFILE, "r");
163 	ASSERT(dfp != NULL, "CAN'T OPEN", DEVFILE, 0);
164 	while ((status = rddev(dfp, &dev)) != FAIL) {
165 		if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
166 			continue;
167 		if (strcmp(flds[F_PHONE], dev.D_line) != SAME)
168 			continue;
169 		if (mlock(dev.D_line) != FAIL)
170 			break;
171 	}
172 	fclose(dfp);
173 	if (status == FAIL) {
174 		logent("DEVICE", "NO");
175 		return(CF_NODEV);
176 	}
177 
178 	sprintf(dcname, "/dev/%s", dev.D_line);
179 	if (setjmp(Sjbuf)) {
180 		delock(dev.D_line);
181 		return(FAIL);
182 	}
183 	signal(SIGALRM, alarmtr);
184 	alarm(10);
185 	getnextfd();
186 	errno = 0;
187 	dcr = open(dcname, 2); /* read/write */
188 	next_fd = -1;
189 	if (dcr < 0 && errno == EACCES)
190 		logent(dcname, "CAN'T OPEN");
191 	alarm(0);
192 	if (dcr < 0) {
193 		delock(dev.D_line);
194 		return(FAIL);
195 	}
196 	fflush(stdout);
197 	fixline(dcr, dev.D_speed);
198 	strcpy(devSel, dev.D_line);	/* for latter unlock */
199 	CU_end = dircls;
200 	return(dcr);
201 }
202 
203 dircls(fd)
204 register int fd;
205 {
206 	if (fd > 0) {
207 		close(fd);
208 		delock(devSel);
209 		}
210 	}
211 
212 #ifdef DATAKIT
213 
214 #include <dk.h>
215 #define DKTRIES 2
216 
217 /***
218  *	dkopn(flds)	make datakit connection
219  *
220  *	return codes:
221  *		>0 - file number - ok
222  *		FAIL - failed
223  */
224 
225 dkopn(flds)
226 char *flds[];
227 {
228 	int dkphone;
229 	register char *cp;
230 	register ret, i;
231 
232 	if (setjmp(Sjbuf))
233 		return(FAIL);
234 
235 	signal(SIGALRM, alarmtr);
236 	dkphone = 0;
237 	cp = flds[F_PHONE];
238 	while(*cp)
239 		dkphone = 10 * dkphone + (*cp++ - '0');
240 	DEBUG(4, "dkphone (%d) ", dkphone);
241 	for (i = 0; i < DKTRIES; i++) {
242 		getnextfd();
243 		ret = dkdial(D_SH, dkphone, 0);
244 		next_fd = -1;
245 		DEBUG(4, "dkdial (%d)\n", ret);
246 		if (ret > -1)
247 			break;
248 	}
249 	return(ret);
250 }
251 #endif
252 
253 #ifdef PNET
254 /***
255  *	pnetopn(flds)
256  *
257  *	call remote machine via Purdue network
258  *	use dial string as host name, speed as socket number
259  * Author: Steve Bellovin
260  */
261 
262 pnetopn(flds)
263 char *flds[];
264 {
265 	int fd;
266 	int socket;
267 	register char *cp;
268 
269 	fd = pnetfile();
270 	DEBUG(4, "pnet fd - %d\n", fd);
271 	if (fd < 0) {
272 		logent("AVAILABLE DEVICE", "NO");
273 		return(CF_NODEV);
274 	}
275 	socket = 0;
276 	for (cp = flds[F_CLASS]; *cp; cp++)
277 		socket = 10*socket + (*cp - '0');
278 	DEBUG(4, "socket - %d\n", socket);
279 	if (setjmp(Sjbuf)) {
280 		DEBUG(4, "pnet timeout  - %s\n", flds[F_PHONE]);
281 		return(FAIL);
282 	}
283 	signal(SIGALRM, alarmtr);
284 	DEBUG(4, "host - %s\n", flds[F_PHONE]);
285 	alarm(15);
286 	if (pnetscon(fd, flds[F_PHONE], socket) < 0) {
287 		DEBUG(4, "pnet connect failed - %s\n", flds[F_PHONE]);
288 		return(FAIL);
289 	}
290 	alarm(0);
291 	return(fd);
292 }
293 #endif	PNET
294 
295 #ifdef UNET
296 /***
297  *	unetopn -- make UNET (tcp-ip) connection
298  *
299  *	return codes:
300  *		>0 - file number - ok
301  *		FAIL - failed
302  */
303 
304 /* Default port of uucico server */
305 #define	DFLTPORT	33
306 
307 unetopn(flds)
308 register char *flds[];
309 {
310 	register int ret, port;
311 	int unetcls();
312 
313 	port = atoi(flds[F_PHONE]);
314 	if (port <= 0 || port > 255)
315 		port = DFLTPORT;
316 	DEBUG(4, "unetopn host %s, ", flds[F_NAME]);
317 	DEBUG(4, "port %d\n", port);
318 	if (setjmp(Sjbuf)) {
319 		logent("tcpopen", "TIMEOUT");
320 		endhnent();	/* see below */
321 		return(CF_DIAL);
322 	}
323 	signal(SIGALRM, alarmtr);
324 	alarm(30);
325 	ret = tcpopen(flds[F_NAME], port, 0, TO_ACTIVE, "rw");
326 	alarm(0);
327 	endhnent();	/* wave magic wand at 3com and incant "eat it, bruce" */
328 	if (ret < 0) {
329 		DEBUG(5, "tcpopen failed: errno %d\n", errno);
330 		logent("tcpopen", "FAILED");
331 		return(CF_DIAL);
332 	}
333 	CU_end = unetcls;
334 	return(ret);
335 }
336 
337 /*
338  * unetcls -- close UNET connection.
339  */
340 unetcls(fd)
341 register int fd;
342 {
343 	DEBUG(4, "UNET CLOSE called\n", 0);
344 	if (fd > 0) {
345 		/* disable this until a timeout is put in
346 		if (ioctl(fd, UIOCCLOSE, STBNULL))
347 			logent("UNET CLOSE", "FAILED");
348 		 */
349 		close(fd);
350 		DEBUG(4, "closed fd %d\n", fd);
351 	}
352 }
353 #endif UNET
354 
355 #ifdef MICOM
356 
357 /*
358  *	micopn: establish connection through a micom.
359  *	Returns descriptor open to tty for reading and writing.
360  *	Negative values (-1...-7) denote errors in connmsg.
361  *	Be sure to disconnect tty when done, via HUPCL or stty 0.
362  */
363 micopn(flds)
364 register char *flds[];
365 {
366 	extern errno;
367 	char *rindex(), *fdig(), dcname[20];
368 	int dh, ok = 0, speed;
369 	register struct condev *cd;
370 	register FILE *dfp;
371 	struct Devices dev;
372 
373 	dfp = fopen(DEVFILE, "r");
374 	ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
375 
376 	signal(SIGALRM, alarmtr);
377 	dh = -1;
378 	for(cd = condevs; ((cd->CU_meth != NULL)&&(dh < 0)); cd++) {
379 		if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
380 			fseek(dfp, (off_t)0, 0);
381 			while(rddev(dfp, &dev) != FAIL) {
382 				if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
383 					continue;
384 				if (snccmp(flds[F_LINE], dev.D_type) != SAME)
385 					continue;
386 				if (mlock(dev.D_line) == FAIL)
387 					continue;
388 
389 				sprintf(dcname, "/dev/%s", dev.D_line);
390 				getnextfd();
391 				alarm(10);
392 				if (setjmp(Sjbuf)) {
393 					delock(dev.D_line);
394 					logent(dev.D_line,"micom open TIMEOUT");
395 					dh = -1;
396 					break;
397 					}
398 				dh = open(dcname, 2);
399 				alarm(0);
400 				next_fd = -1;
401 				if (dh > 0) {
402 					break;
403 					}
404 				devSel[0] = '\0';
405 				delock(dev.D_line);
406 				}
407 			}
408 		}
409 	fclose(dfp);
410 	if (dh < 0)
411 		return(CF_NODEV);
412 
413 	speed = atoi(fdig(flds[F_CLASS]));
414 	fixline(dh, speed);
415 	sleep(1);
416 
417 	/* negotiate with micom */
418 	if (speed != 4800)	/* damn their eyes! */
419 		write(dh, "\r", 1);
420 	else
421 		write(dh, " ", 1);
422 
423 	DEBUG(4, "wanted %s ", "NAME");
424 	ok = expect("NAME", dh);
425 	DEBUG(4, "got %s\n", ok ? "?" : "that");
426 	if (ok == 0) {
427 		write(dh, flds[F_PHONE], strlen(flds[F_PHONE]));
428 		sleep(1);
429 		write(dh, "\r", 1);
430 		DEBUG(4, "wanted %s ", "GO");
431 		ok = expect("GO", dh);
432 		DEBUG(4, "got %s\n", ok ? "?" : "that");
433 	}
434 
435 	if (ok != 0) {
436 		if (dh > 2)
437 			close(dh);
438 		DEBUG(4, "micom failed\n", "");
439 		delock(dev.D_line);
440 		return(CF_DIAL);
441 	} else
442 		DEBUG(4, "micom ok\n", "");
443 
444 	CU_end = cd->CU_clos;
445 	strcat(devSel, dev.D_line);	/* for later unlock */
446 	return(dh);
447 
448 }
449 
450 miccls(fd)
451 register int fd;
452 {
453 
454 	if (fd > 0) {
455 		close(fd);
456 		delock(devSel);
457 		}
458 	}
459 #endif MICOM
460 
461 /***
462  *	Acuopn - open an ACU and dial the number.  The condevs table
463  *		will be searched until a dialing unit is found that is
464  *		free.
465  *
466  *	return codes:	>0 - file number - o.k.
467  *			FAIL - failed
468  */
469 
470 char devSel[20];	/* used for later unlock() */
471 
472 Acuopn(flds)
473 register char *flds[];
474 {
475     char phone[MAXPH+1];
476     register struct condev *cd;
477     register int fd;
478     register FILE *dfp;
479     struct Devices dev;
480 
481     exphone(flds[F_PHONE], phone);
482     devSel[0] = '\0';
483     DEBUG(4, "Dialing %s\n", phone);
484     dfp = fopen(DEVFILE, "r");
485     ASSERT(dfp != NULL, "Can't open", DEVFILE, 0);
486 
487     for(cd = condevs; cd->CU_meth != NULL; cd++) {
488 	if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) {
489 	    fseek(dfp, (off_t)0, 0);
490 	    while(rddev(dfp, &dev) != FAIL) {
491 		if (strcmp(flds[F_CLASS], dev.D_class) != SAME)
492 		    continue;
493 		if (snccmp(flds[F_LINE], dev.D_type) != SAME)
494 		    continue;
495 		if (dev.D_brand[0] == '\0')
496 		    logent("Acuopn","No 'brand' name on ACU");
497 		else if (snccmp(dev.D_brand, cd->CU_brand) != SAME)
498 		    continue;
499 		if (mlock(dev.D_line) == FAIL)
500 		    continue;
501 
502 		DEBUG(4, "Using %s\n", cd->CU_brand);
503 		fd = (*(cd->CU_open))(phone, flds, &dev);
504 		if (fd > 0) {
505 		    CU_end = cd->CU_clos;   /* point CU_end at close func */
506 		    fclose(dfp);
507 		    strcpy(devSel, dev.D_line);   /* save for later unlock() */
508 		    return(fd);
509 		    }
510 		delock(dev.D_line);
511 		}
512 	    }
513 	}
514     fclose(dfp);
515     return(FAIL);
516     }
517 
518 #ifdef DN11
519 
520 /***
521  *	dnopn(ph, flds, dev)	dial remote machine
522  *	char *ph;
523  *	char *flds[];
524  *	struct Devices *dev;
525  *
526  *	return codes:
527  *		file descriptor  -  succeeded
528  *		FAIL  -  failed
529  */
530 
531 dnopn(ph, flds, dev)
532 char *ph;
533 char *flds[];
534 struct Devices *dev;
535 {
536 	char dcname[20], dnname[20], phone[MAXPH+2], c = 0;
537 #ifdef	SYSIII
538 	struct termio ttbuf;
539 #endif
540 	int dnf, dcf;
541 	int nw, lt, pid, status;
542 	unsigned timelim;
543 
544 	sprintf(dnname, "/dev/%s", dev->D_calldev);
545 	errno = 0;
546 
547 	if (setjmp(Sjbuf)) {
548 		logent(dnname, "CAN'T OPEN");
549 		DEBUG(4, "%s Open timed out\n", dnname);
550 		return(CF_NODEV);
551 	}
552 	signal(SIGALRM, alarmtr);
553 	getnextfd();
554 	alarm(10);
555 	dnf = open(dnname, 1);
556 	alarm(0);
557 	next_fd = -1;
558 	if (dnf < 0 && errno == EACCES) {
559 		logent(dnname, "CAN'T OPEN");
560 		logent("DEVICE", "NO");
561 		return(CF_NODEV);
562 		}
563 	/* rti!trt: avoid passing acu file descriptor to children */
564 	fioclex(dnf);
565 
566 	sprintf(dcname, "/dev/%s", dev->D_line);
567 	sprintf(phone, "%s%s", ph, ACULAST);
568 	DEBUG(4, "dc - %s, ", dcname);
569 	DEBUG(4, "acu - %s\n", dnname);
570 	pid = 0;
571 	if (setjmp(Sjbuf)) {
572 		logent("DIALUP DN write", "TIMEOUT");
573 		if (pid)
574 			kill(pid, 9);
575 		delock(dev->D_line);
576 		if (dnf)
577 			close(dnf);
578 		return(FAIL);
579 	}
580 	signal(SIGALRM, alarmtr);
581 	timelim = 5 * strlen(phone);
582 	alarm(timelim < 30 ? 30 : timelim);
583 	if ((pid = fork()) == 0) {
584 		sleep(2);
585 		fclose(stdin);
586 		fclose(stdout);
587 #ifdef	TIOCFLUSH
588 		ioctl(dnf, TIOCFLUSH, STBNULL);
589 #endif
590 		nw = write(dnf, phone, lt = strlen(phone));
591 		if (nw != lt) {
592 			logent("DIALUP ACU write", "FAILED");
593 			exit(1);
594 		}
595 		DEBUG(4, "ACU write ok%s\n", "");
596 		exit(0);
597 	}
598 	/*  open line - will return on carrier */
599 	/* RT needs a sleep here because it returns immediately from open */
600 
601 #if RT
602 	sleep(15);
603 #endif
604 
605 	getnextfd();
606 	errno = 0;
607 	dcf = open(dcname, 2);
608 	next_fd = -1;
609 	if (dcf < 0 && errno == EACCES)
610 		logent(dcname, "CAN'T OPEN");
611 	DEBUG(4, "dcf is %d\n", dcf);
612 	if (dcf < 0) {
613 		logent("DIALUP LINE open", "FAILED");
614 		alarm(0);
615 		kill(pid, 9);
616 		close(dnf);
617 		delock(dev->D_line);
618 		return(FAIL);
619 	}
620 	/* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */
621 /*	ioctl(dcf, TIOCHPCL, STBNULL);*/
622 	while ((nw = wait(&lt)) != pid && nw != -1)
623 		;
624 #ifdef	SYSIII
625 	ioctl(dcf, TCGETA, &ttbuf);
626 	if(!(ttbuf.c_cflag & HUPCL)) {
627 		ttbuf.c_cflag |= HUPCL;
628 		ioctl(dcf, TCSETA, &ttbuf);
629 	}
630 #endif
631 	alarm(0);
632 	fflush(stdout);
633 	fixline(dcf, dev->D_speed);
634 	DEBUG(4, "Fork Stat %o\n", lt);
635 	if (lt != 0) {
636 		close(dcf);
637 		if (dnf)
638 			close(dnf);
639 		delock(dev->D_line);
640 		return(FAIL);
641 	}
642 	return(dcf);
643 }
644 
645 /***
646  *	dncls()		close dn type call unit
647  *
648  *	return codes:	None
649  */
650 dncls(fd)
651 register int fd;
652 {
653 	if (fd > 0) {
654 		close(fd);
655 		sleep(5);
656 		delock(devSel);
657 		}
658 }
659 #endif DN11
660 
661 #ifdef DF02
662 /***
663  *	df2opn(ph, flds, dev)	dial remote machine
664  *	char *ph;
665  *	char *flds[];
666  *	struct Devices *dev;
667  *
668  *	return codes:
669  *		file descriptor  -  succeeded
670  *		FAIL  -  failed
671  *
672  *	Modified 9/28/81 by Bill Shannon (DEC)
673  *	Changed to use DEC DF02 or DF03 ACU
674  */
675 
676 
677 df2opn(ph, flds, dev)
678 char *ph;
679 char *flds[];
680 struct Devices *dev;
681 {
682 	char dcname[20], dnname[20], phone[MAXPH+2], c = 0;
683 #ifdef	SYSIII
684 	struct termio ttbuf;
685 #endif
686 	int dcf, dnf;
687 	int nw, lt, pid, st, status;
688 	unsigned timelim;
689 
690 	sprintf(dnname, "/dev/%s", dev->D_calldev);
691 	if (setjmp(Sjbuf)) {
692 		logent(dnname, "CAN'T OPEN");
693 		DEBUG(4, "%s Open timed out\n", dnname);
694 		return(CF_NODEV);
695 	}
696 	signal(SIGALRM, alarmtr);
697 	getnextfd();
698 	errno = 0;
699 	alarm(10);
700 	dnf = open(dnname, 2 );
701 	alarm(0);
702 	next_fd = -1;
703 	if (dnf < 0 && errno == EACCES) {
704 		logent(dnname, "CAN'T OPEN");
705 		delock(dev->D_line);
706 		logent("DEVICE", "NO");
707 		return(CF_NODEV);
708 		}
709 	/* rti!trt: avoid passing acu file descriptor to children */
710 	fioclex(dnf);
711 
712 	sprintf(dcname, "/dev/%s", dev->D_line);
713 	fixline(dnf, dev->D_speed);
714 	sprintf(phone, "\02%s", ph);
715 	DEBUG(4, "dc - %s, ", dcname);
716 	DEBUG(4, "acu - %s\n", dnname);
717 	pid = 0;
718 	if (setjmp(Sjbuf)) {
719 		logent("DIALUP DN write", "TIMEOUT");
720 		if (pid)
721 			kill(pid, 9);
722 		delock(dev->D_line);
723 		if (dnf)
724 			close(dnf);
725 		return(FAIL);
726 	}
727 	signal(SIGALRM, alarmtr);
728 	timelim = 5 * strlen(phone);
729 	alarm(timelim < 30 ? 30 : timelim);
730 	if ((pid = fork()) == 0) {
731 		sleep(2);
732 		fclose(stdin);
733 		fclose(stdout);
734 #ifdef	TIOCFLUSH
735 		ioctl(dnf, TIOCFLUSH, STBNULL);
736 #endif
737 		write(dnf, "\01", 1);
738 		sleep(1);
739 		nw = write(dnf, phone, lt = strlen(phone));
740 		if (nw != lt) {
741 			logent("DIALUP ACU write", "FAILED");
742 			exit(1);
743 		}
744 		DEBUG(4, "ACU write ok%s\n", "");
745 		exit(0);
746 	}
747 	/*  open line - will return on carrier */
748 	/* RT needs a sleep here because it returns immediately from open */
749 
750 #if RT
751 	sleep(15);
752 #endif
753 
754 	if (read(dnf, &c, 1) != 1 || c != 'A')
755 		dcf = -1;
756 	else
757 		dcf = 0;
758 	DEBUG(4, "dcf is %d\n", dcf);
759 	if (dcf < 0) {
760 		logent("DIALUP LINE open", "FAILED");
761 		alarm(0);
762 		kill(pid, 9);
763 		close(dnf);
764 		delock(dev->D_line);
765 		return(FAIL);
766 	}
767 	dcf = dnf;
768 	dnf = 0;
769 	/* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */
770 /*	ioctl(dcf, TIOCHPCL, STBNULL);*/
771 	while ((nw = wait(&lt)) != pid && nw != -1)
772 		;
773 #ifdef	SYSIII
774 	ioctl(dcf, TCGETA, &ttbuf);
775 	if(!(ttbuf.c_cflag & HUPCL)) {
776 		ttbuf.c_cflag |= HUPCL;
777 		ioctl(dcf, TCSETA, &ttbuf);
778 	}
779 #endif
780 	alarm(0);
781 	fflush(stdout);
782 	fixline(dcf, dev->D_speed);
783 	DEBUG(4, "Fork Stat %o\n", lt);
784 	if (lt != 0) {
785 		close(dcf);
786 		if (dnf)
787 			close(dnf);
788 		delock(dev->D_line);
789 		return(FAIL);
790 	}
791 	return(dcf);
792 }
793 
794 /*
795  * df2cls()	close the DF02/DF03 call unit
796  *
797  *	return codes: none
798  */
799 
800 df2cls(fd)
801 register int fd;
802 {
803 	if (fd > 0) {
804 		close(fd);
805 		sleep(5);
806 		delock(devSel);
807 		}
808 }
809 #endif DF02
810 
811 #ifdef HAYES
812 /***
813  *	hysopn(telno, flds, dev) connect to hayes smartmodem
814  *	char *flds[], *dev[];
815  *
816  *	return codes:
817  *		>0  -  file number  -  ok
818  *		CF_DIAL,CF_DEVICE  -  failed
819  */
820 /*
821  * Define HAYSTONE if you have touch tone dialing.
822  */
823 /*#define HAYSTONE	*/
824 
825 hysopn(telno, flds, dev)
826 char *telno;
827 char *flds[];
828 struct Devices *dev;
829 {
830 	int	dh = -1;
831 	extern errno;
832 	char dcname[20];
833 
834 	sprintf(dcname, "/dev/%s", dev->D_line);
835 	DEBUG(4, "dc - %s\n", dcname);
836 	if (setjmp(Sjbuf)) {
837 		DEBUG(1, "timeout hayes open %s\n", dcname);
838 		logent("hayes open", "TIMEOUT");
839 		if (dh >= 0)
840 			close(dh);
841 		delock(dev->D_line);
842 		return(CF_DIAL);
843 	}
844 	signal(SIGALRM, alarmtr);
845 	getnextfd();
846 	alarm(10);
847 	dh = open(dcname, 2); /* read/write */
848 	alarm(0);
849 
850 	/* modem is open */
851 	next_fd = -1;
852 	if (dh >= 0) {
853 		fixline(dh, dev->D_speed);
854 #ifdef HAYSTONE
855 		write(dh, "\rATDT", 5);
856 #else
857 		write(dh, "\rATDP", 5);
858 #endif
859 		write(dh, telno, strlen(telno));
860 		write(dh, "\r", 1);
861 
862 		if (expect("CONNECT", dh) != 0) {
863 			logent("HSM no carrier", "FAILED");
864 			strcpy(devSel, dev->D_line);
865 			hyscls(dh);
866 			return(CF_DIAL);
867 		}
868 
869 	}
870 	if (dh < 0) {
871 		DEBUG(4, "hayes failed\n", "");
872 		delock(dev->D_line);
873 	}
874 	DEBUG(4, "hayes ok\n", "");
875 	return(dh);
876 }
877 
878 hyscls(fd)
879 int fd;
880 {
881 	char dcname[20];
882 	struct sgttyb hup, sav;
883 
884 	if (fd > 0) {
885 		sprintf(dcname, "/dev/%s", devSel);
886 		DEBUG(4, "Hanging up fd = %d\n", fd);
887 /*
888  * code to drop DTR -- change to 0 baud then back to default.
889  */
890 		gtty(fd, &hup);
891 		gtty(fd, &sav);
892 		hup.sg_ispeed = B0;
893 		hup.sg_ospeed = B0;
894 		stty(fd, &hup);
895 		sleep(2);
896 		stty(fd, &sav);
897 /*
898  * now raise DTR -- close the device & open it again.
899  */
900 		sleep(2);
901 		close(fd);
902 		sleep(2);
903 		fd = open(dcname, 2);
904 /*
905  * Since we have a getty sleeping on this line, when it wakes up it sends
906  * all kinds of garbage to the modem.  Unfortunatly, the modem likes to
907  * execute the previous command when it sees the garbage.  The previous
908  * command was to dial the phone, so let's make the last command reset
909  * the modem.
910  */
911 		sleep(2);
912 		write(fd, "\rATZ\r", 5);
913 		close(fd);
914 		delock(devSel);
915 		}
916 	}
917 
918 #endif HAYES
919 
920 #ifdef HAYESQ
921 /*
922  * New dialout routine to work with Hayes' SMART MODEM
923  * 13-JUL-82, Mike Mitchell
924  * Modified 23-MAR-83 to work with Tom Truscott's (rti!trt)
925  * version of UUCP	(ncsu!mcm)
926  *
927  * The modem should be set to NOT send any result codes to
928  * the system (switch 3 up, 4 down). This end will figure out
929  * what is wrong.
930  *
931  * I had lots of problems with the modem sending
932  * result codes since I am using the same modem for both incomming and
933  * outgoing calls.  I'd occasionally miss the result code (getty would
934  * grab it), and the connect would fail.  Worse yet, the getty would
935  * think the result code was a user name, and send garbage to it while
936  * it was in the command state.  I turned off ALL result codes, and hope
937  * for the best.  99% of the time the modem is in the correct state.
938  * Occassionally it doesn't connect, or the phone was busy, etc., and
939  * uucico sits there trying to log in.  It eventually times out, calling
940  * clsacu() in the process, so it resets itself for the next attempt.
941  */
942 
943 /*
944  * Define HAYSTONE if touch-tone dialing is to be used.  If it is not defined,
945  * Pulse dialing is assumed.
946  */
947 /*#define HAYSTONE*/
948 
949 hysqopn(telno, flds, dev)
950 char *telno, *flds[];
951 struct Devices *dev;
952 {
953 	char dcname[20], phone[MAXPH+10], c = 0;
954 #ifdef	SYSIII
955 	struct termio ttbuf;
956 #endif
957 	int status, dnf;
958 	unsigned timelim;
959 
960 	signal(SIGALRM, alarmtr);
961 	sprintf(dcname, "/dev/%s", dev->D_line);
962 
963 	getnextfd();
964 	if (setjmp(Sjbuf)) {
965 		delock(dev->D_line);
966 		logent("DEVICE", "NO");
967 		DEBUG(4, "Open timed out %s", dcname);
968 		return(CF_NODEV);
969 		}
970 	alarm(10);
971 
972 	if ((dnf = open(dcname, 2)) <= 0) {
973 		delock(dev->D_line);
974 		logent("DEVICE", "NO");
975 		DEBUG(4, "Can't open %s", dcname);
976 		return(CF_NODEV);
977 		}
978 
979 	alarm(0);
980 	next_fd = -1;
981 	fixline(dnf, dev->D_speed);
982 	DEBUG(4, "Hayes port - %s, ", dcname);
983 
984 #ifdef HAYSTONE
985 	sprintf(phone, "\rATDT%s\r", telno);
986 #else
987 	sprintf(phone, "\rATDP%s\r", telno);
988 #endif
989 
990 	write(dnf, phone, strlen(phone));
991 
992 /* calculate delay time for the other system to answer the phone.
993  * Default is 15 seconds, add 2 seconds for each comma in the phone
994  * number.
995  */
996 	timelim = 150;
997 	while(*telno) {
998 		c = *telno++;
999 		if (c == ',')
1000 			timelim += 20;
1001 		else {
1002 #ifdef HAYSTONE
1003 			timelim += 2;	/* .2 seconds per tone */
1004 			}
1005 #else
1006 			if (c == '0') timelim += 10;   /* .1 second per digit */
1007 			else if (c > '0' && c <= '9')
1008 				timelim += (c - '0');
1009 			}
1010 #endif
1011 		}
1012 	alarm(timelim/10);
1013 	if (setjmp(Sjbuf) == 0) {
1014 		read(dnf, &c, 1);
1015 		alarm(0);
1016 		}
1017 
1018 	return(dnf);
1019 	}
1020 
1021 hysqcls(fd)
1022 int fd;
1023 {
1024 	char dcname[20];
1025 	struct sgttyb hup, sav;
1026 
1027 	if (fd > 0) {
1028 		sprintf(dcname, "/dev/%s", devSel);
1029 		DEBUG(4, "Hanging up fd = %d\n", fd);
1030 /*
1031  * code to drop DTR -- change to 0 baud then back to default.
1032  */
1033 		gtty(fd, &hup);
1034 		gtty(fd, &sav);
1035 		hup.sg_ispeed = B0;
1036 		hup.sg_ospeed = B0;
1037 		stty(fd, &hup);
1038 		sleep(2);
1039 		stty(fd, &sav);
1040 /*
1041  * now raise DTR -- close the device & open it again.
1042  */
1043 		sleep(2);
1044 		close(fd);
1045 		sleep(2);
1046 		fd = open(dcname, 2);
1047 /*
1048  * Since we have a getty sleeping on this line, when it wakes up it sends
1049  * all kinds of garbage to the modem.  Unfortunatly, the modem likes to
1050  * execute the previous command when it sees the garbage.  The previous
1051  * command was to dial the phone, so let's make the last command reset
1052  * the modem.
1053  */
1054 		sleep(2);
1055 		write(fd, "\rATZ\r", 5);
1056 		close(fd);
1057 		delock(devSel);
1058 		}
1059 	}
1060 
1061 #endif HAYESQ
1062 
1063 #ifdef	VENTEL
1064 ventopn(telno, flds, dev)
1065 char *flds[], *telno;
1066 struct Devices *dev;
1067 {
1068 	int	dh;
1069 	int	i, ok = -1;
1070 	char dcname[20];
1071 
1072 	sprintf(dcname, "/dev/%s", dev->D_line);
1073 	if (setjmp(Sjbuf)) {
1074 		DEBUG(1, "timeout ventel open\n", "");
1075 		logent("ventel open", "TIMEOUT");
1076 		if (dh >= 0)
1077 			close(dh);
1078 		delock(dev->D_line);
1079 		return(CF_NODEV);
1080 	}
1081 	signal(SIGALRM, alarmtr);
1082 	getnextfd();
1083 	alarm(10);
1084 	dh = open(dcname, 2);
1085 	next_fd = -1;
1086 	if (dh < 0) {
1087 		DEBUG(4,"%s\n", errno == 4 ? "no carrier" : "can't open modem");
1088 		delock(dev->D_line);
1089 		return(errno == 4 ? CF_DIAL : CF_NODEV);
1090 	}
1091 
1092 	/* modem is open */
1093 	fixline(dh, dev->D_speed);
1094 
1095 	/* translate - to % and = to & for VenTel */
1096 	DEBUG(4, "calling %s -> ", telno);
1097 	for (i = 0; i < strlen(telno); ++i) {
1098 		switch(telno[i]) {
1099 		case '-':	/* delay */
1100 			telno[i] = '%';
1101 			break;
1102 		case '=':	/* await dial tone */
1103 			telno[i] = '&';
1104 			break;
1105 		case '<':
1106 			telno[i] = '%';
1107 			break;
1108 		}
1109 	}
1110 	DEBUG(4, "%s\n", telno);
1111 	sleep(1);
1112 	for(i = 0; i < 5; ++i) {	/* make up to 5 tries */
1113  		slowrite(dh, "\r\r");/* awake, thou lowly VenTel! */
1114 
1115 		DEBUG(4, "wanted %s ", "$");
1116 		ok = expect("$", dh);
1117 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1118 		if (ok != 0)
1119 			continue;
1120  		slowrite(dh, "K");	/* "K" (enter number) command */
1121 		DEBUG(4, "wanted %s ", "DIAL: ");
1122 		ok = expect("DIAL: ", dh);
1123 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1124 		if (ok == 0)
1125 			break;
1126 	}
1127 
1128 	if (ok == 0) {
1129  		slowrite(dh, telno); /* send telno, send \r */
1130  		slowrite(dh, "\r");
1131 		DEBUG(4, "wanted %s ", "ONLINE");
1132 		ok = expect("ONLINE!", dh);
1133 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1134 	}
1135 	if (ok != 0) {
1136 		if (dh > 2)
1137 			close(dh);
1138 		DEBUG(4, "venDial failed\n", "");
1139 		return(CF_DIAL);
1140 	} else
1141 		DEBUG(4, "venDial ok\n", "");
1142 	return(dh);
1143 }
1144 
1145 
1146 /*
1147  * uucpdelay:  delay execution for numerator/denominator seconds.
1148  */
1149 
1150 #ifdef INTERVALTIMER
1151 #define uucpdelay(num,denom) intervaldelay(1000000*num/denom)
1152 #include <sys/time.h>
1153 catch alarm sig
1154 SIGALRM
1155 struct itimerval itimerval;
1156 itimerval.itimer_reload =
1157 itimerval.rtime.itimer_interval =
1158 itimerval.rtime.itimer_value =
1159 settimer(ITIMER_REAL, &itimerval);
1160 pause();
1161 alarm comes in
1162 turn off timer.
1163 #endif INTERVALTIMER
1164 
1165 #ifdef FASTTIMER
1166 #define uucpdelay(num,denom) nap(60*num/denom)
1167 /*	Sleep in increments of 60ths of second.	*/
1168 nap (time)
1169 	register int time;
1170 {
1171 	static int fd;
1172 
1173 	if (fd == 0)
1174 		fd = open (FASTTIMER, 0);
1175 
1176 	read (fd, 0, time);
1177 }
1178 #endif FASTTIMER
1179 
1180 #ifdef FTIME
1181 #define uucpdelay(num,denom) ftimedelay(1000*num/denom)
1182 #include <sys/timeb.h>
1183 ftimedelay(n)
1184 {
1185 	static struct timeb loctime;
1186 	ftime(&loctime);
1187 	{register i = loctime.millitm;
1188 	   while (abs((int)(loctime.millitm - i))<n) ftime(&loctime);
1189 	}
1190 }
1191 #endif FTIME
1192 
1193 #ifdef BUSYLOOP
1194 #define uucpdelay(num,denom) busyloop(CPUSPEED*num/denom)
1195 #define CPUSPEED 1000000	/* VAX 780 is 1MIPS */
1196 #define	DELAY(n)	{ register long N = (n); while (--N > 0); }
1197 busyloop(n)
1198 	{
1199 	DELAY(n);
1200 	}
1201 #endif BUSYLOOP
1202 
1203 slowrite(fd, str)
1204 register char *str;
1205 {
1206 	DEBUG(6, "slowrite ", "");
1207 	while (*str) {
1208 		DEBUG(6, "%c", *str);
1209 		uucpdelay(1,10);	/* delay 1/10 second */
1210 		write(fd, str, 1);
1211 		str++;
1212 		}
1213 	DEBUG(6, "\n", "");
1214 }
1215 
1216 
1217 ventcls(fd)
1218 int fd;
1219 {
1220 
1221 	if (fd > 0) {
1222 		close(fd);
1223 		sleep(5);
1224 		delock(devSel);
1225 		}
1226 }
1227 #endif VENTEL
1228 
1229 #ifdef VADIC
1230 
1231 /*
1232  *	vadopn: establish dial-out connection through a Racal-Vadic 3450.
1233  *	Returns descriptor open to tty for reading and writing.
1234  *	Negative values (-1...-7) denote errors in connmsg.
1235  *	Be sure to disconnect tty when done, via HUPCL or stty 0.
1236  */
1237 
1238 vadopn(telno, flds, dev)
1239 char *telno;
1240 char *flds[];
1241 struct Devices *dev;
1242 {
1243 	int	dh = -1;
1244 	int	i, ok, er = 0, delay;
1245 	extern errno;
1246 	char dcname[20];
1247 
1248 	sprintf(dcname, "/dev/%s", dev->D_line);
1249 	if (setjmp(Sjbuf)) {
1250 		DEBUG(1, "timeout vadic open\n", "");
1251 		logent("vadic open", "TIMEOUT");
1252 		if (dh >= 0)
1253 			close(dh);
1254 		delock(dev->D_line);
1255 		return(CF_NODEV);
1256 	}
1257 	signal(SIGALRM, alarmtr);
1258 	getnextfd();
1259 	alarm(10);
1260 	dh = open(dcname, 2);
1261 	alarm(0);
1262 
1263 	/* modem is open */
1264 	next_fd = -1;
1265 	if (dh < 0) {
1266 		delock(dev->D_line);
1267 		return(CF_NODEV);
1268 		}
1269 	fixline(dh, dev->D_speed);
1270 
1271 /* translate - to K for Vadic */
1272 	DEBUG(4, "calling %s -> ", telno);
1273 	delay = 0;
1274 	for (i = 0; i < strlen(telno); ++i) {
1275 		switch(telno[i]) {
1276 		case '=':	/* await dial tone */
1277 		case '-':	/* delay */
1278 		case '<':
1279 			telno[i] = 'K';
1280 			delay += 5;
1281 			break;
1282 		}
1283 	}
1284 	DEBUG(4, "%s\n", telno);
1285 	for(i = 0; i < 5; ++i) {	/* make 5 tries */
1286 		/* wake up Vadic */
1287 		sendthem("\005\\d", dh);
1288 		DEBUG(4, "wanted %s ", "*");
1289 		ok = expect("*", dh);
1290 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1291 		if (ok != 0)
1292 			continue;
1293 
1294 		sendthem("D\\d", dh);	/* "D" (enter number) command */
1295 		DEBUG(4, "wanted %s ", "NUMBER?\\r\\n");
1296 		ok = expect("NUMBER?\r\n", dh);
1297 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1298 		if (ok != 0)
1299 			continue;
1300 
1301 	/* send telno, send \r */
1302 		sendthem(telno, dh);
1303 		ok = expect(telno, dh);
1304 		if (ok == 0)
1305 			ok = expect("\r\n", dh);
1306 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1307 		if (ok != 0)
1308 			continue;
1309 
1310 		sendthem("", dh); /* confirm number */
1311 		DEBUG(4, "wanted %s ", "DIALING: ");
1312 		ok = expect("DIALING: ", dh);
1313 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1314 		if (ok == 0)
1315 			break;
1316 	}
1317 
1318 	if (ok == 0) {
1319 		sleep(10 + delay);	/* give vadic some time */
1320 		DEBUG(4, "wanted ON LINE\\r\\n ", 0);
1321 		ok = expect("ON LINE\r\n", dh);
1322 		DEBUG(4, "got %s\n", ok ? "?" : "that");
1323 	}
1324 
1325 	if (ok != 0) {
1326 		sendthem("I\\d", dh);	/* back to idle */
1327 		if (dh > 2)
1328 			close(dh);
1329 		DEBUG(4, "vadDial failed\n", "");
1330 		delock(dev->D_line);
1331 		return(CF_DIAL);
1332 	}
1333 	DEBUG(4, "vadic ok\n", "");
1334 	return(dh);
1335 }
1336 
1337 vadcls(fd) {
1338 
1339 	if (fd > 0) {
1340 		close(fd);
1341 		sleep(5);
1342 		delock(devSel);
1343 		}
1344 	}
1345 
1346 #endif VADIC
1347 
1348 #ifdef	RVMACS
1349 /*
1350  * Racal-Vadic 'RV820' MACS system with 831 adaptor.
1351  * A typical 300 baud L-devices entry is
1352  *	ACU /dev/tty10 /dev/tty11,48 300 rvmacs
1353  * where tty10 is the communication line (D_Line),
1354  * tty11 is the dialer line (D_calldev),
1355  * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
1356  * and the '8' is the communication port (they are 1-indexed).
1357  * BUGS:
1358  * Only tested with one dialer, one modem
1359  * uses common speed for dialer and communication line.
1360  * UNTESTED
1361  */
1362 
1363 #define	STX	02	/* Access Adaptor */
1364 #define	ETX	03	/* Transfer to Dialer */
1365 #define	SI	017	/* Buffer Empty (end of phone number) */
1366 #define	SOH	01	/* Abort */
1367 
1368 rvmacsopn(ph, flds, dev)
1369 char *ph, *flds[];
1370 struct Devices *dev;
1371 {
1372 	register int va, i, child;
1373 	register char *p;
1374 	char c, acu[20], com[20];
1375 
1376 	child = -1;
1377 	if ((p = index(dev->D_calldev, ',')) == NULL) {
1378 		DEBUG(2, "No dialer/modem specification\n", 0);
1379 		goto failret;
1380 	}
1381 	*p++ = '\0';
1382 	if (setjmp(Sjbuf)) {
1383 		logent("rvmacsopn", "TIMEOUT");
1384 		i = CF_DIAL;
1385 		goto ret;
1386 	}
1387 	DEBUG(4, "STARTING CALL\n", 0);
1388 	sprintf(acu, "/dev/%s", dev->D_calldev);
1389 	getnextfd();
1390 	signal(SIGALRM, alarmtr);
1391 	alarm(30);
1392 	if ((va = open(acu, 2)) < 0) {
1393 		logent(acu, "CAN'T OPEN");
1394 		i = CF_NODEV;
1395 		goto ret;
1396 	}
1397 	fixline(va, dev->D_speed);
1398 
1399 	p_chwrite(va, STX);	/* access adaptor */
1400 	i = *p++ - '0';
1401 	if (i < 0 || i > 7) {
1402 		logent(p-1, "Bad dialer address/modem type\n");
1403 		goto failret;
1404 	}
1405 	p_chwrite(va, i);		/* Send Dialer Address Digit */
1406 	i = *p - '0';
1407 	if (i <= 0 || i > 14) {
1408 		logent(p-1, "Bad modem address\n");
1409 		goto failret;
1410 	}
1411 	p_chwrite(va, i-1);	/* Send Modem Address Digit */
1412 	write(va, ph, strlen(ph));	/* Send Phone Number */
1413 	p_chwrite(va, SI);	/* Send Buffer Empty */
1414 	p_chwrite(va, ETX);	/* Initiate Call */
1415 	sprintf(com, "/dev/%s", dev->D_line);
1416 
1417 	/* create child to open comm line */
1418 	if ((child = fork()) == 0) {
1419 		signal(SIGINT, SIG_DFL);
1420 		open(com, 0);
1421 		sleep(5);
1422 		exit(1);
1423 	}
1424 
1425 	if (read(va, &c, 1) != 1) {
1426 		logent("ACU READ", "FAILED");
1427 		goto failret;
1428 	}
1429 	switch(c) {
1430 	case 'A':
1431 		/* Fine! */
1432 		break;
1433 	case 'B':
1434 		DEBUG(2, "CALL ABORTED\n", 0);
1435 		goto failret;
1436 	case 'D':
1437 		DEBUG(2, "Dialer format error\n", 0);
1438 		goto failret;
1439 	case 'E':
1440 		DEBUG(2, "Dialer parity error\n", 0);
1441 		goto failret;
1442 	case 'F':
1443 		DEBUG(2, "Phone number too long\n", 0);
1444 		goto failret;
1445 	case 'G':
1446 		DEBUG(2, "Busy signal\n", 0);
1447 		goto failret;
1448 	default:
1449 		DEBUG(2, "Unknown MACS return code '%c'\n", i);
1450 		goto failret;
1451 	}
1452 	/*
1453 	 * open line - will return on carrier
1454 	 */
1455 	if ((i = open(com, 2)) < 0) {
1456 		if (errno == EIO)
1457 			logent("carrier", "LOST");
1458 		else
1459 			logent("dialup open", "FAILED");
1460 		goto failret;
1461 	}
1462 	fixline(i, dev->D_speed);
1463 	goto ret;
1464 failret:
1465 	i = CF_DIAL;
1466 ret:
1467 	alarm(0);
1468 	if (child != -1)
1469 		kill(child, SIGKILL);
1470 	close(va);
1471 	return(i);
1472 }
1473 
1474 rvmacscls(fd)
1475 register int fd;
1476 {
1477 	DEBUG(2, "MACS close %d\n", fd);
1478 	p_chwrite(fd, SOH);
1479 /*	ioctl(fd, TIOCCDTR, NULL);*/
1480 	close(fd);
1481 }
1482 #endif
1483