xref: /OK3568_Linux_fs/u-boot/common/zm.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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