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