1/* protj.c 2 The 'j' protocol. 3 4 Copyright (C) 1992, 1994, 2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucp.h" 26 27#if USE_RCS_ID 28const char protj_rcsid[] = "$Id: protj.c,v 1.9 2002/03/05 19:10:41 ian Rel $"; 29#endif 30 31#include <ctype.h> 32#include <errno.h> 33 34#include "uudefs.h" 35#include "uuconf.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. */ 123static char *zJavoid; 124 125/* The number of characters to avoid. */ 126static size_t cJavoid; 127 128/* A buffer used when sending data. */ 129static char *zJbuf; 130 131/* The end of the undecoded data in abPrecbuf. */ 132static int iJrecend; 133 134/* Local functions. */ 135static boolean fjsend_data P((struct sconnection *qconn, const char *zsend, 136 size_t csend, boolean fdoread)); 137static boolean fjreceive_data P((struct sconnection *qconn, size_t cneed, 138 size_t *pcrec, int ctimeout, 139 boolean freport)); 140static 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 146boolean 147fjstart (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 size_t 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 285boolean 286fjshutdown (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 301static boolean 302fjsend_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 448static boolean 449fjreceive_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 ((size_t) 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 520static boolean 521fjprocess_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} 672