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