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