|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)condevs.c 5.6 (Berkeley) 8/12/83"; ! 3: #endif ! 4: ! 5: /* ! 6: * Here are various dialers to establish the machine-machine connection. ! 7: * conn.c/condevs.c was glued together by Mike Mitchell. ! 8: * The dialers were supplied by many people, to whom we are grateful. ! 9: * ! 10: * --------------------------------------------------------------------- ! 11: * NOTE: ! 12: * There is a bug that occurs at least on PDP11s due to a limitation of ! 13: * setjmp/longjmp. If the routine that does a setjmp is interrupted ! 14: * and longjmp-ed to, it loses its register variables (on a pdp11). ! 15: * What works is if the routine that does the setjmp ! 16: * calls a routine and it is the *subroutine* that is interrupted. ! 17: * ! 18: * Anyway, in conclusion, condevs.c is plagued with register variables ! 19: * that are used inside ! 20: * if (setjmp(...)) { ! 21: * .... ! 22: * } ! 23: * ! 24: * THE FIX: In dnopn(), for example, delete the 'register' Devices *dev. ! 25: * (That was causing a core dump; deleting register fixed it.) ! 26: * Also for dnopn delete 'register' int dnf... . ! 27: * In pkopn, delete 'register' flds... . ! 28: * There may be others, especially mcm's version of hysopen. ! 29: * You could just delete all references to register, that is safest. ! 30: * This problem might not occur on 4.1bsd, I am not sure. ! 31: * Tom Truscott ! 32: */ ! 33: #include <sys/types.h> ! 34: #include <errno.h> ! 35: #include <setjmp.h> ! 36: #include <signal.h> ! 37: #include <sgtty.h> ! 38: #include "uucp.h" ! 39: ! 40: extern char devSel[]; /* name to pass to delock() in close */ ! 41: extern int errno, next_fd; ! 42: extern jmp_buf Sjbuf; ! 43: extern int alarmtr(); ! 44: int nulldev(), nodev(), Acuopn(), diropn(), dircls(); ! 45: ! 46: #ifdef DATAKIT ! 47: int dkopn(); ! 48: #endif ! 49: #ifdef DN11 ! 50: int dnopn(), dncls(); ! 51: #endif ! 52: #ifdef HAYES ! 53: int hysopn(), hyscls(); ! 54: #endif ! 55: #ifdef HAYESQ ! 56: int hysqopn(), hysqcls(); /* a version of hayes that doesn't use ret codes */ ! 57: #endif ! 58: #ifdef DF02 ! 59: int df2opn(), df2cls(); ! 60: #endif ! 61: #ifdef PNET ! 62: int pnetopn(); ! 63: #endif ! 64: #ifdef VENTEL ! 65: int ventopn(), ventcls(); ! 66: #endif ! 67: #ifdef UNET ! 68: #include <UNET/unetio.h> ! 69: #include <UNET/tcp.h> ! 70: int unetopn(), unetcls(); ! 71: #endif UNET ! 72: #ifdef VADIC ! 73: int vadopn(), vadcls(); ! 74: #endif VADIC ! 75: #ifdef RVMACS ! 76: int rvmacsopn(), rvmacscls(); ! 77: #endif ! 78: #ifdef MICOM ! 79: int micopn(), miccls(); ! 80: #endif MICOM ! 81: ! 82: struct condev condevs[] = { ! 83: { "DIR", "direct", diropn, nulldev, dircls }, ! 84: #ifdef DATAKIT ! 85: { "DK", "datakit", dkopn, nulldev, nulldev }, ! 86: #endif ! 87: #ifdef PNET ! 88: { "PNET", "pnet", pnetopn, nulldev, nulldev }, ! 89: #endif ! 90: #ifdef UNET ! 91: { "UNET", "UNET", unetopn, nulldev, unetcls }, ! 92: #endif UNET ! 93: #ifdef MICOM ! 94: { "MICOM", "micom", micopn, nulldev, miccls }, ! 95: #endif MICOM ! 96: #ifdef DN11 ! 97: { "ACU", "dn11", Acuopn, dnopn, dncls }, ! 98: #endif ! 99: #ifdef HAYES ! 100: { "ACU", "hayes", Acuopn, hysopn, hyscls }, ! 101: #endif HAYES ! 102: #ifdef HAYESQ /* a version of hayes that doesn't use result codes */ ! 103: { "ACU", "hayesq", Acuopn, hysqopn, hysqcls }, ! 104: #endif HATESQ ! 105: #ifdef DF02 ! 106: { "ACU", "DF02", Acuopn, df2opn, df2cls }, ! 107: #endif ! 108: #ifdef VENTEL ! 109: { "ACU", "ventel", Acuopn, ventopn, ventcls }, ! 110: #endif VENTEL ! 111: #ifdef VADIC ! 112: { "ACU", "vadic", Acuopn, vadopn, vadcls }, ! 113: #endif VADIC ! 114: #ifdef RVMACS ! 115: { "ACU", "rvmacs", Acuopn, rvmacsopn, rvmacscls }, ! 116: #endif RVMACS ! 117: ! 118: /* Insert new entries before this line */ ! 119: { NULL, NULL, NULL, NULL, NULL } }; ! 120: ! 121: /*** ! 122: * nulldev a null device (returns CF_DIAL) ! 123: */ ! 124: int nulldev() ! 125: { ! 126: return(CF_DIAL); ! 127: } ! 128: ! 129: /*** ! 130: * nodev a null device (returns CF_NODEV) ! 131: */ ! 132: int nodev() ! 133: { ! 134: return(CF_NODEV); ! 135: } ! 136: ! 137: ! 138: /* ! 139: * The first things in this file are the generic devices. ! 140: * Generic devices look through L-devices and call the CU_open routines for ! 141: * appropriate devices. Some things, like the Unet interface, or direct ! 142: * connect, do not use the CU_open entry. ACUs must search to find the' ! 143: * right routine to call. ! 144: */ ! 145: ! 146: /*** ! 147: * diropn(flds) connect to hardware line ! 148: * char *flds[]; ! 149: * ! 150: * return codes: ! 151: * >0 - file number - ok ! 152: * FAIL - failed ! 153: */ ! 154: ! 155: diropn(flds) ! 156: register char *flds[]; ! 157: { ! 158: register int dcr, status; ! 159: struct Devices dev; ! 160: char dcname[20]; ! 161: FILE *dfp; ! 162: dfp = fopen(DEVFILE, "r"); ! 163: ASSERT(dfp != NULL, "CAN'T OPEN", DEVFILE, 0); ! 164: while ((status = rddev(dfp, &dev)) != FAIL) { ! 165: if (strcmp(flds[F_CLASS], dev.D_class) != SAME) ! 166: continue; ! 167: if (strcmp(flds[F_PHONE], dev.D_line) != SAME) ! 168: continue; ! 169: if (mlock(dev.D_line) != FAIL) ! 170: break; ! 171: } ! 172: fclose(dfp); ! 173: if (status == FAIL) { ! 174: logent("DEVICE", "NO"); ! 175: return(CF_NODEV); ! 176: } ! 177: ! 178: sprintf(dcname, "/dev/%s", dev.D_line); ! 179: if (setjmp(Sjbuf)) { ! 180: delock(dev.D_line); ! 181: return(FAIL); ! 182: } ! 183: signal(SIGALRM, alarmtr); ! 184: alarm(10); ! 185: getnextfd(); ! 186: errno = 0; ! 187: dcr = open(dcname, 2); /* read/write */ ! 188: next_fd = -1; ! 189: if (dcr < 0 && errno == EACCES) ! 190: logent(dcname, "CAN'T OPEN"); ! 191: alarm(0); ! 192: if (dcr < 0) { ! 193: delock(dev.D_line); ! 194: return(FAIL); ! 195: } ! 196: fflush(stdout); ! 197: fixline(dcr, dev.D_speed); ! 198: strcpy(devSel, dev.D_line); /* for latter unlock */ ! 199: CU_end = dircls; ! 200: return(dcr); ! 201: } ! 202: ! 203: dircls(fd) ! 204: register int fd; ! 205: { ! 206: if (fd > 0) { ! 207: close(fd); ! 208: delock(devSel); ! 209: } ! 210: } ! 211: ! 212: #ifdef DATAKIT ! 213: ! 214: #include <dk.h> ! 215: #define DKTRIES 2 ! 216: ! 217: /*** ! 218: * dkopn(flds) make datakit connection ! 219: * ! 220: * return codes: ! 221: * >0 - file number - ok ! 222: * FAIL - failed ! 223: */ ! 224: ! 225: dkopn(flds) ! 226: char *flds[]; ! 227: { ! 228: int dkphone; ! 229: register char *cp; ! 230: register ret, i; ! 231: ! 232: if (setjmp(Sjbuf)) ! 233: return(FAIL); ! 234: ! 235: signal(SIGALRM, alarmtr); ! 236: dkphone = 0; ! 237: cp = flds[F_PHONE]; ! 238: while(*cp) ! 239: dkphone = 10 * dkphone + (*cp++ - '0'); ! 240: DEBUG(4, "dkphone (%d) ", dkphone); ! 241: for (i = 0; i < DKTRIES; i++) { ! 242: getnextfd(); ! 243: ret = dkdial(D_SH, dkphone, 0); ! 244: next_fd = -1; ! 245: DEBUG(4, "dkdial (%d)\n", ret); ! 246: if (ret > -1) ! 247: break; ! 248: } ! 249: return(ret); ! 250: } ! 251: #endif ! 252: ! 253: #ifdef PNET ! 254: /*** ! 255: * pnetopn(flds) ! 256: * ! 257: * call remote machine via Purdue network ! 258: * use dial string as host name, speed as socket number ! 259: * Author: Steve Bellovin ! 260: */ ! 261: ! 262: pnetopn(flds) ! 263: char *flds[]; ! 264: { ! 265: int fd; ! 266: int socket; ! 267: register char *cp; ! 268: ! 269: fd = pnetfile(); ! 270: DEBUG(4, "pnet fd - %d\n", fd); ! 271: if (fd < 0) { ! 272: logent("AVAILABLE DEVICE", "NO"); ! 273: return(CF_NODEV); ! 274: } ! 275: socket = 0; ! 276: for (cp = flds[F_CLASS]; *cp; cp++) ! 277: socket = 10*socket + (*cp - '0'); ! 278: DEBUG(4, "socket - %d\n", socket); ! 279: if (setjmp(Sjbuf)) { ! 280: DEBUG(4, "pnet timeout - %s\n", flds[F_PHONE]); ! 281: return(FAIL); ! 282: } ! 283: signal(SIGALRM, alarmtr); ! 284: DEBUG(4, "host - %s\n", flds[F_PHONE]); ! 285: alarm(15); ! 286: if (pnetscon(fd, flds[F_PHONE], socket) < 0) { ! 287: DEBUG(4, "pnet connect failed - %s\n", flds[F_PHONE]); ! 288: return(FAIL); ! 289: } ! 290: alarm(0); ! 291: return(fd); ! 292: } ! 293: #endif PNET ! 294: ! 295: #ifdef UNET ! 296: /*** ! 297: * unetopn -- make UNET (tcp-ip) connection ! 298: * ! 299: * return codes: ! 300: * >0 - file number - ok ! 301: * FAIL - failed ! 302: */ ! 303: ! 304: /* Default port of uucico server */ ! 305: #define DFLTPORT 33 ! 306: ! 307: unetopn(flds) ! 308: register char *flds[]; ! 309: { ! 310: register int ret, port; ! 311: int unetcls(); ! 312: ! 313: port = atoi(flds[F_PHONE]); ! 314: if (port <= 0 || port > 255) ! 315: port = DFLTPORT; ! 316: DEBUG(4, "unetopn host %s, ", flds[F_NAME]); ! 317: DEBUG(4, "port %d\n", port); ! 318: if (setjmp(Sjbuf)) { ! 319: logent("tcpopen", "TIMEOUT"); ! 320: endhnent(); /* see below */ ! 321: return(CF_DIAL); ! 322: } ! 323: signal(SIGALRM, alarmtr); ! 324: alarm(30); ! 325: ret = tcpopen(flds[F_NAME], port, 0, TO_ACTIVE, "rw"); ! 326: alarm(0); ! 327: endhnent(); /* wave magic wand at 3com and incant "eat it, bruce" */ ! 328: if (ret < 0) { ! 329: DEBUG(5, "tcpopen failed: errno %d\n", errno); ! 330: logent("tcpopen", "FAILED"); ! 331: return(CF_DIAL); ! 332: } ! 333: CU_end = unetcls; ! 334: return(ret); ! 335: } ! 336: ! 337: /* ! 338: * unetcls -- close UNET connection. ! 339: */ ! 340: unetcls(fd) ! 341: register int fd; ! 342: { ! 343: DEBUG(4, "UNET CLOSE called\n", 0); ! 344: if (fd > 0) { ! 345: /* disable this until a timeout is put in ! 346: if (ioctl(fd, UIOCCLOSE, STBNULL)) ! 347: logent("UNET CLOSE", "FAILED"); ! 348: */ ! 349: close(fd); ! 350: DEBUG(4, "closed fd %d\n", fd); ! 351: } ! 352: } ! 353: #endif UNET ! 354: ! 355: #ifdef MICOM ! 356: ! 357: /* ! 358: * micopn: establish connection through a micom. ! 359: * Returns descriptor open to tty for reading and writing. ! 360: * Negative values (-1...-7) denote errors in connmsg. ! 361: * Be sure to disconnect tty when done, via HUPCL or stty 0. ! 362: */ ! 363: micopn(flds) ! 364: register char *flds[]; ! 365: { ! 366: extern errno; ! 367: char *rindex(), *fdig(), dcname[20]; ! 368: int dh, ok = 0, speed; ! 369: register struct condev *cd; ! 370: register FILE *dfp; ! 371: struct Devices dev; ! 372: ! 373: dfp = fopen(DEVFILE, "r"); ! 374: ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); ! 375: ! 376: signal(SIGALRM, alarmtr); ! 377: dh = -1; ! 378: for(cd = condevs; ((cd->CU_meth != NULL)&&(dh < 0)); cd++) { ! 379: if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) { ! 380: fseek(dfp, (off_t)0, 0); ! 381: while(rddev(dfp, &dev) != FAIL) { ! 382: if (strcmp(flds[F_CLASS], dev.D_class) != SAME) ! 383: continue; ! 384: if (snccmp(flds[F_LINE], dev.D_type) != SAME) ! 385: continue; ! 386: if (mlock(dev.D_line) == FAIL) ! 387: continue; ! 388: ! 389: sprintf(dcname, "/dev/%s", dev.D_line); ! 390: getnextfd(); ! 391: alarm(10); ! 392: if (setjmp(Sjbuf)) { ! 393: delock(dev.D_line); ! 394: logent(dev.D_line,"micom open TIMEOUT"); ! 395: dh = -1; ! 396: break; ! 397: } ! 398: dh = open(dcname, 2); ! 399: alarm(0); ! 400: next_fd = -1; ! 401: if (dh > 0) { ! 402: break; ! 403: } ! 404: devSel[0] = '\0'; ! 405: delock(dev.D_line); ! 406: } ! 407: } ! 408: } ! 409: fclose(dfp); ! 410: if (dh < 0) ! 411: return(CF_NODEV); ! 412: ! 413: speed = atoi(fdig(flds[F_CLASS])); ! 414: fixline(dh, speed); ! 415: sleep(1); ! 416: ! 417: /* negotiate with micom */ ! 418: if (speed != 4800) /* damn their eyes! */ ! 419: write(dh, "\r", 1); ! 420: else ! 421: write(dh, " ", 1); ! 422: ! 423: DEBUG(4, "wanted %s ", "NAME"); ! 424: ok = expect("NAME", dh); ! 425: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 426: if (ok == 0) { ! 427: write(dh, flds[F_PHONE], strlen(flds[F_PHONE])); ! 428: sleep(1); ! 429: write(dh, "\r", 1); ! 430: DEBUG(4, "wanted %s ", "GO"); ! 431: ok = expect("GO", dh); ! 432: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 433: } ! 434: ! 435: if (ok != 0) { ! 436: if (dh > 2) ! 437: close(dh); ! 438: DEBUG(4, "micom failed\n", ""); ! 439: delock(dev.D_line); ! 440: return(CF_DIAL); ! 441: } else ! 442: DEBUG(4, "micom ok\n", ""); ! 443: ! 444: CU_end = cd->CU_clos; ! 445: strcat(devSel, dev.D_line); /* for later unlock */ ! 446: return(dh); ! 447: ! 448: } ! 449: ! 450: miccls(fd) ! 451: register int fd; ! 452: { ! 453: ! 454: if (fd > 0) { ! 455: close(fd); ! 456: delock(devSel); ! 457: } ! 458: } ! 459: #endif MICOM ! 460: ! 461: /*** ! 462: * Acuopn - open an ACU and dial the number. The condevs table ! 463: * will be searched until a dialing unit is found that is ! 464: * free. ! 465: * ! 466: * return codes: >0 - file number - o.k. ! 467: * FAIL - failed ! 468: */ ! 469: ! 470: char devSel[20]; /* used for later unlock() */ ! 471: ! 472: Acuopn(flds) ! 473: register char *flds[]; ! 474: { ! 475: char phone[MAXPH+1]; ! 476: register struct condev *cd; ! 477: register int fd; ! 478: register FILE *dfp; ! 479: struct Devices dev; ! 480: ! 481: exphone(flds[F_PHONE], phone); ! 482: devSel[0] = '\0'; ! 483: DEBUG(4, "Dialing %s\n", phone); ! 484: dfp = fopen(DEVFILE, "r"); ! 485: ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); ! 486: ! 487: for(cd = condevs; cd->CU_meth != NULL; cd++) { ! 488: if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) { ! 489: fseek(dfp, (off_t)0, 0); ! 490: while(rddev(dfp, &dev) != FAIL) { ! 491: if (strcmp(flds[F_CLASS], dev.D_class) != SAME) ! 492: continue; ! 493: if (snccmp(flds[F_LINE], dev.D_type) != SAME) ! 494: continue; ! 495: if (dev.D_brand[0] == '\0') ! 496: logent("Acuopn","No 'brand' name on ACU"); ! 497: else if (snccmp(dev.D_brand, cd->CU_brand) != SAME) ! 498: continue; ! 499: if (mlock(dev.D_line) == FAIL) ! 500: continue; ! 501: ! 502: DEBUG(4, "Using %s\n", cd->CU_brand); ! 503: fd = (*(cd->CU_open))(phone, flds, &dev); ! 504: if (fd > 0) { ! 505: CU_end = cd->CU_clos; /* point CU_end at close func */ ! 506: fclose(dfp); ! 507: strcpy(devSel, dev.D_line); /* save for later unlock() */ ! 508: return(fd); ! 509: } ! 510: delock(dev.D_line); ! 511: } ! 512: } ! 513: } ! 514: fclose(dfp); ! 515: return(FAIL); ! 516: } ! 517: ! 518: #ifdef DN11 ! 519: ! 520: /*** ! 521: * dnopn(ph, flds, dev) dial remote machine ! 522: * char *ph; ! 523: * char *flds[]; ! 524: * struct Devices *dev; ! 525: * ! 526: * return codes: ! 527: * file descriptor - succeeded ! 528: * FAIL - failed ! 529: */ ! 530: ! 531: dnopn(ph, flds, dev) ! 532: char *ph; ! 533: char *flds[]; ! 534: struct Devices *dev; ! 535: { ! 536: char dcname[20], dnname[20], phone[MAXPH+2], c = 0; ! 537: #ifdef SYSIII ! 538: struct termio ttbuf; ! 539: #endif ! 540: int dnf, dcf; ! 541: int nw, lt, pid, status; ! 542: unsigned timelim; ! 543: ! 544: sprintf(dnname, "/dev/%s", dev->D_calldev); ! 545: errno = 0; ! 546: ! 547: if (setjmp(Sjbuf)) { ! 548: logent(dnname, "CAN'T OPEN"); ! 549: DEBUG(4, "%s Open timed out\n", dnname); ! 550: return(CF_NODEV); ! 551: } ! 552: signal(SIGALRM, alarmtr); ! 553: getnextfd(); ! 554: alarm(10); ! 555: dnf = open(dnname, 1); ! 556: alarm(0); ! 557: next_fd = -1; ! 558: if (dnf < 0 && errno == EACCES) { ! 559: logent(dnname, "CAN'T OPEN"); ! 560: logent("DEVICE", "NO"); ! 561: return(CF_NODEV); ! 562: } ! 563: /* rti!trt: avoid passing acu file descriptor to children */ ! 564: fioclex(dnf); ! 565: ! 566: sprintf(dcname, "/dev/%s", dev->D_line); ! 567: sprintf(phone, "%s%s", ph, ACULAST); ! 568: DEBUG(4, "dc - %s, ", dcname); ! 569: DEBUG(4, "acu - %s\n", dnname); ! 570: pid = 0; ! 571: if (setjmp(Sjbuf)) { ! 572: logent("DIALUP DN write", "TIMEOUT"); ! 573: if (pid) ! 574: kill(pid, 9); ! 575: delock(dev->D_line); ! 576: if (dnf) ! 577: close(dnf); ! 578: return(FAIL); ! 579: } ! 580: signal(SIGALRM, alarmtr); ! 581: timelim = 5 * strlen(phone); ! 582: alarm(timelim < 30 ? 30 : timelim); ! 583: if ((pid = fork()) == 0) { ! 584: sleep(2); ! 585: fclose(stdin); ! 586: fclose(stdout); ! 587: #ifdef TIOCFLUSH ! 588: ioctl(dnf, TIOCFLUSH, STBNULL); ! 589: #endif ! 590: nw = write(dnf, phone, lt = strlen(phone)); ! 591: if (nw != lt) { ! 592: logent("DIALUP ACU write", "FAILED"); ! 593: exit(1); ! 594: } ! 595: DEBUG(4, "ACU write ok%s\n", ""); ! 596: exit(0); ! 597: } ! 598: /* open line - will return on carrier */ ! 599: /* RT needs a sleep here because it returns immediately from open */ ! 600: ! 601: #if RT ! 602: sleep(15); ! 603: #endif ! 604: ! 605: getnextfd(); ! 606: errno = 0; ! 607: dcf = open(dcname, 2); ! 608: next_fd = -1; ! 609: if (dcf < 0 && errno == EACCES) ! 610: logent(dcname, "CAN'T OPEN"); ! 611: DEBUG(4, "dcf is %d\n", dcf); ! 612: if (dcf < 0) { ! 613: logent("DIALUP LINE open", "FAILED"); ! 614: alarm(0); ! 615: kill(pid, 9); ! 616: close(dnf); ! 617: delock(dev->D_line); ! 618: return(FAIL); ! 619: } ! 620: /* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */ ! 621: /* ioctl(dcf, TIOCHPCL, STBNULL);*/ ! 622: while ((nw = wait(<)) != pid && nw != -1) ! 623: ; ! 624: #ifdef SYSIII ! 625: ioctl(dcf, TCGETA, &ttbuf); ! 626: if(!(ttbuf.c_cflag & HUPCL)) { ! 627: ttbuf.c_cflag |= HUPCL; ! 628: ioctl(dcf, TCSETA, &ttbuf); ! 629: } ! 630: #endif ! 631: alarm(0); ! 632: fflush(stdout); ! 633: fixline(dcf, dev->D_speed); ! 634: DEBUG(4, "Fork Stat %o\n", lt); ! 635: if (lt != 0) { ! 636: close(dcf); ! 637: if (dnf) ! 638: close(dnf); ! 639: delock(dev->D_line); ! 640: return(FAIL); ! 641: } ! 642: return(dcf); ! 643: } ! 644: ! 645: /*** ! 646: * dncls() close dn type call unit ! 647: * ! 648: * return codes: None ! 649: */ ! 650: dncls(fd) ! 651: register int fd; ! 652: { ! 653: if (fd > 0) { ! 654: close(fd); ! 655: sleep(5); ! 656: delock(devSel); ! 657: } ! 658: } ! 659: #endif DN11 ! 660: ! 661: #ifdef DF02 ! 662: /*** ! 663: * df2opn(ph, flds, dev) dial remote machine ! 664: * char *ph; ! 665: * char *flds[]; ! 666: * struct Devices *dev; ! 667: * ! 668: * return codes: ! 669: * file descriptor - succeeded ! 670: * FAIL - failed ! 671: * ! 672: * Modified 9/28/81 by Bill Shannon (DEC) ! 673: * Changed to use DEC DF02 or DF03 ACU ! 674: */ ! 675: ! 676: ! 677: df2opn(ph, flds, dev) ! 678: char *ph; ! 679: char *flds[]; ! 680: struct Devices *dev; ! 681: { ! 682: char dcname[20], dnname[20], phone[MAXPH+2], c = 0; ! 683: #ifdef SYSIII ! 684: struct termio ttbuf; ! 685: #endif ! 686: int dcf, dnf; ! 687: int nw, lt, pid, st, status; ! 688: unsigned timelim; ! 689: ! 690: sprintf(dnname, "/dev/%s", dev->D_calldev); ! 691: if (setjmp(Sjbuf)) { ! 692: logent(dnname, "CAN'T OPEN"); ! 693: DEBUG(4, "%s Open timed out\n", dnname); ! 694: return(CF_NODEV); ! 695: } ! 696: signal(SIGALRM, alarmtr); ! 697: getnextfd(); ! 698: errno = 0; ! 699: alarm(10); ! 700: dnf = open(dnname, 2 ); ! 701: alarm(0); ! 702: next_fd = -1; ! 703: if (dnf < 0 && errno == EACCES) { ! 704: logent(dnname, "CAN'T OPEN"); ! 705: delock(dev->D_line); ! 706: logent("DEVICE", "NO"); ! 707: return(CF_NODEV); ! 708: } ! 709: /* rti!trt: avoid passing acu file descriptor to children */ ! 710: fioclex(dnf); ! 711: ! 712: sprintf(dcname, "/dev/%s", dev->D_line); ! 713: fixline(dnf, dev->D_speed); ! 714: sprintf(phone, "\02%s", ph); ! 715: DEBUG(4, "dc - %s, ", dcname); ! 716: DEBUG(4, "acu - %s\n", dnname); ! 717: pid = 0; ! 718: if (setjmp(Sjbuf)) { ! 719: logent("DIALUP DN write", "TIMEOUT"); ! 720: if (pid) ! 721: kill(pid, 9); ! 722: delock(dev->D_line); ! 723: if (dnf) ! 724: close(dnf); ! 725: return(FAIL); ! 726: } ! 727: signal(SIGALRM, alarmtr); ! 728: timelim = 5 * strlen(phone); ! 729: alarm(timelim < 30 ? 30 : timelim); ! 730: if ((pid = fork()) == 0) { ! 731: sleep(2); ! 732: fclose(stdin); ! 733: fclose(stdout); ! 734: #ifdef TIOCFLUSH ! 735: ioctl(dnf, TIOCFLUSH, STBNULL); ! 736: #endif ! 737: write(dnf, "\01", 1); ! 738: sleep(1); ! 739: nw = write(dnf, phone, lt = strlen(phone)); ! 740: if (nw != lt) { ! 741: logent("DIALUP ACU write", "FAILED"); ! 742: exit(1); ! 743: } ! 744: DEBUG(4, "ACU write ok%s\n", ""); ! 745: exit(0); ! 746: } ! 747: /* open line - will return on carrier */ ! 748: /* RT needs a sleep here because it returns immediately from open */ ! 749: ! 750: #if RT ! 751: sleep(15); ! 752: #endif ! 753: ! 754: if (read(dnf, &c, 1) != 1 || c != 'A') ! 755: dcf = -1; ! 756: else ! 757: dcf = 0; ! 758: DEBUG(4, "dcf is %d\n", dcf); ! 759: if (dcf < 0) { ! 760: logent("DIALUP LINE open", "FAILED"); ! 761: alarm(0); ! 762: kill(pid, 9); ! 763: close(dnf); ! 764: delock(dev->D_line); ! 765: return(FAIL); ! 766: } ! 767: dcf = dnf; ! 768: dnf = 0; ! 769: /* brl-bmd.351 (Doug Kingston) says the next ioctl is unneeded . */ ! 770: /* ioctl(dcf, TIOCHPCL, STBNULL);*/ ! 771: while ((nw = wait(<)) != pid && nw != -1) ! 772: ; ! 773: #ifdef SYSIII ! 774: ioctl(dcf, TCGETA, &ttbuf); ! 775: if(!(ttbuf.c_cflag & HUPCL)) { ! 776: ttbuf.c_cflag |= HUPCL; ! 777: ioctl(dcf, TCSETA, &ttbuf); ! 778: } ! 779: #endif ! 780: alarm(0); ! 781: fflush(stdout); ! 782: fixline(dcf, dev->D_speed); ! 783: DEBUG(4, "Fork Stat %o\n", lt); ! 784: if (lt != 0) { ! 785: close(dcf); ! 786: if (dnf) ! 787: close(dnf); ! 788: delock(dev->D_line); ! 789: return(FAIL); ! 790: } ! 791: return(dcf); ! 792: } ! 793: ! 794: /* ! 795: * df2cls() close the DF02/DF03 call unit ! 796: * ! 797: * return codes: none ! 798: */ ! 799: ! 800: df2cls(fd) ! 801: register int fd; ! 802: { ! 803: if (fd > 0) { ! 804: close(fd); ! 805: sleep(5); ! 806: delock(devSel); ! 807: } ! 808: } ! 809: #endif DF02 ! 810: ! 811: #ifdef HAYES ! 812: /*** ! 813: * hysopn(telno, flds, dev) connect to hayes smartmodem ! 814: * char *flds[], *dev[]; ! 815: * ! 816: * return codes: ! 817: * >0 - file number - ok ! 818: * CF_DIAL,CF_DEVICE - failed ! 819: */ ! 820: /* ! 821: * Define HAYSTONE if you have touch tone dialing. ! 822: */ ! 823: /*#define HAYSTONE */ ! 824: ! 825: hysopn(telno, flds, dev) ! 826: char *telno; ! 827: char *flds[]; ! 828: struct Devices *dev; ! 829: { ! 830: int dh = -1; ! 831: extern errno; ! 832: char dcname[20]; ! 833: ! 834: sprintf(dcname, "/dev/%s", dev->D_line); ! 835: DEBUG(4, "dc - %s\n", dcname); ! 836: if (setjmp(Sjbuf)) { ! 837: DEBUG(1, "timeout hayes open %s\n", dcname); ! 838: logent("hayes open", "TIMEOUT"); ! 839: if (dh >= 0) ! 840: close(dh); ! 841: delock(dev->D_line); ! 842: return(CF_DIAL); ! 843: } ! 844: signal(SIGALRM, alarmtr); ! 845: getnextfd(); ! 846: alarm(10); ! 847: dh = open(dcname, 2); /* read/write */ ! 848: alarm(0); ! 849: ! 850: /* modem is open */ ! 851: next_fd = -1; ! 852: if (dh >= 0) { ! 853: fixline(dh, dev->D_speed); ! 854: #ifdef HAYSTONE ! 855: write(dh, "\rATDT", 5); ! 856: #else ! 857: write(dh, "\rATDP", 5); ! 858: #endif ! 859: write(dh, telno, strlen(telno)); ! 860: write(dh, "\r", 1); ! 861: ! 862: if (expect("CONNECT", dh) != 0) { ! 863: logent("HSM no carrier", "FAILED"); ! 864: strcpy(devSel, dev->D_line); ! 865: hyscls(dh); ! 866: return(CF_DIAL); ! 867: } ! 868: ! 869: } ! 870: if (dh < 0) { ! 871: DEBUG(4, "hayes failed\n", ""); ! 872: delock(dev->D_line); ! 873: } ! 874: DEBUG(4, "hayes ok\n", ""); ! 875: return(dh); ! 876: } ! 877: ! 878: hyscls(fd) ! 879: int fd; ! 880: { ! 881: char dcname[20]; ! 882: struct sgttyb hup, sav; ! 883: ! 884: if (fd > 0) { ! 885: sprintf(dcname, "/dev/%s", devSel); ! 886: DEBUG(4, "Hanging up fd = %d\n", fd); ! 887: /* ! 888: * code to drop DTR -- change to 0 baud then back to default. ! 889: */ ! 890: gtty(fd, &hup); ! 891: gtty(fd, &sav); ! 892: hup.sg_ispeed = B0; ! 893: hup.sg_ospeed = B0; ! 894: stty(fd, &hup); ! 895: sleep(2); ! 896: stty(fd, &sav); ! 897: /* ! 898: * now raise DTR -- close the device & open it again. ! 899: */ ! 900: sleep(2); ! 901: close(fd); ! 902: sleep(2); ! 903: fd = open(dcname, 2); ! 904: /* ! 905: * Since we have a getty sleeping on this line, when it wakes up it sends ! 906: * all kinds of garbage to the modem. Unfortunatly, the modem likes to ! 907: * execute the previous command when it sees the garbage. The previous ! 908: * command was to dial the phone, so let's make the last command reset ! 909: * the modem. ! 910: */ ! 911: sleep(2); ! 912: write(fd, "\rATZ\r", 5); ! 913: close(fd); ! 914: delock(devSel); ! 915: } ! 916: } ! 917: ! 918: #endif HAYES ! 919: ! 920: #ifdef HAYESQ ! 921: /* ! 922: * New dialout routine to work with Hayes' SMART MODEM ! 923: * 13-JUL-82, Mike Mitchell ! 924: * Modified 23-MAR-83 to work with Tom Truscott's (rti!trt) ! 925: * version of UUCP (ncsu!mcm) ! 926: * ! 927: * The modem should be set to NOT send any result codes to ! 928: * the system (switch 3 up, 4 down). This end will figure out ! 929: * what is wrong. ! 930: * ! 931: * I had lots of problems with the modem sending ! 932: * result codes since I am using the same modem for both incomming and ! 933: * outgoing calls. I'd occasionally miss the result code (getty would ! 934: * grab it), and the connect would fail. Worse yet, the getty would ! 935: * think the result code was a user name, and send garbage to it while ! 936: * it was in the command state. I turned off ALL result codes, and hope ! 937: * for the best. 99% of the time the modem is in the correct state. ! 938: * Occassionally it doesn't connect, or the phone was busy, etc., and ! 939: * uucico sits there trying to log in. It eventually times out, calling ! 940: * clsacu() in the process, so it resets itself for the next attempt. ! 941: */ ! 942: ! 943: /* ! 944: * Define HAYSTONE if touch-tone dialing is to be used. If it is not defined, ! 945: * Pulse dialing is assumed. ! 946: */ ! 947: /*#define HAYSTONE*/ ! 948: ! 949: hysqopn(telno, flds, dev) ! 950: char *telno, *flds[]; ! 951: struct Devices *dev; ! 952: { ! 953: char dcname[20], phone[MAXPH+10], c = 0; ! 954: #ifdef SYSIII ! 955: struct termio ttbuf; ! 956: #endif ! 957: int status, dnf; ! 958: unsigned timelim; ! 959: ! 960: signal(SIGALRM, alarmtr); ! 961: sprintf(dcname, "/dev/%s", dev->D_line); ! 962: ! 963: getnextfd(); ! 964: if (setjmp(Sjbuf)) { ! 965: delock(dev->D_line); ! 966: logent("DEVICE", "NO"); ! 967: DEBUG(4, "Open timed out %s", dcname); ! 968: return(CF_NODEV); ! 969: } ! 970: alarm(10); ! 971: ! 972: if ((dnf = open(dcname, 2)) <= 0) { ! 973: delock(dev->D_line); ! 974: logent("DEVICE", "NO"); ! 975: DEBUG(4, "Can't open %s", dcname); ! 976: return(CF_NODEV); ! 977: } ! 978: ! 979: alarm(0); ! 980: next_fd = -1; ! 981: fixline(dnf, dev->D_speed); ! 982: DEBUG(4, "Hayes port - %s, ", dcname); ! 983: ! 984: #ifdef HAYSTONE ! 985: sprintf(phone, "\rATDT%s\r", telno); ! 986: #else ! 987: sprintf(phone, "\rATDP%s\r", telno); ! 988: #endif ! 989: ! 990: write(dnf, phone, strlen(phone)); ! 991: ! 992: /* calculate delay time for the other system to answer the phone. ! 993: * Default is 15 seconds, add 2 seconds for each comma in the phone ! 994: * number. ! 995: */ ! 996: timelim = 150; ! 997: while(*telno) { ! 998: c = *telno++; ! 999: if (c == ',') ! 1000: timelim += 20; ! 1001: else { ! 1002: #ifdef HAYSTONE ! 1003: timelim += 2; /* .2 seconds per tone */ ! 1004: } ! 1005: #else ! 1006: if (c == '0') timelim += 10; /* .1 second per digit */ ! 1007: else if (c > '0' && c <= '9') ! 1008: timelim += (c - '0'); ! 1009: } ! 1010: #endif ! 1011: } ! 1012: alarm(timelim/10); ! 1013: if (setjmp(Sjbuf) == 0) { ! 1014: read(dnf, &c, 1); ! 1015: alarm(0); ! 1016: } ! 1017: ! 1018: return(dnf); ! 1019: } ! 1020: ! 1021: hysqcls(fd) ! 1022: int fd; ! 1023: { ! 1024: char dcname[20]; ! 1025: struct sgttyb hup, sav; ! 1026: ! 1027: if (fd > 0) { ! 1028: sprintf(dcname, "/dev/%s", devSel); ! 1029: DEBUG(4, "Hanging up fd = %d\n", fd); ! 1030: /* ! 1031: * code to drop DTR -- change to 0 baud then back to default. ! 1032: */ ! 1033: gtty(fd, &hup); ! 1034: gtty(fd, &sav); ! 1035: hup.sg_ispeed = B0; ! 1036: hup.sg_ospeed = B0; ! 1037: stty(fd, &hup); ! 1038: sleep(2); ! 1039: stty(fd, &sav); ! 1040: /* ! 1041: * now raise DTR -- close the device & open it again. ! 1042: */ ! 1043: sleep(2); ! 1044: close(fd); ! 1045: sleep(2); ! 1046: fd = open(dcname, 2); ! 1047: /* ! 1048: * Since we have a getty sleeping on this line, when it wakes up it sends ! 1049: * all kinds of garbage to the modem. Unfortunatly, the modem likes to ! 1050: * execute the previous command when it sees the garbage. The previous ! 1051: * command was to dial the phone, so let's make the last command reset ! 1052: * the modem. ! 1053: */ ! 1054: sleep(2); ! 1055: write(fd, "\rATZ\r", 5); ! 1056: close(fd); ! 1057: delock(devSel); ! 1058: } ! 1059: } ! 1060: ! 1061: #endif HAYESQ ! 1062: ! 1063: #ifdef VENTEL ! 1064: ventopn(telno, flds, dev) ! 1065: char *flds[], *telno; ! 1066: struct Devices *dev; ! 1067: { ! 1068: int dh; ! 1069: int i, ok = -1; ! 1070: char dcname[20]; ! 1071: ! 1072: sprintf(dcname, "/dev/%s", dev->D_line); ! 1073: if (setjmp(Sjbuf)) { ! 1074: DEBUG(1, "timeout ventel open\n", ""); ! 1075: logent("ventel open", "TIMEOUT"); ! 1076: if (dh >= 0) ! 1077: close(dh); ! 1078: delock(dev->D_line); ! 1079: return(CF_NODEV); ! 1080: } ! 1081: signal(SIGALRM, alarmtr); ! 1082: getnextfd(); ! 1083: alarm(10); ! 1084: dh = open(dcname, 2); ! 1085: next_fd = -1; ! 1086: if (dh < 0) { ! 1087: DEBUG(4,"%s\n", errno == 4 ? "no carrier" : "can't open modem"); ! 1088: delock(dev->D_line); ! 1089: return(errno == 4 ? CF_DIAL : CF_NODEV); ! 1090: } ! 1091: ! 1092: /* modem is open */ ! 1093: fixline(dh, dev->D_speed); ! 1094: ! 1095: /* translate - to % and = to & for VenTel */ ! 1096: DEBUG(4, "calling %s -> ", telno); ! 1097: for (i = 0; i < strlen(telno); ++i) { ! 1098: switch(telno[i]) { ! 1099: case '-': /* delay */ ! 1100: telno[i] = '%'; ! 1101: break; ! 1102: case '=': /* await dial tone */ ! 1103: telno[i] = '&'; ! 1104: break; ! 1105: case '<': ! 1106: telno[i] = '%'; ! 1107: break; ! 1108: } ! 1109: } ! 1110: DEBUG(4, "%s\n", telno); ! 1111: sleep(1); ! 1112: for(i = 0; i < 5; ++i) { /* make up to 5 tries */ ! 1113: slowrite(dh, "\r\r");/* awake, thou lowly VenTel! */ ! 1114: ! 1115: DEBUG(4, "wanted %s ", "$"); ! 1116: ok = expect("$", dh); ! 1117: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1118: if (ok != 0) ! 1119: continue; ! 1120: slowrite(dh, "K"); /* "K" (enter number) command */ ! 1121: DEBUG(4, "wanted %s ", "DIAL: "); ! 1122: ok = expect("DIAL: ", dh); ! 1123: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1124: if (ok == 0) ! 1125: break; ! 1126: } ! 1127: ! 1128: if (ok == 0) { ! 1129: slowrite(dh, telno); /* send telno, send \r */ ! 1130: slowrite(dh, "\r"); ! 1131: DEBUG(4, "wanted %s ", "ONLINE"); ! 1132: ok = expect("ONLINE!", dh); ! 1133: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1134: } ! 1135: if (ok != 0) { ! 1136: if (dh > 2) ! 1137: close(dh); ! 1138: DEBUG(4, "venDial failed\n", ""); ! 1139: return(CF_DIAL); ! 1140: } else ! 1141: DEBUG(4, "venDial ok\n", ""); ! 1142: return(dh); ! 1143: } ! 1144: ! 1145: ! 1146: /* ! 1147: * uucpdelay: delay execution for numerator/denominator seconds. ! 1148: */ ! 1149: ! 1150: #ifdef INTERVALTIMER ! 1151: #define uucpdelay(num,denom) intervaldelay(1000000*num/denom) ! 1152: #include <sys/time.h> ! 1153: catch alarm sig ! 1154: SIGALRM ! 1155: struct itimerval itimerval; ! 1156: itimerval.itimer_reload = ! 1157: itimerval.rtime.itimer_interval = ! 1158: itimerval.rtime.itimer_value = ! 1159: settimer(ITIMER_REAL, &itimerval); ! 1160: pause(); ! 1161: alarm comes in ! 1162: turn off timer. ! 1163: #endif INTERVALTIMER ! 1164: ! 1165: #ifdef FASTTIMER ! 1166: #define uucpdelay(num,denom) nap(60*num/denom) ! 1167: /* Sleep in increments of 60ths of second. */ ! 1168: nap (time) ! 1169: register int time; ! 1170: { ! 1171: static int fd; ! 1172: ! 1173: if (fd == 0) ! 1174: fd = open (FASTTIMER, 0); ! 1175: ! 1176: read (fd, 0, time); ! 1177: } ! 1178: #endif FASTTIMER ! 1179: ! 1180: #ifdef FTIME ! 1181: #define uucpdelay(num,denom) ftimedelay(1000*num/denom) ! 1182: #include <sys/timeb.h> ! 1183: ftimedelay(n) ! 1184: { ! 1185: static struct timeb loctime; ! 1186: ftime(&loctime); ! 1187: {register i = loctime.millitm; ! 1188: while (abs((int)(loctime.millitm - i))<n) ftime(&loctime); ! 1189: } ! 1190: } ! 1191: #endif FTIME ! 1192: ! 1193: #ifdef BUSYLOOP ! 1194: #define uucpdelay(num,denom) busyloop(CPUSPEED*num/denom) ! 1195: #define CPUSPEED 1000000 /* VAX 780 is 1MIPS */ ! 1196: #define DELAY(n) { register long N = (n); while (--N > 0); } ! 1197: busyloop(n) ! 1198: { ! 1199: DELAY(n); ! 1200: } ! 1201: #endif BUSYLOOP ! 1202: ! 1203: slowrite(fd, str) ! 1204: register char *str; ! 1205: { ! 1206: DEBUG(6, "slowrite ", ""); ! 1207: while (*str) { ! 1208: DEBUG(6, "%c", *str); ! 1209: uucpdelay(1,10); /* delay 1/10 second */ ! 1210: write(fd, str, 1); ! 1211: str++; ! 1212: } ! 1213: DEBUG(6, "\n", ""); ! 1214: } ! 1215: ! 1216: ! 1217: ventcls(fd) ! 1218: int fd; ! 1219: { ! 1220: ! 1221: if (fd > 0) { ! 1222: close(fd); ! 1223: sleep(5); ! 1224: delock(devSel); ! 1225: } ! 1226: } ! 1227: #endif VENTEL ! 1228: ! 1229: #ifdef VADIC ! 1230: ! 1231: /* ! 1232: * vadopn: establish dial-out connection through a Racal-Vadic 3450. ! 1233: * Returns descriptor open to tty for reading and writing. ! 1234: * Negative values (-1...-7) denote errors in connmsg. ! 1235: * Be sure to disconnect tty when done, via HUPCL or stty 0. ! 1236: */ ! 1237: ! 1238: vadopn(telno, flds, dev) ! 1239: char *telno; ! 1240: char *flds[]; ! 1241: struct Devices *dev; ! 1242: { ! 1243: int dh = -1; ! 1244: int i, ok, er = 0, delay; ! 1245: extern errno; ! 1246: char dcname[20]; ! 1247: ! 1248: sprintf(dcname, "/dev/%s", dev->D_line); ! 1249: if (setjmp(Sjbuf)) { ! 1250: DEBUG(1, "timeout vadic open\n", ""); ! 1251: logent("vadic open", "TIMEOUT"); ! 1252: if (dh >= 0) ! 1253: close(dh); ! 1254: delock(dev->D_line); ! 1255: return(CF_NODEV); ! 1256: } ! 1257: signal(SIGALRM, alarmtr); ! 1258: getnextfd(); ! 1259: alarm(10); ! 1260: dh = open(dcname, 2); ! 1261: alarm(0); ! 1262: ! 1263: /* modem is open */ ! 1264: next_fd = -1; ! 1265: if (dh < 0) { ! 1266: delock(dev->D_line); ! 1267: return(CF_NODEV); ! 1268: } ! 1269: fixline(dh, dev->D_speed); ! 1270: ! 1271: /* translate - to K for Vadic */ ! 1272: DEBUG(4, "calling %s -> ", telno); ! 1273: delay = 0; ! 1274: for (i = 0; i < strlen(telno); ++i) { ! 1275: switch(telno[i]) { ! 1276: case '=': /* await dial tone */ ! 1277: case '-': /* delay */ ! 1278: case '<': ! 1279: telno[i] = 'K'; ! 1280: delay += 5; ! 1281: break; ! 1282: } ! 1283: } ! 1284: DEBUG(4, "%s\n", telno); ! 1285: for(i = 0; i < 5; ++i) { /* make 5 tries */ ! 1286: /* wake up Vadic */ ! 1287: sendthem("\005\\d", dh); ! 1288: DEBUG(4, "wanted %s ", "*"); ! 1289: ok = expect("*", dh); ! 1290: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1291: if (ok != 0) ! 1292: continue; ! 1293: ! 1294: sendthem("D\\d", dh); /* "D" (enter number) command */ ! 1295: DEBUG(4, "wanted %s ", "NUMBER?\\r\\n"); ! 1296: ok = expect("NUMBER?\r\n", dh); ! 1297: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1298: if (ok != 0) ! 1299: continue; ! 1300: ! 1301: /* send telno, send \r */ ! 1302: sendthem(telno, dh); ! 1303: ok = expect(telno, dh); ! 1304: if (ok == 0) ! 1305: ok = expect("\r\n", dh); ! 1306: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1307: if (ok != 0) ! 1308: continue; ! 1309: ! 1310: sendthem("", dh); /* confirm number */ ! 1311: DEBUG(4, "wanted %s ", "DIALING: "); ! 1312: ok = expect("DIALING: ", dh); ! 1313: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1314: if (ok == 0) ! 1315: break; ! 1316: } ! 1317: ! 1318: if (ok == 0) { ! 1319: sleep(10 + delay); /* give vadic some time */ ! 1320: DEBUG(4, "wanted ON LINE\\r\\n ", 0); ! 1321: ok = expect("ON LINE\r\n", dh); ! 1322: DEBUG(4, "got %s\n", ok ? "?" : "that"); ! 1323: } ! 1324: ! 1325: if (ok != 0) { ! 1326: sendthem("I\\d", dh); /* back to idle */ ! 1327: if (dh > 2) ! 1328: close(dh); ! 1329: DEBUG(4, "vadDial failed\n", ""); ! 1330: delock(dev->D_line); ! 1331: return(CF_DIAL); ! 1332: } ! 1333: DEBUG(4, "vadic ok\n", ""); ! 1334: return(dh); ! 1335: } ! 1336: ! 1337: vadcls(fd) { ! 1338: ! 1339: if (fd > 0) { ! 1340: close(fd); ! 1341: sleep(5); ! 1342: delock(devSel); ! 1343: } ! 1344: } ! 1345: ! 1346: #endif VADIC ! 1347: ! 1348: #ifdef RVMACS ! 1349: /* ! 1350: * Racal-Vadic 'RV820' MACS system with 831 adaptor. ! 1351: * A typical 300 baud L-devices entry is ! 1352: * ACU /dev/tty10 /dev/tty11,48 300 rvmacs ! 1353: * where tty10 is the communication line (D_Line), ! 1354: * tty11 is the dialer line (D_calldev), ! 1355: * the '4' is the dialer address + modem type (viz. dialer 0, Bell 103), ! 1356: * and the '8' is the communication port (they are 1-indexed). ! 1357: * BUGS: ! 1358: * Only tested with one dialer, one modem ! 1359: * uses common speed for dialer and communication line. ! 1360: * UNTESTED ! 1361: */ ! 1362: ! 1363: #define STX 02 /* Access Adaptor */ ! 1364: #define ETX 03 /* Transfer to Dialer */ ! 1365: #define SI 017 /* Buffer Empty (end of phone number) */ ! 1366: #define SOH 01 /* Abort */ ! 1367: ! 1368: rvmacsopn(ph, flds, dev) ! 1369: char *ph, *flds[]; ! 1370: struct Devices *dev; ! 1371: { ! 1372: register int va, i, child; ! 1373: register char *p; ! 1374: char c, acu[20], com[20]; ! 1375: ! 1376: child = -1; ! 1377: if ((p = index(dev->D_calldev, ',')) == NULL) { ! 1378: DEBUG(2, "No dialer/modem specification\n", 0); ! 1379: goto failret; ! 1380: } ! 1381: *p++ = '\0'; ! 1382: if (setjmp(Sjbuf)) { ! 1383: logent("rvmacsopn", "TIMEOUT"); ! 1384: i = CF_DIAL; ! 1385: goto ret; ! 1386: } ! 1387: DEBUG(4, "STARTING CALL\n", 0); ! 1388: sprintf(acu, "/dev/%s", dev->D_calldev); ! 1389: getnextfd(); ! 1390: signal(SIGALRM, alarmtr); ! 1391: alarm(30); ! 1392: if ((va = open(acu, 2)) < 0) { ! 1393: logent(acu, "CAN'T OPEN"); ! 1394: i = CF_NODEV; ! 1395: goto ret; ! 1396: } ! 1397: fixline(va, dev->D_speed); ! 1398: ! 1399: p_chwrite(va, STX); /* access adaptor */ ! 1400: i = *p++ - '0'; ! 1401: if (i < 0 || i > 7) { ! 1402: logent(p-1, "Bad dialer address/modem type\n"); ! 1403: goto failret; ! 1404: } ! 1405: p_chwrite(va, i); /* Send Dialer Address Digit */ ! 1406: i = *p - '0'; ! 1407: if (i <= 0 || i > 14) { ! 1408: logent(p-1, "Bad modem address\n"); ! 1409: goto failret; ! 1410: } ! 1411: p_chwrite(va, i-1); /* Send Modem Address Digit */ ! 1412: write(va, ph, strlen(ph)); /* Send Phone Number */ ! 1413: p_chwrite(va, SI); /* Send Buffer Empty */ ! 1414: p_chwrite(va, ETX); /* Initiate Call */ ! 1415: sprintf(com, "/dev/%s", dev->D_line); ! 1416: ! 1417: /* create child to open comm line */ ! 1418: if ((child = fork()) == 0) { ! 1419: signal(SIGINT, SIG_DFL); ! 1420: open(com, 0); ! 1421: sleep(5); ! 1422: exit(1); ! 1423: } ! 1424: ! 1425: if (read(va, &c, 1) != 1) { ! 1426: logent("ACU READ", "FAILED"); ! 1427: goto failret; ! 1428: } ! 1429: switch(c) { ! 1430: case 'A': ! 1431: /* Fine! */ ! 1432: break; ! 1433: case 'B': ! 1434: DEBUG(2, "CALL ABORTED\n", 0); ! 1435: goto failret; ! 1436: case 'D': ! 1437: DEBUG(2, "Dialer format error\n", 0); ! 1438: goto failret; ! 1439: case 'E': ! 1440: DEBUG(2, "Dialer parity error\n", 0); ! 1441: goto failret; ! 1442: case 'F': ! 1443: DEBUG(2, "Phone number too long\n", 0); ! 1444: goto failret; ! 1445: case 'G': ! 1446: DEBUG(2, "Busy signal\n", 0); ! 1447: goto failret; ! 1448: default: ! 1449: DEBUG(2, "Unknown MACS return code '%c'\n", i); ! 1450: goto failret; ! 1451: } ! 1452: /* ! 1453: * open line - will return on carrier ! 1454: */ ! 1455: if ((i = open(com, 2)) < 0) { ! 1456: if (errno == EIO) ! 1457: logent("carrier", "LOST"); ! 1458: else ! 1459: logent("dialup open", "FAILED"); ! 1460: goto failret; ! 1461: } ! 1462: fixline(i, dev->D_speed); ! 1463: goto ret; ! 1464: failret: ! 1465: i = CF_DIAL; ! 1466: ret: ! 1467: alarm(0); ! 1468: if (child != -1) ! 1469: kill(child, SIGKILL); ! 1470: close(va); ! 1471: return(i); ! 1472: } ! 1473: ! 1474: rvmacscls(fd) ! 1475: register int fd; ! 1476: { ! 1477: DEBUG(2, "MACS close %d\n", fd); ! 1478: p_chwrite(fd, SOH); ! 1479: /* ioctl(fd, TIOCCDTR, NULL);*/ ! 1480: close(fd); ! 1481: } ! 1482: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.