Annotation of 42BSD/usr.bin/uucp/condevs.c, revision 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.