|
|
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: if ((bp = pk->p_ipool) == NULL) { ! 245: DEBUG(7, "bp NULL %s\n", ""); ! 246: return; ! 247: } ! 248: pk->p_ipool = (char **) *bp; ! 249: ret = pkcget(pk->p_ifn, (char *) bp, pk->p_rsize); ! 250: if (ret == 0) ! 251: pkdata(h->cntl, h->sum, pk, bp); ! 252: } ! 253: } ! 254: ! 255: ! 256: pkdata(c, sum, pk, bp) ! 257: register struct pack *pk; ! 258: unsigned short sum; ! 259: char c; ! 260: char **bp; ! 261: { ! 262: register x; ! 263: int t; ! 264: char m; ! 265: ! 266: if (pk->p_state & DRAINO || !(pk->p_state & LIVE)) { ! 267: pk->p_msg |= pk->p_rmsg; ! 268: pkoutput(pk); ! 269: goto drop; ! 270: } ! 271: t = next[pk->p_pr]; ! 272: for(x=pk->p_pr; x!=t; x = (x-1)&7) { ! 273: if (pk->p_is[x] == 0) ! 274: goto slot; ! 275: } ! 276: drop: ! 277: *bp = (char *)pk->p_ipool; ! 278: pk->p_ipool = bp; ! 279: return; ! 280: ! 281: slot: ! 282: m = mask[x]; ! 283: pk->p_imap |= m; ! 284: pk->p_is[x] = c; ! 285: pk->p_isum[x] = sum; ! 286: pk->p_ib[x] = (char *)bp; ! 287: return; ! 288: } ! 289: ! 290: #define PKMAXBUF 128 ! 291: ! 292: /* ! 293: * Start transmission on output device ! 294: * device associated with pk. ! 295: * For asynch devices (t_line==1) framing is ! 296: * imposed. For devices with framing and crc ! 297: * in the driver (t_line==2) the transfer is ! 298: * passed on to the driver. ! 299: */ ! 300: pkxstart(pk, cntl, x) ! 301: register struct pack *pk; ! 302: int x; ! 303: char cntl; ! 304: { ! 305: register char *p; ! 306: register short checkword; ! 307: register char hdchk; ! 308: int ret; ! 309: ! 310: p = (caddr_t) &pk->p_ohbuf; ! 311: *p++ = SYN; ! 312: if (x < 0) { ! 313: *p++ = hdchk = 9; ! 314: checkword = cntl; ! 315: } else { ! 316: *p++ = hdchk = pk->p_lpsize; ! 317: checkword = pk->p_osum[x] ^ (unsigned)(cntl & 0377); ! 318: } ! 319: checkword = CHECK - checkword; ! 320: *p = checkword; ! 321: hdchk ^= *p++; ! 322: *p = checkword>>8; ! 323: hdchk ^= *p++; ! 324: *p = cntl; ! 325: hdchk ^= *p++; ! 326: *p = hdchk; ! 327: ! 328: /* ! 329: * writes ! 330: */ ! 331: DEBUG(9, "send %o\n", (unsigned) cntl); ! 332: p = (caddr_t) & pk->p_ohbuf; ! 333: if (x < 0) { ! 334: ret = write(pk->p_ofn, p, HDRSIZ); ! 335: PKASSERT(ret == HDRSIZ, "PKXSTART ret", "", ret); ! 336: } else { ! 337: register char *b, *q; ! 338: register int i; ! 339: char buf[PKMAXBUF + HDRSIZ]; ! 340: ! 341: ! 342: /* ! 343: for (i = 0, b = buf; i < HDRSIZ; i++) ! 344: *b++ = *p++; ! 345: for (i = 0, p = pk->p_ob[x]; i < pk->p_xsize; i++) ! 346: *b++ = *p++; ! 347: */ ! 348: i = HDRSIZ; ! 349: b = buf; ! 350: q = p; ! 351: do ! 352: *b++ = *q++; ! 353: while(--i); ! 354: if(i = pk->p_xsize){ ! 355: q = pk->p_ob[x]; ! 356: do ! 357: *b++ = *q++; ! 358: while(--i); ! 359: } ! 360: ret = write(pk->p_ofn, buf, pk->p_xsize + HDRSIZ); ! 361: PKASSERT(ret == pk->p_xsize + HDRSIZ, ! 362: "PKXSTART ret", "", ret); ! 363: } ! 364: if (pk->p_msg) ! 365: pkoutput(pk); ! 366: return; ! 367: } ! 368: ! 369: ! 370: ! 371: ! 372: /* ! 373: * get n characters from input ! 374: * b -> buffer for characters ! 375: * fn -> file descriptor ! 376: * n -> requested number of characters ! 377: * return: ! 378: * n -> number of characters returned ! 379: * 0 -> end of file ! 380: */ ! 381: jmp_buf Getjbuf; ! 382: cgalarm() { longjmp(Getjbuf, 1); } ! 383: int npkccall, npkctry, npkcnap, npkcchar; ! 384: ! 385: pkcget(fn, b, n) ! 386: register int n; ! 387: register char *b; ! 388: register int fn; ! 389: { ! 390: register int ret; ! 391: register int donap; ! 392: ! 393: if (n == 0) ! 394: return(0); ! 395: npkccall++; ! 396: donap = (linebaudrate > 0 && linebaudrate < 4800); ! 397: if (setjmp(Getjbuf)) { ! 398: Ntimeout++; ! 399: DEBUG(4, "alarm %d\n", Ntimeout); ! 400: return(-1); ! 401: } ! 402: (void) signal(SIGALRM, cgalarm); ! 403: ! 404: (void) alarm((unsigned) (n < HDRSIZ ? 10 : 20)); ! 405: while (1) { ! 406: if ((ret = read(fn, b, n)) == 0) { ! 407: (void) alarm(0); ! 408: return(-1); ! 409: } ! 410: npkctry++; ! 411: npkcchar += ret; ! 412: PKASSERT(ret > 0, "PKCGET READ", "", ret); ! 413: if ((n -= ret) <= 0) ! 414: break; ! 415: #ifdef PKSPEEDUP ! 416: if (donap) { ! 417: sleep(1); ! 418: npkcnap++; ! 419: } ! 420: #endif PKSPEEDUP ! 421: b += ret; ! 422: } ! 423: (void) alarm(0); ! 424: return(0); ! 425: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.