|
|
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: #include <setjmp.h> ! 8: #include <signal.h> ! 9: ! 10: #define PKTIME 10 ! 11: int Errorrate; ! 12: int Conbad = 0; ! 13: int Ntimeout = 0; ! 14: #define CONBAD 5 ! 15: #define NTIMEOUT 50 ! 16: /* ! 17: * packet driver support routines ! 18: * ! 19: */ ! 20: ! 21: struct pack *pklines[NPLINES]; ! 22: ! 23: /* ! 24: * start initial synchronization. ! 25: */ ! 26: ! 27: struct pack * ! 28: pkopen(ifn, ofn) ! 29: int ifn, ofn; ! 30: { ! 31: struct pack *pk; ! 32: char **bp; ! 33: int i; ! 34: ! 35: if (++pkactive >= NPLINES) ! 36: return(NULL); ! 37: if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL) ! 38: return(NULL); ! 39: pkzero((caddr_t) pk, sizeof (struct pack)); ! 40: pk->p_ifn = ifn; ! 41: pk->p_ofn = ofn; ! 42: pk->p_xsize = pk->p_rsize = PACKSIZE; ! 43: pk->p_rwindow = pk->p_swindow = WINDOWS; ! 44: /* allocate input windows */ ! 45: for (i = 0; i < pk->p_rwindow; i++) { ! 46: if ((bp = (char **) GETEPACK) == NULL) ! 47: break; ! 48: *bp = (char *) pk->p_ipool; ! 49: pk->p_ipool = bp; ! 50: } ! 51: if (i == 0) ! 52: return(NULL); ! 53: pk->p_rwindow = i; ! 54: ! 55: /* start synchronization */ ! 56: pk->p_msg = pk->p_rmsg = M_INITA; ! 57: for (i = 0; i < NPLINES; i++) { ! 58: if (pklines[i] == NULL) { ! 59: pklines[i] = pk; ! 60: break; ! 61: } ! 62: } ! 63: if (i >= NPLINES) ! 64: return(NULL); ! 65: pkoutput(pk); ! 66: ! 67: while ((pk->p_state & LIVE) == 0) { ! 68: PKGETPKT(pk); ! 69: } ! 70: ! 71: pkreset(pk); ! 72: return(pk); ! 73: } ! 74: ! 75: ! 76: /* ! 77: * input framing and block checking. ! 78: * frame layout for most devices is: ! 79: * ! 80: * S|K|X|Y|C|Z| ... data ... | ! 81: * ! 82: * where S == initial synch byte ! 83: * K == encoded frame size (indexes pksizes[]) ! 84: * X, Y == block check bytes ! 85: * C == control byte ! 86: * Z == XOR of header (K^X^Y^C) ! 87: * data == 0 or more data bytes ! 88: * ! 89: */ ! 90: ! 91: int pksizes[] = { ! 92: 1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1 ! 93: }; ! 94: ! 95: #define GETRIES 5 ! 96: /* ! 97: * Pseudo-dma byte collection. ! 98: */ ! 99: ! 100: pkgetpack(ipk) ! 101: struct pack *ipk; ! 102: { ! 103: int ret, k, tries; ! 104: register char *p; ! 105: struct pack *pk; ! 106: struct header *h; ! 107: unsigned short sum; ! 108: int ifn; ! 109: char **bp; ! 110: char hdchk; ! 111: ! 112: if (Conbad > CONBAD /* || Ntimeout > NTIMEOUT */) ! 113: pkfail(); ! 114: pk = PADDR; ! 115: ifn = pk->p_ifn; ! 116: ! 117: /* find HEADER */ ! 118: for (tries = 0; tries < GETRIES; ) { ! 119: p = (caddr_t) &pk->p_ihbuf; ! 120: if ((ret = pkcget(ifn, p, 1)) < 0) { ! 121: /* set up retransmit or REJ */ ! 122: tries++; ! 123: pk->p_msg |= pk->p_rmsg; ! 124: if (pk->p_msg == 0) ! 125: pk->p_msg |= M_RR; ! 126: if ((pk->p_state & LIVE) == LIVE) ! 127: pk->p_state |= RXMIT; ! 128: pkoutput(pk); ! 129: continue; ! 130: } ! 131: if (*p != SYN) ! 132: continue; ! 133: p++; ! 134: ret = pkcget(ifn, p, HDRSIZ - 1); ! 135: if (ret == -1) ! 136: continue; ! 137: break; ! 138: } ! 139: if (tries >= GETRIES) { ! 140: PKDEBUG(4, "tries = %d\n", tries); ! 141: pkfail(); ! 142: } ! 143: ! 144: h = (struct header * ) &pk->p_ihbuf; ! 145: p = (caddr_t) h; ! 146: hdchk = p[1] ^ p[2] ^ p[3] ^ p[4]; ! 147: p += 2; ! 148: sum = (unsigned) *p++ & 0377; ! 149: sum |= (unsigned) *p << 8; ! 150: h->sum = sum; ! 151: PKDEBUG(7, "rec h->cntl %o\n", (unsigned) h->cntl); ! 152: k = h->ksize; ! 153: if (hdchk != h->ccntl) { ! 154: /* bad header */ ! 155: PKDEBUG(7, "bad header %o,", hdchk); ! 156: PKDEBUG(7, "h->ccntl %o\n", h->ccntl); ! 157: Conbad++; ! 158: return; ! 159: } ! 160: if (k == 9) { ! 161: if (h->sum + h->cntl == CHECK) { ! 162: pkcntl(h->cntl, pk); ! 163: Conbad = 0; ! 164: PKDEBUG(7, "state - %o\n", pk->p_state); ! 165: } ! 166: else { ! 167: /* bad header */ ! 168: Conbad++; ! 169: PKDEBUG(7, "bad header %o\n", h->cntl); ! 170: pk->p_state |= BADFRAME; ! 171: } ! 172: return; ! 173: } ! 174: if (k && pksizes[k] == pk->p_rsize) { ! 175: pk->p_rpr = h->cntl & MOD8; ! 176: pksack(pk); ! 177: Conbad = 0; ! 178: bp = pk->p_ipool; ! 179: pk->p_ipool = (char **) *bp; ! 180: if (bp == NULL) { ! 181: PKDEBUG(7, "bp NULL %s\n", ""); ! 182: return; ! 183: } ! 184: } ! 185: else { ! 186: Conbad++; ! 187: return; ! 188: } ! 189: ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); ! 190: PKASSERT(ret != -1, "PKGETPKT CAN't READ %d", ret); ! 191: pkdata(h->cntl, h->sum, pk, (char *) bp); ! 192: return; ! 193: } ! 194: ! 195: ! 196: pkdata(c, sum, pk, bp) ! 197: char c; ! 198: short sum; ! 199: register struct pack *pk; ! 200: char **bp; ! 201: { ! 202: register x; ! 203: int t; ! 204: char m; ! 205: ! 206: if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { ! 207: pk->p_msg |= pk->p_rmsg; ! 208: pkoutput(pk); ! 209: goto drop; ! 210: } ! 211: t = next[pk->p_pr]; ! 212: for(x=pk->p_pr; x!=t; x = (x-1)&7) { ! 213: if (pk->p_is[x] == 0) ! 214: goto slot; ! 215: } ! 216: drop: ! 217: *bp = (char *)pk->p_ipool; ! 218: pk->p_ipool = bp; ! 219: return; ! 220: ! 221: slot: ! 222: m = mask[x]; ! 223: pk->p_imap |= m; ! 224: pk->p_is[x] = c; ! 225: pk->p_isum[x] = sum; ! 226: pk->p_ib[x] = (char *)bp; ! 227: return; ! 228: } ! 229: ! 230: ! 231: ! 232: /* ! 233: * setup input transfers ! 234: */ ! 235: pkrstart(pk) ! 236: {} ! 237: ! 238: /* ! 239: * Start transmission on output device associated with pk. ! 240: * For asynch devices (t_line==1) framing is ! 241: * imposed. For devices with framing and crc ! 242: * in the driver (t_line==2) the transfer is ! 243: * passed on to the driver. ! 244: */ ! 245: pkxstart(pk, cntl, x) ! 246: struct pack *pk; ! 247: char cntl; ! 248: register x; ! 249: { ! 250: register char *p; ! 251: int ret; ! 252: short checkword; ! 253: char hdchk; ! 254: ! 255: p = (caddr_t) &pk->p_ohbuf; ! 256: *p++ = SYN; ! 257: if (x < 0) { ! 258: *p++ = hdchk = 9; ! 259: checkword = cntl; ! 260: } ! 261: else { ! 262: *p++ = hdchk = pk->p_lpsize; ! 263: checkword = pk->p_osum[x] ^ (unsigned)(cntl&0377); ! 264: } ! 265: checkword = CHECK - checkword; ! 266: *p = checkword; ! 267: hdchk ^= *p++; ! 268: *p = checkword>>8; ! 269: hdchk ^= *p++; ! 270: *p = cntl; ! 271: hdchk ^= *p++; ! 272: *p = hdchk; ! 273: /* writes */ ! 274: PKDEBUG(7, "send %o\n", (unsigned) cntl); ! 275: p = (caddr_t) & pk->p_ohbuf; ! 276: if (x < 0) { ! 277: GENERROR(p, HDRSIZ); ! 278: ret = write(pk->p_ofn, p, HDRSIZ); ! 279: PKASSERT(ret == HDRSIZ, "PKXSTART ret %d", ret); ! 280: } ! 281: else { ! 282: char buf[PACKSIZE + HDRSIZ], *b; ! 283: int i; ! 284: for (i = 0, b = buf; i < HDRSIZ; i++) ! 285: *b++ = *p++; ! 286: for (i = 0, p = pk->p_ob[x]; i < pk->p_rsize; i++) ! 287: *b++ = *p++; ! 288: GENERROR(buf, pk->p_rsize + HDRSIZ); ! 289: ret = write(pk->p_ofn, buf, pk->p_rsize + HDRSIZ); ! 290: PKASSERT(ret == pk->p_rsize + HDRSIZ, ! 291: "PKXSTART ret %d", ret); ! 292: } ! 293: if (pk->p_msg) ! 294: pkoutput(pk); ! 295: return; ! 296: } ! 297: ! 298: ! 299: pkmove(p1, p2, count, flag) ! 300: char *p1, *p2; ! 301: int count, flag; ! 302: { ! 303: char *s, *d; ! 304: int i; ! 305: if (flag == B_WRITE) { ! 306: s = p2; ! 307: d = p1; ! 308: } ! 309: else { ! 310: s = p1; ! 311: d = p2; ! 312: } ! 313: for (i = 0; i < count; i++) ! 314: *d++ = *s++; ! 315: return; ! 316: } ! 317: ! 318: ! 319: /*** ! 320: * pkcget(fn, b, n) get n characters from input ! 321: * char *b; - buffer for characters ! 322: * int fn; - file descriptor ! 323: * int n; - requested number of characters ! 324: * ! 325: * return codes: ! 326: * n - number of characters returned ! 327: * 0 - end of file ! 328: */ ! 329: ! 330: jmp_buf Getjbuf; ! 331: cgalarm() { longjmp(Getjbuf, 1); } ! 332: ! 333: pkcget(fn, b, n) ! 334: int fn, n; ! 335: char *b; ! 336: { ! 337: int nchars, ret; ! 338: ! 339: if (setjmp(Getjbuf)) { ! 340: Ntimeout++; ! 341: PKDEBUG(4, "alarm %d\n", Ntimeout); ! 342: return(-1); ! 343: } ! 344: signal(SIGALRM, cgalarm); ! 345: ! 346: for (nchars = 0; nchars < n; nchars += ret) { ! 347: alarm(PKTIME); ! 348: ret = read(fn, b, n - nchars); ! 349: if (ret == 0) { ! 350: alarm(0); ! 351: return(-1); ! 352: } ! 353: PKASSERT(ret > 0, "PKCGET READ %d", ret); ! 354: b += ret; ! 355: } ! 356: alarm(0); ! 357: return(0); ! 358: } ! 359: ! 360: ! 361: generror(p, s) ! 362: char *p; ! 363: int s; ! 364: { ! 365: int r; ! 366: if (Errorrate != 0 && (rand() % Errorrate) == 0) { ! 367: r = rand() % s; ! 368: fprintf(stderr, "gen err at %o, (%o), ", r, (unsigned) *(p + r)); ! 369: *(p + r) += 1; ! 370: } ! 371: return; ! 372: } ! 373: ! 374:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.