|
|
1.1 ! root 1: /* /sccs/src/cmd/uucp/s.pk1.c ! 2: pk1.c 1.2 8/30/84 17:37:38 ! 3: */ ! 4: #include "uucp.h" ! 5: VERSION(@(#)pk1.c 1.2); ! 6: ! 7: #define USER 1 ! 8: ! 9: #include "pk.h" ! 10: #include <sys/buf.h> ! 11: ! 12: ! 13: /* ! 14: ** Code added to allow translation of states from numbers to ! 15: ** letters, to be done in such a way as to be meaningful to ! 16: ** John Q. Public ! 17: */ ! 18: struct { ! 19: int state; ! 20: char *msg; ! 21: } st_trans[] = { ! 22: DEAD, "Dead!", ! 23: INITa, "INIT code a", ! 24: INITb, "INIT code b", ! 25: LIVE, "O.K.", ! 26: RXMIT, "Rcv/Xmit", ! 27: RREJ, "RREJ?", ! 28: PDEBUG, "PDEBUG?", ! 29: DRAINO, "Draino...", ! 30: WAITO, "Waiting", ! 31: DOWN, "Link down", ! 32: RCLOSE, "RCLOSE?", ! 33: BADFRAME, "Bad frame", ! 34: -1, "End of the line", ! 35: }; ! 36: ! 37: ! 38: ! 39: #define PKMAXSTMSG 40 ! 40: extern int Errorrate; ! 41: int Connodata = 0; /* Continuous Non Valid Data Count */ ! 42: int Ntimeout = 0; ! 43: #define CONNODATA 20 /* Max Continuous Non Valid Data Count */ ! 44: #define NTIMEOUT 50 /* This is not currently used, but maybe future */ ! 45: ! 46: /* ! 47: * packet driver support routines ! 48: * ! 49: */ ! 50: extern struct pack *pklines[]; ! 51: ! 52: /* ! 53: * start initial synchronization. ! 54: */ ! 55: struct pack * ! 56: pkopen(ifn, ofn) ! 57: int ifn, ofn; ! 58: { ! 59: register struct pack *pk; ! 60: register char **bp; ! 61: register int i; ! 62: char *malloc(); ! 63: ! 64: if (++pkactive >= NPLINES) ! 65: return(NULL); ! 66: if ((pk = (struct pack *) malloc(sizeof (struct pack))) == NULL) ! 67: return(NULL); ! 68: pkzero((caddr_t) pk, sizeof (struct pack)); ! 69: pk->p_ifn = ifn; ! 70: pk->p_ofn = ofn; ! 71: pk->p_xsize = pk->p_rsize = PACKSIZE; ! 72: pk->p_rwindow = pk->p_swindow = WINDOWS; ! 73: ! 74: /* ! 75: * allocate input window ! 76: */ ! 77: for (i = 0; i < pk->p_rwindow; i++) { ! 78: if ((bp = (char **) malloc((unsigned) pk->p_xsize)) == NULL) ! 79: break; ! 80: *bp = (char *) pk->p_ipool; ! 81: pk->p_ipool = bp; ! 82: } ! 83: if (i == 0) ! 84: return(NULL); ! 85: pk->p_rwindow = i; ! 86: ! 87: /* ! 88: * start synchronization ! 89: */ ! 90: pk->p_msg = pk->p_rmsg = M_INITA; ! 91: for (i = 0; i < NPLINES; i++) { ! 92: if (pklines[i] == NULL) { ! 93: pklines[i] = pk; ! 94: break; ! 95: } ! 96: } ! 97: if (i >= NPLINES) ! 98: return(NULL); ! 99: pkoutput(pk); ! 100: ! 101: for (i = 0; i < PKMAXSTMSG; i++) { ! 102: pkgetpack(pk); ! 103: if ((pk->p_state & LIVE) != 0) ! 104: break; ! 105: } ! 106: if (i >= PKMAXSTMSG) ! 107: return(NULL); ! 108: ! 109: pkreset(pk); ! 110: return(pk); ! 111: } ! 112: ! 113: /* ! 114: * input framing and block checking. ! 115: * frame layout for most devices is: ! 116: * ! 117: * S|K|X|Y|C|Z| ... data ... | ! 118: * ! 119: * where S == initial synch byte ! 120: * K == encoded frame size (indexes pksizes[]) ! 121: * X, Y == block check bytes ! 122: * C == control byte ! 123: * Z == XOR of header (K^X^Y^C) ! 124: * data == 0 or more data bytes ! 125: * ! 126: */ ! 127: #define GETRIES 10 ! 128: #define GESYN 4100 /* overkill */ ! 129: ! 130: /* ! 131: * Pseudo-dma byte collection. ! 132: */ ! 133: pkgetpack(ipk) ! 134: register struct pack *ipk; ! 135: { ! 136: register char *p; ! 137: register struct pack *pk; ! 138: register struct header *h; ! 139: unsigned short sum; ! 140: int i, ret, k, tries, ifn, notsyn; ! 141: char **bp, hdchk, msgline[80], delimc; ! 142: ! 143: pk = ipk; ! 144: if ((pk->p_state & DOWN) || ! 145: Connodata > CONNODATA /* || Ntimeout > NTIMEOUT */ ) ! 146: pkfail(); ! 147: ifn = pk->p_ifn; ! 148: ! 149: /*= ! 150: * find HEADER ! 151: */ ! 152: for (tries = 0, notsyn = 0; tries < GETRIES && notsyn < GESYN; ) { ! 153: p = (caddr_t) &pk->p_ihbuf; ! 154: if ((ret = pkcget(ifn, p, 1)) < 0) { ! 155: ! 156: /* ! 157: * set up retransmit or REJ ! 158: */ ! 159: tries++; ! 160: pk->p_msg |= pk->p_rmsg; ! 161: if (pk->p_msg == 0) ! 162: pk->p_msg |= M_RR; ! 163: if ((pk->p_state & LIVE) == LIVE) ! 164: pk->p_state |= RXMIT; ! 165: pkoutput(pk); ! 166: continue; ! 167: } ! 168: if (*p != SYN) { ! 169: notsyn++; ! 170: continue; ! 171: } ! 172: p++; ! 173: ret = pkcget(ifn, p, HDRSIZ - 1); ! 174: if (ret == -1) ! 175: continue; ! 176: break; ! 177: } ! 178: if (tries >= GETRIES) { ! 179: DEBUG(4, "tries = %d\n", tries); ! 180: pkfail(); ! 181: } ! 182: if (notsyn >= GESYN) { ! 183: DEBUG(4, "notsyn = %d\n", notsyn); ! 184: pkfail(); ! 185: } ! 186: ! 187: Connodata++; ! 188: DEBUG(9, "pkgetpack: Connodata=%d\n", Connodata); ! 189: h = (struct header * ) &pk->p_ihbuf; ! 190: p = (caddr_t) h; ! 191: hdchk = p[1] ^ p[2] ^ p[3] ^ p[4]; ! 192: p += 2; ! 193: sum = (unsigned) *p++ & 0377; ! 194: sum |= (unsigned) *p << 8; ! 195: h->sum = sum; ! 196: DEBUG(9, "rec h->cntl %o\n", (unsigned) h->cntl); ! 197: k = h->ksize; ! 198: if (hdchk != h->ccntl) { ! 199: ! 200: /* ! 201: * bad header ! 202: */ ! 203: DEBUG(7, "bad header %o,", hdchk); ! 204: DEBUG(7, "h->ccntl %o\n", h->ccntl); ! 205: return; ! 206: } ! 207: if (k == 9) { ! 208: if (h->sum + h->cntl == CHECK) { ! 209: pkcntl(h->cntl, pk); ! 210: /* ! 211: ** New code added to make the state diagnostics ! 212: ** meaningful to human beings that can't figure ! 213: ** out bizarre, silly, cryptic numbers. ! 214: ** ! 215: ** Exhibit A: DEBUG(7, "state - %o\n", pk->p_state); ! 216: */ ! 217: if(Debug >= 7) { ! 218: sprintf(msgline,"state -"); ! 219: delimc = ' '; ! 220: for(i=0;st_trans[i].state!= -1;i++) { ! 221: if(pk->p_state&st_trans[i].state){ ! 222: sprintf(msgline,"%s%c[%s]",msgline,delimc, ! 223: st_trans[i].msg); ! 224: delimc = '&'; ! 225: } ! 226: } ! 227: sprintf(msgline,"%s (%o)\n",msgline,pk->p_state); ! 228: DEBUG(7,"%s",msgline); ! 229: } ! 230: ! 231: } else { ! 232: ! 233: /* ! 234: * bad header ! 235: */ ! 236: DEBUG(7, "bad header %o\n", h->cntl); ! 237: pk->p_state |= BADFRAME; ! 238: } ! 239: return; ! 240: } ! 241: if (k && pksizes[k] == pk->p_rsize) { ! 242: pk->p_rpr = h->cntl & MOD8; ! 243: pksack(pk); ! 244: bp = pk->p_ipool; ! 245: if ((bp = pk->p_ipool) == NULL) { ! 246: DEBUG(7, "bp NULL %s\n", ""); ! 247: return; ! 248: } ! 249: pk->p_ipool = (char **) *bp; ! 250: ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); ! 251: if (ret == 0) ! 252: pkdata(h->cntl, h->sum, pk, bp); ! 253: } ! 254: } ! 255: ! 256: ! 257: pkdata(c, sum, pk, bp) ! 258: register struct pack *pk; ! 259: unsigned short sum; ! 260: char c; ! 261: char **bp; ! 262: { ! 263: register x; ! 264: int t; ! 265: char m; ! 266: ! 267: if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { ! 268: pk->p_msg |= pk->p_rmsg; ! 269: pkoutput(pk); ! 270: goto drop; ! 271: } ! 272: t = next[pk->p_pr]; ! 273: for(x=pk->p_pr; x!=t; x = (x-1)&7) { ! 274: if (pk->p_is[x] == 0) ! 275: goto slot; ! 276: } ! 277: drop: ! 278: *bp = (char *)pk->p_ipool; ! 279: pk->p_ipool = bp; ! 280: return; ! 281: ! 282: slot: ! 283: m = mask[x]; ! 284: pk->p_imap |= m; ! 285: pk->p_is[x] = c; ! 286: pk->p_isum[x] = sum; ! 287: pk->p_ib[x] = (char *)bp; ! 288: return; ! 289: } ! 290: ! 291: #define PKMAXBUF 128 ! 292: ! 293: /* ! 294: * Start transmission on output device ! 295: * device associated with pk. ! 296: * For asynch devices (t_line==1) framing is ! 297: * imposed. For devices with framing and crc ! 298: * in the driver (t_line==2) the transfer is ! 299: * passed on to the driver. ! 300: */ ! 301: pkxstart(pk, cntl, x) ! 302: register struct pack *pk; ! 303: int x; ! 304: char cntl; ! 305: { ! 306: register char *p; ! 307: register short checkword; ! 308: register char hdchk; ! 309: int ret; ! 310: ! 311: p = (caddr_t) &pk->p_ohbuf; ! 312: *p++ = SYN; ! 313: if (x < 0) { ! 314: *p++ = hdchk = 9; ! 315: checkword = cntl; ! 316: } else { ! 317: *p++ = hdchk = pk->p_lpsize; ! 318: checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377); ! 319: } ! 320: checkword = CHECK - checkword; ! 321: *p = checkword; ! 322: hdchk ^= *p++; ! 323: *p = checkword>>8; ! 324: hdchk ^= *p++; ! 325: *p = cntl; ! 326: hdchk ^= *p++; ! 327: *p = hdchk; ! 328: ! 329: /* ! 330: * writes ! 331: */ ! 332: DEBUG(9, "send %o\n", (unsigned) cntl); ! 333: p = (caddr_t) & pk->p_ohbuf; ! 334: if (x < 0) { ! 335: ret = write(pk->p_ofn, p, HDRSIZ); ! 336: PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret); ! 337: } else { ! 338: register char *b, *q; ! 339: register int i; ! 340: char buf[PKMAXBUF + HDRSIZ]; ! 341: ! 342: ! 343: /* ! 344: for (i = 0, b = buf; i < HDRSIZ; i++) ! 345: *b++ = *p++; ! 346: for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) ! 347: *b++ = *p++; ! 348: */ ! 349: i = HDRSIZ; ! 350: b = buf; ! 351: q = p; ! 352: do ! 353: *b++ = *q++; ! 354: while(--i); ! 355: if(i = pk->p_xsize){ ! 356: q = pk->p_ob[x]; ! 357: do ! 358: *b++ = *q++; ! 359: while(--i); ! 360: } ! 361: ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ); ! 362: PKASSERT(ret == pk->p_xsize + HDRSIZ, ! 363: "PKXSTART ret", "", ret); ! 364: } ! 365: if (pk->p_msg) ! 366: pkoutput(pk); ! 367: return; ! 368: } ! 369: ! 370: ! 371: ! 372: ! 373: /* ! 374: * get n characters from input ! 375: * b -> buffer for characters ! 376: * fn -> file descriptor ! 377: * n -> requested number of characters ! 378: * return: ! 379: * n -> number of characters returned ! 380: * 0 -> end of file ! 381: */ ! 382: jmp_buf Getjbuf; ! 383: cgalarm() { longjmp(Getjbuf, 1); } ! 384: int npkccall, npkctry, npkcnap, npkcchar; ! 385: ! 386: pkcget(fn, b, n) ! 387: register int n; ! 388: register char *b; ! 389: register int fn; ! 390: { ! 391: register int ret; ! 392: register int donap; ! 393: ! 394: if (n == 0) ! 395: return(0); ! 396: npkccall++; ! 397: donap = (linebaudrate > 0 && linebaudrate < 4800); ! 398: if (setjmp(Getjbuf)) { ! 399: Ntimeout++; ! 400: DEBUG(4, "alarm %d\n", Ntimeout); ! 401: return(-1); ! 402: } ! 403: (void) signal(SIGALRM, cgalarm); ! 404: ! 405: (void) alarm((unsigned) (n < HDRSIZ ? 10 : 20)); ! 406: while (1) { ! 407: if ((ret = read(fn, b, n)) == 0) { ! 408: (void) alarm(0); ! 409: return(-1); ! 410: } ! 411: npkctry++; ! 412: npkcchar += ret; ! 413: PKASSERT(ret > 0, "PKCGET READ", "", ret); ! 414: if ((n -= ret) <= 0) ! 415: break; ! 416: #ifdef PKSPEEDUP ! 417: if (donap) { ! 418: sleep(1); ! 419: npkcnap++; ! 420: #ifdef BSD4_2 ! 421: } else { ! 422: nap(HZ/6); ! 423: #endif BSD4_2 ! 424: } ! 425: #endif PKSPEEDUP ! 426: b += ret; ! 427: } ! 428: (void) alarm(0); ! 429: return(0); ! 430: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.