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