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

unix.superglobalmegacorp.com

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