1 /*
2  *	binkleyforce -- unix FTN mailer project
3  *
4  *	Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
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 of the License, or
9  *	(at your option) any later version.
10  *
11  *	$Id: prot_zmmisc.c,v 1.1.1.1 2004/09/09 09:52:39 kstepanenkov Exp $
12  */
13 
14 #include "includes.h"
15 #include "confread.h"
16 #include "logger.h"
17 #include "util.h"
18 #include "io.h"
19 #include "prot_zmodem.h"
20 
21 int  Z_Rxexp;		/* True means timer expired                  */
22 int  Z_Rxtout;		/* Seconds to wait for receiving whole block */
23 int  Z_Rxwait;		/* Seconds to wait for character available   */
24 int  Z_Rxframeind;	/* ZBIN ZBIN32, or ZHEX type of frame received */
25 int  Z_Rxtype;		/* Type of header received                   */
26 int  Z_Rxcount;		/* Count of data bytes received              */
27 int  Z_Txnulls;		/* Number of nulls to send at beginning of ZDATA hdr */
28 char Z_Rxhdr[4];	/* Received header                           */
29 char Z_Txhdr[4];	/* Transmitted header                        */
30 long Z_Rxpos;		/* Received file position                    */
31 int  Z_Txfcs32;		/* TRUE means send binary frames with 32 bit FCS */
32 int  Z_Txcrc32;		/* Display flag indicating 32 bit CRC being sent */
33 int  Z_Rxcrc32;		/* Display flag indicating 32 bit CRC being received */
34 char Z_Attn[ZATTNLEN+1];/* Attention string rx sends to tx on err     */
35 int  Z_Ctlesc;		/* Encode control characters                 */
36 int  Z_Lastsent;	/* Character we sent last                    */
37 
38 #ifdef DEBUG
39 static const char *FrameTypes[] =
40 {
41 	"Unused",		/*           (-7) */
42 	"Unused",		/*           (-6) */
43 	"CRC error",		/* ZCRCERR   (-5) */
44 	"Bad frame",		/* ZERROR    (-4) */
45 	"I/O Error",		/* ZEXIT     (-3) */
46 	"Carrier Lost",		/* ZHANGUP   (-2) */
47 	"Timer out",		/* ZTIMER    (-1) */
48 #define FTOFFSET 7
49 	"ZRQINIT",
50 	"ZRINIT",
51 	"ZSINIT",
52 	"ZACK",
53 	"ZFILE",
54 	"ZSKIP",
55 	"ZNAK",
56 	"ZABORT",
57 	"ZFIN",
58 	"ZRPOS",
59 	"ZDATA",
60 	"ZEOF",
61 	"ZFERR",
62 	"ZCRC",
63 	"ZCHALLENGE",
64 	"ZCOMPL",
65 	"ZCAN",
66 	"ZFREECNT",
67 	"ZCOMMAND",
68 	"ZSTDERR",
69 	"Unused"
70 #define FRTYPES 22		/* Total number of frame types in this array */
71 				/*  not including psuedo negative entries    */
72 };
73 #endif
74 
75 static int  zrbhdr16(char *hdr);
76 static int  zrbhdr32(char *hdr);
77 static int  zrhhdr(char *hdr);
78 static int  zrdat32(char *buf, int length, long pos);
79 static int  zrdat16(char *buf, int length, long pos);
80 static int  zgethex(void);
81 static int  noxrd7(void);
82 static int  zdlread(void);
83 static int  zputhex(int c);
84 static void zsendline_init(char *);
85 
zalarmh(int sig_no)86 static void zalarmh(int sig_no)
87 {
88 	DEB((D_PROT, "zalarmh: got SIGALRM (timer expired!)"));
89 	Z_Rxexp = 1;
90 }
91 
setalarm(int sec)92 void setalarm(int sec)
93 {
94 	static int allready = 0;
95 
96 	if( !sec )
97 	{
98 		alarm(0); return;
99 	}
100 
101 	Z_Rxexp = 0;
102 
103 	if( allready == 0 )
104 	{
105 		if( signal(SIGALRM, zalarmh) == SIG_ERR )
106 		{
107 			logerr("can't setup SIGALRM handler");
108 			return;
109 		}
110 		allready = 1;
111 	}
112 
113 	alarm(sec);
114 }
115 
116 /* ------------------------------------------------------------------------- */
117 /* Read a byte, checking for ZMODEM escape encoding                          */
118 /* including five CAN which represents a quick abort                         */
119 /* ------------------------------------------------------------------------- */
zmodem_getbyte(void)120 static int zmodem_getbyte(void)
121 {
122 	int c;
123 	int cancount = 0;
124 	int gotdle = 0;
125 
126 	while(1)
127 	{
128 		if( Z_Rxexp )
129 			return ZTIMER;
130 
131 		if( (c = GETCHAR(Z_Rxwait)) < 0 )
132 			return c;
133 
134 		if( gotdle )
135 		{
136 			if( c != CAN )
137 				cancount = 0;
138 
139 			switch( c ) {
140 			case CAN:
141 				if( ++cancount > 5 )
142 					return GOTCAN;
143 				break;
144 			case ZCRCE:
145 			case ZCRCG:
146 			case ZCRCQ:
147 			case ZCRCW:
148 				return c|GOTOR;
149 			case ZRUB0:
150 				return 0177;
151 			case ZRUB1:
152 				return 0377;
153 			case XON:
154 			case XOFF:
155 			case XON|0200:
156 			case XOFF|0200:
157 				break;
158 			default:
159 				if( !Z_Ctlesc || (c & 140) )
160 				{
161 					if( (c & 0140) == 0100 )
162 						return c^0100;
163 					else
164 						bf_log("zmodem: got bad escape sequence 0x%x", c);
165 				}
166 			}
167 		}
168 		else
169 		{
170 			switch(c) {
171 			case ZDLE:
172 				gotdle = 1;
173 				break;
174 			case XON:
175 			case XOFF:
176 			case XON|0200:
177 			case XOFF|0200:
178 				break;
179 			default:
180 				if( !Z_Ctlesc || (c & 0140) )
181 				{
182 					return c;
183 				}
184 			}
185 		}
186 	}
187 
188 	return 0;
189 }
190 
zmodem_getbyte_raw(void)191 static int zmodem_getbyte_raw(void)
192 {
193 	int c;
194 
195 	while(1)
196 	{
197 		if( Z_Rxexp )
198 			return ZTIMER;
199 
200 		if( (c = GETCHAR(Z_Rxwait)) < 0 )
201 			return c;
202 
203 		c &= 0177;
204 
205 		switch(c) {
206 		case XON:
207 		case XOFF:
208 			break;
209 		case '\r':
210 		case '\n':
211 		case ZDLE:
212 			return c;
213 		default:
214 			if( !Z_Ctlesc || (c & 0140) )
215 				return c;
216 		}
217 	}
218 
219 	return 0;
220 }
221 
zmodem_putbyte(int c)222 static int zmodem_putbyte(int c)
223 {
224 	static int last_esc = -2;
225 	static char tab[256];
226 	int rc;
227 
228 	if( Z_Ctlesc != last_esc )
229 	{
230 		zsendline_init(tab);
231 		last_esc = Z_Ctlesc;
232 	}
233 
234 	switch( tab[(unsigned char)(c)] ) {
235 	case 0:
236 		if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
237 			return rc;
238 		break;
239 
240 	case 1:
241 		if( (rc = BUFCHAR(ZDLE)) < 0 )
242 			return rc;
243 		c ^= 0100;
244 		if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
245 			return rc;
246 		break;
247 
248 	case 2:
249 		/* Escape for telnet escape sequence */
250 		if( (Z_Lastsent & 0177) != '@' )
251 		{
252 			if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
253 				return rc;
254 		}
255 		else
256 		{
257 			c ^= 0100;
258 			if( (rc = BUFCHAR(ZDLE)) < 0 )
259 				return rc;
260 			if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
261 				return rc;
262 		}
263 		break;
264 
265 	default:
266 		ASSERT_MSG();
267 	}
268 
269 	return ZOK;
270 }
271 
zdlread(void)272 static int zdlread(void)
273 {
274 	int c, cancnt = 0;
275 
276 	/* Quick check for non control characters */
277 	for(;;)
278 	{
279 		if( Z_Rxexp )
280 			return(ZTIMER);
281 
282 		c = GETCHAR(Z_Rxwait);
283 
284 		if( (c & 0140) || (c < 0) )
285 			return(c);
286 
287 		switch( c ) {
288 		case ZDLE:
289 			break;
290 		case XON:
291 		case XOFF:
292 		case XON|0200:
293 		case XOFF|0200:
294 			continue;
295 		default:
296 			if( Z_Ctlesc && !(c & 0140) )
297 				continue;
298 			return(c);
299 		}
300 		break;
301 	}
302 
303 	for(;;)
304 	{
305 		if( Z_Rxexp )
306 			return(ZTIMER);
307 
308 		if( (c = GETCHAR(Z_Rxwait)) < 0 )
309 			return(c);
310 
311 		if( c != CAN )
312 			cancnt = 0;
313 
314 		switch( c ) {
315 		case CAN:
316 			if( ++cancnt >= 5 )
317 				return(GOTCAN);
318 			continue;
319 		case ZCRCE:
320 		case ZCRCG:
321 		case ZCRCQ:
322 		case ZCRCW:
323 			return(c | GOTOR);
324 		case ZRUB0:
325 			return(0177);
326 		case ZRUB1:
327 			return(0377);
328 		case XON:
329 		case XOFF:
330 		case XON|0200:
331 		case XOFF|0200:
332 			continue;
333 		default:
334 			if( Z_Ctlesc && !(c & 0140) )
335 				continue;
336 			if( (c & 0140) == 0100 )
337 				return(c^0100);
338 
339 			/* It was unknown escape sequence */
340 			DEB((D_PROT, "zdlread: bad escape sequence 0x%x", c));
341 
342 			return(ZERROR);
343 		}
344 	}
345 }
346 
347 /* ------------------------------------------------------------------------- */
348 /* Read a character from the modem line with timeout.                        */
349 /* Eat parity, XON and XOFF characters.                                      */
350 /* ------------------------------------------------------------------------- */
noxrd7(void)351 static int noxrd7(void)
352 {
353 	int c;
354 
355 	for(;;)
356 	{
357 		if( Z_Rxexp )
358 			return(ZTIMER);
359 
360 		if( (c = GETCHAR(Z_Rxwait)) < 0 )
361 			return(c);
362 
363 		switch( c &= 0177 ) {
364 		case XON:
365 		case XOFF:
366 			continue;
367 		default:
368 			if( Z_Ctlesc && !(c & 0140) )
369 				continue;
370 		case '\r':
371 		case '\n':
372 		case ZDLE:
373 			return(c);
374 		}
375 	}
376 }
377 
378 /* ------------------------------------------------------------------------- */
379 /* Send character $c with ZMODEM escape sequence encoding.                   */
380 /* Escape XON, XOFF. Escape CR following @ (Telenet net escape)              */
381 /* Warning: Put result to buffer with BUFCHAR function! Use FLUSHBUF later!  */
382 /* ------------------------------------------------------------------------- */
zsendline(char c)383 int zsendline(char c)
384 {
385 	static int last_esc = -2;
386 	static char tab[256];
387 	int rc;
388 
389 	if( Z_Ctlesc != last_esc )
390 	{
391 		zsendline_init(tab);
392 		last_esc = Z_Ctlesc;
393 	}
394 
395 	switch( tab[(unsigned char)(c)] ) {
396 	case 0:
397 		if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
398 			return(rc);
399 		break;
400 	case 1:
401 		if( (rc = BUFCHAR(ZDLE)) < 0 )
402 			return(rc);
403 		c ^= 0100;
404 		if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
405 			return(rc);
406 		break;
407 	case 2:
408 		/* Escape for telnet escape sequence */
409 		if( (Z_Lastsent & 0177) != '@' )
410 		{
411 			if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
412 				return(rc);
413 		}
414 		else
415 		{
416 			c ^= 0100;
417 			if( (rc = BUFCHAR(ZDLE)) < 0 )
418 				return(rc);
419 			if( (rc = BUFCHAR(Z_Lastsent = c)) < 0 )
420 				return(rc);
421 		}
422 		break;
423 	}
424 
425 	return(ZOK);
426 }
427 
428 /* ------------------------------------------------------------------------- */
429 /* Send ZMODEM binary header hdr of type $type                               */
430 /* ------------------------------------------------------------------------- */
zsbhdr(int type,char * hdr)431 int zsbhdr(int type, char *hdr)
432 {
433 	int n, rc;
434 	unsigned short crc;
435 	unsigned long crc32;
436 
437 	DEB((D_PROT, "zsbhdr: %s %lx (CRC%s)", FrameTypes[type+FTOFFSET],
438 		rclhdr(hdr), Z_Txfcs32?"32":"16"));
439 
440 	if( type == ZDATA )
441 		for( n=Z_Txnulls; --n >= 0; )
442 		{
443 			if( (rc = BUFCHAR('\0')) < 0 )
444 				return(rc);
445 		}
446 
447 	if( (rc = BUFCHAR(ZPAD)) < 0 )
448 		return(rc);
449 	if( (rc = BUFCHAR(ZDLE)) < 0 )
450 		return(rc);
451 
452 	Z_Txcrc32 = Z_Txfcs32;
453 
454 	if( Z_Txcrc32 )
455 	{
456 		/* Use CRC32 */
457 		crc32 = 0xFFFFFFFFL;
458 
459 		if( (rc = BUFCHAR(ZBIN32)) < 0 )
460 			return(rc);
461 		if( (rc = zsendline(type)) < 0 )
462 			return(rc);
463 		crc32 = updcrc32(type, crc32);
464 
465 		for( n = 4; --n >= 0; ++hdr )
466 		{
467 			crc32 = updcrc32((0377 & *hdr), crc32);
468 			if( (rc = zsendline((*hdr) & 0377)) < 0 )
469 				return(rc);
470 		}
471 
472 		crc32 = ~crc32;
473 
474 		for( n = 4; --n >= 0; )
475 		{
476 			if( (rc = zsendline(crc32 & 0377)) < 0 )
477 				return(rc);
478 			crc32 >>= 8;
479 		}
480 	}
481 	else /* CRC-16 */
482 	{
483 		crc = 0;
484 
485 		if( (rc = BUFCHAR(ZBIN)) < 0 )
486 			return rc;
487 		if( (rc = zsendline(type)) < 0 )
488 			return(rc);
489 		crc = updcrc16(type, crc);
490 
491 		for( n = 4; --n >= 0; ++hdr )
492 		{
493 			if( (rc = zsendline((*hdr) & 0377)) < 0 )
494 				return(rc);
495 			crc = updcrc16(((*hdr) & 0377), crc);
496 		}
497 
498 		crc = updcrc16(0,updcrc16(0,crc));
499 		if( (rc = zsendline((crc>>8) & 0377)) < 0 )
500 			return(rc);
501 		if( (rc = zsendline((crc   ) & 0377)) < 0 )
502 			return(rc);
503 	}
504 
505 	if( (rc = FLUSHBUF()) < 0 )
506 		return(rc);
507 	if( type != ZDATA && (rc = FLUSHOUT()) < 0 )
508 		return rc;
509 
510 	return(0);
511 }
512 
513 /* ------------------------------------------------------------------------- */
514 /* Send ZMODEM HEX header hdr of type $type                                  */
515 /* ------------------------------------------------------------------------- */
zshhdr(int type,char * hdr)516 int zshhdr(int type, char *hdr)
517 {
518 	int n, rc;
519 	unsigned short crc;
520 
521 	DEB((D_PROT, "zshhdr: %s %lx (CRC16)",
522 		FrameTypes[(type & 0x7f)+FTOFFSET], rclhdr(hdr)));
523 
524 	Z_Txcrc32 = 0;
525 
526 	if( (rc = BUFCHAR(ZPAD)) < 0 ) return(rc);
527 	if( (rc = BUFCHAR(ZPAD)) < 0 ) return(rc);
528 	if( (rc = BUFCHAR(ZDLE)) < 0 ) return(rc);
529 	if( (rc = BUFCHAR(ZHEX)) < 0 ) return(rc);
530 	if( (rc = zputhex(type)) < 0 ) return(rc);
531 
532 	crc = updcrc16(type, 0);
533 	for( n = 4; --n >= 0; ++hdr )
534 	{
535 		if( (rc = zputhex(*hdr & 0377)) < 0 )
536 			return(rc);
537 		crc = updcrc16((*hdr & 0377), crc);
538 	}
539 
540 	crc = updcrc16(0, updcrc16(0,crc));
541 	if( (rc = zputhex((crc>>8)&0377)) < 0 ) return(rc);
542 	if( (rc = zputhex((crc   )&0377)) < 0 ) return(rc);
543 
544 	/* Make it printable on remote machine */
545 	if( (rc = BUFCHAR('\r')) < 0 ) return(rc);
546 	if( (rc = BUFCHAR('\n')) < 0 ) return(rc);
547 
548 	/* Uncork the remote in case a fake XOFF has stopped data flow */
549 	if( type != ZFIN && type != ZACK )
550 	{
551 		if( (rc = BUFCHAR(XON)) < 0 )
552 			return(rc);
553 	}
554 
555 	if( (rc = FLUSHBUF()) < 0 ) return(rc);
556 	if( (rc = FLUSHOUT()) < 0 ) return(rc);
557 
558 	return(0);
559 }
560 
561 /* ------------------------------------------------------------------------- */
562 /* Send binary array buf of length length, with ending ZDLE sequence frameend*/
563 /* $pos must point to current offset of sending file (for logging only)      */
564 /* ------------------------------------------------------------------------- */
565 #ifdef DEBUG
566 static const char *Zendnames[] = {"ZCRCE", "ZCRCG", "ZCRCQ", "ZCRCW"};
567 #endif
568 
zsdata(const char * buf,int length,int frameend,long pos)569 int zsdata(const char *buf, int length, int frameend, long pos)
570 {
571 	int n, rc;
572 	unsigned short crc;
573 	unsigned long crc32;
574 
575 	DEB((D_PROT, "zsdata: %d %s (CRC%s) from %d pos", length,
576 		Zendnames[(frameend-ZCRCE)&3], Z_Txcrc32?"32":"16", pos));
577 
578 	if( Z_Txcrc32 )
579 	{
580 		crc32 = 0xFFFFFFFFL;
581 
582 		for( ; --length >= 0; ++buf )
583 		{
584 			if( (rc = zsendline((*buf) & 0377)) < 0 )
585 				return(rc);
586 			crc32 = updcrc32(((*buf) & 0377), crc32);
587 		}
588 
589 		if( (rc = BUFCHAR(ZDLE)) < 0 )
590 			return(rc);
591 		if( (rc = BUFCHAR(frameend)) < 0 )
592 			return(rc);
593 		crc32 = updcrc32(frameend, crc32);
594 
595 		crc32 = ~crc32;
596 		for( n = 4; --n >= 0; )
597 		{
598 			if( (rc = zsendline(crc32 & 0377)) < 0 )
599 				return(rc);
600 			crc32 >>= 8;
601 		}
602 	}
603 	else /* CRC-16 */
604 	{
605 		crc = 0;
606 		for( ; --length >= 0; ++buf )
607 		{
608 			if( (rc = zsendline((*buf) & 0377)) < 0 )
609 				return(rc);
610 			crc = updcrc16((*buf & 0377), crc);
611 		}
612 
613 		if( (rc = BUFCHAR(ZDLE)) < 0 )
614 			return(rc);
615 		if( (rc = BUFCHAR(frameend)) < 0 )
616 			return(rc);
617 		crc = updcrc16(frameend, crc);
618 
619 		crc = updcrc16(0, updcrc16(0, crc));
620 		if( (rc = zsendline((crc>>8) & 0377)) < 0
621 		 || (rc = zsendline((crc   ) & 0377)) < 0 )
622 			return(rc);
623 	}
624 
625 	if( (rc = FLUSHBUF()) < 0 )
626 		return(rc);
627 
628 	if( frameend == ZCRCW )
629 	{
630 		if( (rc = PUTCHAR(XON)) < 0 )
631 			return(rc);
632 		if( (rc = FLUSHOUT())   < 0 )
633 			return(rc);
634 	}
635 
636 	return(0);
637 }
638 
639 /* ------------------------------------------------------------------------- */
640 /* Receive array buf of max length+1 with ending ZDLE sequence               */
641 /* and CRC.  Returns the ending character or error code.                     */
642 /* $pos must contatain current offset of receiving file (for logging only!)  */
643 /* ------------------------------------------------------------------------- */
zrdata(char * buf,int length,long pos)644 int zrdata(char *buf, int length, long pos)
645 {
646 	return (Z_Rxframeind == ZBIN32) ? zrdat32(buf, length, pos)
647 	                                : zrdat16(buf, length, pos);
648 }
649 
zrdat16(char * buf,int length,long pos)650 static int zrdat16(char *buf, int length, long pos)
651 {
652 	int c;
653 	unsigned short crc;
654 	char *end;
655 	int d;
656 
657 	Z_Rxcount = 0;
658 	crc = 0;
659 	end = buf + length;
660 
661 	while( buf <= end )
662 	{
663 		if( (c=zdlread()) & ~0377 )
664 		{
665 switch_again:
666 			switch( c ) {
667 			case GOTCRCE:
668 			case GOTCRCG:
669 			case GOTCRCQ:
670 			case GOTCRCW:
671 				d = c;
672 				c &= 0377;
673 				crc = updcrc16(c, crc);
674 
675 				if( (c=zdlread()) & ~0377 ) goto switch_again;
676 				crc = updcrc16(c, crc);
677 
678 				if( (c=zdlread()) & ~0377 ) goto switch_again;
679 				crc = updcrc16(c, crc);
680 
681 				Z_Rxcount = length - (end - buf);
682 
683 				if( crc & 0xFFFF )
684 				{
685 					DEB((D_PROT, "zrdat16: %d %s : Bad CRC",
686 						Z_Rxcount, Zendnames[(d-GOTCRCE)&3]));;
687 					bf_log("ZDATA with bad CRC");
688 
689 					return ZCRCERR;
690 				}
691 
692 				DEB((D_PROT, "zrdat16: %d %s (CRC16) at %d pos",
693 					Z_Rxcount, Zendnames[(d-GOTCRCE)&3], pos));
694 
695 				return d;
696 
697 			case GOTCAN:
698 				DEB((D_PROT, "zrdat16: Sender CANceled"));
699 				return ZCAN;
700 
701 			case ZHANGUP:
702 			case ZTIMER:
703 			case ZEXIT:
704 				DEB((D_PROT, "zrdat16: zdlread() return %s",
705 					( c == ZHANGUP ) ? "ZHANGUP":
706 					( c == ZEXIT   ) ? "ZEXIT":
707 					( c == ZTIMER  ) ? "ZTIMER" : "Unknown"));
708 				return c;
709 
710 			default:
711 				DEB((D_PROT, "zrdat16: $zdlread return %d", c));
712 				return c;
713 			}
714 		}
715 		*buf++ = c;
716 		crc = updcrc16(c, crc);
717 	}
718 
719 	bf_log("zmodem: data packet too long");
720 	DEB((D_PROT, "zrdat16: data packet too long"));
721 
722 	return ZERROR;
723 }
724 
zrdat32(char * buf,int length,long pos)725 static int zrdat32(char *buf, int length, long pos)
726 {
727 	int c, d;
728 	unsigned long crc;
729 	char *end;
730 
731 	Z_Rxcount = 0;
732 	crc = 0xFFFFFFFFL;
733 	end = buf + length;
734 
735 	while( buf <= end )
736 	{
737 		if( (c = zdlread()) & ~0377 )
738 		{
739 switch_again:
740 			switch( c ) {
741 			case GOTCRCE:
742 			case GOTCRCG:
743 			case GOTCRCQ:
744 			case GOTCRCW:
745 				d = c;
746 				c &= 0377;
747 				crc = updcrc32(c, crc);
748 				if( (c = zdlread()) & ~0377 ) goto switch_again;
749 				crc = updcrc32(c, crc);
750 
751 				if( (c = zdlread()) & ~0377 ) goto switch_again;
752 				crc = updcrc32(c, crc);
753 
754 				if( (c = zdlread()) & ~0377 ) goto switch_again;
755 				crc = updcrc32(c, crc);
756 
757 				if( (c = zdlread()) & ~0377 ) goto switch_again;
758 				crc = updcrc32(c, crc);
759 
760 				Z_Rxcount = length - (end - buf);
761 
762 				if( crc != 0xDEBB20E3 )
763 				{
764 					DEB((D_PROT, "zrdat32: %d %s : Bad CRC",
765 						Z_Rxcount, Zendnames[(d-GOTCRCE)&3]));
766 					bf_log("DATA with bad CRC");
767 
768 					return ZCRCERR;
769 				}
770 
771 				DEB((D_PROT, "zrdat32: %d %s (CRC32) at %d pos",
772 					Z_Rxcount, Zendnames[(d-GOTCRCE)&3], pos));
773 
774 				return d;
775 
776 			case GOTCAN:
777 				DEB((D_PROT, "zrdat32: Sender CANceled"));
778 				return ZCAN;
779 
780 			case ZEXIT:
781 			case ZTIMER:
782 			case ZHANGUP:
783 				DEB((D_PROT, "zrdat32: zdlread() return %s",
784 					( c == ZHANGUP ) ? "ZHANGUP":
785 					( c == ZEXIT   ) ? "ZEXIT":
786 					( c == ZTIMER  ) ? "ZTIMER" : "Unknown"));
787 				return c;
788 
789 			default:
790 				DEB((D_PROT, "zrdat32: $zdlread return %d", c));
791 				return c;
792 			}
793 		}
794 		*buf++ = c;
795 		crc = updcrc32(c, crc);
796 	}
797 
798 	bf_log("zmodem: data packet too long");
799 	DEB((D_PROT, "zrdat32: data packet too long"));
800 
801 	return ZERROR;
802 }
803 
804 /* ------------------------------------------------------------------------- */
805 /* Read a ZMODEM header to hdr, either binary or hex.                        */
806 /* On success, set Z_Rxpos and return type of header.                        */
807 /* Otherwise return negative on error.                                       */
808 /* Return ZERROR instantly if ZCRCW sequence, for fast error recovery.       */
809 /* ------------------------------------------------------------------------- */
zgethdr(char * hdr)810 int zgethdr(char *hdr)
811 {
812 	int c, n, cancount;
813 
814 	n        = 8192;    /* Maximum number of garbage chars */
815 	cancount = 5;       /* CANcel on this can number */
816 
817 	Z_Rxframeind = 0;
818 	Z_Rxtype     = 0;
819 
820 again:
821 	if( Z_Rxexp ) { c = ZTIMER; goto fifi; }
822 
823 	switch( c = GETCHAR(Z_Rxwait) ) {
824 	case ZEXIT:
825 	case ZHANGUP:
826 	case ZTIMER:
827 		goto fifi;
828 	case CAN:
829 gotcan:
830 		if( --cancount == 0 )
831 		{
832 			c = ZCAN; goto fifi;
833 		}
834 
835 		if( Z_Rxexp ) { c = ZTIMER; goto fifi; }
836 
837 		switch( c = GETCHAR(Z_Rxwait) ) {
838 		case ZCRCW:
839 			/* Return immediate ERROR if ZCRCW sequence seen */
840 			c = ZERROR;
841 		case ZEXIT:
842 		case ZHANGUP:
843 		case ZTIMER:
844 			goto fifi;
845 		default:
846 			break;
847 		case CAN:
848 			if( --cancount == 0 )
849 			{
850 				c = ZCAN; goto fifi;
851 			}
852 			goto again;
853 		}
854 	default:
855 		if( --n == 0 ) {
856 			DEB((D_PROT, "zgethdr: garbage count exceeded"));
857 			c = ZERROR; goto fifi;
858 		}
859 		cancount = 5;
860 		goto again;
861 	case ZPAD|0200:		/* This is what we want. */
862 	case ZPAD:		/* This is what we want. */
863 		break;
864 	}
865 	cancount = 5;
866 
867 splat:
868 	switch( c = noxrd7() ) {
869 	case ZPAD:
870 		goto splat;
871 	case ZEXIT:
872 	case ZHANGUP:
873 	case ZTIMER:
874 		goto fifi;
875 	default:
876 		if( --n == 0 ) {
877 			DEB((D_PROT, "zgethdr: garbage count exceeded"));
878 			c = ZERROR; goto fifi;
879 		}
880 		goto again;
881 	case ZDLE:		/* This is what we want. */
882 		break;
883 	}
884 
885 	switch( c=noxrd7() ) {
886 	case ZEXIT:
887 	case ZHANGUP:
888 	case ZTIMER:
889 		goto fifi;
890 	case ZBIN:
891 		/* receive binary header with crc16 */
892 		Z_Rxcrc32    = 0;
893 		Z_Rxframeind = ZBIN;
894 		c = zrbhdr16(hdr);
895 		break;
896 	case ZBIN32:
897 		/* receive binary header with crc32 */
898 		Z_Rxcrc32    = 1;
899 		Z_Rxframeind = ZBIN32;
900 		c = zrbhdr32(hdr);
901 		break;
902 	case ZHEX:
903 		/* receive hex header (all hex headers have crc16) */
904 		Z_Rxcrc32    = 0;
905 		Z_Rxframeind = ZHEX;
906 		c = zrhhdr(hdr);
907 		break;
908 	case CAN:
909 		goto gotcan;
910 	default:
911 		if( --n == 0 ) {
912 			DEB((D_PROT, "zgethdr: garbage count exceeded"));
913 			c = ZERROR; goto fifi;
914 		}
915 		goto again;
916 	}
917 
918 	if( c >= 0 )
919 	{
920 		Z_Rxpos = hdr[ZP3] & 0377;
921 		Z_Rxpos = (Z_Rxpos<<8) + (hdr[ZP2] & 0377);
922 		Z_Rxpos = (Z_Rxpos<<8) + (hdr[ZP1] & 0377);
923 		Z_Rxpos = (Z_Rxpos<<8) + (hdr[ZP0] & 0377);
924 	}
925 
926 fifi:
927     	if( c == GOTCAN )
928 		c = ZCAN;
929 
930 #ifdef DEBUG
931 	if( (c >= -7) && (c <= FRTYPES) )
932 		DEB((D_PROT, "zgethdr: %s %lx", FrameTypes[c+FTOFFSET], Z_Rxpos));
933 	else
934 		DEB((D_PROT, "zgethdr: %d %lx", c, Z_Rxpos));
935 #endif
936 
937 	return(c);
938 }
939 
940 /* ------------------------------------------------------------------------- */
941 /* Receive a binary style header (type and position)                         */
942 /* ------------------------------------------------------------------------- */
zrbhdr16(char * hdr)943 static int zrbhdr16(char *hdr)
944 {
945 	int c, n;
946 	unsigned short crc;
947 
948 	if( (c = zdlread()) < 0 )
949 		return(c);
950 	Z_Rxtype = c;
951 	crc = updcrc16(c, 0);
952 
953 	for( n = 4; --n >= 0; ++hdr )
954 	{
955 		if( (c = zdlread()) < 0 )
956 			return(c);
957 		crc = updcrc16(c, crc);
958 		*hdr = c;
959 	}
960 
961 	if( (c = zdlread()) < 0 )
962 		return(c);
963 	crc = updcrc16(c, crc);
964 
965 	if( (c = zdlread()) < 0 )
966 		return(c);
967 	crc = updcrc16(c, crc);
968 
969 	if( crc & 0xFFFF )
970 	{
971 		DEB((D_PROT, "zrbhdr: Bad CRC"));
972 		bf_log("Bad CRC");
973 		return(ZCRCERR);
974 	}
975 
976 	return(Z_Rxtype);
977 }
978 
979 /* ------------------------------------------------------------------------- */
980 /* Receive a binary style header (type and position) with 32 bit FCS         */
981 /* ------------------------------------------------------------------------- */
zrbhdr32(char * hdr)982 static int zrbhdr32(char *hdr)
983 {
984 	int c, n;
985 	unsigned long crc;
986 
987 	if( (c = zdlread()) < 0 )
988 		return c;
989 	Z_Rxtype = c;
990 	crc = 0xFFFFFFFFL;
991 	crc = updcrc32(c, crc);
992 
993 	for( n = 4; --n >= 0; ++hdr )
994 	{
995 		if( (c = zdlread()) < 0 )
996 			return(c);
997 		crc = updcrc32(c, crc);
998 		*hdr = c;
999 	}
1000 
1001 	for( n = 4; --n >= 0; )
1002 	{
1003 		if( (c = zdlread()) < 0 )
1004 			return(c);
1005 		crc = updcrc32(c, crc);
1006 	}
1007 
1008 	if( crc != 0xDEBB20E3 )
1009 	{
1010 		DEB((D_PROT, "zrbhdr32: Bad CRC"));
1011 		bf_log("Bad CRC");
1012 		return(ZCRCERR);
1013 	}
1014 
1015 	return(Z_Rxtype);
1016 }
1017 
1018 
1019 /* ------------------------------------------------------------------------- */
1020 /* Receive a hex style header (type and position)                            */
1021 /* ------------------------------------------------------------------------- */
zrhhdr(char * hdr)1022 static int zrhhdr(char *hdr)
1023 {
1024 	int c, n;
1025 	unsigned short crc;
1026 
1027 	if( (c = zgethex()) < 0 )
1028 		return(c);
1029 	Z_Rxtype = c; crc = updcrc16(c, 0);
1030 
1031 	for( n = 4; --n >= 0; )
1032 	{
1033 		if( (c = zgethex()) < 0 )
1034 			return(c);
1035 		crc = updcrc16(c, crc);
1036 		*hdr++ = c;
1037 	}
1038 
1039 	if( (c = zgethex()) < 0 )
1040 		return(c);
1041 	crc = updcrc16(c, crc);
1042 
1043 	if( (c = zgethex()) < 0 )
1044 		return(c);
1045 	crc = updcrc16(c, crc);
1046 
1047 	if( crc & 0xFFFF )
1048 	{
1049 		DEB((D_PROT, "zrhhdr: Bad CRC"));
1050 		bf_log("Bad CRC");
1051 		return(ZCRCERR);
1052 	}
1053 
1054 	if( CHARWAIT(0) )
1055 	{
1056 		/* There is some characters available.. */
1057 
1058 		switch( (c = GETCHAR(1)) ) {
1059 		case 0215:
1060 		case 015:
1061 	 		/* Throw away possible cr/lf */
1062 			if( (c = GETCHAR(1)) < 0 && c != ZTIMER )
1063 				return(c);
1064 			break;
1065 		case ZEXIT:
1066 		case ZHANGUP:
1067 			return(c);
1068 		}
1069 	}
1070 
1071 	return(Z_Rxtype);
1072 }
1073 
1074 /* ------------------------------------------------------------------------- */
1075 /* Write a byte as two hex digits                                            */
1076 /* ------------------------------------------------------------------------- */
zputhex(int c)1077 static int zputhex(int c)
1078 {
1079 	static char digits[] = "0123456789abcdef";
1080 	int rc;
1081 
1082 	if( (rc = BUFCHAR(digits[(c&0xF0)>>4])) < 0
1083 	 || (rc = BUFCHAR(digits[(c&0x0F)   ])) < 0 )
1084 		return rc;
1085 
1086 	return(0);
1087 }
1088 
1089 /* ------------------------------------------------------------------------- */
1090 /* Init an array of 256 entries, mark codes we must escape with value > 0    */
1091 /* ------------------------------------------------------------------------- */
zsendline_init(char * tab)1092 static void zsendline_init(char *tab)
1093 {
1094 	int i;
1095 
1096 	for( i = 0; i < 256; i++ )
1097 	{
1098 		if( i & 0140 )
1099 			tab[i] = 0;
1100 		else
1101 		{
1102 			switch( i ) {
1103 			case ZDLE:
1104 			case XOFF: /* ^Q */
1105 			case XON:  /* ^S */
1106 			case 020:  /* ^P */
1107 			case (XOFF | 0200):
1108 			case (XON  | 0200):
1109 			case (020  | 0200):
1110 				tab[i] = 1;
1111 				break;
1112 			case 015:
1113 			case (015 | 0200):
1114 				if( Z_Ctlesc )
1115 					tab[i] = 1;
1116 				else
1117 					tab[i] = 2;
1118 				break;
1119 			default:
1120 				if( Z_Ctlesc )
1121 					tab[i] = 1;
1122 				else
1123 					tab[i] = 0;
1124 			}
1125 		} /* end of if */
1126 	} /* end of for */
1127 }
1128 
1129 /* ------------------------------------------------------------------------- */
1130 /* Decode two lower case hex digits into an 8 bit byte value                 */
1131 /* ------------------------------------------------------------------------- */
zgethex(void)1132 static int zgethex(void)
1133 {
1134 	int c, n;
1135 
1136 	if( (c = noxrd7()) < 0 )
1137 		return(c);
1138 
1139 	n = c - '0';
1140 	if( n > 9 ) n -= ('a' - ':');
1141 
1142 	if( n & ~0xF )
1143 		return(ZERROR);
1144 	if( (c = noxrd7()) < 0 )
1145 		return(c);
1146 
1147 	c -= '0';
1148 	if( c > 9 ) c -= ('a' - ':');
1149 	if( c & ~0xF )
1150 		return(ZERROR);
1151 
1152 	c += (n<<4);
1153 
1154 	return(c);
1155 }
1156 
1157 /* ------------------------------------------------------------------------- */
1158 /* Store long integer pos in hdr                                             */
1159 /* ------------------------------------------------------------------------- */
stohdr(char * hdr,long pos)1160 void stohdr(char *hdr, long pos)
1161 {
1162 	hdr[ZP0] = (pos    ) & 0377;
1163 	hdr[ZP1] = (pos>>8 ) & 0377;
1164 	hdr[ZP2] = (pos>>16) & 0377;
1165 	hdr[ZP3] = (pos>>24) & 0377;
1166 }
1167 
1168 /* ------------------------------------------------------------------------- */
1169 /* Recover a long integer from a header                                      */
1170 /* ------------------------------------------------------------------------- */
rclhdr(char * hdr)1171 long rclhdr(char *hdr)
1172 {
1173 	register long l;
1174 
1175 	l = (hdr[ZP3] & 0377);
1176 	l = (l << 8) | (hdr[ZP2] & 0377);
1177 	l = (l << 8) | (hdr[ZP1] & 0377);
1178 	l = (l << 8) | (hdr[ZP0] & 0377);
1179 	return(l);
1180 }
1181