|
|
1.1 ! root 1: /* protj.c ! 2: The 'j' protocol. ! 3: ! 4: Copyright (C) 1992 Ian Lance Taylor ! 5: ! 6: This file is part of the Taylor UUCP package. ! 7: ! 8: This program is free software; you can redistribute it and/or ! 9: modify it under the terms of the GNU General Public License as ! 10: published by the Free Software Foundation; either version 2 of the ! 11: License, or (at your option) any later version. ! 12: ! 13: This program is distributed in the hope that it will be useful, but ! 14: WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 16: General Public License for more details. ! 17: ! 18: You should have received a copy of the GNU General Public License ! 19: along with this program; if not, write to the Free Software ! 20: Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 21: ! 22: The author of the program may be contacted at [email protected] or ! 23: c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. ! 24: */ ! 25: ! 26: #include "uucp.h" ! 27: ! 28: #if USE_RCS_ID ! 29: const char protj_rcsid[] = "$Id: protj.c,v 1.1 93/07/30 07:53:35 bin Exp Locker: bin $"; ! 30: #endif ! 31: ! 32: #include <ctype.h> ! 33: #include <errno.h> ! 34: ! 35: #include "uudefs.h" ! 36: #include "conn.h" ! 37: #include "trans.h" ! 38: #include "system.h" ! 39: #include "prot.h" ! 40: ! 41: /* The 'j' protocol. ! 42: ! 43: The 'j' protocol is a wrapper around the 'i' protocol, which avoids ! 44: the use of certain characters, such as XON and XOFF. ! 45: ! 46: Each 'j' protocol packet begins with a '^' character, followed by a ! 47: two byte encoded size giving the total number of bytes in the ! 48: packet. The first byte is HIGH, the second byte is LOW, and the ! 49: number of bytes is (HIGH - 32) * 64 + (LOW - 32), where 32 <= HIGH ! 50: < 127 and 32 <= LOW < 96 (i.e., HIGH and LOW are printable ASCII ! 51: characters). This is followed by a '=' character. The next two ! 52: bytes are the number of data bytes in the packet, using the same ! 53: encoding. This is followed by a '@' character, and then that ! 54: number of data bytes. The remaining bytes in the packet are ! 55: indices of bytes which must be transformed, followed by a trailing ! 56: '~' character. The indices are encoded in the following overly ! 57: complex format. ! 58: ! 59: Each byte index is two bytes long. The first byte in the index is ! 60: INDEX-HIGH and the second is INDEX-LOW. If 32 <= INDEX-HIGH < 126, ! 61: the byte index refers to the byte at position (INDEX-HIGH - 32) * ! 62: 32 + INDEX-LOW % 32 in the actual data, where 32 <= INDEX-LOW < ! 63: 127. If 32 <= INDEX-LOW < 64, then 128 must be added to the ! 64: indexed byte. If 64 <= INDEX-LOW < 96, then the indexed byte must ! 65: be exclusive or'red with 32. If 96 <= INDEX-LOW < 127, both ! 66: operations must be performed. If INDEX-HIGH == 126, then the byte ! 67: index refers to the byte at position (INDEX-LOW - 32) * 32 + 31, ! 68: where 32 <= INDEX-LOW < 126. 128 must be added to the byte, and it ! 69: must be exclusive or'red with 32. This unfortunately requires a ! 70: special test (when encoding INDEX-LOW must be checked for 127; when ! 71: decoding INDEX-HIGH must be checked for 126). It does, however, ! 72: permit the byte indices field to consist exclusively of printable ! 73: ASCII characters. ! 74: ! 75: The maximum value for a byte index is (125 - 32) * 32 + 31 == 3007, ! 76: so the is the maximum number of data bytes permitted. Since it is ! 77: convenient to have each 'j' protocol packet correspond to each 'i' ! 78: protocol packet, we restrict the 'i' protocol accordingly. ! 79: ! 80: Note that this encoding method assumes that we can send all ! 81: printable ASCII characters. */ ! 82: ! 83: /* The first byte of each packet. I just picked these values ! 84: randomly, trying to get characters that were perhaps slightly less ! 85: likely to appear in normal text. */ ! 86: #define FIRST '\136' ! 87: ! 88: /* The fourth byte of each packet. */ ! 89: #define FOURTH '\075' ! 90: ! 91: /* The seventh byte of each packet. */ ! 92: #define SEVENTH '\100' ! 93: ! 94: /* The trailing byte of each packet. */ ! 95: #define TRAILER '\176' ! 96: ! 97: /* The length of the header. */ ! 98: #define CHDRLEN (7) ! 99: ! 100: /* Get a number of bytes encoded in a two byte length at the start of ! 101: a packet. */ ! 102: #define CGETLENGTH(b1, b2) (((b1) - 32) * 64 + ((b2) - 32)) ! 103: ! 104: /* Set the high and low bytes of a two byte length at the start of a ! 105: packet. */ ! 106: #define ISETLENGTH_FIRST(i) ((i) / 64 + 32) ! 107: #define ISETLENGTH_SECOND(i) ((i) % 64 + 32) ! 108: ! 109: /* The maximum packet size we support, as determined by the byte ! 110: indices. */ ! 111: #define IMAXPACKSIZE ((125 - 32) * 32 + 31) ! 112: ! 113: /* Amount to offset the bytes in the byte index by. */ ! 114: #define INDEX_OFFSET (32) ! 115: ! 116: /* Maximum value of INDEX-LOW, before offsetting. */ ! 117: #define INDEX_MAX_LOW (32) ! 118: ! 119: /* Maximum value of INDEX-HIGH, before offsetting. */ ! 120: #define INDEX_MAX_HIGH (94) ! 121: ! 122: /* The set of characters to avoid. */ ! 123: static char *zJavoid; ! 124: ! 125: /* The number of characters to avoid. */ ! 126: static size_t cJavoid; ! 127: ! 128: /* A buffer used when sending data. */ ! 129: static char *zJbuf; ! 130: ! 131: /* The end of the undecoded data in abPrecbuf. */ ! 132: static int iJrecend; ! 133: ! 134: /* Local functions. */ ! 135: static boolean fjsend_data P((struct sconnection *qconn, const char *zsend, ! 136: size_t csend, boolean fdoread)); ! 137: static boolean fjreceive_data P((struct sconnection *qconn, size_t cneed, ! 138: size_t *pcrec, int ctimeout, ! 139: boolean freport)); ! 140: static boolean fjprocess_data P((size_t *pcneed)); ! 141: ! 142: /* Start the protocol. We first send over the list of characters to ! 143: avoid as an escape sequence, starting with FIRST and ending with ! 144: TRAILER. There is no error checking done on this string. */ ! 145: ! 146: boolean ! 147: fjstart (qdaemon, pzlog) ! 148: struct sdaemon *qdaemon; ! 149: char **pzlog; ! 150: { ! 151: size_t clen; ! 152: char *zsend; ! 153: int b; ! 154: size_t cbuf, cgot; ! 155: char *zbuf; ! 156: int i; ! 157: ! 158: /* Send the characters we want to avoid to the other side. */ ! 159: clen = strlen (zJavoid_parameter); ! 160: zsend = zbufalc (clen + 3); ! 161: zsend[0] = FIRST; ! 162: memcpy (zsend + 1, zJavoid_parameter, clen); ! 163: zsend[clen + 1] = TRAILER; ! 164: zsend[clen + 2] = '\0'; ! 165: if (! fsend_data (qdaemon->qconn, zsend, clen + 2, TRUE)) ! 166: { ! 167: ubuffree (zsend); ! 168: return FALSE; ! 169: } ! 170: ubuffree (zsend); ! 171: ! 172: /* Read the characters the other side wants to avoid. */ ! 173: while ((b = breceive_char (qdaemon->qconn, cIsync_timeout, TRUE)) ! 174: != FIRST) ! 175: { ! 176: if (b < 0) ! 177: { ! 178: if (b == -1) ! 179: ulog (LOG_ERROR, "Timed out in 'j' protocol startup"); ! 180: return FALSE; ! 181: } ! 182: } ! 183: ! 184: cbuf = 20; ! 185: zbuf = zbufalc (cbuf); ! 186: cgot = 0; ! 187: while ((b = breceive_char (qdaemon->qconn, cIsync_timeout, TRUE)) ! 188: != TRAILER) ! 189: { ! 190: if (b < 0) ! 191: { ! 192: ubuffree (zbuf); ! 193: if (b == -1) ! 194: ulog (LOG_ERROR, "Timed out in 'j' protocol startup"); ! 195: return FALSE; ! 196: } ! 197: if (cgot + 1 >= cbuf) ! 198: { ! 199: char *znew; ! 200: ! 201: cbuf += 20; ! 202: znew = zbufalc (cbuf); ! 203: memcpy (znew, zbuf, cgot); ! 204: ubuffree (zbuf); ! 205: zbuf = znew; ! 206: } ! 207: zbuf[cgot] = b; ! 208: ++cgot; ! 209: } ! 210: zbuf[cgot] = '\0'; ! 211: ! 212: /* Merge the local and remote avoid bytes into one list, translated ! 213: into bytes. */ ! 214: cgot = cescape (zbuf); ! 215: ! 216: clen = strlen (zJavoid_parameter); ! 217: zJavoid = zbufalc (clen + cgot + 1); ! 218: memcpy (zJavoid, zJavoid_parameter, clen + 1); ! 219: cJavoid = cescape (zJavoid); ! 220: ! 221: for (i = 0; i < cgot; i++) ! 222: { ! 223: if (memchr (zJavoid, zbuf[i], cJavoid) == NULL) ! 224: { ! 225: zJavoid[cJavoid] = zbuf[i]; ! 226: ++cJavoid; ! 227: } ! 228: } ! 229: ! 230: ubuffree (zbuf); ! 231: ! 232: /* We can't avoid ASCII printable characters, since the encoding ! 233: method assumes that they can always be sent. If it ever turns ! 234: out to be important, a different encoding method could be used, ! 235: perhaps keyed by a different FIRST character. */ ! 236: if (cJavoid == 0) ! 237: { ! 238: ulog (LOG_ERROR, "No characters to avoid in 'j' protocol"); ! 239: return FALSE; ! 240: } ! 241: for (i = 0; i < cJavoid; i++) ! 242: { ! 243: if (zJavoid[i] >= 32 && zJavoid[i] <= 126) ! 244: { ! 245: ulog (LOG_ERROR, "'j' protocol can't avoid character '\\%03o'", ! 246: zJavoid[i]); ! 247: return FALSE; ! 248: } ! 249: } ! 250: ! 251: /* If we are avoiding XON and XOFF, use XON/XOFF handshaking. */ ! 252: if (memchr (zJavoid, '\021', cJavoid) != NULL ! 253: && memchr (zJavoid, '\023', cJavoid) != NULL) ! 254: { ! 255: if (! fconn_set (qdaemon->qconn, PARITYSETTING_NONE, ! 256: STRIPSETTING_EIGHTBITS, XONXOFF_ON)) ! 257: return FALSE; ! 258: } ! 259: ! 260: /* Let the port settle. */ ! 261: usysdep_sleep (2); ! 262: ! 263: /* Allocate a buffer we use when sending data. We will probably ! 264: never actually need one this big; if this code is ported to a ! 265: computer with small amounts of memory, this should be changed to ! 266: increase the buffer size as needed. */ ! 267: zJbuf = zbufalc (CHDRLEN + IMAXPACKSIZE * 3 + 1); ! 268: zJbuf[0] = FIRST; ! 269: zJbuf[3] = FOURTH; ! 270: zJbuf[6] = SEVENTH; ! 271: ! 272: /* iJrecend is the end of the undecoded data, and iPrecend is the ! 273: end of the decoded data. At this point there is no decoded data, ! 274: and we must initialize the variables accordingly. */ ! 275: iJrecend = iPrecend; ! 276: iPrecend = iPrecstart; ! 277: ! 278: /* Now do the 'i' protocol startup. */ ! 279: return fijstart (qdaemon, pzlog, IMAXPACKSIZE, fjsend_data, ! 280: fjreceive_data); ! 281: } ! 282: ! 283: /* Shut down the protocol. */ ! 284: ! 285: boolean ! 286: fjshutdown (qdaemon) ! 287: struct sdaemon *qdaemon; ! 288: { ! 289: boolean fret; ! 290: ! 291: fret = fishutdown (qdaemon); ! 292: ubuffree (zJavoid); ! 293: ubuffree (zJbuf); ! 294: return fret; ! 295: } ! 296: ! 297: /* Encode a packet of data and send it. This copies the data, which ! 298: is a waste of time, but calling fsend_data three times (for the ! 299: header, the body, and the trailer) would waste even more time. */ ! 300: ! 301: static boolean ! 302: fjsend_data (qconn, zsend, csend, fdoread) ! 303: struct sconnection *qconn; ! 304: const char *zsend; ! 305: size_t csend; ! 306: boolean fdoread; ! 307: { ! 308: char *zput, *zindex; ! 309: const char *zfrom, *zend; ! 310: char bfirst, bsecond; ! 311: int iprecendhold; ! 312: boolean fret; ! 313: ! 314: zput = zJbuf + CHDRLEN; ! 315: zindex = zput + csend; ! 316: zfrom = zsend; ! 317: zend = zsend + csend; ! 318: ! 319: /* Optimize for the common case of avoiding two characters. */ ! 320: bfirst = zJavoid[0]; ! 321: if (cJavoid <= 1) ! 322: bsecond = bfirst; ! 323: else ! 324: bsecond = zJavoid[1]; ! 325: while (zfrom < zend) ! 326: { ! 327: char b; ! 328: boolean f128, f32; ! 329: int i, ihigh, ilow; ! 330: ! 331: b = *zfrom++; ! 332: if (b != bfirst && b != bsecond) ! 333: { ! 334: int ca; ! 335: char *za; ! 336: ! 337: if (cJavoid <= 2) ! 338: { ! 339: *zput++ = b; ! 340: continue; ! 341: } ! 342: ! 343: ca = cJavoid - 2; ! 344: za = zJavoid + 2; ! 345: while (ca-- != 0) ! 346: if (*za++ == b) ! 347: break; ! 348: ! 349: if (ca < 0) ! 350: { ! 351: *zput++ = b; ! 352: continue; ! 353: } ! 354: } ! 355: ! 356: if ((b & 0x80) == 0) ! 357: f128 = FALSE; ! 358: else ! 359: { ! 360: b &=~ 0x80; ! 361: f128 = TRUE; ! 362: } ! 363: if (b >= 32 && b != 127) ! 364: f32 = FALSE; ! 365: else ! 366: { ! 367: b ^= 0x20; ! 368: f32 = TRUE; ! 369: } ! 370: ! 371: /* We must now put the byte index into the buffer. The byte ! 372: index is encoded similarly to the length of the actual data, ! 373: but the byte index also encodes the operations that must be ! 374: performed on the byte. The first byte in the index is the ! 375: most significant bits. If we only had to subtract 128 from ! 376: the byte, we use the second byte directly. If we had to xor ! 377: the byte with 32, we add 32 to the second byte index. If we ! 378: had to perform both operations, we add 64 to the second byte ! 379: index. However, if we had to perform both operations, and ! 380: the second byte index was 31, then after adding 64 and ! 381: offsetting by 32 we would come up with 127, which we are not ! 382: permitted to use. Therefore, in this special case we set the ! 383: first byte of the index to 126 and put the original first ! 384: byte into the second byte position instead. This is why we ! 385: could not permit the high byte of the length of the actual ! 386: data to be 126. We can get away with the switch because both ! 387: the value of the second byte index (31) and the operations to ! 388: perform (both) are known. */ ! 389: i = zput - (zJbuf + CHDRLEN); ! 390: ihigh = i / INDEX_MAX_LOW; ! 391: ilow = i % INDEX_MAX_LOW; ! 392: ! 393: if (f128 && ! f32) ! 394: ; ! 395: else if (f32 && ! f128) ! 396: ilow += INDEX_MAX_LOW; ! 397: else ! 398: { ! 399: /* Both operations had to be performed. */ ! 400: if (ilow != INDEX_MAX_LOW - 1) ! 401: ilow += 2 * INDEX_MAX_LOW; ! 402: else ! 403: { ! 404: ilow = ihigh; ! 405: ihigh = INDEX_MAX_HIGH; ! 406: } ! 407: } ! 408: ! 409: *zindex++ = ihigh + INDEX_OFFSET; ! 410: *zindex++ = ilow + INDEX_OFFSET; ! 411: *zput++ = b; ! 412: } ! 413: ! 414: *zindex++ = TRAILER; ! 415: ! 416: /* Set the lengths into the buffer. zJbuf[0,3,6] were set when ! 417: zJbuf was allocated, and are never changed thereafter. */ ! 418: zJbuf[1] = ISETLENGTH_FIRST (zindex - zJbuf); ! 419: zJbuf[2] = ISETLENGTH_SECOND (zindex - zJbuf); ! 420: zJbuf[4] = ISETLENGTH_FIRST (csend); ! 421: zJbuf[5] = ISETLENGTH_SECOND (csend); ! 422: ! 423: /* Send the data over the line. We must preserve iPrecend as ! 424: discussed in fjreceive_data. */ ! 425: iprecendhold = iPrecend; ! 426: iPrecend = iJrecend; ! 427: fret = fsend_data (qconn, zJbuf, (size_t) (zindex - zJbuf), fdoread); ! 428: iJrecend = iPrecend; ! 429: iPrecend = iprecendhold; ! 430: ! 431: /* Process any bytes that may have been placed in abPrecbuf. */ ! 432: if (fret && iPrecend != iJrecend) ! 433: { ! 434: if (! fjprocess_data ((size_t *) NULL)) ! 435: return FALSE; ! 436: } ! 437: ! 438: return fret; ! 439: } ! 440: ! 441: /* Receive and decode data. This is called by fiwait_for_packet. We ! 442: need to be able to return decoded data between iPrecstart and ! 443: iPrecend, while not losing any undecoded partial packets we may ! 444: have read. We use iJrecend as a pointer to the end of the ! 445: undecoded data, and set iPrecend for the decoded data. iPrecend ! 446: points to the start of the undecoded data. */ ! 447: ! 448: static boolean ! 449: fjreceive_data (qconn, cineed, pcrec, ctimeout, freport) ! 450: struct sconnection *qconn; ! 451: size_t cineed; ! 452: size_t *pcrec; ! 453: int ctimeout; ! 454: boolean freport; ! 455: { ! 456: int iprecendstart; ! 457: size_t cjneed; ! 458: size_t crec; ! 459: int cnew; ! 460: ! 461: iprecendstart = iPrecend; ! 462: ! 463: /* Figure out how many bytes we need to decode the next packet. */ ! 464: if (! fjprocess_data (&cjneed)) ! 465: return FALSE; ! 466: ! 467: /* As we long as we read some data but don't have enough to decode a ! 468: packet, we try to read some more. We decrease the timeout each ! 469: time so that we will not wait forever if the connection starts ! 470: dribbling data. */ ! 471: do ! 472: { ! 473: int iprecendhold; ! 474: size_t cneed; ! 475: ! 476: if (cjneed > cineed) ! 477: cneed = cjneed; ! 478: else ! 479: cneed = cineed; ! 480: ! 481: /* We are setting iPrecend to the end of the decoded data for ! 482: the 'i' protocol. When we do the actual read, we have to set ! 483: it to the end of the undecoded data so that any undecoded ! 484: data we have received is not overwritten. */ ! 485: iprecendhold = iPrecend; ! 486: iPrecend = iJrecend; ! 487: if (! freceive_data (qconn, cneed, &crec, ctimeout, freport)) ! 488: return FALSE; ! 489: iJrecend = iPrecend; ! 490: iPrecend = iprecendhold; ! 491: ! 492: /* Process any data we have received. This will set iPrecend to ! 493: the end of the new decoded data. */ ! 494: if (! fjprocess_data (&cjneed)) ! 495: return FALSE; ! 496: ! 497: cnew = iPrecend - iprecendstart; ! 498: if (cnew < 0) ! 499: cnew += CRECBUFLEN; ! 500: ! 501: if (cnew > cineed) ! 502: cineed = 0; ! 503: else ! 504: cineed -= cnew; ! 505: ! 506: --ctimeout; ! 507: } ! 508: while (cnew == 0 && crec > 0 && ctimeout > 0); ! 509: ! 510: DEBUG_MESSAGE1 (DEBUG_PROTO, "fjreceive_data: Got %d decoded bytes", ! 511: cnew); ! 512: ! 513: *pcrec = cnew; ! 514: return TRUE; ! 515: } ! 516: ! 517: /* Decode the data in the buffer, optionally returning the number of ! 518: bytes needed to complete the next packet. */ ! 519: ! 520: static boolean ! 521: fjprocess_data (pcneed) ! 522: size_t *pcneed; ! 523: { ! 524: int istart; ! 525: ! 526: istart = iPrecend; ! 527: while (istart != iJrecend) ! 528: { ! 529: int i, iget; ! 530: char ab[CHDRLEN]; ! 531: int cpacket, cdata, chave; ! 532: int iindex, iendindex; ! 533: ! 534: /* Find the next occurrence of FIRST. If we have to skip some ! 535: garbage bytes to get to it, zero them out (so they don't ! 536: confuse the 'i' protocol) and advance iPrecend. This will ! 537: save us from looking at them again. */ ! 538: if (abPrecbuf[istart] != FIRST) ! 539: { ! 540: int cintro; ! 541: char *zintro; ! 542: size_t cskipped; ! 543: ! 544: cintro = iJrecend - istart; ! 545: if (cintro < 0) ! 546: cintro = CRECBUFLEN - istart; ! 547: ! 548: zintro = memchr (abPrecbuf + istart, FIRST, (size_t) cintro); ! 549: if (zintro == NULL) ! 550: { ! 551: bzero (abPrecbuf + istart, (size_t) cintro); ! 552: istart = (istart + cintro) % CRECBUFLEN; ! 553: iPrecend = istart; ! 554: continue; ! 555: } ! 556: ! 557: cskipped = zintro - (abPrecbuf + istart); ! 558: bzero (abPrecbuf + istart, cskipped); ! 559: istart += cskipped; ! 560: iPrecend = istart; ! 561: } ! 562: ! 563: for (i = 0, iget = istart; ! 564: i < CHDRLEN && iget != iJrecend; ! 565: ++i, iget = (iget + 1) % CRECBUFLEN) ! 566: ab[i] = abPrecbuf[iget]; ! 567: ! 568: if (i < CHDRLEN) ! 569: { ! 570: if (pcneed != NULL) ! 571: *pcneed = CHDRLEN - i; ! 572: return TRUE; ! 573: } ! 574: ! 575: cpacket = CGETLENGTH (ab[1], ab[2]); ! 576: cdata = CGETLENGTH (ab[4], ab[5]); ! 577: ! 578: /* Make sure the header has the right magic characters, that the ! 579: data is not larger than the packet, and that we have an even ! 580: number of byte index characters. */ ! 581: if (ab[3] != FOURTH ! 582: || ab[6] != SEVENTH ! 583: || cdata > cpacket - CHDRLEN - 1 ! 584: || (cpacket - cdata - CHDRLEN - 1) % 2 == 1) ! 585: { ! 586: istart = (istart + 1) % CRECBUFLEN; ! 587: continue; ! 588: } ! 589: ! 590: chave = iJrecend - istart; ! 591: if (chave < 0) ! 592: chave += CRECBUFLEN; ! 593: ! 594: if (chave < cpacket) ! 595: { ! 596: if (pcneed != NULL) ! 597: *pcneed = cpacket - chave; ! 598: return TRUE; ! 599: } ! 600: ! 601: /* Figure out where the byte indices start and end. */ ! 602: iindex = (istart + CHDRLEN + cdata) % CRECBUFLEN; ! 603: iendindex = (istart + cpacket - 1) % CRECBUFLEN; ! 604: ! 605: /* Make sure the magic trailer character is there. */ ! 606: if (abPrecbuf[iendindex] != TRAILER) ! 607: { ! 608: istart = (istart + 1) % CRECBUFLEN; ! 609: continue; ! 610: } ! 611: ! 612: /* We have a packet to decode. The decoding process is simpler ! 613: than the encoding process, since all we have to do is examine ! 614: the byte indices. We zero out the byte indices as we go, so ! 615: that they will not confuse the 'i' protocol. */ ! 616: while (iindex != iendindex) ! 617: { ! 618: int ihigh, ilow; ! 619: boolean f32, f128; ! 620: int iset; ! 621: ! 622: ihigh = abPrecbuf[iindex] - INDEX_OFFSET; ! 623: abPrecbuf[iindex] = 0; ! 624: iindex = (iindex + 1) % CRECBUFLEN; ! 625: ilow = abPrecbuf[iindex] - INDEX_OFFSET; ! 626: abPrecbuf[iindex] = 0; ! 627: iindex = (iindex + 1) % CRECBUFLEN; ! 628: ! 629: /* Now we must undo the encoding, by adding 128 and xoring ! 630: with 32 as appropriate. Which to do is encoded in the ! 631: low byte, except that if the high byte is the special ! 632: value 126, then the low byte is actually the high byte ! 633: and both operations are performed. */ ! 634: f128 = TRUE; ! 635: f32 = TRUE; ! 636: if (ihigh == INDEX_MAX_HIGH) ! 637: iset = ilow * INDEX_MAX_LOW + INDEX_MAX_LOW - 1; ! 638: else ! 639: { ! 640: iset = ihigh * INDEX_MAX_LOW + ilow % INDEX_MAX_LOW; ! 641: if (ilow < INDEX_MAX_LOW) ! 642: f32 = FALSE; ! 643: else if (ilow < 2 * INDEX_MAX_LOW) ! 644: f128 = FALSE; ! 645: } ! 646: ! 647: /* Now iset is the index from the start of the data to the ! 648: byte to modify; adjust it to an index in abPrecbuf. */ ! 649: iset = (istart + CHDRLEN + iset) % CRECBUFLEN; ! 650: ! 651: if (f128) ! 652: abPrecbuf[iset] |= 0x80; ! 653: if (f32) ! 654: abPrecbuf[iset] ^= 0x20; ! 655: } ! 656: ! 657: /* Zero out the header and trailer to avoid confusing the 'i' ! 658: protocol, and update iPrecend to the end of decoded data. */ ! 659: for (i = 0, iget = istart; ! 660: i < CHDRLEN && iget != iJrecend; ! 661: ++i, iget = (iget + 1) % CRECBUFLEN) ! 662: abPrecbuf[iget] = 0; ! 663: abPrecbuf[iendindex] = 0; ! 664: iPrecend = (iendindex + 1) % CRECBUFLEN; ! 665: istart = iPrecend; ! 666: } ! 667: ! 668: if (pcneed != NULL) ! 669: *pcneed = CHDRLEN + 1; ! 670: return TRUE; ! 671: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.