xref: /original-bsd/usr.bin/uucp/libacu/rvmacs.c (revision c374ae69)
1 #ifndef lint
2 static char sccsid[] = "@(#)rvmacs.c	4.1 (Berkeley) 01/22/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.
17  */
18 
19 #define	STX	02	/* Access Adaptor */
20 #define	ETX	03	/* Transfer to Dialer */
21 #define	SI	017	/* Buffer Empty (end of phone number) */
22 #define	ABORT	01	/* Abort */
23 
24 #define	pc(fd, x)	(c = x, write(fd, &c, 1))
25 
26 rvmacsopn(ph, flds, dev)
27 char *ph, *flds[];
28 struct Devices *dev;
29 {
30 	register int va, i, child;
31 	register char *p;
32 	char *q;
33 	char c, acu[20], com[20];
34 	int baudrate;
35 	int timelim;
36 	int pid, status;
37 	int zero = 0;
38 	struct sgttyb sg;
39 
40 	child = -1;
41 	sprintf(com, "/dev/%s", dev->D_line);
42 	sprintf(acu, "/dev/%s", dev->D_calldev);
43 	if ((p = index(acu, ',')) == NULL) {
44 		DEBUG(2, "No dialer/modem specification\n", 0);
45 		return CF_DIAL;
46 	}
47 	*p++ = '\0';
48 	if (setjmp(Sjbuf)) {
49 		logent("rvmacsopn", "TIMEOUT");
50 		goto failret;
51 	}
52 	DEBUG(4, "STARTING CALL\n", 0);
53 	getnextfd();
54 	signal(SIGALRM, alarmtr);
55 	timelim = 5 * strlen(ph);
56 	alarm(timelim < 45 ? 45 : timelim);
57 
58 	if ((va = open(acu, 2)) < 0) {
59 		logent(acu, "CAN'T OPEN");
60 		alarm(0);
61 		return CF_DIAL;
62 	}
63 
64 	/* rti!trt: avoid passing acu file descriptor to children */
65 	next_fd = -1;
66 	fioclex(va);
67 
68 	if ((child = fork()) == 0) {
69 		/* create child to do dialing */
70 		sleep(2);
71 		fclose(stdin);
72 		fclose(stdout);
73 		sg.sg_flags = RAW|ANYP;
74 		sg.sg_ispeed = sg.sg_ospeed = B1200;
75 		ioctl(va, TIOCSETP, &sg);
76 		pc(va, ABORT);
77 		sleep(1);
78 		ioctl(va, TIOCFLUSH, &zero);
79 		pc(va, STX);	/* access adaptor */
80 		pc(va, *p++);	/* Send Dialer Address Digit */
81 		pc(va, *p);	/* Send Modem Address Digit */
82 		while (*ph && *ph != '<') {
83 			switch (*ph) {
84 			case '_':
85 			case '-':
86 			case '=':
87 				pc(va, '=');
88 				break;
89 			default:
90 				if (*ph >= '0' && *ph <= '9')
91 					pc(va, *ph);
92 				break;
93 			}
94 			ph++;
95 		}
96 		pc(va, '<');	/* Transfer Control to Modem (sigh) */
97 		pc(va, SI);	/* Send Buffer Empty */
98 		pc(va, ETX);	/* Initiate Call */
99 		sleep(1);
100 
101 		if (read(va, &c, 1) != 1) {
102 			close(va);
103 			logent("ACU READ", _FAILED);
104 			exit(1);
105 		}
106 		if (c == 'B' || c == 'G') {
107 			char cc;
108 			pc(va, ABORT);
109 			read(va, &cc, 1);
110 		}
111 		DEBUG(4, "Dialer returned %c\n", c);
112 		close(va);
113 		exit(c != 'A');
114 	}
115 	/*
116 	 * open line - will return on carrier
117 	 */
118 	if ((i = open(com, 2)) < 0) {
119 		if (errno == EIO)
120 			logent("carrier", "LOST");
121 		else
122 			logent("dialup open", _FAILED);
123 		goto failret;
124 	}
125 	while ((pid = wait(&status)) != child && pid != -1)
126 		;
127 	alarm(0);
128 	if (status) {
129 		close(i);
130 		close(va);		/* XXX */
131 		return CF_DIAL;
132 	}
133 	fixline(i, dev->D_speed);
134 	return i;
135 
136 failret:
137 	alarm(0);
138 	close(va);
139 	if (child != -1)
140 		kill(child, SIGKILL);
141 	return CF_DIAL;
142 }
143 
144 rvmacscls(fd)
145 register int fd;
146 {
147 	if (fd > 0) {
148 		ioctl(fd, TIOCCDTR, STBNULL);
149 		sleep(1);
150 		ioctl(fd, TIOCNXCL, STBNULL);
151 		close(fd);
152 		delock(devSel);
153 	}
154 }
155 #endif
156