# 2.11BSD#431 - /usr/src/usr.bin/uucp/pk0.c

##### Functions

    bzero             X
    pkaccept          X
    pkclose           X
    pkcntl            X
    pkoutput          X
    pkread            X
    pkreset           X
    pksack            X
    pksize            X
    pkwrite           X

##### Variables

    Reacks            X
    mask              X
    next              X
    pklines           X

##### Macros

    PKRSKEW           X
    PKRTIME           X
    PKWSKEW           X
    PKWTIME           X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static char sccsid[] = "@(#)pk0.c	5.7.1 (2.11BSD) 1997/10/2";
       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] = (char *)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: }

#### Defined functions

bzero defined in line 555; used 3 times

- in /usr/src/usr.bin/uucp/aculib/bsdtcp.c line 45
- in /usr/src/usr.bin/uucp/pk1.c line 55
- in /usr/src/usr.bin/uucp/uucpd.c line 84

pkaccept defined in line 112; used 1 times

- in line 247

pkclose defined in line 479; used 1 times

- in /usr/src/usr.bin/uucp/gio.c line 35

pkcntl defined in line 28; used 1 times

- in /usr/src/usr.bin/uucp/pk1.c line 188

pkoutput defined in line 372; used 10 times

- in line 109, 291, 316, 346, 496, 508
- in /usr/src/usr.bin/uucp/pk1.c line 85, 163, 231, 318

pkread defined in line 233; used 2 times

- in /usr/src/usr.bin/uucp/gio.c line 75, 214

pkreset defined in line 546; used 1 times

- in /usr/src/usr.bin/uucp/pk1.c line 97

pksack defined in line 352; used 3 times

- in line 84, 98
- in /usr/src/usr.bin/uucp/pk1.c line 200

pksize defined in line 564; used 1 times

- in line 417

pkwrite defined in line 296; used 1 times

- in /usr/src/usr.bin/uucp/gio.c line 235

#### Defined variables

Reacks defined in line 17; used 4 times

- in line 89-97(4)

mask defined in line 13; used 9 times

- in line 141, 159, 201, 427
- in /usr/src/usr.bin/uucp/pk0.c line 141, 159, 201, 427
- in /usr/src/usr.bin/uucp/pk1.c line 245

next defined in line 12; used 17 times

- in line 124, 201(2), 251, 319, 359, 389, 448
- in /usr/src/usr.bin/uucp/pk0.c line 124, 201(2), 251, 319, 359, 389, 448
- in /usr/src/usr.bin/uucp/pk1.c line 234

pklines defined in line 15; used 4 times

- in line 513-514(2)
- in /usr/src/usr.bin/uucp/pk1.c line 76-77(2)

sccsid defined in line 2; never used

#### Defined macros

PKRSKEW defined in line 21; used 1 times

- in line 245

PKRTIME defined in line 19; used 1 times

- in line 244

PKWSKEW defined in line 22; used 1 times

- in line 311

PKWTIME defined in line 20; used 1 times

- in line 310

Last modified: 1997-10-03 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1180 |