xref: /illumos-gate/usr/src/cmd/tip/aculib/biz31.c (revision 7c478bd9)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 /*
6  * Copyright (c) 1983 Regents of the University of California.
7  * All rights reserved. The Berkeley software License Agreement
8  * specifies the terms and conditions for redistribution.
9  */
10 #ident	"%Z%%M%	%I%	%E% SMI"	/* from UCB 4.7 6/25/83 */
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	sigjmp_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, TCFLSH, TCOFLUSH);
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++) {
111 		switch (c) {
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 
129 static void
130 sigALRM()
131 {
132 
133 	timeout = 1;
134 	siglongjmp(timeoutbuf, 1);
135 }
136 
137 static int
138 detect(s)
139 	register char *s;
140 {
141 	char c;
142 	sig_handler_t f;
143 
144 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
145 	timeout = 0;
146 	while (*s) {
147 		if (sigsetjmp(timeoutbuf, 1)) {
148 			printf("\07timeout waiting for reply\n");
149 			biz31_abort();
150 			break;
151 		}
152 		alarm(number(value(DIALTIMEOUT)));
153 		read(FD, &c, 1);
154 		alarm(0);
155 		if (c != *s++)
156 			break;
157 	}
158 	signal(SIGALRM, f);
159 	return (timeout == 0);
160 }
161 
162 static int
163 flush(s)
164 	register char *s;
165 {
166 	char c;
167 	sig_handler_t f;
168 
169 	f = signal(SIGALRM, (sig_handler_t)sigALRM);
170 	while (*s++) {
171 		if (sigsetjmp(timeoutbuf, 1))
172 			break;
173 		alarm(10);
174 		read(FD, &c, 1);
175 		alarm(0);
176 	}
177 	signal(SIGALRM, f);
178 	timeout = 0;			/* guard against disconnection */
179 }
180 
181 /*
182  * This convoluted piece of code attempts to get
183  *  the bizcomp in sync.  If you don't have the capacity or nread
184  *  call there are gory ways to simulate this.
185  */
186 static int
187 bizsync(fd)
188 {
189 #ifdef FIOCAPACITY
190 	struct capacity b;
191 #define	chars(b)	((b).cp_nbytes)
192 #define	IOCTL	FIOCAPACITY
193 #endif
194 #ifdef FIONREAD
195 	long b;
196 #define	chars(b)	(b)
197 #define	IOCTL	FIONREAD
198 #endif
199 	register int already = 0;
200 	char buf[10];
201 
202 retry:
203 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
204 		ioctl(fd, TCFLSH, TCIOFLUSH);
205 	write(fd, "\rp>\r", 4);
206 	sleep(1);
207 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
208 		if (chars(b) != 10) {
209 	nono:
210 			if (already > MAXRETRY)
211 				return (0);
212 			write(fd, DISCONNECT_CMD, 4);
213 			sleep(2);
214 			already++;
215 			goto retry;
216 		} else {
217 			read(fd, buf, 10);
218 			if (strncmp(buf, "p >\r\n\r\n>", 8))
219 				goto nono;
220 		}
221 	}
222 	return (1);
223 }
224