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: }

Defined functions

bzero defined in line 555; used 2 times
pkaccept defined in line 112; used 1 times
pkclose defined in line 479; used 1 times
pkcntl defined in line 28; used 1 times
pkoutput defined in line 372; used 10 times
pkread defined in line 233; used 2 times
pkreset defined in line 546; used 1 times
pksack defined in line 352; used 3 times
pksize defined in line 564; used 1 times
pkwrite defined in line 296; used 1 times

Defined variables

Reacks defined in line 17; used 4 times
mask defined in line 13; used 9 times
next defined in line 12; used 17 times
pklines defined in line 15; used 4 times
sccsid defined in line 2; never used

Defined macros

PKRSKEW defined in line 21; used 1 times
PKRTIME defined in line 19; used 1 times
PKWSKEW defined in line 22; used 1 times
PKWTIME defined in line 20; used 1 times
Last modified: 1986-05-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1866
Valid CSS Valid XHTML 1.0 Strict