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