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

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

unix.superglobalmegacorp.com

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