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