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