xref: /original-bsd/usr.bin/tip/aculib/biz31.c (revision 57124d5e)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)biz31.c	5.1 (Berkeley) 06/06/85";
9 #endif not lint
10 
11 #include "tip.h"
12 
13 #define MAXRETRY	3		/* sync up retry count */
14 #define DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
15 
16 static	int sigALRM();
17 static	int timeout = 0;
18 static	jmp_buf timeoutbuf;
19 
20 /*
21  * Dial up on a BIZCOMP Model 1031 with either
22  * 	tone dialing (mod = "f")
23  *	pulse dialing (mod = "w")
24  */
25 static int
26 biz_dialer(num, mod)
27 	char *num, *mod;
28 {
29 	register int connected = 0;
30 
31 	if (!bizsync(FD)) {
32 		logent(value(HOST), "", "biz", "out of sync");
33 		printf("bizcomp out of sync\n");
34 		delock(uucplock);
35 		exit(0);
36 	}
37 	if (boolean(value(VERBOSE)))
38 		printf("\nstarting call...");
39 	echo("#\rk$\r$\n");			/* disable auto-answer */
40 	echo("$>$.$ #\r");			/* tone/pulse dialing */
41 	echo(mod);
42 	echo("$\r$\n");
43 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
44 	echo(DISCONNECT_CMD);
45 	echo("\r$\n$\r$\n");
46 	echo("$>$.$ #\rr$ ");			/* repeat dial */
47 	echo(num);
48 	echo("\r$\n");
49 	if (boolean(value(VERBOSE)))
50 		printf("ringing...");
51 	/*
52 	 * The reply from the BIZCOMP should be:
53 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
54 	 *	` CONNECTION\r\n^G'		success
55 	 */
56 	connected = detect(" ");
57 #ifdef ACULOG
58 	if (timeout) {
59 		char line[80];
60 
61 		sprintf(line, "%d second dial timeout",
62 			number(value(DIALTIMEOUT)));
63 		logent(value(HOST), num, "biz", line);
64 	}
65 #endif
66 	if (!connected)
67 		flush(" NO CONNECTION\r\n\07\r\n");
68 	else
69 		flush("CONNECTION\r\n\07");
70 	if (timeout)
71 		biz31_disconnect();	/* insurance */
72 	return (connected);
73 }
74 
75 biz31w_dialer(num, acu)
76 	char *num, *acu;
77 {
78 
79 	return (biz_dialer(num, "w"));
80 }
81 
82 biz31f_dialer(num, acu)
83 	char *num, *acu;
84 {
85 
86 	return (biz_dialer(num, "f"));
87 }
88 
89 biz31_disconnect()
90 {
91 
92 	write(FD, DISCONNECT_CMD, 4);
93 	sleep(2);
94 	ioctl(FD, TIOCFLUSH);
95 }
96 
97 biz31_abort()
98 {
99 
100 	write(FD, "\33", 1);
101 }
102 
103 static int
104 echo(s)
105 	register char *s;
106 {
107 	char c;
108 
109 	while (c = *s++) switch (c) {
110 
111 	case '$':
112 		read(FD, &c, 1);
113 		s++;
114 		break;
115 
116 	case '#':
117 		c = *s++;
118 		write(FD, &c, 1);
119 		break;
120 
121 	default:
122 		write(FD, &c, 1);
123 		read(FD, &c, 1);
124 	}
125 }
126 
127 static int
128 sigALRM()
129 {
130 
131 	timeout = 1;
132 	longjmp(timeoutbuf, 1);
133 }
134 
135 static int
136 detect(s)
137 	register char *s;
138 {
139 	char c;
140 	int (*f)();
141 
142 	f = signal(SIGALRM, sigALRM);
143 	timeout = 0;
144 	while (*s) {
145 		if (setjmp(timeoutbuf)) {
146 			printf("\07timeout waiting for reply\n");
147 			biz31_abort();
148 			break;
149 		}
150 		alarm(number(value(DIALTIMEOUT)));
151 		read(FD, &c, 1);
152 		alarm(0);
153 		if (c != *s++)
154 			break;
155 	}
156 	signal(SIGALRM, f);
157 	return (timeout == 0);
158 }
159 
160 static int
161 flush(s)
162 	register char *s;
163 {
164 	char c;
165 	int (*f)();
166 
167 	f = signal(SIGALRM, sigALRM);
168 	while (*s++) {
169 		if (setjmp(timeoutbuf))
170 			break;
171 		alarm(10);
172 		read(FD, &c, 1);
173 		alarm(0);
174 	}
175 	signal(SIGALRM, f);
176 	timeout = 0;			/* guard against disconnection */
177 }
178 
179 /*
180  * This convoluted piece of code attempts to get
181  *  the bizcomp in sync.  If you don't have the capacity or nread
182  *  call there are gory ways to simulate this.
183  */
184 static int
185 bizsync(fd)
186 {
187 #ifdef FIOCAPACITY
188 	struct capacity b;
189 #	define chars(b)	((b).cp_nbytes)
190 #	define IOCTL	FIOCAPACITY
191 #endif
192 #ifdef FIONREAD
193 	long b;
194 #	define chars(b)	(b)
195 #	define IOCTL	FIONREAD
196 #endif
197 	register int already = 0;
198 	char buf[10];
199 
200 retry:
201 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
202 		ioctl(fd, TIOCFLUSH);
203 	write(fd, "\rp>\r", 4);
204 	sleep(1);
205 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
206 		if (chars(b) != 10) {
207 	nono:
208 			if (already > MAXRETRY)
209 				return (0);
210 			write(fd, DISCONNECT_CMD, 4);
211 			sleep(2);
212 			already++;
213 			goto retry;
214 		} else {
215 			read(fd, buf, 10);
216 			if (strncmp(buf, "p >\r\n\r\n>", 8))
217 				goto nono;
218 		}
219 	}
220 	return (1);
221 }
222