Annotation of researchv10dc/cmd/uucp/pk0.c, revision 1.1.1.1

1.1       root        1: /*     /sccs/src/cmd/uucp/s.pk0.c
                      2:        pk0.c   1.2     8/30/84 17:37:36
                      3: */
                      4: #include "uucp.h"
                      5: VERSION(@(#)pk0.c      1.2);
                      6: #define USER   1
                      7: 
                      8: #include "pk.h"
                      9: #include <sys/buf.h>
                     10: 
                     11: extern int Connodata;          /* Continuous No Valid Data Count */
                     12: 
                     13: /*
                     14:  * packet driver
                     15:  */
                     16: extern struct pack *pklines[];
                     17: 
                     18: /*
                     19:  * receive control messages
                     20:  *     c       -> message type fields
                     21:  *     pk      -> line control unit
                     22:  */
                     23: pkcntl(c, pk)
                     24: register struct pack *pk;
                     25: {
                     26:        register cntl, val;
                     27:        static int reack = 0;
                     28: 
                     29:        val = c & MOD8;
                     30:        cntl = (c>>3) & MOD8;
                     31: 
                     32:        if ( ! ISCNTL(c) ) {
                     33:                fprintf(stderr, "not cntl\n");
                     34:                return;
                     35:        }
                     36: 
                     37:        if (pk->p_mode & 02)
                     38:                fprintf(stderr, "%o ",c);
                     39:        switch(cntl) {
                     40: 
                     41:        case INITB:
                     42:                val++;
                     43:                pk->p_xsize = pksizes[val];
                     44:                pk->p_lpsize = val;
                     45:                pk->p_bits = 1;
                     46:                if (pk->p_state & LIVE) {
                     47:                        pk->p_msg |= M_INITC;
                     48:                        break;
                     49:                }
                     50:                pk->p_state |= INITb;
                     51:                if ((pk->p_state & INITa)==0) {
                     52:                        break;
                     53:                }
                     54:                pk->p_rmsg &= ~M_INITA;
                     55:                pk->p_msg |= M_INITC;
                     56:                break;
                     57: 
                     58:        case INITC:
                     59:                if ((pk->p_state&INITab)==INITab) {
                     60:                        pk->p_state = LIVE;
                     61:                        pk->p_rmsg &= ~M_INITB;
                     62:                } else
                     63:                        pk->p_msg |= M_INITB;
                     64:                if (val)
                     65:                        pk->p_swindow = val;
                     66:                break;
                     67:        case INITA:
                     68:                if (val==0 && pk->p_state&LIVE) {
                     69:                        fprintf(stderr, "alloc change not implemented\n");
                     70:                        break;
                     71:                }
                     72:                if (val) {
                     73:                        pk->p_state |= INITa;
                     74:                        pk->p_msg |= M_INITB;
                     75:                        pk->p_rmsg |= M_INITB;
                     76:                        pk->p_swindow = val;
                     77:                }
                     78:                break;
                     79:        case RJ:
                     80:                pk->p_state |= RXMIT;
                     81:                pk->p_msg |= M_RR;
                     82:                pk->p_rpr = val;
                     83:                (void) pksack(pk);
                     84:                DEBUG(9, "pkcntl: RJ: Connodata=%d\n", Connodata);
                     85:                break;
                     86:        case RR:
                     87:                pk->p_rpr = val;
                     88:                if (pk->p_rpr != pk->p_ps) {
                     89:                        reack = 0;
                     90:                        (void) pksack(pk);
                     91:                } else {
                     92:                        DEBUG(9, "pkcntl: reack %d\n", reack);
                     93:                        if (++reack >= 4) {
                     94:                                DEBUG(6, "reack ovfl %d\n", val);
                     95:                                pk->p_state |= RXMIT;
                     96:                                pk->p_msg |= M_RR;
                     97:                                reack = 0;
                     98:                        }
                     99:                }
                    100:                break;
                    101:        case SRJ:
                    102:                fprintf(stderr, "srj not implemented\n");
                    103:                break;
                    104:        case CLOSE:
                    105:                pk->p_state = DOWN+RCLOSE;
                    106:                return;
                    107:        }
                    108:        if (pk->p_msg)
                    109:                pkoutput(pk);
                    110: }
                    111: 
                    112: pkaccept(pk)
                    113: register struct pack *pk;
                    114: {
                    115:        register x,seq;
                    116:        char m, cntl, *p, imask, **bp;
                    117:        int bad,accept,skip,t,cc;
                    118:        unsigned short sum;
                    119: 
                    120: 
                    121:        bad = accept = skip = 0;
                    122: 
                    123:        /*
                    124:         * wait for input
                    125:         */
                    126:        x = next[pk->p_pr];
                    127:        while ((imask=pk->p_imap) == 0 && pk->p_rcount==0) {
                    128:                pkgetpack(pk);
                    129:        }
                    130:        pk->p_imap = 0;
                    131: 
                    132: 
                    133:        /*
                    134:         * determine input window in m.
                    135:         */
                    136:        t = (~(-1<<pk->p_rwindow)) <<x;
                    137:        m = t;
                    138:        m |= t>>8;
                    139: 
                    140: 
                    141:        /*
                    142:         * mark newly accepted input buffers
                    143:         */
                    144:        for(x=0; x<8; x++) {
                    145: 
                    146:                if ((imask & mask[x]) == 0)
                    147:                        continue;
                    148: 
                    149:                if (((cntl=pk->p_is[x])&0200)==0) {
                    150:                        bad++;
                    151: free:
                    152:                        bp = (char **)pk->p_ib[x];
                    153:                        *bp = (char *)pk->p_ipool;
                    154:                        pk->p_ipool = bp;
                    155:                        pk->p_is[x] = 0;
                    156:                        continue;
                    157:                }
                    158: 
                    159:                pk->p_is[x] = ~(B_COPY+B_MARK);
                    160:                sum = (unsigned)chksum(pk->p_ib[x], pk->p_rsize) ^ (unsigned)(cntl&0377);
                    161:                sum += pk->p_isum[x];
                    162:                if (sum == CHECK) {
                    163:                        seq = (cntl>>3) & MOD8;
                    164:                        if (m & mask[seq]) {
                    165:                                if (pk->p_is[seq] & (B_COPY | B_MARK)) {
                    166:                                dup:
                    167:                                        pk->p_msg |= M_RR;
                    168:                                        skip++;
                    169:                                        goto free;
                    170:                                }
                    171:                                if (x != seq) {
                    172:                                        p = pk->p_ib[x];
                    173:                                        pk->p_ib[x] = pk->p_ib[seq];
                    174:                                        pk->p_is[x] = pk->p_is[seq];
                    175:                                        pk->p_ib[seq] = p;
                    176:                                }
                    177:                                pk->p_is[seq] = B_MARK;
                    178:                                accept++;
                    179:                                cc = 0;
                    180:                                if (cntl&B_SHORT) {
                    181:                                        pk->p_is[seq] = B_MARK+B_SHORT;
                    182:                                        p = pk->p_ib[seq];
                    183:                                        cc = (unsigned)*p++ & 0377;
                    184:                                        if (cc & 0200) {
                    185:                                                cc &= 0177;
                    186:                                                cc |= *p << 7;
                    187:                                        }
                    188:                                }
                    189:                                pk->p_isum[seq] = pk->p_rsize - cc;
                    190:                        } else {
                    191:                                goto dup;
                    192:                        }
                    193:                } else {
                    194:                        bad++;
                    195:                        goto free;
                    196:                }
                    197:        }
                    198: 
                    199:        /*
                    200:         * scan window again turning marked buffers into
                    201:         * COPY buffers and looking for missing sequence
                    202:         * numbers.
                    203:         */
                    204:        accept = 0;
                    205:        for(x=next[pk->p_pr],t= -1; m & mask[x]; x = next[x]) {
                    206:                if (pk->p_is[x] & B_MARK)
                    207:                        pk->p_is[x] |= B_COPY;
                    208: 
                    209:                if (pk->p_is[x] & B_COPY) {
                    210:                        if (t >= 0) {
                    211:                                bp = (char **)pk->p_ib[x];
                    212:                                *bp = (char *)pk->p_ipool;
                    213:                                pk->p_ipool = bp;
                    214:                                pk->p_is[x] = 0;
                    215:                                skip++;
                    216:                        } else 
                    217:                                accept++;
                    218:                } else {
                    219:                        if (t<0)
                    220:                                t = x;
                    221:                }
                    222:        }
                    223: 
                    224:        if (bad) {
                    225:                pk->p_msg |= M_RJ;
                    226:        }
                    227: 
                    228:        if (skip) {
                    229:                pk->p_msg |= M_RR;
                    230:        }
                    231: 
                    232:        pk->p_rcount = accept;
                    233:        return(accept);
                    234: }
                    235: 
                    236: 
                    237: pkread(ipk, ibuf, icount)
                    238: int icount; char *ibuf; struct pack *ipk;
                    239: {
                    240:        register struct pack *pk;
                    241:        register x;
                    242:        int is,cc,xfr,count;
                    243:        char *cp, **bp;
                    244: 
                    245:        pk = ipk;
                    246:        xfr = 0;
                    247:        count = 0;
                    248:        while (pkaccept(pk)==0)
                    249:                ;
                    250:        Connodata = 0;          /* accecpted a packet -- good data */
                    251: 
                    252: 
                    253:        while (icount) {
                    254: 
                    255:                x = next[pk->p_pr];
                    256:                is = pk->p_is[x];
                    257: 
                    258:                if (is & B_COPY) {
                    259:                        cc = MIN(pk->p_isum[x], icount);
                    260:                        if (cc==0 && xfr) {
                    261:                                break;
                    262:                        }
                    263:                        if (is & B_RESID)
                    264:                                cp = pk->p_rptr;
                    265:                        else {
                    266:                                cp = pk->p_ib[x];
                    267:                                if (is & B_SHORT) {
                    268:                                        if (*cp++ & 0200)
                    269:                                                cp++;
                    270:                                }
                    271:                        }
                    272:                        {
                    273:                                register char *p, *q;
                    274:                                register int c;
                    275: 
                    276:                                if(c=cc){
                    277:                                        p = ibuf;
                    278:                                        q = cp;
                    279:                                        do
                    280:                                                *p++ = *q++;
                    281:                                        while(--c);
                    282:                                        ibuf += cc;
                    283:                                        icount -= cc;
                    284:                                }
                    285:                        }
                    286:                        count += cc;
                    287:                        xfr++;
                    288:                        pk->p_isum[x] -= cc;
                    289:                        if (pk->p_isum[x] == 0) {
                    290:                                pk->p_pr = x;
                    291:                                bp = (char **)pk->p_ib[x];
                    292:                                *bp = (char *)pk->p_ipool;
                    293:                                pk->p_ipool = bp;
                    294:                                pk->p_is[x] = 0;
                    295:                                pk->p_rcount--;
                    296:                                pk->p_msg |= M_RR;
                    297:                        } else {
                    298:                                pk->p_rptr = cp+cc;
                    299:                                pk->p_is[x] |= B_RESID;
                    300:                        }
                    301:                        if (cc==0)
                    302:                                break;
                    303:                } else
                    304:                        break;
                    305:        }
                    306:        pkoutput(pk);
                    307:        return(count);
                    308: }
                    309: 
                    310: 
                    311: 
                    312: 
                    313: pkwrite(ipk, ibuf, icount)
                    314: int icount; char *ibuf; struct pack *ipk;
                    315: {
                    316:        register struct pack *pk;
                    317:        register x;
                    318:        caddr_t cp;
                    319:        int partial;
                    320:        int cc, fc, count;
                    321:        char *malloc();
                    322: 
                    323:        pk = ipk;
                    324:        if (pk->p_state&DOWN || !pk->p_state&LIVE) {
                    325:                return(-1);
                    326:        }
                    327: 
                    328:        count = icount;
                    329:        do {
                    330:                while (pk->p_xcount>=pk->p_swindow)  {
                    331:                        pkoutput(pk);
                    332:                        pkgetpack(pk);
                    333:                }
                    334:                x = next[pk->p_pscopy];
                    335:                while (pk->p_os[x]!=B_NULL)  {
                    336:                        pkgetpack(pk);
                    337:                }
                    338:                pk->p_os[x] = B_MARK;
                    339:                pk->p_pscopy = x;
                    340:                pk->p_xcount++;
                    341: 
                    342:                cp = pk->p_ob[x] = (caddr_t) malloc((unsigned) pk->p_xsize);
                    343:                partial = 0;
                    344:                if ((int)icount < pk->p_xsize) {
                    345:                        cc = icount;
                    346:                        fc = pk->p_xsize - cc;
                    347:                        *cp = fc&0177;
                    348:                        if (fc > 127) {
                    349:                                *cp++ |= 0200;
                    350:                                *cp++ = fc>>7;
                    351:                        } else
                    352:                                cp++;
                    353:                        partial = B_SHORT;
                    354:                } else
                    355:                        cc = pk->p_xsize;
                    356:                {
                    357:                        register char *p, *q;
                    358:                        register int c;
                    359: 
                    360:                        if(c=cc){
                    361:                                q = ibuf;
                    362:                                p = cp;
                    363:                                do
                    364:                                        *p++ = *q++;
                    365:                                while(--c);
                    366:                                ibuf += cc;
                    367:                                icount -= cc;
                    368:                        }
                    369:                }
                    370:                pk->p_osum[x] = chksum(pk->p_ob[x], pk->p_xsize);
                    371:                pk->p_os[x] = B_READY+partial;
                    372:                pkoutput(pk);
                    373:        } while (icount);
                    374: 
                    375:        return(count);
                    376: }
                    377: 
                    378: pksack(pk)
                    379: register struct pack *pk;
                    380: {
                    381:        register x, i;
                    382: 
                    383:        i = 0;
                    384:        for(x=pk->p_ps; x!=pk->p_rpr; ) {
                    385:                x = next[x];
                    386:                if (pk->p_os[x]&B_SENT) {
                    387:                        i++;
                    388:                        Connodata = 0;
                    389:                        pk->p_os[x] = B_NULL;
                    390:                        pk->p_state &= ~WAITO;
                    391:                        pk->p_xcount--;
                    392:                        free((char *) pk->p_ob[x]);
                    393:                        pk->p_ps = x;
                    394:                }
                    395:        }
                    396:        return(i);
                    397: }
                    398: 
                    399: 
                    400: 
                    401: pkoutput(pk)
                    402: register struct pack *pk;
                    403: {
                    404: register x;
                    405: char bstate;
                    406: int i;
                    407: 
                    408:        if (pk->p_obusy++) {
                    409:                pk->p_obusy--;
                    410:                return;
                    411:        }
                    412: 
                    413: 
                    414:        /*
                    415:         * find seq number and buffer state
                    416:         * of next output packet
                    417:         */
                    418:        if (pk->p_state&RXMIT)
                    419:                pk->p_nxtps = next[pk->p_rpr];
                    420:        x = pk->p_nxtps;
                    421:        bstate = pk->p_os[x];
                    422: 
                    423: 
                    424:        /*
                    425:         * Send control packet if indicated
                    426:         */
                    427:        if (pk->p_msg) {
                    428:                if (pk->p_msg & ~M_RR || !(bstate&B_READY) ) {
                    429:                        x = pk->p_msg;
                    430:                        for(i=0; i<8; i++) 
                    431:                                if (x&1)
                    432:                                        break; 
                    433: else
                    434:                                x >>= 1;
                    435:                        x = i;
                    436:                        x <<= 3;
                    437:                        switch(i) {
                    438:                        case CLOSE:
                    439:                                break;
                    440:                        case RJ:
                    441:                        case RR:
                    442:                                x += pk->p_pr;
                    443:                                break;
                    444:                        case SRJ:
                    445:                                break;
                    446:                        case INITB:
                    447:                                x += pksize(pk->p_rsize);
                    448:                                break;
                    449:                        case INITC:
                    450:                                x += pk->p_rwindow;
                    451:                                break;
                    452:                        case INITA:
                    453:                                x += pk->p_rwindow;
                    454:                                break;
                    455:                        }
                    456: 
                    457:                        pk->p_msg &= ~mask[i];
                    458:                        pkxstart(pk, x, -1);
                    459:                        goto out;
                    460:                }
                    461:        }
                    462: 
                    463: 
                    464:        /*
                    465:         * Don't send data packets if line is marked dead.
                    466:         */
                    467:        if (pk->p_state&DOWN) {
                    468:                goto out;
                    469:        }
                    470: 
                    471:        /*
                    472:         * Start transmission (or retransmission) of data packets.
                    473:         */
                    474:        if (bstate & (B_READY|B_SENT)) {
                    475:                char seq;
                    476: 
                    477:                bstate |= B_SENT;
                    478:                seq = x;
                    479:                pk->p_nxtps = next[x];
                    480: 
                    481:                x = 0200+pk->p_pr+(seq<<3);
                    482:                if (bstate & B_SHORT)
                    483:                        x |= 0100;
                    484:                pkxstart(pk, x, seq);
                    485:                pk->p_os[seq] = bstate;
                    486:                pk->p_state &= ~RXMIT;
                    487:                pk->p_nout++;
                    488:                goto out;
                    489:        }
                    490: 
                    491:        /*
                    492:         * enable timeout if there's nothing to send
                    493:         * and transmission buffers are languishing
                    494:         */
                    495:        if (pk->p_xcount) {
                    496:                pk->p_timer = 2;
                    497:                pk->p_state |= WAITO;
                    498:        } else
                    499:                pk->p_state &= ~WAITO;
                    500: out:
                    501:        pk->p_obusy = 0;
                    502: }
                    503: 
                    504: /*
                    505:  * shut down line by ignoring new input
                    506:  * letting output drain
                    507:  * releasing space and turning off line discipline
                    508:  */
                    509: pkclose(ipk)
                    510: struct pack *ipk;
                    511: {
                    512: register struct pack *pk;
                    513: register i;
                    514: int rcheck;
                    515: char **bp;
                    516: 
                    517:        pk = ipk;
                    518:        pk->p_state |= DRAINO;
                    519: 
                    520:        /*
                    521:         * try to flush output
                    522:         */
                    523:        i = 0;
                    524:        pk->p_timer = 2;
                    525:        while (pk->p_xcount && pk->p_state&LIVE) {
                    526:                if (pk->p_state&(RCLOSE+DOWN) || ++i > 2)
                    527:                        break;
                    528:                pkoutput(pk);
                    529:        }
                    530:        pk->p_timer = 0;
                    531:        pk->p_state |= DOWN;
                    532: 
                    533:        /*
                    534:         * try to exchange CLOSE messages
                    535:         */
                    536:        i = 0;
                    537:        while ((pk->p_state&RCLOSE)==0 && i<2) {
                    538:                pk->p_msg = M_CLOSE;
                    539:                pk->p_timer = 2;
                    540:                pkoutput(pk);
                    541:                i++;
                    542:        }
                    543: 
                    544: 
                    545:        for(i=0;i<NPLINES;i++)
                    546:                if (pklines[i]==pk)  {
                    547:                        pklines[i] = NULL;
                    548:                }
                    549: 
                    550:        /*
                    551:         * free space
                    552:         */
                    553:        rcheck = 0;
                    554:        for (i=0;i<8;i++) {
                    555:                if (pk->p_os[i]!=B_NULL) {
                    556:                        free((char *) pk->p_ob[i]);
                    557:                        pk->p_xcount--;
                    558:                }
                    559:                if (pk->p_is[i]!=B_NULL)  {
                    560:                        free((char *) pk->p_ib[i]);
                    561:                        rcheck++;
                    562:                }
                    563:        }
                    564:        while (pk->p_ipool != NULL) {
                    565:                bp = pk->p_ipool;
                    566:                pk->p_ipool = (char **)*bp;
                    567:                rcheck++;
                    568:                free((char *) bp);
                    569:        }
                    570:        if (rcheck  != pk->p_rwindow) {
                    571:                fprintf(stderr, "r short %d want %d\n",rcheck,pk->p_rwindow);
                    572:                fprintf(stderr, "rcount = %d\n",pk->p_rcount);
                    573:                fprintf(stderr, "xcount = %d\n",pk->p_xcount);
                    574:        }
                    575:        free((char *) pk);
                    576: }
                    577: 
                    578: 
                    579: 
                    580: pkreset(pk)
                    581: register struct pack *pk;
                    582: {
                    583: 
                    584:        pk->p_ps = pk->p_pr =  pk->p_rpr = 0;
                    585:        pk->p_nxtps = 1;
                    586: }
                    587: 
                    588: chksum(s,n)
                    589: register char *s;
                    590: register n;
                    591: {
                    592:        register short sum;
                    593:        register unsigned short t;
                    594:        register short x;
                    595: 
                    596:        sum = -1;
                    597:        x = 0;
                    598: 
                    599:        do {
                    600:                if (sum<0) {
                    601:                        sum <<= 1;
                    602:                        sum++;
                    603:                } else
                    604:                        sum <<= 1;
                    605:                t = sum;
                    606:                sum += (unsigned)*s++ & 0377;
                    607:                x += sum^n;
                    608:                if ((unsigned short)sum <= t) {
                    609:                        sum ^= x;
                    610:                }
                    611:        } while (--n > 0);
                    612: 
                    613:        return(sum);
                    614: }
                    615: 
                    616: pkzero(s,n)
                    617: register char *s;
                    618: register n;
                    619: {
                    620:        while (n--)
                    621:                *s++ = 0;
                    622: }
                    623: 
                    624: pksize(n)
                    625: register n;
                    626: {
                    627:        register k;
                    628: 
                    629:        n >>= 5;
                    630:        for(k=0; n >>= 1; k++);
                    631:        return(k);
                    632: }

unix.superglobalmegacorp.com

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