1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)biz31.c 8.1 (Berkeley) 06/06/93";
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
biz_dialer(num,mod)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
biz31w_dialer(num,acu)76 biz31w_dialer(num, acu)
77 char *num, *acu;
78 {
79
80 return (biz_dialer(num, "w"));
81 }
82
biz31f_dialer(num,acu)83 biz31f_dialer(num, acu)
84 char *num, *acu;
85 {
86
87 return (biz_dialer(num, "f"));
88 }
89
biz31_disconnect()90 biz31_disconnect()
91 {
92
93 write(FD, DISCONNECT_CMD, 4);
94 sleep(2);
95 ioctl(FD, TIOCFLUSH);
96 }
97
biz31_abort()98 biz31_abort()
99 {
100
101 write(FD, "\33", 1);
102 }
103
104 static int
echo(s)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
sigALRM()129 sigALRM()
130 {
131
132 timeout = 1;
133 longjmp(timeoutbuf, 1);
134 }
135
136 static int
detect(s)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
flush(s)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
bizsync(fd)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