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