|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)pk1.c 5.9 (Berkeley) 5/30/86"; ! 3: #endif ! 4: ! 5: #include <signal.h> ! 6: #include "uucp.h" ! 7: #include "pk.h" ! 8: #include <setjmp.h> ! 9: #ifdef BSD4_2 ! 10: #include <sys/time.h> ! 11: #endif BSD4_2 ! 12: ! 13: #ifdef VMS ! 14: #include <eunice/eunice.h> ! 15: #include <vms/iodef.h> ! 16: #include <vms/ssdef.h> ! 17: int iomask[2]; ! 18: #endif VMS ! 19: ! 20: #define PKMAXSTMSG 40 ! 21: #define MAXPKTIME 32 /* was 16 */ ! 22: #define CONNODATA 10 ! 23: #define MAXTIMEOUT 32 ! 24: ! 25: extern int errno; ! 26: extern int Retries; ! 27: extern char *sys_errlist[]; ! 28: extern jmp_buf Sjbuf; ! 29: extern char *malloc(); ! 30: ! 31: int Connodata = 0; ! 32: int Ntimeout = 0; ! 33: int pktimeout = 4; ! 34: int pktimeskew = 2; ! 35: /* ! 36: * packet driver support routines ! 37: * ! 38: */ ! 39: ! 40: extern struct pack *pklines[]; ! 41: ! 42: /* ! 43: * start initial synchronization. ! 44: */ ! 45: ! 46: struct pack * ! 47: pkopen(ifn, ofn) ! 48: int ifn, ofn; ! 49: { ! 50: register struct pack *pk; ! 51: register char **bp; ! 52: register int i; ! 53: ! 54: if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL) ! 55: return NULL; ! 56: bzero((caddr_t) pk, sizeof (struct pack)); ! 57: pk->p_ifn = ifn; ! 58: pk->p_ofn = ofn; ! 59: pk->p_xsize = pk->p_rsize = PACKSIZE; ! 60: pk->p_rwindow = pk->p_swindow = WINDOWS; ! 61: /* allocate input windows */ ! 62: for (i = 0; i < pk->p_rwindow; i++) { ! 63: if ((bp = (char **) malloc((unsigned)pk->p_xsize)) == NULL) ! 64: break; ! 65: *bp = (char *) pk->p_ipool; ! 66: pk->p_ipool = bp; ! 67: } ! 68: if (i == 0) { ! 69: DEBUG(1, "pkopen: can't malloc i = 0\n", CNULL); ! 70: return NULL; ! 71: } ! 72: pk->p_rwindow = i; ! 73: ! 74: /* start synchronization */ ! 75: pk->p_msg = pk->p_rmsg = M_INITA; ! 76: for (i = 0; i < NPLINES; i++) { ! 77: if (pklines[i] == NULL) { ! 78: pklines[i] = pk; ! 79: break; ! 80: } ! 81: } ! 82: if (i >= NPLINES) { ! 83: DEBUG(1,"pkopen: i>=NPLINES\n", CNULL); ! 84: return NULL; ! 85: } ! 86: pkoutput(pk); ! 87: ! 88: for (i = 0; i < PKMAXSTMSG; i++) { ! 89: pkgetpack(pk); ! 90: if ((pk->p_state & LIVE) != 0) ! 91: break; ! 92: } ! 93: if (i >= PKMAXSTMSG) { ! 94: DEBUG(1, "pkopen: i>= PKMAXSTMSG\n", CNULL); ! 95: return NULL; ! 96: } ! 97: ! 98: pkreset(pk); ! 99: return pk; ! 100: } ! 101: ! 102: ! 103: /* ! 104: * input framing and block checking. ! 105: * frame layout for most devices is: ! 106: * ! 107: * S|K|X|Y|C|Z| ... data ... | ! 108: * ! 109: * where S == initial synch byte ! 110: * K == encoded frame size (indexes pksizes[]) ! 111: * X, Y == block check bytes ! 112: * C == control byte ! 113: * Z == XOR of header (K^X^Y^C) ! 114: * data == 0 or more data bytes ! 115: * ! 116: */ ! 117: ! 118: int pksizes[] = { ! 119: 1, 32, 64, 128, 256, 512, 1024, 2048, 4096, 1 ! 120: }; ! 121: ! 122: #define GETRIES 10 ! 123: /* ! 124: * Pseudo-dma byte collection. ! 125: */ ! 126: ! 127: pkgetpack(pk) ! 128: register struct pack *pk; ! 129: { ! 130: int k, tries, noise; ! 131: register char *p; ! 132: register struct header *h; ! 133: unsigned short sum; ! 134: int ifn; ! 135: char **bp; ! 136: char hdchk; ! 137: ! 138: if ((pk->p_state & DOWN) || Connodata > CONNODATA || Ntimeout > MAXTIMEOUT) ! 139: pkfail(); ! 140: ifn = pk->p_ifn; ! 141: ! 142: /* find HEADER */ ! 143: for (tries = 0, noise = 0; tries < GETRIES; ) { ! 144: p = (caddr_t) &pk->p_ihbuf; ! 145: if (pkcget(ifn, p, 1) == SUCCESS) { ! 146: if (*p++ == SYN) { ! 147: if (pkcget(ifn, p, HDRSIZ-1) == SUCCESS) ! 148: break; ! 149: } else { ! 150: if (noise++ < 10 || noise < (3*pk->p_rsize)) ! 151: continue; ! 152: } ! 153: DEBUG(4, "Noisy line - set up RXMIT\n", CNULL); ! 154: noise = 0; ! 155: } ! 156: /* set up retransmit or REJ */ ! 157: tries++; ! 158: Retries++; ! 159: pk->p_msg |= pk->p_rmsg; ! 160: if (pk->p_msg == 0) ! 161: pk->p_msg |= M_RR; ! 162: if ((pk->p_state & LIVE) == LIVE) ! 163: pk->p_state |= RXMIT; ! 164: pkoutput(pk); ! 165: } ! 166: if (tries >= GETRIES) { ! 167: DEBUG(4, "tries = %d\n", tries); ! 168: pkfail(); ! 169: } ! 170: ! 171: Connodata++; ! 172: h = (struct header *) &pk->p_ihbuf; ! 173: p = (caddr_t) h; ! 174: hdchk = p[1] ^ p[2] ^ p[3] ^ p[4]; ! 175: p += 2; ! 176: sum = (unsigned) *p++ & 0377; ! 177: sum |= (unsigned) *p << 8; ! 178: h->sum = sum; ! 179: DEBUG(7, "rec h->cntl 0%o\n", h->cntl&0xff); ! 180: k = h->ksize; ! 181: if (hdchk != h->ccntl) { ! 182: /* bad header */ ! 183: DEBUG(7, "bad header 0%o,", hdchk&0xff); ! 184: DEBUG(7, "h->ccntl 0%o\n", h->ccntl&0xff); ! 185: return; ! 186: } ! 187: if (k == 9) { ! 188: if (((h->sum + h->cntl) & 0xffff) == CHECK) { ! 189: pkcntl(h->cntl, pk); ! 190: DEBUG(7, "state - 0%o\n", pk->p_state); ! 191: } else { ! 192: /* bad header */ ! 193: pk->p_state |= BADFRAME; ! 194: DEBUG(7, "bad header (k==9) 0%o\n", h->cntl&0xff); ! 195: } ! 196: return; ! 197: } ! 198: if (k && pksizes[k] == pk->p_rsize) { ! 199: pk->p_rpr = (h->cntl >> 3) & MOD8; ! 200: pksack(pk); ! 201: bp = pk->p_ipool; ! 202: if (bp == NULL) { ! 203: DEBUG(7, "bp NULL %s\n", ""); ! 204: return; ! 205: } ! 206: pk->p_ipool = (char **) *bp; ! 207: Connodata = 0; ! 208: } else ! 209: return; ! 210: ! 211: if (pkcget(pk->p_ifn, (char *) bp, pk->p_rsize) == SUCCESS) { ! 212: pkdata(h->cntl, h->sum, pk, (char **) bp); ! 213: } else { ! 214: *bp = (char *)pk->p_ipool; ! 215: pk->p_ipool = bp; ! 216: } ! 217: } ! 218: ! 219: pkdata(c, sum, pk, bp) ! 220: char c; ! 221: unsigned short sum; ! 222: register struct pack *pk; ! 223: char **bp; ! 224: { ! 225: register x; ! 226: int t; ! 227: char m; ! 228: ! 229: if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { ! 230: pk->p_msg |= pk->p_rmsg; ! 231: pkoutput(pk); ! 232: goto drop; ! 233: } ! 234: t = next[pk->p_pr]; ! 235: for(x=pk->p_pr; x!=t; x = (x-1)&7) { ! 236: if (pk->p_is[x] == 0) ! 237: goto slot; ! 238: } ! 239: drop: ! 240: *bp = (char *)pk->p_ipool; ! 241: pk->p_ipool = bp; ! 242: return; ! 243: ! 244: slot: ! 245: m = mask[x]; ! 246: pk->p_imap |= m; ! 247: pk->p_is[x] = c; ! 248: pk->p_isum[x] = sum; ! 249: pk->p_ib[x] = (char *)bp; ! 250: } ! 251: ! 252: /* ! 253: * setup input transfers ! 254: */ ! 255: #define PKMAXBUF 128 ! 256: /* ! 257: * Start transmission on output device associated with pk. ! 258: * For asynch devices (t_line==1) framing is ! 259: * imposed. For devices with framing and crc ! 260: * in the driver (t_line==2) the transfer is ! 261: * passed on to the driver. ! 262: */ ! 263: pkxstart(pk, cntl, x) ! 264: register struct pack *pk; ! 265: char cntl; ! 266: register x; ! 267: { ! 268: register char *p; ! 269: short checkword; ! 270: char hdchk; ! 271: ! 272: p = (caddr_t) &pk->p_ohbuf; ! 273: *p++ = SYN; ! 274: if (x < 0) { ! 275: *p++ = hdchk = 9; ! 276: checkword = cntl; ! 277: } else { ! 278: *p++ = hdchk = pk->p_lpsize; ! 279: checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377); ! 280: } ! 281: checkword = CHECK - checkword; ! 282: *p = checkword; ! 283: hdchk ^= *p++; ! 284: *p = checkword>>8; ! 285: hdchk ^= *p++; ! 286: *p = cntl; ! 287: hdchk ^= *p++; ! 288: *p = hdchk; ! 289: /* writes */ ! 290: DEBUG(7, "send 0%o\n", cntl&0xff); ! 291: p = (caddr_t) & pk->p_ohbuf; ! 292: if (x < 0) { ! 293: if(write(pk->p_ofn, p, HDRSIZ) != HDRSIZ) { ! 294: alarm(0); ! 295: logent("PKXSTART write failed", sys_errlist[errno]); ! 296: longjmp(Sjbuf, 4); ! 297: } ! 298: } else { ! 299: char buf[PKMAXBUF + HDRSIZ + TAILSIZE], *b; ! 300: int i; ! 301: for (i = 0, b = buf; i < HDRSIZ; i++) ! 302: *b++ = *p++; ! 303: for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) ! 304: *b++ = *p++; ! 305: #if TAILSIZE != 0 ! 306: for (i = 0; i < TAILSIZE; i++) ! 307: *b++ = '\0'; ! 308: #endif TAILSIZE ! 309: if (write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ + TAILSIZE) ! 310: != (HDRSIZ + TAILSIZE + pk->p_xsize)) { ! 311: alarm(0); ! 312: logent("PKXSTART write failed", sys_errlist[errno]); ! 313: longjmp(Sjbuf, 5); ! 314: } ! 315: Connodata = 0; ! 316: } ! 317: if (pk->p_msg) ! 318: pkoutput(pk); ! 319: } ! 320: ! 321: ! 322: pkmove(p1, p2, count, flag) ! 323: char *p1, *p2; ! 324: int count, flag; ! 325: { ! 326: register char *s, *d; ! 327: register int i; ! 328: ! 329: if (flag == B_WRITE) { ! 330: s = p2; ! 331: d = p1; ! 332: } else { ! 333: s = p1; ! 334: d = p2; ! 335: } ! 336: for (i = 0; i < count; i++) ! 337: *d++ = *s++; ! 338: } ! 339: ! 340: ! 341: /* ! 342: * get n characters from input ! 343: * ! 344: * return codes: ! 345: * n - number of characters returned ! 346: * 0 - end of file ! 347: */ ! 348: ! 349: jmp_buf Getjbuf; ! 350: cgalarm() ! 351: { ! 352: longjmp(Getjbuf, 1); ! 353: } ! 354: ! 355: pkcget(fn, b, n) ! 356: int fn; ! 357: register char *b; ! 358: register int n; ! 359: { ! 360: register int ret; ! 361: extern int linebaudrate; ! 362: #ifdef BSD4_2 ! 363: long r, itime = 100000L; /* guess it's been 1/10th second since we ! 364: last read the line */ ! 365: struct timeval tv; ! 366: #endif BSD4_2 ! 367: #ifdef VMS ! 368: short iosb[4]; ! 369: int SYS$QioW(); /* use this for long reads on vms */ ! 370: #endif VMS ! 371: ! 372: if (setjmp(Getjbuf)) { ! 373: Ntimeout++; ! 374: DEBUG(4, "pkcget: alarm %d\n", pktimeout * 1000 + Ntimeout); ! 375: pktimeout += pktimeskew; ! 376: if (pktimeout > MAXPKTIME) ! 377: pktimeout = MAXPKTIME; ! 378: return FAIL; ! 379: } ! 380: signal(SIGALRM, cgalarm); ! 381: ! 382: alarm(pktimeout); ! 383: while (n > 0) { ! 384: #ifdef BSD4_2 ! 385: if (linebaudrate > 0) { ! 386: r = n * 100000L; ! 387: r = r / linebaudrate; ! 388: r = (r * 100) - itime; ! 389: itime = 0; ! 390: /* we predict that more than 1/50th of a ! 391: second will go by before the read will ! 392: give back all that we want. */ ! 393: if (r > 20000) { ! 394: tv.tv_sec = r / 1000000L; ! 395: tv.tv_usec = r % 1000000L; ! 396: DEBUG(11, "PKCGET stall for %d", tv.tv_sec); ! 397: DEBUG(11, ".%06d sec\n", tv.tv_usec); ! 398: (void) select (0, (int *)0, (int *)0, (int *)0, &tv); ! 399: } ! 400: } ! 401: #endif BSD4_2 ! 402: #ifndef VMS ! 403: ret = read(fn, b, n); ! 404: #else VMS ! 405: _$Cancel_IO_On_Signal = FD_FAB_Pointer[fn]; ! 406: ret = SYS$QioW(_$EFN,(FD_FAB_Pointer[fn]->fab).fab$l_stv, ! 407: IO$_READVBLK|IO$M_NOFILTR|IO$M_NOECHO, ! 408: iosb,0,0,b,n,0, ! 409: iomask,0,0); ! 410: _$Cancel_IO_On_Signal = 0; ! 411: if (ret == SS$_NORMAL) ! 412: ret = iosb[1]+iosb[3]; /* get length of transfer */ ! 413: else ! 414: ret = 0; ! 415: #endif VMS ! 416: if (ret == 0) { ! 417: alarm(0); ! 418: return FAIL; ! 419: } ! 420: if (ret <= 0) { ! 421: alarm(0); ! 422: logent(sys_errlist[errno],"FAILED pkcget Read"); ! 423: longjmp(Sjbuf, 6); ! 424: } ! 425: b += ret; ! 426: n -= ret; ! 427: } ! 428: alarm(0); ! 429: return SUCCESS; ! 430: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.