xref: /netbsd-src/usr.bin/tip/aculib/biz31.c (revision fad4c9f71477ae11cea2ee75ec82151ac770a534)
1 /*	$NetBSD: biz31.c,v 1.11 2006/04/03 02:25:27 perry Exp $	*/
2 
3 /*
4  * Copyright (c) 1983, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)biz31.c	8.1 (Berkeley) 6/6/93";
36 #endif
37 __RCSID("$NetBSD: biz31.c,v 1.11 2006/04/03 02:25:27 perry Exp $");
38 #endif /* not lint */
39 
40 #include "tip.h"
41 
42 #define MAXRETRY	3		/* sync up retry count */
43 #define DISCONNECT_CMD	"\21\25\11\24"	/* disconnection string */
44 
45 static	void sigALRM();
46 static	int timeout = 0;
47 static	jmp_buf timeoutbuf;
48 
49 /*
50  * Dial up on a BIZCOMP Model 1031 with either
51  * 	tone dialing (mod = "f")
52  *	pulse dialing (mod = "w")
53  */
54 static int
55 biz_dialer(char *num, char *mod)
56 {
57 	int connected = 0;
58 
59 	if (!bizsync(FD)) {
60 		logent(value(HOST), "", "biz", "out of sync");
61 		printf("bizcomp out of sync\n");
62 		exit(0);
63 	}
64 	if (boolean(value(VERBOSE)))
65 		printf("\nstarting call...");
66 	echo("#\rk$\r$\n");			/* disable auto-answer */
67 	echo("$>$.$ #\r");			/* tone/pulse dialing */
68 	echo(mod);
69 	echo("$\r$\n");
70 	echo("$>$.$ #\re$ ");			/* disconnection sequence */
71 	echo(DISCONNECT_CMD);
72 	echo("\r$\n$\r$\n");
73 	echo("$>$.$ #\rr$ ");			/* repeat dial */
74 	echo(num);
75 	echo("\r$\n");
76 	if (boolean(value(VERBOSE)))
77 		printf("ringing...");
78 	/*
79 	 * The reply from the BIZCOMP should be:
80 	 *	`^G NO CONNECTION\r\n^G\r\n'	failure
81 	 *	` CONNECTION\r\n^G'		success
82 	 */
83 	connected = detect(" ");
84 	if (!connected)
85 		flush(" NO CONNECTION\r\n\07\r\n");
86 	else
87 		flush("CONNECTION\r\n\07");
88 	if (timeout)
89 		biz31_disconnect();	/* insurance */
90 	return (connected);
91 }
92 
93 biz31w_dialer(char *num, char *acu)
94 {
95 
96 	return (biz_dialer(num, "w"));
97 }
98 
99 biz31f_dialer(char *num, char *acu)
100 {
101 
102 	return (biz_dialer(num, "f"));
103 }
104 
105 biz31_disconnect(void)
106 {
107 
108 	write(FD, DISCONNECT_CMD, 4);
109 	sleep(2);
110 	tcflush(FD, TCIOFLUSH);
111 }
112 
113 biz31_abort(void)
114 {
115 
116 	write(FD, "\33", 1);
117 }
118 
119 static int
120 echo(char *s)
121 {
122 	char c;
123 
124 	while (c = *s++) switch (c) {
125 	case '$':
126 		read(FD, &c, 1);
127 		s++;
128 		break;
129 
130 	case '#':
131 		c = *s++;
132 		write(FD, &c, 1);
133 		break;
134 
135 	default:
136 		write(FD, &c, 1);
137 		read(FD, &c, 1);
138 	}
139 }
140 
141 static void
142 sigALRM(void)
143 {
144 
145 	timeout = 1;
146 	longjmp(timeoutbuf, 1);
147 }
148 
149 static int
150 detect(char *s)
151 {
152 	sig_t f;
153 	char c;
154 
155 	f = signal(SIGALRM, sigALRM);
156 	timeout = 0;
157 	while (*s) {
158 		if (setjmp(timeoutbuf)) {
159 			printf("\07timeout waiting for reply\n");
160 			biz31_abort();
161 			break;
162 		}
163 		alarm(number(value(DIALTIMEOUT)));
164 		read(FD, &c, 1);
165 		alarm(0);
166 		if (c != *s++)
167 			break;
168 	}
169 	signal(SIGALRM, f);
170 	return (timeout == 0);
171 }
172 
173 static int
174 flush(char *s)
175 {
176 	sig_t f;
177 	char c;
178 
179 	f = signal(SIGALRM, sigALRM);
180 	while (*s++) {
181 		if (setjmp(timeoutbuf))
182 			break;
183 		alarm(10);
184 		read(FD, &c, 1);
185 		alarm(0);
186 	}
187 	signal(SIGALRM, f);
188 	timeout = 0;			/* guard against disconnection */
189 }
190 
191 /*
192  * This convoluted piece of code attempts to get
193  *  the bizcomp in sync.  If you don't have the capacity or nread
194  *  call there are gory ways to simulate this.
195  */
196 static int
197 bizsync(int fd)
198 {
199 #ifdef FIOCAPACITY
200 	struct capacity b;
201 #	define chars(b)	((b).cp_nbytes)
202 #	define IOCTL	FIOCAPACITY
203 #endif
204 #ifdef FIONREAD
205 	long b;
206 #	define chars(b)	(b)
207 #	define IOCTL	FIONREAD
208 #endif
209 	int already = 0;
210 	char buf[10];
211 
212 retry:
213 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
214 		tcflush(FD, TCIOFLUSH);
215 	write(fd, "\rp>\r", 4);
216 	sleep(1);
217 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
218 		if (chars(b) != 10) {
219 	nono:
220 			if (already > MAXRETRY)
221 				return (0);
222 			write(fd, DISCONNECT_CMD, 4);
223 			sleep(2);
224 			already++;
225 			goto retry;
226 		} else {
227 			read(fd, buf, 10);
228 			if (strncmp(buf, "p >\r\n\r\n>", 8))
229 				goto nono;
230 		}
231 	}
232 	return (1);
233 }
234