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