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

unix.superglobalmegacorp.com

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