Annotation of 43BSDReno/usr.bin/uucp/pk1.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)pk1.c      5.11    (Berkeley) 4/5/88";
        !             3: #endif
        !             4: 
        !             5: #include <signal.h>
        !             6: #include "uucp.h"
        !             7: #include "pk.h"
        !             8: #include <setjmp.h>
        !             9: #ifdef BSD4_2
        !            10: #include <sys/time.h>
        !            11: #include <sys/uio.h>
        !            12: #else /* !BSD4_2 */
        !            13: struct iovec {
        !            14:        caddr_t iov_base;
        !            15:        int iov_len;
        !            16: }
        !            17: #endif /* !BSD4_2 */
        !            18: 
        !            19: #ifdef VMS
        !            20: #include <eunice/eunice.h>
        !            21: #include <vms/iodef.h>
        !            22: #include <vms/ssdef.h>
        !            23: int iomask[2];
        !            24: #endif VMS
        !            25: 
        !            26: #define PKMAXSTMSG 40
        !            27: #define        MAXPKTIME 32    /* was 16 */
        !            28: #define CONNODATA 10
        !            29: #define MAXTIMEOUT 32
        !            30: 
        !            31: extern int errno;
        !            32: extern int Retries;
        !            33: extern char *sys_errlist[];
        !            34: extern jmp_buf Sjbuf;
        !            35: extern char *malloc();
        !            36: 
        !            37: int Connodata = 0;
        !            38: int Ntimeout = 0;
        !            39: int pktimeout = 4;
        !            40: int pktimeskew = 2;
        !            41: /*
        !            42:  * packet driver support routines
        !            43:  *
        !            44:  */
        !            45: 
        !            46: extern struct pack *pklines[];
        !            47: 
        !            48: /*
        !            49:  * start initial synchronization.
        !            50:  */
        !            51: 
        !            52: struct pack *
        !            53: pkopen(ifn, ofn)
        !            54: int ifn, ofn;
        !            55: {
        !            56:        register struct pack *pk;
        !            57:        register char **bp;
        !            58:        register int i;
        !            59: 
        !            60:        if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL)
        !            61:                return NULL;
        !            62:        bzero((caddr_t) pk, sizeof (struct pack));
        !            63:        pk->p_ifn = ifn;
        !            64:        pk->p_ofn = ofn;
        !            65:        pk->p_xsize = pk->p_rsize = PACKSIZE;
        !            66:        pk->p_rwindow = pk->p_swindow = WINDOWS;
        !            67:        /*  allocate input windows */
        !            68:        for (i = 0; i < pk->p_rwindow; i++) {
        !            69:                if ((bp = (char **) malloc((unsigned)pk->p_xsize)) == NULL)
        !            70:                        break;
        !            71:                *bp = (char *) pk->p_ipool;
        !            72:                pk->p_ipool = bp;
        !            73:        }
        !            74:        if (i == 0) {
        !            75:                DEBUG(1, "pkopen: can't malloc i = 0\n", CNULL);
        !            76:                return NULL;
        !            77:        }
        !            78:        pk->p_rwindow = i;
        !            79: 
        !            80:        /* start synchronization */
        !            81:        pk->p_msg = pk->p_rmsg = M_INITA;
        !            82:        for (i = 0; i < NPLINES; i++) {
        !            83:                if (pklines[i] == NULL) {
        !            84:                        pklines[i] = pk;
        !            85:                        break;
        !            86:                }
        !            87:        }
        !            88:        if (i >= NPLINES) {
        !            89:                DEBUG(1,"pkopen: i>=NPLINES\n", CNULL);
        !            90:                return NULL;
        !            91:        }
        !            92:        pkoutput(pk);
        !            93: 
        !            94:        for (i = 0; i < PKMAXSTMSG; i++) {
        !            95:                pkgetpack(pk);
        !            96:                if ((pk->p_state & LIVE) != 0)
        !            97:                        break;
        !            98:        }
        !            99:        if (i >= PKMAXSTMSG) {
        !           100:                DEBUG(1, "pkopen: i>= PKMAXSTMSG\n", CNULL);
        !           101:                return NULL;
        !           102:        }
        !           103: 
        !           104:        pkreset(pk);
        !           105:        return pk;
        !           106: }
        !           107: 
        !           108: 
        !           109: /*
        !           110:  * input framing and block checking.
        !           111:  * frame layout for most devices is:
        !           112:  *
        !           113:  *     S|K|X|Y|C|Z|  ... data ... |
        !           114:  *
        !           115:  *     where   S       == initial synch byte
        !           116:  *             K       == encoded frame size (indexes pksizes[])
        !           117:  *             X, Y    == block check bytes
        !           118:  *             C       == control byte
        !           119:  *             Z       == XOR of header (K^X^Y^C)
        !           120:  *             data    == 0 or more data bytes
        !           121:  *
        !           122:  */
        !           123: 
        !           124: int pksizes[] = {
        !           125:        1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
        !           126: };
        !           127: 
        !           128: #define GETRIES 10
        !           129: /*
        !           130:  * Pseudo-dma byte collection.
        !           131:  */
        !           132: 
        !           133: pkgetpack(pk)
        !           134: register struct pack *pk;
        !           135: {
        !           136:        int k, tries, noise;
        !           137:        register char *p;
        !           138:        register struct header *h;
        !           139:        unsigned short sum;
        !           140:        int ifn;
        !           141:        char **bp;
        !           142:        char hdchk;
        !           143: 
        !           144:        if ((pk->p_state & DOWN) || Connodata > CONNODATA || Ntimeout > MAXTIMEOUT)
        !           145:                pkfail();
        !           146:        ifn = pk->p_ifn;
        !           147: 
        !           148:        /* find HEADER */
        !           149:        for (tries = 0, noise = 0; tries < GETRIES; ) {
        !           150:                p = (caddr_t) &pk->p_ihbuf;
        !           151:                if (pkcget(ifn, p, 1) == SUCCESS) {
        !           152:                        if (*p++ == SYN) {
        !           153:                                if (pkcget(ifn, p, HDRSIZ-1) == SUCCESS)
        !           154:                                        break;
        !           155:                        } else {
        !           156:                                if (noise++ < 10 || noise < (3*pk->p_rsize))
        !           157:                                        continue;
        !           158:                        }
        !           159:                        DEBUG(4, "Noisy line - set up RXMIT\n", CNULL);
        !           160:                        noise = 0;
        !           161:                }
        !           162:                /* set up retransmit or REJ */
        !           163:                tries++;
        !           164:                Retries++;
        !           165:                pk->p_msg |= pk->p_rmsg;
        !           166:                if (pk->p_msg == 0)
        !           167:                        pk->p_msg |= M_RR;
        !           168:                if ((pk->p_state & LIVE) == LIVE)
        !           169:                        pk->p_state |= RXMIT;
        !           170:                pkoutput(pk);
        !           171:        }
        !           172:        if (tries >= GETRIES) {
        !           173:                DEBUG(4, "tries = %d\n", tries);
        !           174:                pkfail();
        !           175:        }
        !           176: 
        !           177:        Connodata++;
        !           178:        h = (struct header *) &pk->p_ihbuf;
        !           179:        p = (caddr_t) h;
        !           180:        hdchk = p[1] ^ p[2] ^ p[3] ^ p[4];
        !           181:        p += 2;
        !           182:        sum = (unsigned) *p++ & 0377;
        !           183:        sum |= (unsigned) *p << 8;
        !           184:        h->sum = sum;
        !           185:        DEBUG(7, "rec h->cntl 0%o\n", h->cntl&0xff);
        !           186:        k = h->ksize;
        !           187:        if (hdchk != h->ccntl) {
        !           188:                /* bad header */
        !           189:                DEBUG(7, "bad header 0%o,", hdchk&0xff);
        !           190:                DEBUG(7, "h->ccntl 0%o\n", h->ccntl&0xff);
        !           191:                return;
        !           192:        }
        !           193:        if (k == 9) {
        !           194:                if (((h->sum + h->cntl) & 0xffff) == CHECK) {
        !           195:                        pkcntl(h->cntl, pk);
        !           196:                        DEBUG(7, "state - 0%o\n", pk->p_state);
        !           197:                } else {
        !           198:                        /*  bad header */
        !           199:                        pk->p_state |= BADFRAME;
        !           200:                        DEBUG(7, "bad header (k==9) 0%o\n", h->cntl&0xff);
        !           201:                }
        !           202:                return;
        !           203:        }
        !           204:        if (k && pksizes[k] == pk->p_rsize) {
        !           205:                pk->p_rpr = h->cntl & MOD8;
        !           206:                DEBUG(7, "end pksack 0%o\n", pk->p_rpr);
        !           207:                pksack(pk);
        !           208:                bp = pk->p_ipool;
        !           209:                if (bp == NULL) {
        !           210:                        DEBUG(7, "bp NULL %s\n", "");
        !           211:                        return;
        !           212:                }
        !           213:                pk->p_ipool = (char **) *bp;
        !           214:                Connodata = 0;
        !           215:        } else
        !           216:                return;
        !           217: 
        !           218:        if (pkcget(pk->p_ifn, (char *) bp, pk->p_rsize) == SUCCESS) {
        !           219:                pkdata(h->cntl, h->sum, pk, (char **) bp);
        !           220:        } else {
        !           221:                *bp = (char *)pk->p_ipool;
        !           222:                pk->p_ipool = bp;
        !           223:        }
        !           224: }
        !           225: 
        !           226: pkdata(c, sum, pk, bp)
        !           227: char c;
        !           228: unsigned short sum;
        !           229: register struct pack *pk;
        !           230: char **bp;
        !           231: {
        !           232:        register x;
        !           233:        register int t;
        !           234: 
        !           235:        if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) {
        !           236:                pk->p_msg |= pk->p_rmsg;
        !           237:                pkoutput(pk);
        !           238:                goto drop;
        !           239:        }
        !           240:        t = next[pk->p_pr];
        !           241:        for(x = pk->p_pr; x != t; x = (x-1)&7) {
        !           242:                if (pk->p_is[x] == 0) {
        !           243:                        pk->p_imap |= mask[x];
        !           244:                        pk->p_is[x] = c;
        !           245:                        pk->p_isum[x] = sum;
        !           246:                        pk->p_ib[x] = (char *)bp;
        !           247:                        return;
        !           248:                }
        !           249:        }
        !           250: drop:
        !           251:        *bp = (char *)pk->p_ipool;
        !           252:        pk->p_ipool = bp;
        !           253: }
        !           254: 
        !           255: /*
        !           256:  * setup input transfers
        !           257:  *
        !           258:  * Start transmission on output device associated with pk.
        !           259:  * For asynch devices (t_line==1) framing is
        !           260:  * imposed.  For devices with framing and crc
        !           261:  * in the driver (t_line==2) the transfer is
        !           262:  * passed on to the driver.
        !           263:  */
        !           264: pkxstart(pk, cntl, x)
        !           265: register struct pack *pk;
        !           266: char cntl;
        !           267: register x;
        !           268: {
        !           269:        register char *p;
        !           270:        short checkword;
        !           271:        char hdchk;
        !           272: 
        !           273:        p = (caddr_t) &pk->p_ohbuf;
        !           274:        *p++ = SYN;
        !           275:        if (x < 0) {
        !           276:                *p++ = hdchk = 9;
        !           277:                checkword = cntl;
        !           278:        } else {
        !           279:                *p++ = hdchk = pk->p_lpsize;
        !           280:                checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377);
        !           281:        }
        !           282:        checkword = CHECK - checkword;
        !           283:        *p = checkword;
        !           284:        hdchk ^= *p++;
        !           285:        *p = checkword>>8;
        !           286:        hdchk ^= *p++;
        !           287:        *p = cntl;
        !           288:        hdchk ^= *p++;
        !           289:        *p = hdchk;
        !           290:        /*  writes  */
        !           291:        DEBUG(7, "send 0%o\n", cntl&0xff);
        !           292:        p = (caddr_t) & pk->p_ohbuf;
        !           293:        if (x < 0) {
        !           294:                if(write(pk->p_ofn, p, HDRSIZ) != HDRSIZ) {
        !           295:                        alarm(0);
        !           296:                        logent("PKXSTART write failed", sys_errlist[errno]);
        !           297:                        longjmp(Sjbuf, 4);
        !           298:                }
        !           299:        } else {
        !           300:                struct iovec iov[2];
        !           301: 
        !           302:                iov[0].iov_base = p;
        !           303:                iov[0].iov_len = HDRSIZ;
        !           304:                iov[1].iov_base = pk->p_ob[x];
        !           305:                iov[1].iov_len = pk->p_xsize;
        !           306: 
        !           307:                if (writev(pk->p_ofn, iov, 2) < 0) {
        !           308:                        alarm(0);
        !           309:                        logent("PKXSTART write failed", sys_errlist[errno]);
        !           310:                        longjmp(Sjbuf, 5);
        !           311:                }
        !           312: #ifdef 0
        !           313:                char buf[PKMAXBUF + HDRSIZ], *b;
        !           314:                int i;
        !           315:                for (i = 0, b = buf; i < HDRSIZ; i++)
        !           316:                        *b++ = *p++;
        !           317:                for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++)
        !           318:                        *b++ = *p++;
        !           319: 
        !           320:                if (write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ)
        !           321:                    != (HDRSIZ + pk->p_xsize)) {
        !           322:                        alarm(0);
        !           323:                        logent("PKXSTART write failed", sys_errlist[errno]);
        !           324:                        longjmp(Sjbuf, 5);
        !           325:                }
        !           326: #endif 0
        !           327:                Connodata = 0;
        !           328:        }
        !           329:        if (pk->p_msg)
        !           330:                pkoutput(pk);
        !           331: }
        !           332: 
        !           333: /*
        !           334:  *     get n characters from input
        !           335:  *
        !           336:  *     return codes:
        !           337:  *             n - number of characters returned
        !           338:  *             0 - end of file
        !           339:  */
        !           340: 
        !           341: jmp_buf Getjbuf;
        !           342: cgalarm()
        !           343: {
        !           344:        longjmp(Getjbuf, 1);
        !           345: }
        !           346: 
        !           347: pkcget(fn, b, n)
        !           348: int fn;
        !           349: register char *b;
        !           350: register int n;
        !           351: {
        !           352:        register int ret;
        !           353:        extern int linebaudrate;
        !           354: #ifdef BSD4_2
        !           355:        long r, itime = 100000L; /* guess it's been 1/10th second since we
        !           356:                                    last read the line */
        !           357:        struct timeval tv;
        !           358: #endif BSD4_2
        !           359: #ifdef VMS
        !           360:        short iosb[4];
        !           361:        int SYS$QioW(); /* use this for long reads on vms */
        !           362: #endif VMS
        !           363: 
        !           364:        if (setjmp(Getjbuf)) {
        !           365:                Ntimeout++;
        !           366:                DEBUG(4, "pkcget: alarm %d\n", pktimeout * 1000 + Ntimeout);
        !           367:                pktimeout += pktimeskew;
        !           368:                if (pktimeout > MAXPKTIME)
        !           369:                        pktimeout = MAXPKTIME;
        !           370:                return FAIL;
        !           371:        }
        !           372:        signal(SIGALRM, cgalarm);
        !           373: 
        !           374:        alarm(pktimeout);
        !           375:        while (n > 0) {
        !           376: #ifdef BSD4_2
        !           377:                if (linebaudrate > 0) {
        !           378:                        r = n  * 100000L;
        !           379:                        r = r / linebaudrate;
        !           380:                        r = (r * 100) - itime;
        !           381:                        itime = 0;
        !           382:                        /* we predict that more than 1/50th of a
        !           383:                           second will go by before the read will
        !           384:                           give back all that we want. */
        !           385:                        if (r > 20000) {
        !           386:                                tv.tv_sec = r / 1000000L;
        !           387:                                tv.tv_usec = r % 1000000L;
        !           388:                                DEBUG(11, "PKCGET stall for %d", tv.tv_sec);
        !           389:                                DEBUG(11, ".%06d sec\n", tv.tv_usec);
        !           390:                                (void) select (0, (int *)0, (int *)0, (int *)0, &tv);
        !           391:                        }
        !           392:                }
        !           393: #endif BSD4_2
        !           394: #ifndef VMS
        !           395:                ret = read(fn, b, n);
        !           396: #else VMS
        !           397:                _$Cancel_IO_On_Signal = FD_FAB_Pointer[fn];
        !           398:                ret = SYS$QioW(_$EFN,(FD_FAB_Pointer[fn]->fab).fab$l_stv,
        !           399:                                IO$_READVBLK|IO$M_NOFILTR|IO$M_NOECHO,
        !           400:                                iosb,0,0,b,n,0,
        !           401:                                iomask,0,0);
        !           402:                _$Cancel_IO_On_Signal = 0;
        !           403:                if (ret == SS$_NORMAL)
        !           404:                        ret = iosb[1]+iosb[3];   /* get length of transfer */
        !           405:                else
        !           406:                        ret = 0;
        !           407: #endif VMS
        !           408:                if (ret == 0) {
        !           409:                        alarm(0);
        !           410:                        return FAIL;
        !           411:                }
        !           412:                if (ret <= 0) {
        !           413:                        alarm(0);
        !           414:                        logent(sys_errlist[errno],"FAILED pkcget Read");
        !           415:                        longjmp(Sjbuf, 6);
        !           416:                }
        !           417:                b += ret;
        !           418:                n -= ret;
        !           419:        }
        !           420:        alarm(0);
        !           421:        return SUCCESS;
        !           422: }

unix.superglobalmegacorp.com

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