lock alias file while rebuilding if flock system call available
[unix-history] / usr / src / usr.bin / tip / aculib / hayes.c
CommitLineData
e316be98
MAN
1#ifndef lint
2static char sccsid[] = "@(#)hayes.c 1.1 (Berkeley) 85/04/11 ";
3#endif
4
5/*
6 * Routines for calling up on a Hayes Modem
7 * (based on the old VenTel driver).
8 * The modem is expected to be strapped for "echo".
9 * Also, the switches enabling the DTR and CD lines
10 * must be set correctly.
11 * NOTICE:
12 * The easy way to hang up a modem is always simply to
13 * clear the DTR signal. However, if the +++ sequence
14 * (which switches the modem back to local mode) is sent
15 * before modem is hung up, removal of the DTR signal
16 * has no effect (except that it prevents the modem from
17 * recognizing commands).
18 * (by Helge Skrivervik, Calma Company, Sunnyvale, CA. 1984)
19 */
20/*
21 * TODO:
22 * It is probably not a good idea to switch the modem
23 * state between 'verbose' and terse (status messages).
24 * This should be kicked out and we should use verbose
25 * mode only. This would make it consistent with normal
26 * interactive use thru the command 'tip dialer'.
27 */
28#include "tip.h"
29
30#define min(a,b) ((a < b) ? a : b)
31
32static int sigALRM();
33static int timeout = 0;
34static jmp_buf timeoutbuf;
35static char gobble();
36#define DUMBUFLEN 40
37static char dumbuf[DUMBUFLEN];
38
39#define DIALING 1
40#define IDLE 2
41#define CONNECTED 3
42#define FAILED 4
43static int state = IDLE;
44
45hay_dialer(num, acu)
46 register char *num;
47 char *acu;
48{
49 register char *cp;
50 register int connected = 0;
51 char dummy;
52#ifdef ACULOG
53 char line[80];
54#endif
55 if (hay_sync() == 0) /* make sure we can talk to the modem */
56 return(0);
57 if (boolean(value(VERBOSE)))
58 printf("\ndialing...");
59 fflush(stdout);
60 ioctl(FD, TIOCHPCL, 0);
61 ioctl(FD, TIOCFLUSH, 0); /* get rid of garbage */
62 write(FD, "ATv0\r", 5); /* tell modem to use short status codes */
63 gobble("\r");
64 gobble("\r");
65 write(FD, "ATTD", 4); /* send dial command */
66 write(FD, num, strlen(num));
67 state = DIALING;
68 write(FD, "\r", 1);
69 connected = 0;
70 if (gobble("\r")) {
71 if ((dummy = gobble("01234")) != '1')
72 error_rep(dummy);
73 else
74 connected = 1;
75 }
76 if (connected)
77 state = CONNECTED;
78 else {
79 state = FAILED;
80 return (connected); /* lets get out of here.. */
81 }
82 ioctl(FD, TIOCFLUSH, 0);
83#ifdef ACULOG
84 if (timeout) {
85 sprintf(line, "%d second dial timeout",
86 number(value(DIALTIMEOUT)));
87 logent(value(HOST), num, "hayes", line);
88 }
89#endif
90 if (timeout)
91 hay_disconnect(); /* insurance */
92 return (connected);
93}
94
95
96hay_disconnect()
97{
98 char c;
99 int len, rlen;
100
101 /* first hang up the modem*/
102#ifdef DEBUG
103 printf("\rdisconnecting modem....\n\r");
104#endif
105 ioctl(FD, TIOCCDTR, 0);
106 sleep(1);
107 ioctl(FD, TIOCSDTR, 0);
108 goodbye();
109}
110
111hay_abort()
112{
113
114 char c;
115
116 write(FD, "\r", 1); /* send anything to abort the call */
117 hay_disconnect();
118}
119
120static int
121sigALRM()
122{
123
124 printf("\07timeout waiting for reply\n\r");
125 timeout = 1;
126 longjmp(timeoutbuf, 1);
127}
128
129static char
130gobble(match)
131 register char *match;
132{
133 char c;
134 int (*f)();
135 int i, status = 0;
136
137 signal(SIGALRM, sigALRM);
138 timeout = 0;
139#ifdef DEBUG
140 printf("\ngobble: waiting for %s\n", match);
141#endif
142 do {
143 if (setjmp(timeoutbuf)) {
144 signal(SIGALRM, f);
145 return (0);
146 }
147 alarm(number(value(DIALTIMEOUT)));
148 read(FD, &c, 1);
149 alarm(0);
150 c &= 0177;
151#ifdef DEBUG
152 printf("%c 0x%x ", c, c);
153#endif
154 for (i = 0; i < strlen(match); i++)
155 if (c == match[i])
156 status = c;
157 } while (status == 0);
158 signal(SIGALRM, SIG_DFL);
159#ifdef DEBUG
160 printf("\n");
161#endif
162 return (status);
163}
164
165error_rep(c)
166 register char c;
167{
168 printf("\n\r");
169 switch (c) {
170
171 case '0':
172 printf("OK");
173 break;
174
175 case '1':
176 printf("CONNECT");
177 break;
178
179 case '2':
180 printf("RING");
181 break;
182
183 case '3':
184 printf("NO CARRIER");
185 break;
186
187 case '4':
188 printf("ERROR in input");
189 break;
190
191 case '5':
192 printf("CONNECT 1200");
193 break;
194
195 default:
196 printf("Unknown Modem error: %c (0x%x)", c, c);
197 }
198 printf("\n\r");
199 return;
200}
201
202/*
203 * set modem back to normal verbose status codes.
204 */
205goodbye()
206{
207 int len, rlen;
208 char c;
209
210 ioctl(FD, TIOCFLUSH, &len); /* get rid of trash */
211 if (hay_sync()) {
212 sleep(1);
213#ifndef DEBUG
214 ioctl(FD, TIOCFLUSH, 0);
215#endif
216 write(FD, "ATH0\r", 5); /* insurance */
217#ifndef DEBUG
218 c = gobble("03");
219 if (c != '0' && c != '3') {
220 printf("cannot hang up modem\n\r");
221 printf("please use 'tip dialer' to make sure the line is hung up\n\r");
222 }
223#endif
224 sleep(1);
225 ioctl(FD, FIONREAD, &len);
226#ifdef DEBUG
227 printf("goodbye1: len=%d -- ", len);
228 rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
229 dumbuf[rlen] = '\0';
230 printf("read (%d): %s\r\n", rlen, dumbuf);
231#endif
232 write(FD, "ATv1\r", 5);
233 sleep(1);
234#ifdef DEBUG
235 ioctl(FD, FIONREAD, &len);
236 printf("goodbye2: len=%d -- ", len);
237 rlen = read(FD, dumbuf, min(len, DUMBUFLEN));
238 dumbuf[rlen] = '\0';
239 printf("read (%d): %s\r\n", rlen, dumbuf);
240#endif
241 }
242 ioctl(FD, TIOCFLUSH, 0); /* clear the input buffer */
243 ioctl(FD, TIOCCDTR, 0); /* clear DTR (insurance) */
244 close(FD);
245}
246
247#define MAXRETRY 5
248
249hay_sync()
250{
251 int len, retry = 0;
252
253 while (retry++ <= MAXRETRY) {
254 write(FD, "AT\r", 3);
255 sleep(1);
256 ioctl(FD, FIONREAD, &len);
257 if (len) {
258 len = read(FD, dumbuf, min(len, DUMBUFLEN));
259 if (index(dumbuf, '0') ||
260 (index(dumbuf, 'O') && index(dumbuf, 'K')))
261 return(1);
262#ifdef DEBUG
263 dumbuf[len] = '\0';
264 printf("hay_sync: (\"%s\") %d\n\r", dumbuf, retry);
265#endif
266 }
267 ioctl(FD, TIOCCDTR, 0);
268 ioctl(FD, TIOCSDTR, 0);
269 }
270 printf("Cannot synchronize with hayes...\n\r");
271 return(0);
272}