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

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

unix.superglobalmegacorp.com

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