Annotation of cci/usr/src/usr.bin/uucp/condevs.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.