Annotation of 3BSD/cmd/uucp/pk1.c, revision 1.1

1.1     ! root        1: #define USER   1
        !             2: #include <stdio.h>
        !             3: #include <sys/pk.p>
        !             4: #include <sys/param.h>
        !             5: #include <sys/pk.h>
        !             6: #include <sys/buf.h>
        !             7: #include <setjmp.h>
        !             8: #include <signal.h>
        !             9: 
        !            10: #define PKTIME 10
        !            11: int Errorrate;
        !            12: int Conbad = 0;
        !            13: int Ntimeout = 0;
        !            14: #define CONBAD 5
        !            15: #define NTIMEOUT 50
        !            16: /*
        !            17:  * packet driver support routines
        !            18:  *
        !            19:  */
        !            20: 
        !            21: struct pack *pklines[NPLINES];
        !            22: 
        !            23: /*
        !            24:  * start initial synchronization.
        !            25:  */
        !            26: 
        !            27: struct pack *
        !            28: pkopen(ifn, ofn)
        !            29: int ifn, ofn;
        !            30: {
        !            31:        struct pack *pk;
        !            32:        char **bp;
        !            33:        int i;
        !            34: 
        !            35:        if (++pkactive >= NPLINES)
        !            36:                return(NULL);
        !            37:        if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL)
        !            38:                return(NULL);
        !            39:        pkzero((caddr_t) pk, sizeof (struct pack));
        !            40:        pk->p_ifn = ifn;
        !            41:        pk->p_ofn = ofn;
        !            42:        pk->p_xsize = pk->p_rsize = PACKSIZE;
        !            43:        pk->p_rwindow = pk->p_swindow = WINDOWS;
        !            44:        /*  allocate input windows */
        !            45:        for (i = 0; i < pk->p_rwindow; i++) {
        !            46:                if ((bp = (char **) GETEPACK) == NULL)
        !            47:                        break;
        !            48:                *bp = (char *) pk->p_ipool;
        !            49:                pk->p_ipool = bp;
        !            50:        }
        !            51:        if (i == 0)
        !            52:                return(NULL);
        !            53:        pk->p_rwindow = i;
        !            54: 
        !            55:        /* start synchronization */
        !            56:        pk->p_msg = pk->p_rmsg = M_INITA;
        !            57:        for (i = 0; i < NPLINES; i++) {
        !            58:                if (pklines[i] == NULL) {
        !            59:                        pklines[i] = pk;
        !            60:                        break;
        !            61:                }
        !            62:        }
        !            63:        if (i >= NPLINES)
        !            64:                return(NULL);
        !            65:        pkoutput(pk);
        !            66: 
        !            67:        while ((pk->p_state & LIVE) == 0) {
        !            68:                PKGETPKT(pk);
        !            69:        }
        !            70: 
        !            71:        pkreset(pk);
        !            72:        return(pk);
        !            73: }
        !            74: 
        !            75: 
        !            76: /*
        !            77:  * input framing and block checking.
        !            78:  * frame layout for most devices is:
        !            79:  *     
        !            80:  *     S|K|X|Y|C|Z|  ... data ... |
        !            81:  *
        !            82:  *     where   S       == initial synch byte
        !            83:  *             K       == encoded frame size (indexes pksizes[])
        !            84:  *             X, Y    == block check bytes
        !            85:  *             C       == control byte
        !            86:  *             Z       == XOR of header (K^X^Y^C)
        !            87:  *             data    == 0 or more data bytes
        !            88:  *
        !            89:  */
        !            90: 
        !            91: int pksizes[] = {
        !            92:        1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1
        !            93: };
        !            94: 
        !            95: #define GETRIES 5
        !            96: /*
        !            97:  * Pseudo-dma byte collection.
        !            98:  */
        !            99: 
        !           100: pkgetpack(ipk)
        !           101: struct pack *ipk;
        !           102: {
        !           103:        int ret, k, tries;
        !           104:        register char *p;
        !           105:        struct pack *pk;
        !           106:        struct header *h;
        !           107:        unsigned short sum;
        !           108:        int ifn;
        !           109:        char **bp;
        !           110:        char hdchk;
        !           111: 
        !           112:        if (Conbad > CONBAD /* || Ntimeout > NTIMEOUT */)
        !           113:                pkfail();
        !           114:        pk = PADDR;
        !           115:        ifn = pk->p_ifn;
        !           116: 
        !           117:        /* find HEADER */
        !           118:        for (tries = 0; tries < GETRIES; ) {
        !           119:                p = (caddr_t) &pk->p_ihbuf;
        !           120:                if ((ret = pkcget(ifn, p, 1)) < 0) {
        !           121:                        /* set up retransmit or REJ */
        !           122:                        tries++;
        !           123:                        pk->p_msg |= pk->p_rmsg;
        !           124:                        if (pk->p_msg == 0)
        !           125:                                pk->p_msg |= M_RR;
        !           126:                        if ((pk->p_state & LIVE) == LIVE)
        !           127:                                pk->p_state |= RXMIT;
        !           128:                        pkoutput(pk);
        !           129:                        continue;
        !           130:                }
        !           131:                if (*p != SYN)
        !           132:                        continue;
        !           133:                p++;
        !           134:                ret = pkcget(ifn, p, HDRSIZ - 1);
        !           135:                if (ret == -1)
        !           136:                        continue;
        !           137:                break;
        !           138:        }
        !           139:        if (tries >= GETRIES) {
        !           140:                PKDEBUG(4, "tries = %d\n", tries);
        !           141:                pkfail();
        !           142:        }
        !           143: 
        !           144:        h = (struct header * ) &pk->p_ihbuf;
        !           145:        p = (caddr_t) h;
        !           146:        hdchk = p[1] ^ p[2] ^ p[3] ^ p[4];
        !           147:        p += 2;
        !           148:        sum = (unsigned) *p++ & 0377;
        !           149:        sum |= (unsigned) *p << 8;
        !           150:        h->sum = sum;
        !           151:        PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl);
        !           152:        k = h->ksize;
        !           153:        if (hdchk != h->ccntl) {
        !           154:                /* bad header */
        !           155:                PKDEBUG(7, "bad header %o,", hdchk);
        !           156:                PKDEBUG(7, "h->ccntl %o\n", h->ccntl);
        !           157:                Conbad++;
        !           158:                return;
        !           159:        }
        !           160:        if (k == 9) {
        !           161:                if (h->sum + h->cntl == CHECK) {
        !           162:                        pkcntl(h->cntl, pk);
        !           163:                        Conbad = 0;
        !           164:                        PKDEBUG(7, "state - %o\n", pk->p_state);
        !           165:                }
        !           166:                else {
        !           167:                        /*  bad header */
        !           168:                        Conbad++;
        !           169:                        PKDEBUG(7, "bad header %o\n", h->cntl);
        !           170:                        pk->p_state |= BADFRAME;
        !           171:                }
        !           172:                return;
        !           173:        }
        !           174:        if (k && pksizes[k] == pk->p_rsize) {
        !           175:                pk->p_rpr = h->cntl & MOD8;
        !           176:                pksack(pk);
        !           177:                Conbad = 0;
        !           178:                bp = pk->p_ipool;
        !           179:                pk->p_ipool = (char **) *bp;
        !           180:                if (bp == NULL) {
        !           181:                        PKDEBUG(7, "bp NULL %s\n", "");
        !           182:                return;
        !           183:                }
        !           184:        }
        !           185:        else {
        !           186:                Conbad++;
        !           187:                return;
        !           188:        }
        !           189:        ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize);
        !           190:        PKASSERT(ret != -1, "PKGETPKT CAN't READ %d", ret);
        !           191:        pkdata(h->cntl, h->sum, pk, (char *) bp);
        !           192:        return;
        !           193: }
        !           194: 
        !           195: 
        !           196: pkdata(c, sum, pk, bp)
        !           197: char c;
        !           198: short sum;
        !           199: register struct pack *pk;
        !           200: char **bp;
        !           201: {
        !           202: register x;
        !           203: int t;
        !           204: char m;
        !           205: 
        !           206:        if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) {
        !           207:                pk->p_msg |= pk->p_rmsg;
        !           208:                pkoutput(pk);
        !           209:                goto drop;
        !           210:        }
        !           211:        t = next[pk->p_pr];
        !           212:        for(x=pk->p_pr; x!=t; x = (x-1)&7) {
        !           213:                if (pk->p_is[x] == 0)
        !           214:                        goto slot;
        !           215:        }
        !           216: drop:
        !           217:        *bp = (char *)pk->p_ipool;
        !           218:        pk->p_ipool = bp;
        !           219:        return;
        !           220: 
        !           221: slot:
        !           222:        m = mask[x];
        !           223:        pk->p_imap |= m;
        !           224:        pk->p_is[x] = c;
        !           225:        pk->p_isum[x] = sum;
        !           226:        pk->p_ib[x] = (char *)bp;
        !           227:        return;
        !           228: }
        !           229: 
        !           230: 
        !           231: 
        !           232: /*
        !           233:  * setup input transfers
        !           234:  */
        !           235: pkrstart(pk)
        !           236: {}
        !           237: 
        !           238: /*
        !           239:  * Start transmission on output device associated with pk.
        !           240:  * For asynch devices (t_line==1) framing is
        !           241:  * imposed.  For devices with framing and crc
        !           242:  * in the driver (t_line==2) the transfer is
        !           243:  * passed on to the driver.
        !           244:  */
        !           245: pkxstart(pk, cntl, x)
        !           246: struct pack *pk;
        !           247: char cntl;
        !           248: register x;
        !           249: {
        !           250:        register char *p;
        !           251:        int ret;
        !           252:        short checkword;
        !           253:        char hdchk;
        !           254: 
        !           255:        p = (caddr_t) &pk->p_ohbuf;
        !           256:        *p++ = SYN;
        !           257:        if (x < 0) {
        !           258:                *p++ = hdchk = 9;
        !           259:                checkword = cntl;
        !           260:        }
        !           261:        else {
        !           262:                *p++ = hdchk = pk->p_lpsize;
        !           263:                checkword = pk->p_osum[x] ^ (unsigned)(cntl&0377);
        !           264:        }
        !           265:        checkword = CHECK - checkword;
        !           266:        *p = checkword;
        !           267:        hdchk ^= *p++;
        !           268:        *p = checkword>>8;
        !           269:        hdchk ^= *p++;
        !           270:        *p = cntl;
        !           271:        hdchk ^= *p++;
        !           272:        *p = hdchk;
        !           273:  /*  writes  */
        !           274: PKDEBUG(7, "send %o\n", (unsigned) cntl);
        !           275:        p = (caddr_t) & pk->p_ohbuf;
        !           276:        if (x < 0) {
        !           277:                GENERROR(p, HDRSIZ);
        !           278:                ret = write(pk->p_ofn, p, HDRSIZ);
        !           279:                PKASSERT(ret == HDRSIZ, "PKXSTART ret %d", ret);
        !           280:        }
        !           281:        else {
        !           282:                char buf[PACKSIZE + HDRSIZ], *b;
        !           283:                int i;
        !           284:                for (i = 0, b = buf; i < HDRSIZ; i++) 
        !           285:                        *b++ = *p++;
        !           286:                for (i = 0, p = pk->p_ob[x]; i < pk->p_rsize; i++)
        !           287:                        *b++ = *p++;
        !           288:                GENERROR(buf, pk->p_rsize + HDRSIZ);
        !           289:                ret = write(pk->p_ofn, buf, pk->p_rsize + HDRSIZ);
        !           290:                PKASSERT(ret == pk->p_rsize + HDRSIZ,
        !           291:                  "PKXSTART ret %d", ret);
        !           292:        }
        !           293:        if (pk->p_msg)
        !           294:                pkoutput(pk);
        !           295:        return;
        !           296: }
        !           297: 
        !           298: 
        !           299: pkmove(p1, p2, count, flag)
        !           300: char *p1, *p2;
        !           301: int count, flag;
        !           302: {
        !           303:        char *s, *d;
        !           304:        int i;
        !           305:        if (flag == B_WRITE) {
        !           306:                s = p2;
        !           307:                d = p1;
        !           308:        }
        !           309:        else {
        !           310:                s = p1;
        !           311:                d = p2;
        !           312:        }
        !           313:        for (i = 0; i < count; i++)
        !           314:                *d++ = *s++;
        !           315:        return;
        !           316: }
        !           317: 
        !           318: 
        !           319: /***
        !           320:  *     pkcget(fn, b, n)        get n characters from input
        !           321:  *     char *b;                - buffer for characters
        !           322:  *     int fn;                 - file descriptor
        !           323:  *     int n;                  - requested number of characters
        !           324:  *
        !           325:  *     return codes:
        !           326:  *             n - number of characters returned
        !           327:  *             0 - end of file
        !           328:  */
        !           329: 
        !           330: jmp_buf Getjbuf;
        !           331: cgalarm() { longjmp(Getjbuf, 1); }
        !           332: 
        !           333: pkcget(fn, b, n)
        !           334: int fn, n;
        !           335: char *b;
        !           336: {
        !           337:        int nchars, ret;
        !           338: 
        !           339:        if (setjmp(Getjbuf)) {
        !           340:                Ntimeout++;
        !           341:                PKDEBUG(4, "alarm %d\n", Ntimeout);
        !           342:                return(-1);
        !           343:        }
        !           344:        signal(SIGALRM, cgalarm);
        !           345: 
        !           346:        for (nchars = 0; nchars < n; nchars += ret) {
        !           347:                alarm(PKTIME);
        !           348:                ret = read(fn, b, n - nchars);
        !           349:                if (ret == 0) {
        !           350:                        alarm(0);
        !           351:                        return(-1);
        !           352:                }
        !           353:                PKASSERT(ret > 0, "PKCGET READ %d", ret);
        !           354:                b += ret;
        !           355:        }
        !           356:        alarm(0);
        !           357:        return(0);
        !           358: }
        !           359: 
        !           360: 
        !           361: generror(p, s)
        !           362: char *p;
        !           363: int s;
        !           364: {
        !           365:        int r;
        !           366:        if (Errorrate != 0 && (rand() % Errorrate) == 0) {
        !           367:                r = rand() % s;
        !           368: fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r));
        !           369:                *(p + r) += 1;
        !           370:        }
        !           371:        return;
        !           372: }
        !           373: 
        !           374: 

unix.superglobalmegacorp.com

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