|
|
1.1 root 1: /*
2: * Copyright (c) 1986 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)courier.c 5.5 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: #define write cour_write
25: /*
26: * Routines for calling up on a Courier modem.
27: * Derived from Hayes driver.
28: */
29: #include "tip.h"
30: #include <stdio.h>
31:
32: #define MAXRETRY 5
33:
34: static void sigALRM();
35: static int timeout = 0;
36: static int connected = 0;
37: static jmp_buf timeoutbuf, intbuf;
38: static int (*osigint)();
39:
40: cour_dialer(num, acu)
41: register char *num;
42: char *acu;
43: {
44: register char *cp;
45: #ifdef ACULOG
46: char line[80];
47: #endif
48: if (boolean(value(VERBOSE)))
49: printf("Using \"%s\"\n", acu);
50:
51: ioctl(FD, TIOCHPCL, 0);
52: /*
53: * Get in synch.
54: */
55: if (!coursync()) {
56: badsynch:
57: printf("can't synchronize with courier\n");
58: #ifdef ACULOG
59: logent(value(HOST), num, "courier", "can't synch up");
60: #endif
61: return (0);
62: }
63: write(FD, "AT E0\r", 6); /* turn off echoing */
64: sleep(1);
65: #ifdef DEBUG
66: if (boolean(value(VERBOSE)))
67: verbose_read();
68: #endif
69: ioctl(FD, TIOCFLUSH, 0); /* flush any clutter */
70: write(FD, "AT C1 E0 H0 Q0 X6 V1\r", 21);
71: if (!cour_swallow("\r\nOK\r\n"))
72: goto badsynch;
73: fflush(stdout);
74: write(FD, "AT D", 4);
75: for (cp = num; *cp; cp++)
76: if (*cp == '=')
77: *cp = ',';
78: write(FD, num, strlen(num));
79: write(FD, "\r", 1);
80: connected = cour_connect();
81: #ifdef ACULOG
82: if (timeout) {
83: sprintf(line, "%d second dial timeout",
84: number(value(DIALTIMEOUT)));
85: logent(value(HOST), num, "cour", line);
86: }
87: #endif
88: if (timeout)
89: cour_disconnect();
90: return (connected);
91: }
92:
93: cour_disconnect()
94: {
95: /* first hang up the modem*/
96: ioctl(FD, TIOCCDTR, 0);
97: sleep(1);
98: ioctl(FD, TIOCSDTR, 0);
99: coursync(); /* reset */
100: close(FD);
101: }
102:
103: cour_abort()
104: {
105: write(FD, "\r", 1); /* send anything to abort the call */
106: cour_disconnect();
107: }
108:
109: static void
110: sigALRM()
111: {
112: printf("\07timeout waiting for reply\n");
113: timeout = 1;
114: longjmp(timeoutbuf, 1);
115: }
116:
117: static int
118: cour_swallow(match)
119: register char *match;
120: {
121: sig_t f;
122: char c;
123:
124: f = signal(SIGALRM, sigALRM);
125: timeout = 0;
126: do {
127: if (*match =='\0') {
128: signal(SIGALRM, f);
129: return (1);
130: }
131: if (setjmp(timeoutbuf)) {
132: signal(SIGALRM, f);
133: return (0);
134: }
135: alarm(number(value(DIALTIMEOUT)));
136: read(FD, &c, 1);
137: alarm(0);
138: c &= 0177;
139: #ifdef DEBUG
140: if (boolean(value(VERBOSE)))
141: putchar(c);
142: #endif
143: } while (c == *match++);
144: #ifdef DEBUG
145: if (boolean(value(VERBOSE)))
146: fflush(stdout);
147: #endif
148: signal(SIGALRM, SIG_DFL);
149: return (0);
150: }
151:
152: struct baud_msg {
153: char *msg;
154: int baud;
155: } baud_msg[] = {
156: "", B300,
157: " 1200", B1200,
158: " 2400", B2400,
159: 0, 0,
160: };
161:
162: static int
163: cour_connect()
164: {
165: char c;
166: int nc, nl, n;
167: struct sgttyb sb;
168: char dialer_buf[64];
169: struct baud_msg *bm;
170: sig_t f;
171:
172: if (cour_swallow("\r\n") == 0)
173: return (0);
174: f = signal(SIGALRM, sigALRM);
175: again:
176: nc = 0; nl = sizeof(dialer_buf)-1;
177: bzero(dialer_buf, sizeof(dialer_buf));
178: timeout = 0;
179: for (nc = 0, nl = sizeof(dialer_buf)-1 ; nl > 0 ; nc++, nl--) {
180: if (setjmp(timeoutbuf))
181: break;
182: alarm(number(value(DIALTIMEOUT)));
183: n = read(FD, &c, 1);
184: alarm(0);
185: if (n <= 0)
186: break;
187: c &= 0x7f;
188: if (c == '\r') {
189: if (cour_swallow("\n") == 0)
190: break;
191: if (!dialer_buf[0])
192: goto again;
193: if (strcmp(dialer_buf, "RINGING") == 0 &&
194: boolean(value(VERBOSE))) {
195: #ifdef DEBUG
196: printf("%s\r\n", dialer_buf);
197: #endif
198: goto again;
199: }
200: if (strncmp(dialer_buf, "CONNECT",
201: sizeof("CONNECT")-1) != 0)
202: break;
203: for (bm = baud_msg ; bm ; bm++)
204: if (strcmp(bm->msg,
205: dialer_buf+sizeof("CONNECT")-1) == 0) {
206: if (ioctl(FD, TIOCGETP, &sb) < 0) {
207: perror("TIOCGETP");
208: goto error;
209: }
210: sb.sg_ispeed = sb.sg_ospeed = bm->baud;
211: if (ioctl(FD, TIOCSETP, &sb) < 0) {
212: perror("TIOCSETP");
213: goto error;
214: }
215: signal(SIGALRM, f);
216: #ifdef DEBUG
217: if (boolean(value(VERBOSE)))
218: printf("%s\r\n", dialer_buf);
219: #endif
220: return (1);
221: }
222: break;
223: }
224: dialer_buf[nc] = c;
225: #ifdef notdef
226: if (boolean(value(VERBOSE)))
227: putchar(c);
228: #endif
229: }
230: error1:
231: printf("%s\r\n", dialer_buf);
232: error:
233: signal(SIGALRM, f);
234: return (0);
235: }
236:
237: /*
238: * This convoluted piece of code attempts to get
239: * the courier in sync.
240: */
241: static int
242: coursync()
243: {
244: int already = 0;
245: int len;
246: char buf[40];
247:
248: while (already++ < MAXRETRY) {
249: ioctl(FD, TIOCFLUSH, 0); /* flush any clutter */
250: write(FD, "\rAT Z\r", 6); /* reset modem */
251: bzero(buf, sizeof(buf));
252: sleep(1);
253: ioctl(FD, FIONREAD, &len);
254: if (len) {
255: len = read(FD, buf, sizeof(buf));
256: #ifdef DEBUG
257: buf[len] = '\0';
258: printf("coursync: (\"%s\")\n\r", buf);
259: #endif
260: if (index(buf, '0') ||
261: (index(buf, 'O') && index(buf, 'K')))
262: return(1);
263: }
264: /*
265: * If not strapped for DTR control,
266: * try to get command mode.
267: */
268: sleep(1);
269: write(FD, "+++", 3);
270: sleep(1);
271: /*
272: * Toggle DTR to force anyone off that might have left
273: * the modem connected.
274: */
275: ioctl(FD, TIOCCDTR, 0);
276: sleep(1);
277: ioctl(FD, TIOCSDTR, 0);
278: }
279: write(FD, "\rAT Z\r", 6);
280: return (0);
281: }
282:
283: #undef write
284:
285: cour_write(fd, cp, n)
286: int fd;
287: char *cp;
288: int n;
289: {
290: struct sgttyb sb;
291: #ifdef notdef
292: if (boolean(value(VERBOSE)))
293: write(1, cp, n);
294: #endif
295: ioctl(fd, TIOCGETP, &sb);
296: ioctl(fd, TIOCSETP, &sb);
297: cour_nap();
298: for ( ; n-- ; cp++) {
299: write(fd, cp, 1);
300: ioctl(fd, TIOCGETP, &sb);
301: ioctl(fd, TIOCSETP, &sb);
302: cour_nap();
303: }
304: }
305:
306: #ifdef DEBUG
307: verbose_read()
308: {
309: int n = 0;
310: char buf[BUFSIZ];
311:
312: if (ioctl(FD, FIONREAD, &n) < 0)
313: return;
314: if (n <= 0)
315: return;
316: if (read(FD, buf, n) != n)
317: return;
318: write(1, buf, n);
319: }
320: #endif
321:
322: /*
323: * Code stolen from /usr/src/lib/libc/gen/sleep.c
324: */
325: #include <sys/time.h>
326:
327: #define mask(s) (1<<((s)-1))
328: #define setvec(vec, a) \
329: vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0
330:
331: static napms = 50; /* Give the courier 50 milliseconds between characters */
332:
333: static int ringring;
334:
335: cour_nap()
336: {
337:
338: static void cour_napx();
339: int omask;
340: struct itimerval itv, oitv;
341: register struct itimerval *itp = &itv;
342: struct sigvec vec, ovec;
343:
344: timerclear(&itp->it_interval);
345: timerclear(&itp->it_value);
346: if (setitimer(ITIMER_REAL, itp, &oitv) < 0)
347: return;
348: setvec(ovec, SIG_DFL);
349: omask = sigblock(mask(SIGALRM));
350: itp->it_value.tv_sec = napms/1000;
351: itp->it_value.tv_usec = ((napms%1000)*1000);
352: setvec(vec, cour_napx);
353: ringring = 0;
354: (void) sigvec(SIGALRM, &vec, &ovec);
355: (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0);
356: while (!ringring)
357: sigpause(omask &~ mask(SIGALRM));
358: (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
359: (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
360: (void) sigsetmask(omask);
361: }
362:
363: static void
364: cour_napx()
365: {
366: ringring = 1;
367: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.