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
noxrd7(void)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
zgeth1(void)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
zgethex(void)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
zdlread(void)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
zdlread2(int c)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
zsendline(int c)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
zsendline_s(const char * s,size_t count)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
zsbhdr(int type,char * hdr)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
zsbh32(char * hdr,int type)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
zshhdr(int type,char * hdr)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
zsdata(const char * buf,size_t length,int frameend)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
zsda32(const char * buf,size_t length,int frameend)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
count_blk(int size)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
printout_blocksizes(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
zrdata(char * buf,int length,size_t * bytes_received)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
zrdat32(char * buf,int length,size_t * bytes_received)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
zgethdr(char * hdr,int eflag,size_t * Rxpos)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
zrbhdr(char * hdr)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
zrbhdr32(char * hdr)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
zrhhdr(char * hdr)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
zputhex(int c,char * pos)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
zsendline_init(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
stohdr(size_t pos)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
rclhdr(char * hdr)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