1 /* 2 zm.c - zmodem protocol handling lowlevelstuff 3 Copyright (C) until 1998 Chuck Forsberg (OMEN Technology Inc) 4 Copyright (C) 1996, 1997 Uwe Ohse 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. 20 21 originally written by Chuck Forsberg 22 */ 23 /* historical comment: -- uwe 24 * Z M . C 25 * ZMODEM protocol primitives 26 * 05-09-88 Chuck Forsberg Omen Technology Inc 27 * 28 * Entry point Functions: 29 * zsbhdr(type, hdr) send binary header 30 * zshhdr(type, hdr) send hex header 31 * zgethdr(hdr, eflag) receive header - binary or hex 32 * zsdata(buf, len, frameend) send data 33 * zrdata(buf, len, bytes_received) receive data 34 * stohdr(pos) store position data in Txhdr 35 * long rclhdr(hdr) recover position offset from header 36 */ 37 38 39 #include "zglobal.h" 40 41 #include <stdio.h> 42 43 unsigned int Rxtimeout = 100; /* Tenths of seconds to wait for something */ 44 45 /* Globals used by ZMODEM functions */ 46 int Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame received */ 47 int Rxtype; /* Type of header received */ 48 char Rxhdr[4]; /* Received header */ 49 char Txhdr[4]; /* Transmitted header */ 50 long Txpos; /* Transmitted file position */ 51 int Txfcs32; /* TRUE means send binary frames with 32 bit FCS */ 52 int Crc32t; /* Display flag indicating 32 bit CRC being sent */ 53 int Crc32; /* Display flag indicating 32 bit CRC being received */ 54 int Znulls; /* Number of nulls to send at beginning of ZDATA hdr */ 55 char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */ 56 57 static char lastsent; /* Last char we sent */ 58 int turbo_escape; 59 int bytes_per_error=0; 60 61 static const char *frametypes[] = { 62 "Carrier Lost", /* -3 */ 63 "TIMEOUT", /* -2 */ 64 "ERROR", /* -1 */ 65 #define FTOFFSET 3 66 "ZRQINIT", 67 "ZRINIT", 68 "ZSINIT", 69 "ZACK", 70 "ZFILE", 71 "ZSKIP", 72 "ZNAK", 73 "ZABORT", 74 "ZFIN", 75 "ZRPOS", 76 "ZDATA", 77 "ZEOF", 78 "ZFERR", 79 "ZCRC", 80 "ZCHALLENGE", 81 "ZCOMPL", 82 "ZCAN", 83 "ZFREECNT", 84 "ZCOMMAND", 85 "ZSTDERR", 86 "xxxxx" 87 #define FRTYPES 22 /* Total number of frame types in this array */ 88 /* not including psuedo negative entries */ 89 }; 90 91 #define badcrc _("Bad CRC") 92 /* static char *badcrc = "Bad CRC"; */ 93 static inline int noxrd7 __P ((void)); 94 static inline int zdlread __P ((void)); 95 static int zdlread2 __P ((int)) LRZSZ_ATTRIB_REGPARM(1); 96 static inline int zgeth1 __P ((void)); 97 static void zputhex __P ((int c, char *pos)); 98 static inline int zgethex __P ((void)); 99 static int zrbhdr __P ((char *hdr)); 100 static int zrbhdr32 __P ((char *hdr)); 101 static int zrhhdr __P ((char *hdr)); 102 static char zsendline_tab[256]; 103 static int zrdat32 __P ((char *buf, int length, size_t *)); 104 static void zsbh32 __P ((char *hdr, int type)); 105 106 extern int zmodem_requested; 107 108 109 /* 110 * Read a character from the modem line with timeout. 111 * Eat parity, XON and XOFF characters. 112 */ 113 static inline int 114 noxrd7(void) 115 { 116 register int c; 117 118 for (;;) { 119 if ((c = READLINE_PF(Rxtimeout)) < 0) 120 return c; 121 switch (c &= 0177) { 122 case XON: 123 case XOFF: 124 continue; 125 default: 126 if (Zctlesc && !(c & 0140)) 127 continue; 128 case '\r': 129 case '\n': 130 case ZDLE: 131 return c; 132 } 133 } 134 } 135 136 static inline int 137 zgeth1(void) 138 { 139 register int c, n; 140 141 if ((c = noxrd7()) < 0) 142 return c; 143 n = c - '0'; 144 if (n > 9) 145 n -= ('a' - ':'); 146 if (n & ~0xF) 147 return ERROR; 148 if ((c = noxrd7()) < 0) 149 return c; 150 c -= '0'; 151 if (c > 9) 152 c -= ('a' - ':'); 153 if (c & ~0xF) 154 return ERROR; 155 c += (n<<4); 156 return c; 157 } 158 159 /* Decode two lower case hex digits into an 8 bit byte value */ 160 static inline int 161 zgethex(void) 162 { 163 register int c; 164 165 c = zgeth1(); 166 VPRINTF(9,("zgethex: %02X", c)); 167 return c; 168 } 169 170 /* 171 * Read a byte, checking for ZMODEM escape encoding 172 * including CAN*5 which represents a quick abort 173 */ 174 static inline int 175 zdlread(void) 176 { 177 int c; 178 /* Quick check for non control characters */ 179 if ((c = READLINE_PF(Rxtimeout)) & 0140) 180 return c; 181 return zdlread2(c); 182 } 183 /* no, i don't like gotos. -- uwe */ 184 static int 185 zdlread2(int c) 186 { 187 goto jump_over; /* bad style */ 188 189 again: 190 /* Quick check for non control characters */ 191 if ((c = READLINE_PF(Rxtimeout)) & 0140) 192 return c; 193 jump_over: 194 switch (c) { 195 case ZDLE: 196 break; 197 case XON: 198 case (XON|0200): 199 case XOFF: 200 case (XOFF|0200): 201 goto again; 202 default: 203 if (Zctlesc && !(c & 0140)) { 204 goto again; 205 } 206 return c; 207 } 208 again2: 209 if ((c = READLINE_PF(Rxtimeout)) < 0) 210 return c; 211 if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0) 212 return c; 213 if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0) 214 return c; 215 if (c == CAN && (c = READLINE_PF(Rxtimeout)) < 0) 216 return c; 217 switch (c) { 218 case CAN: 219 return GOTCAN; 220 case ZCRCE: 221 case ZCRCG: 222 case ZCRCQ: 223 case ZCRCW: 224 return (c | GOTOR); 225 case ZRUB0: 226 return 0177; 227 case ZRUB1: 228 return 0377; 229 case XON: 230 case (XON|0200): 231 case XOFF: 232 case (XOFF|0200): 233 goto again2; 234 default: 235 if (Zctlesc && ! (c & 0140)) { 236 goto again2; 237 } 238 if ((c & 0140) == 0100) 239 return (c ^ 0100); 240 break; 241 } 242 VPRINTF(2,(_("Bad escape sequence %x"), c)); 243 return ERROR; 244 } 245 246 247 248 /* 249 * Send character c with ZMODEM escape sequence encoding. 250 * Escape XON, XOFF. Escape CR following @ (Telenet net escape) 251 */ 252 inline void 253 zsendline(int c) 254 { 255 256 switch(zsendline_tab[(unsigned) (c&=0377)]) 257 { 258 case 0: 259 xsendline(lastsent = c); 260 break; 261 case 1: 262 xsendline(ZDLE); 263 c ^= 0100; 264 xsendline(lastsent = c); 265 break; 266 case 2: 267 if ((lastsent & 0177) != '@') { 268 xsendline(lastsent = c); 269 } else { 270 xsendline(ZDLE); 271 c ^= 0100; 272 xsendline(lastsent = c); 273 } 274 break; 275 } 276 } 277 278 static inline void 279 zsendline_s(const char *s, size_t count) 280 { 281 const char *end=s+count; 282 while(s!=end) { 283 int last_esc=0; 284 const char *t=s; 285 while (t!=end) { 286 last_esc=zsendline_tab[(unsigned) ((*t) & 0377)]; 287 if (last_esc) 288 break; 289 t++; 290 } 291 if (t!=s) { 292 //fwrite(s,(size_t)(t-s),1,stdout); 293 send_data(1, s, t-s); 294 lastsent=t[-1]; 295 s=t; 296 } 297 if (last_esc) { 298 int c=*s; 299 switch(last_esc) { 300 case 0: 301 xsendline(lastsent = c); 302 break; 303 case 1: 304 xsendline(ZDLE); 305 c ^= 0100; 306 xsendline(lastsent = c); 307 break; 308 case 2: 309 if ((lastsent & 0177) != '@') { 310 xsendline(lastsent = c); 311 } else { 312 xsendline(ZDLE); 313 c ^= 0100; 314 xsendline(lastsent = c); 315 } 316 break; 317 } 318 s++; 319 } 320 } 321 } 322 323 324 /* Send ZMODEM binary header hdr of type type */ 325 void 326 zsbhdr(int type, char *hdr) 327 { 328 register int n; 329 register unsigned short crc; 330 331 VPRINTF(3,("zsbhdr: %s %lx", frametypes[type+FTOFFSET], rclhdr(hdr))); 332 if (type == ZDATA) 333 for (n = Znulls; --n >=0; ) 334 xsendline(0); 335 336 xsendline(ZPAD); xsendline(ZDLE); 337 338 Crc32t=Txfcs32; 339 if (Crc32t) 340 zsbh32(hdr, type); 341 else { 342 xsendline(ZBIN); zsendline(type); crc = updcrc(type, 0); 343 344 for (n=4; --n >= 0; ++hdr) { 345 zsendline(*hdr); 346 crc = updcrc((0377& *hdr), crc); 347 } 348 crc = updcrc(0,updcrc(0,crc)); 349 zsendline(crc>>8); 350 zsendline(crc); 351 } 352 if (type != ZDATA) 353 flushmo(); 354 } 355 356 357 /* Send ZMODEM binary header hdr of type type */ 358 static void 359 zsbh32(char *hdr, int type) 360 { 361 register int n; 362 register unsigned long crc; 363 364 xsendline(ZBIN32); zsendline(type); 365 crc = 0xFFFFFFFFL; crc = UPDC32(type, crc); 366 367 for (n=4; --n >= 0; ++hdr) { 368 crc = UPDC32((0377 & *hdr), crc); 369 zsendline(*hdr); 370 } 371 crc = ~crc; 372 for (n=4; --n >= 0;) { 373 zsendline((int)crc); 374 crc >>= 8; 375 } 376 } 377 378 /* Send ZMODEM HEX header hdr of type type */ 379 void 380 zshhdr(int type, char *hdr) 381 { 382 register int n; 383 register unsigned short crc; 384 char s[30]; 385 size_t len; 386 387 VPRINTF(3,("zshhdr: %s %lx", frametypes[(type & 0x7f)+FTOFFSET], rclhdr(hdr))); 388 s[0]=ZPAD; 389 s[1]=ZPAD; 390 s[2]=ZDLE; 391 s[3]=ZHEX; 392 zputhex(type & 0x7f ,s+4); 393 len=6; 394 Crc32t = 0; 395 396 crc = updcrc((type & 0x7f), 0); 397 for (n=4; --n >= 0; ++hdr) { 398 zputhex(*hdr,s+len); 399 len += 2; 400 crc = updcrc((0377 & *hdr), crc); 401 } 402 crc = updcrc(0,updcrc(0,crc)); 403 zputhex(crc>>8,s+len); 404 zputhex(crc,s+len+2); 405 len+=4; 406 407 /* Make it printable on remote machine */ 408 s[len++]=015; 409 s[len++]=0212; 410 /* 411 * Uncork the remote in case a fake XOFF has stopped data flow 412 */ 413 if (type != ZFIN && type != ZACK) 414 { 415 s[len++]=021; 416 } 417 flushmo(); 418 send_data(1,s,len); 419 } 420 421 /* 422 * Send binary array buf of length length, with ending ZDLE sequence frameend 423 */ 424 static const char *Zendnames[] = { "ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"}; 425 void 426 zsdata(const char *buf, size_t length, int frameend) 427 { 428 register unsigned short crc; 429 430 VPRINTF(3,("zsdata: %lu %s", (unsigned long) length, 431 Zendnames[(frameend-ZCRCE)&3])); 432 crc = 0; 433 do { 434 zsendline(*buf); crc = updcrc((0377 & *buf), crc); 435 buf++; 436 } while (--length>0); 437 xsendline(ZDLE); xsendline(frameend); 438 crc = updcrc(frameend, crc); 439 440 crc = updcrc(0,updcrc(0,crc)); 441 zsendline(crc>>8); zsendline(crc); 442 if (frameend == ZCRCW) { 443 xsendline(XON); flushmo(); 444 } 445 } 446 447 void 448 zsda32(const char *buf, size_t length, int frameend) 449 { 450 int c; 451 unsigned long crc; 452 int i; 453 VPRINTF(3,("zsdat32: %d %s", length, Zendnames[(frameend-ZCRCE)&3])); 454 455 crc = 0xFFFFFFFFL; 456 zsendline_s(buf,length); 457 for (; length; length--) { 458 c = *buf & 0377; 459 crc = UPDC32(c, crc); 460 buf++; 461 } 462 xsendline(ZDLE); xsendline(frameend); 463 crc = UPDC32(frameend, crc); 464 465 crc = ~crc; 466 for (i=4; --i >= 0;) { 467 c=(int) crc; 468 if (c & 0140) 469 xsendline(lastsent = c); 470 else 471 zsendline(c); 472 crc >>= 8; 473 } 474 if (frameend == ZCRCW) { 475 xsendline(XON); flushmo(); 476 } 477 } 478 479 #if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ <= 4) 480 # undef DEBUG_BLOCKSIZE 481 #endif 482 483 #ifdef DEBUG_BLOCKSIZE 484 struct debug_blocksize { 485 int size; 486 long count; 487 }; 488 struct debug_blocksize blocksizes[]={ 489 {32,0}, 490 {64,0}, 491 {128,0}, 492 {256,0}, 493 {512,0}, 494 {1024,0}, 495 {2048,0}, 496 {4096,0}, 497 {8192,0}, 498 {0,0} 499 }; 500 static inline void 501 count_blk(int size) 502 { 503 int i; 504 for (i=0;blocksizes[i].size;i++) { 505 if (blocksizes[i].size==size) { 506 blocksizes[i].count++; 507 return; 508 } 509 } 510 blocksizes[i].count++; 511 } 512 513 static void printout_blocksizes(void) __attribute__((__destructor__)); 514 static void 515 printout_blocksizes(void) 516 { 517 int i; 518 for (i=0;blocksizes[i].size;i++) { 519 if (blocksizes[i].count) { 520 lsyslog(LOG_DEBUG,"%4d byte: %ld blocks\n", 521 blocksizes[i].size,blocksizes[i].count); 522 } 523 } 524 if (blocksizes[i].count) { 525 lsyslog(LOG_DEBUG,"unk. byte: %ld blocks", 526 blocksizes[i].count); 527 } 528 } 529 #define COUNT_BLK(x) count_blk(x) 530 #else 531 #define COUNT_BLK(x) 532 #endif 533 534 /* 535 * Receive array buf of max length with ending ZDLE sequence 536 * and CRC. Returns the ending character or error code. 537 * NB: On errors may store length+1 bytes! 538 */ 539 int 540 zrdata(char *buf, int length, size_t *bytes_received) 541 { 542 register int c; 543 register unsigned short crc; 544 register char *end; 545 register int d; 546 547 *bytes_received=0; 548 if (Rxframeind == ZBIN32) 549 return zrdat32(buf, length, bytes_received); 550 551 crc = 0; end = buf + length; 552 while (buf <= end) { 553 if ((c = zdlread()) & ~0377) { 554 crcfoo: 555 switch (c) { 556 case GOTCRCE: 557 case GOTCRCG: 558 case GOTCRCQ: 559 case GOTCRCW: 560 { 561 d = c; 562 c &= 0377; 563 crc = updcrc(c, crc); 564 if ((c = zdlread()) & ~0377) 565 goto crcfoo; 566 crc = updcrc(c, crc); 567 if ((c = zdlread()) & ~0377) 568 goto crcfoo; 569 crc = updcrc(c, crc); 570 if (crc & 0xFFFF) { 571 zperr(badcrc); 572 return ERROR; 573 } 574 *bytes_received = length - (end - buf); 575 COUNT_BLK(*bytes_received); 576 VPRINTF(3,("zrdata: %lu %s", (unsigned long) (*bytes_received), 577 Zendnames[(d-GOTCRCE)&3])); 578 return d; 579 } 580 case GOTCAN: 581 zperr(_("Sender Canceled")); 582 return ZCAN; 583 case TIMEOUT: 584 zperr(_("TIMEOUT")); 585 return c; 586 default: 587 zperr(_("Bad data subpacket")); 588 return c; 589 } 590 } 591 *buf++ = c; 592 crc = updcrc(c, crc); 593 } 594 zperr(_("Data subpacket too long")); 595 return ERROR; 596 } 597 598 static int 599 zrdat32(char *buf, int length, size_t *bytes_received) 600 { 601 register int c; 602 register unsigned long crc; 603 register char *end; 604 register int d; 605 606 crc = 0xFFFFFFFFL; end = buf + length; 607 while (buf <= end) { 608 if ((c = zdlread()) & ~0377) { 609 crcfoo: 610 switch (c) { 611 case GOTCRCE: 612 case GOTCRCG: 613 case GOTCRCQ: 614 case GOTCRCW: 615 d = c; 616 c &= 0377; 617 crc = UPDC32(c, crc); 618 if ((c = zdlread()) & ~0377) 619 goto crcfoo; 620 crc = UPDC32(c, crc); 621 if ((c = zdlread()) & ~0377) 622 goto crcfoo; 623 crc = UPDC32(c, crc); 624 if ((c = zdlread()) & ~0377) 625 goto crcfoo; 626 crc = UPDC32(c, crc); 627 if ((c = zdlread()) & ~0377) 628 goto crcfoo; 629 crc = UPDC32(c, crc); 630 if (crc != 0xDEBB20E3) { 631 zperr(badcrc); 632 return ERROR; 633 } 634 *bytes_received = length - (end - buf); 635 COUNT_BLK(*bytes_received); 636 VPRINTF(3,("zrdat32: %lu %s", (unsigned long) *bytes_received, 637 Zendnames[(d-GOTCRCE)&3])); 638 return d; 639 case GOTCAN: 640 zperr(_("Sender Canceled")); 641 return ZCAN; 642 case TIMEOUT: 643 zperr(_("TIMEOUT")); 644 return c; 645 default: 646 zperr(_("Bad data subpacket")); 647 return c; 648 } 649 } 650 *buf++ = c; 651 crc = UPDC32(c, crc); 652 } 653 zperr(_("Data subpacket too long")); 654 return ERROR; 655 } 656 657 /* 658 * Read a ZMODEM header to hdr, either binary or hex. 659 * eflag controls local display of non zmodem characters: 660 * 0: no display 661 * 1: display printing characters only 662 * 2: display all non ZMODEM characters 663 * On success, set Zmodem to 1, set Rxpos and return type of header. 664 * Otherwise return negative on error. 665 * Return ERROR instantly if ZCRCW sequence, for fast error recovery. 666 */ 667 int 668 zgethdr(char *hdr, int eflag, size_t *Rxpos) 669 { 670 register int c, cancount; 671 unsigned int max_garbage; /* Max bytes before start of frame */ 672 size_t rxpos=0; /* keep gcc happy */ 673 674 max_garbage = Zrwindow + Baudrate; 675 Rxframeind = Rxtype = 0; 676 677 startover: 678 cancount = 5; 679 again: 680 /* Return immediate ERROR if ZCRCW sequence seen */ 681 switch (c = READLINE_PF(Rxtimeout)) { 682 case RCDO: 683 case TIMEOUT: 684 goto fifi; 685 case CAN: 686 gotcan: 687 if (--cancount <= 0) { 688 c = ZCAN; goto fifi; 689 } 690 switch (c = READLINE_PF(1)) { 691 case TIMEOUT: 692 goto again; 693 case ZCRCW: 694 c = ERROR; 695 /* **** FALL THRU TO **** */ 696 case RCDO: 697 goto fifi; 698 default: 699 break; 700 case CAN: 701 if (--cancount <= 0) { 702 c = ZCAN; goto fifi; 703 } 704 goto again; 705 } 706 /* **** FALL THRU TO **** */ 707 default: 708 agn2: 709 if ( --max_garbage == 0) { 710 zperr(_("Garbage count exceeded")); 711 return(ERROR); 712 } 713 //if (eflag && ((c &= 0177) & 0140) && Verbose) 714 // vchar(c); 715 //else if (eflag > 1 && Verbose) 716 // vchar(c); 717 goto startover; 718 case ZPAD|0200: /* This is what we want. */ 719 case ZPAD: /* This is what we want. */ 720 break; 721 } 722 cancount = 5; 723 splat: 724 switch (c = noxrd7()) { 725 case ZPAD: 726 goto splat; 727 case RCDO: 728 case TIMEOUT: 729 goto fifi; 730 default: 731 goto agn2; 732 case ZDLE: /* This is what we want. */ 733 break; 734 } 735 736 switch (c = noxrd7()) { 737 case RCDO: 738 case TIMEOUT: 739 goto fifi; 740 case ZBIN: 741 Rxframeind = ZBIN; Crc32 = FALSE; 742 c = zrbhdr(hdr); 743 break; 744 case ZBIN32: 745 Crc32 = Rxframeind = ZBIN32; 746 c = zrbhdr32(hdr); 747 break; 748 case ZHEX: 749 Rxframeind = ZHEX; Crc32 = FALSE; 750 c = zrhhdr(hdr); 751 break; 752 case CAN: 753 goto gotcan; 754 default: 755 goto agn2; 756 } 757 rxpos = hdr[ZP3] & 0377; 758 rxpos = (rxpos<<8) + (hdr[ZP2] & 0377); 759 rxpos = (rxpos<<8) + (hdr[ZP1] & 0377); 760 rxpos = (rxpos<<8) + (hdr[ZP0] & 0377); 761 fifi: 762 switch (c) { 763 case GOTCAN: 764 c = ZCAN; 765 /* **** FALL THRU TO **** */ 766 case ZNAK: 767 case ZCAN: 768 case ERROR: 769 case TIMEOUT: 770 case RCDO: 771 zperr(_("Got %s"), frametypes[c+FTOFFSET]); 772 /* **** FALL THRU TO **** */ 773 default: 774 if (c >= -3 && c <= FRTYPES) 775 VPRINTF(3,("zgethdr: %s %lx", frametypes[c+FTOFFSET], (unsigned long) rxpos)); 776 else 777 VPRINTF(3,("zgethdr: %d %lx", c, (unsigned long) rxpos)); 778 } 779 if (Rxpos) 780 *Rxpos=rxpos; 781 return c; 782 } 783 784 /* Receive a binary style header (type and position) */ 785 static int 786 zrbhdr(char *hdr) 787 { 788 register int c, n; 789 register unsigned short crc; 790 791 if ((c = zdlread()) & ~0377) 792 return c; 793 Rxtype = c; 794 crc = updcrc(c, 0); 795 796 for (n=4; --n >= 0; ++hdr) { 797 if ((c = zdlread()) & ~0377) 798 return c; 799 crc = updcrc(c, crc); 800 *hdr = c; 801 } 802 if ((c = zdlread()) & ~0377) 803 return c; 804 crc = updcrc(c, crc); 805 if ((c = zdlread()) & ~0377) 806 return c; 807 crc = updcrc(c, crc); 808 if (crc & 0xFFFF) { 809 zperr(badcrc); 810 return ERROR; 811 } 812 protocol = ZM_ZMODEM; 813 zmodem_requested=TRUE; 814 return Rxtype; 815 } 816 817 /* Receive a binary style header (type and position) with 32 bit FCS */ 818 static int 819 zrbhdr32(char *hdr) 820 { 821 register int c, n; 822 register unsigned long crc; 823 824 if ((c = zdlread()) & ~0377) 825 return c; 826 Rxtype = c; 827 crc = 0xFFFFFFFFL; crc = UPDC32(c, crc); 828 #ifdef DEBUGZ 829 VPRINTF(3,("zrbhdr32 c=%X crc=%lX", c, crc)i); 830 #endif 831 832 for (n=4; --n >= 0; ++hdr) { 833 if ((c = zdlread()) & ~0377) 834 return c; 835 crc = UPDC32(c, crc); 836 *hdr = c; 837 #ifdef DEBUGZ 838 VPRINTF(3,("zrbhdr32 c=%X crc=%lX", c, crc)); 839 #endif 840 } 841 for (n=4; --n >= 0;) { 842 if ((c = zdlread()) & ~0377) 843 return c; 844 crc = UPDC32(c, crc); 845 #ifdef DEBUGZ 846 VPRINTF(3,("zrbhdr32 c=%X crc=%lX", c, crc)); 847 #endif 848 } 849 if (crc != 0xDEBB20E3) { 850 zperr(badcrc); 851 return ERROR; 852 } 853 protocol = ZM_ZMODEM; 854 zmodem_requested=TRUE; 855 return Rxtype; 856 } 857 858 859 /* Receive a hex style header (type and position) */ 860 static int 861 zrhhdr(char *hdr) 862 { 863 register int c; 864 register unsigned short crc; 865 register int n; 866 867 if ((c = zgethex()) < 0) 868 return c; 869 Rxtype = c; 870 crc = updcrc(c, 0); 871 872 for (n=4; --n >= 0; ++hdr) { 873 if ((c = zgethex()) < 0) 874 return c; 875 crc = updcrc(c, crc); 876 *hdr = c; 877 } 878 if ((c = zgethex()) < 0) 879 return c; 880 crc = updcrc(c, crc); 881 if ((c = zgethex()) < 0) 882 return c; 883 crc = updcrc(c, crc); 884 if (crc & 0xFFFF) { 885 zperr(badcrc); return ERROR; 886 } 887 switch ( c = READLINE_PF(1)) { 888 case 0215: 889 /* **** FALL THRU TO **** */ 890 case 015: 891 /* Throw away possible cr/lf */ 892 READLINE_PF(1); 893 break; 894 } 895 protocol = ZM_ZMODEM; 896 zmodem_requested=TRUE; 897 return Rxtype; 898 } 899 900 /* Write a byte as two hex digits */ 901 static void 902 zputhex(int c, char *pos) 903 { 904 static char digits[] = "0123456789abcdef"; 905 906 VPRINTF(9,("zputhex: %02X", c)); 907 pos[0]=digits[(c&0xF0)>>4]; 908 pos[1]=digits[c&0x0F]; 909 } 910 911 void 912 zsendline_init(void) 913 { 914 int i; 915 for (i=0;i<256;i++) { 916 if (i & 0140) 917 zsendline_tab[i]=0; 918 else { 919 switch(i) 920 { 921 case ZDLE: 922 case XOFF: /* ^Q */ 923 case XON: /* ^S */ 924 case (XOFF | 0200): 925 case (XON | 0200): 926 zsendline_tab[i]=1; 927 break; 928 case 020: /* ^P */ 929 case 0220: 930 if (turbo_escape) 931 zsendline_tab[i]=0; 932 else 933 zsendline_tab[i]=1; 934 break; 935 case 015: 936 case 0215: 937 if (Zctlesc) 938 zsendline_tab[i]=1; 939 else if (!turbo_escape) 940 zsendline_tab[i]=2; 941 else 942 zsendline_tab[i]=0; 943 break; 944 default: 945 if (Zctlesc) 946 zsendline_tab[i]=1; 947 else 948 zsendline_tab[i]=0; 949 } 950 } 951 } 952 } 953 954 955 956 /* Store pos in Txhdr */ 957 void 958 stohdr(size_t pos) 959 { 960 long lpos=(long) pos; 961 Txhdr[ZP0] = lpos; 962 Txhdr[ZP1] = lpos>>8; 963 Txhdr[ZP2] = lpos>>16; 964 Txhdr[ZP3] = lpos>>24; 965 } 966 967 /* Recover a long integer from a header */ 968 long 969 rclhdr(char *hdr) 970 { 971 long l; 972 973 l = (hdr[ZP3] & 0377); 974 l = (l << 8) | (hdr[ZP2] & 0377); 975 l = (l << 8) | (hdr[ZP1] & 0377); 976 l = (l << 8) | (hdr[ZP0] & 0377); 977 return l; 978 } 979 980 /* End of zm.c */ 981