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