Annotation of 42BSD/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 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(&lt)) != 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(&lt)) != 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

unix.superglobalmegacorp.com

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