xref: /original-bsd/usr.bin/tip/aculib/biz31.c (revision 6c57d260)
1 /*	biz31.c	4.1	81/05/09	*/
2 #include "tip.h"
3 
4 #if BIZCOMP
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 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 		biz_disconnect();	/* insurance */
63 	return(connected);
64 }
65 
66 bizw_dialer(num, acu)
67 char *num, *acu;
68 {
69 	return(biz_dialer(num, "w"));
70 }
71 
72 bizf_dialer(num, acu)
73 char *num, *acu;
74 {
75 	return(biz_dialer(num, "f"));
76 }
77 
78 biz_disconnect()
79 {
80 	write(FD, DISCONNECT, 4);
81 	sleep(2);
82 	ioctl(FD, TIOCFLUSH);
83 }
84 
85 biz_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++)
98 		switch(c)
99 		{
100 			case '$':
101 				read(FD, &c, 1);
102 				s++;
103 				break;
104 			case '#':
105 				c = *s++;
106 				write(FD, &c, 1);
107 				break;
108 			default:
109 				write(FD, &c, 1);
110 				read(FD, &c, 1);
111 		}
112 }
113 
114 static int
115 sigALRM()
116 {
117 	signal(SIGALRM, SIG_IGN);
118 	printf("\07timeout waiting for reply\n");
119 	timeout = 1;
120 }
121 
122 static int
123 detect(s)
124 register char *s;
125 {
126 	char c;
127 
128 	signal(SIGALRM, biz_abort);
129 	timeout = 0;
130 	while (*s)
131 	{
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 	{
154 		alarm(10);
155 		read(FD, &c, 1);
156 		alarm(0);
157 		if (timeout)
158 			break;
159 	}
160 	signal(SIGALRM, SIG_DFL);
161 	timeout = 0;			/* guard against disconnection */
162 	return(1);
163 }
164 
165 /*
166  * This convoluted piece of code attempts to get
167  *  the bizcomp in sync.  If you don't have the capacity or nread
168  *  call there are gory ways to simulate this.
169  */
170 static int
171 bizsync(fd)
172 {
173 #ifdef FIOCAPACITY
174 	struct capacity b;
175 #	define chars(b)	((b).cp_nbytes)
176 #	define IOCTL	FIOCAPACITY
177 #endif
178 #ifdef FIONREAD
179 	long b;
180 #	define chars(b)	(b)
181 #	define IOCTL	FIONREAD
182 #endif
183 	register int already = 0;
184 	char buf[10];
185 
186 retry:
187 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0 && chars(b) > 0)
188 		ioctl(fd, TIOCFLUSH);
189 	write(fd, "\rp>\r", 4);
190 	sleep(1);
191 	if (ioctl(fd, IOCTL, (caddr_t)&b) >= 0) {
192 		if (chars(b) != 10) {
193 	nono:
194 			if (already > MAXRETRY)
195 				return(0);
196 			write(fd, DISCONNECT, 4);
197 			sleep(2);
198 			already++;
199 			goto retry;
200 		} else {
201 			read(fd, buf, 10);
202 			if (strncmp(buf, "p >\r\n\r\n>", 8))
203 				goto nono;
204 		}
205 	}
206 	return(1);
207 }
208 #endif
209