Annotation of 42BSD/usr.bin/uucp/pk0.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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