|
|
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.