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