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