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