xref: /original-bsd/usr.bin/uucp/libacu/rvmacs.c (revision ec35a16d)
1 /*-
2  * Copyright (c) 1985, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.proprietary.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)rvmacs.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 #include "condevs.h"
13 
14 /*
15  * Racal-Vadic 'RV820' MACS system with 831 adaptor.
16  * A typical 300 baud L-devices entry is
17  *	ACU tty10 tty11,48 300 rvmacs
18  * where tty10 is the communication line (D_Line),
19  * tty11 is the dialer line (D_calldev),
20  * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103),
21  * the '8' is the communication port,
22  * We assume the dialer speed is 1200 baud unless MULTISPEED is defined.
23  * We extended the semantics of the L-devices entry to allow you
24  * to set the speed at which the computer talks to the dialer:
25  *	ACU cul0 cua0,0<,2400 1200 rvmacs
26  * This is interpreted as above, except that the number following the second
27  * comma in the third field is taken to be the speed at which the computer
28  * must communicate with the dialer.  (If omitted, it defaults to the value
29  * in the fourth field.)  Note -- just after the call completes and you get
30  * carrier, the line speed is reset to the speed indicated in the fourth field.
31  * To get this ability, define "MULTISPEED", as below.
32  *
33  */
34 #define MULTISPEED		/* for dialers which work at various speeds */
35 
36 #define	STX	02	/* Access Adaptor */
37 #define	ETX	03	/* Transfer to Dialer */
38 #define	SI	017	/* Buffer Empty (end of phone number) */
39 #define	ABORT	01	/* Abort */
40 
41 #define	pc(fd, x)	(c = x, write(fd, &c, 1))
42 
43 rvmacsopn(ph, flds, dev)
44 char *ph, *flds[];
45 struct Devices *dev;
46 {
47 	register int va, i, child;
48 	register char *p;
49 	char c, acu[20], com[20];
50 	int baudrate;
51 	int timelim;
52 	int pid, status;
53 	int zero = 0;
54 #ifdef MULTISPEED
55 	char *pp;
56 #else !MULTISPEED
57 	struct sgttyb sg;
58 #endif MULTISPEED
59 
60 	child = -1;
61 	sprintf(com, "/dev/%s", dev->D_line);
62 	sprintf(acu, "/dev/%s", dev->D_calldev);
63 	if ((p = index(acu, ',')) == NULL) {
64 		DEBUG(2, "No dialer/modem specification\n", 0);
65 		return CF_DIAL;
66 	}
67 	*p++ = '\0';
68 #ifdef MULTISPEED
69 	baudrate = dev->D_speed;
70 	if ((pp = index(p, ',')) != NULL){
71 		baudrate = atoi(pp+1);
72 		DEBUG(5, "Using speed %d baud\n", baudrate);
73 	}
74 #endif MULTISPEED
75 	if (setjmp(Sjbuf)) {
76 		logent("rvmacsopn", "TIMEOUT");
77 		goto failret;
78 	}
79 	DEBUG(4, "STARTING CALL\n", 0);
80 	getnextfd();
81 	signal(SIGALRM, alarmtr);
82 	timelim = 5 * strlen(ph);
83 	alarm(timelim < 45 ? 45 : timelim);
84 
85 	if ((va = open(acu, 2)) < 0) {
86 		logent(acu, "CAN'T OPEN");
87 		alarm(0);
88 		return CF_DIAL;
89 	}
90 
91 	/* rti!trt: avoid passing acu file descriptor to children */
92 	next_fd = -1;
93 	fioclex(va);
94 
95 	if ((child = fork()) == 0) {
96 		/* create child to do dialing */
97 		sleep(2);
98 		fclose(stdin);
99 		fclose(stdout);
100 #ifdef MULTISPEED
101 		fixline(va, baudrate);
102 #else !MULTISPEED
103 		sg.sg_flags = RAW|ANYP;
104 		sg.sg_ispeed = sg.sg_ospeed = B1200;
105 		ioctl(va, TIOCSETP, &sg);
106 #endif MULTISPEED
107 		pc(va, ABORT);
108 		sleep(1);
109 		ioctl(va, TIOCFLUSH, &zero);
110 		pc(va, STX);	/* access adaptor */
111 		pc(va, *p++);	/* Send Dialer Address Digit */
112 		pc(va, *p);	/* Send Modem Address Digit */
113 		while (*ph && *ph != '<') {
114 			switch (*ph) {
115 			case '_':
116 			case '-':
117 			case '=':
118 				pc(va, '=');
119 				break;
120 			default:
121 				if (*ph >= '0' && *ph <= '9')
122 					pc(va, *ph);
123 				break;
124 			}
125 			ph++;
126 		}
127 		pc(va, '<');	/* Transfer Control to Modem (sigh) */
128 		pc(va, SI);	/* Send Buffer Empty */
129 		pc(va, ETX);	/* Initiate Call */
130 		sleep(1);
131 
132 		if (read(va, &c, 1) != 1) {
133 			close(va);
134 			logent("ACU READ", _FAILED);
135 			exit(1);
136 		}
137 		if (c == 'B' || c == 'G') {
138 			char cc;
139 			pc(va, ABORT);
140 			read(va, &cc, 1);
141 		}
142 		DEBUG(4, "Dialer returned %c\n", c);
143 		close(va);
144 		exit(c != 'A');
145 	}
146 	/*
147 	 * open line - will return on carrier
148 	 */
149 	if ((i = open(com, 2)) < 0) {
150 		if (errno == EIO)
151 			logent("carrier", "LOST");
152 		else
153 			logent("dialup open", _FAILED);
154 		goto failret;
155 	}
156 	while ((pid = wait(&status)) != child && pid != -1)
157 		;
158 	alarm(0);
159 	if (status) {
160 		close(i);
161 		close(va);		/* XXX */
162 		return CF_DIAL;
163 	}
164 	fixline(i, dev->D_speed);
165 	return i;
166 
167 failret:
168 	alarm(0);
169 	close(va);
170 	if (child != -1)
171 		kill(child, SIGKILL);
172 	return CF_DIAL;
173 }
174 
175 rvmacscls(fd)
176 register int fd;
177 {
178 	if (fd > 0) {
179 		char c;
180 
181 		pc(fd, ABORT);
182 		ioctl(fd, TIOCCDTR, STBNULL);
183 		sleep(1);
184 		ioctl(fd, TIOCNXCL, STBNULL);
185 		close(fd);
186 		delock(devSel);
187 	}
188 }
189