|
|
1.1 root 1: /* zmodem.c */
2:
3: /* Synchronet ZMODEM Functions */
4:
5: /* $Id: zmodem.c,v 1.71 2006/09/07 00:43:59 rswindell Exp $ */
6:
7: /******************************************************************************/
8: /* Project : Unite! File : zmodem general Version : 1.02 */
9: /* */
10: /* (C) Mattheij Computer Service 1994 */
11: /* */
12: /* contact us through (in order of preference) */
13: /* */
14: /* email: [email protected] */
15: /* mail: MCS */
16: /* Prinses Beatrixlaan 535 */
17: /* 2284 AT RIJSWIJK */
18: /* The Netherlands */
19: /* voice phone: 31+070-3936926 */
20: /******************************************************************************/
21:
22: /*
23: * zmodem primitives and other code common to zmtx and zmrx
24: */
25:
26: #include <stdio.h>
27: #include <string.h>
28: #include <stdarg.h> /* va_list */
29: #include <sys/stat.h> /* struct stat */
30:
31: #include "genwrap.h"
32: #include "dirwrap.h" /* getfname() */
33: #include "filewrap.h" /* filelength() */
34:
35: #include "zmodem.h"
36: #include "crc16.h"
37: #include "crc32.h"
38:
39: #include "sexyz.h"
40: #include "telnet.h"
41:
42: #define ENDOFFRAME 2
43: #define FRAMEOK 1
44: #define TIMEOUT -1 /* rx routine did not receive a character within timeout */
45: #define INVHDR -2 /* invalid header received; but within timeout */
46: #define ZDLEESC 0x8000 /* one of ZCRCE; ZCRCG; ZCRCQ or ZCRCW was received; ZDLE escaped */
47:
48: #define BADSUBPKT 0x80
49:
50: #define HDRLEN 5 /* size of a zmodem header */
51:
52: static int lprintf(zmodem_t* zm, int level, const char *fmt, ...)
53: {
54: va_list argptr;
55: char sbuf[1024];
56:
57: if(zm->lputs==NULL)
58: return(-1);
59:
60: va_start(argptr,fmt);
61: vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
62: sbuf[sizeof(sbuf)-1]=0;
63: va_end(argptr);
64: return(zm->lputs(zm->cbdata,level,sbuf));
65: }
66:
67: static BOOL is_connected(zmodem_t* zm)
68: {
69: if(zm->is_connected!=NULL)
70: return(zm->is_connected(zm->cbdata));
71: return(TRUE);
72: }
73:
74: static BOOL is_cancelled(zmodem_t* zm)
75: {
76: if(zm->is_cancelled!=NULL)
77: return(zm->cancelled=zm->is_cancelled(zm->cbdata));
78: return(zm->cancelled);
79: }
80: int zmodem_data_waiting(zmodem_t* zm, unsigned timeout)
81: {
82: if(zm->data_waiting)
83: return(zm->data_waiting(zm->cbdata, timeout));
84: return(FALSE);
85: }
86:
87: static char *chr(int ch)
88: {
89: static char str[25];
90:
91: switch(ch) {
92: case TIMEOUT: return("TIMEOUT");
93: case ZRQINIT: return("ZRQINIT");
94: case ZRINIT: return("ZRINIT");
95: case ZSINIT: return("ZSINIT");
96: case ZACK: return("ZACK");
97: case ZFILE: return("ZFILE");
98: case ZSKIP: return("ZSKIP");
99: case ZCRC: return("ZCRC");
100: case ZNAK: return("ZNAK");
101: case ZABORT: return("ZABORT");
102: case ZFIN: return("ZFIN");
103: case ZRPOS: return("ZRPOS");
104: case ZDATA: return("ZDATA");
105: case ZEOF: return("ZEOF");
106: case ZPAD: return("ZPAD");
107: case ZCAN: return("ZCAN");
108: case ZDLE: return("ZDLE");
109: case ZDLEE: return("ZDLEE");
110: case ZBIN: return("ZBIN");
111: case ZHEX: return("ZHEX");
112: case ZBIN32: return("ZBIN32");
113: case ZRESC: return("ZRESC");
114: case ZCRCE: return("ZCRCE");
115: case ZCRCG: return("ZCRCG");
116: case ZCRCQ: return("ZCRCQ");
117: case ZCRCW: return("ZCRCW");
118:
119: }
120: if(ch>=' ' && ch<='~')
121: sprintf(str,"'%c' (%02Xh)",(uchar)ch,(uchar)ch);
122: else
123: sprintf(str,"%u (%02Xh)",(uchar)ch,(uchar)ch);
124: return(str);
125: }
126:
127: static char* frame_desc(int frame)
128: {
129: static char str[25];
130:
131: if(frame==TIMEOUT)
132: return("TIMEOUT");
133:
134: if(frame==INVHDR)
135: return("Invalid Header");
136:
137: if(frame&BADSUBPKT)
138: strcpy(str,"BAD ");
139: else
140: str[0]=0;
141:
142: switch(frame&~BADSUBPKT) {
143: case ZRQINIT: strcat(str,"ZRQINIT"); break;
144: case ZRINIT: strcat(str,"ZRINIT"); break;
145: case ZSINIT: strcat(str,"ZSINIT"); break;
146: case ZACK: strcat(str,"ZACK"); break;
147: case ZFILE: strcat(str,"ZFILE"); break;
148: case ZSKIP: strcat(str,"ZSKIP"); break;
149: case ZNAK: strcat(str,"ZNAK"); break;
150: case ZABORT: strcat(str,"ZABORT"); break;
151: case ZFIN: strcat(str,"ZFIN"); break;
152: case ZRPOS: strcat(str,"ZRPOS"); break;
153: case ZDATA: strcat(str,"ZDATA"); break;
154: case ZEOF: strcat(str,"ZEOF"); break;
155: case ZFERR: strcat(str,"ZFERR"); break;
156: case ZCRC: strcat(str,"ZCRC"); break;
157: case ZCHALLENGE: strcat(str,"ZCHALLENGE"); break;
158: case ZCOMPL: strcat(str,"ZCOMPL"); break;
159: case ZCAN: strcat(str,"ZCAN"); break;
160: case ZFREECNT: strcat(str,"ZFREECNT"); break;
161: case ZCOMMAND: strcat(str,"ZCOMMAND"); break;
162: case ZSTDERR: strcat(str,"ZSTDERR"); break;
163: default:
164: sprintf(str,"Unknown (%08X)", frame);
165: break;
166: }
167: return(str);
168: }
169:
170:
171: /*
172: * read bytes as long as rdchk indicates that
173: * more data is available.
174: */
175:
176: void zmodem_recv_purge(zmodem_t* zm)
177: {
178: while(zm->recv_byte(zm->cbdata,0)>=0);
179: }
180:
181: /*
182: * transmit a character.
183: * this is the raw modem interface
184: */
185:
186: int zmodem_send_raw(zmodem_t* zm, unsigned char ch)
187: {
188: int result;
189:
190: if((result=zm->send_byte(zm->cbdata,ch,zm->send_timeout))!=0)
191: lprintf(zm,LOG_ERR,"send_raw SEND ERROR: %d",result);
192:
193: zm->last_sent = ch;
194:
195: return result;
196: }
197:
198: /*
199: * transmit a character ZDLE escaped
200: */
201:
202: int zmodem_send_esc(zmodem_t* zm, unsigned char c)
203: {
204: int result;
205:
206: if((result=zmodem_send_raw(zm, ZDLE))!=0)
207: return(result);
208: /*
209: * exclusive or; not an or so ZDLE becomes ZDLEE
210: */
211: return zmodem_send_raw(zm, (uchar)(c ^ 0x40));
212: }
213:
214: /*
215: * transmit a character; ZDLE escaping if appropriate
216: */
217:
218: int zmodem_tx(zmodem_t* zm, unsigned char c)
219: {
220: int result;
221:
222: switch (c) {
223: case DLE:
224: case DLE|0x80: /* even if high-bit set */
225: case XON:
226: case XON|0x80:
227: case XOFF:
228: case XOFF|0x80:
229: case ZDLE:
230: return zmodem_send_esc(zm, c);
231: case CR:
232: case CR|0x80:
233: if(zm->escape_ctrl_chars && (zm->last_sent&0x7f) == '@')
234: return zmodem_send_esc(zm, c);
235: break;
236: case TELNET_IAC:
237: if(zm->escape_telnet_iac) {
238: if((result=zmodem_send_raw(zm, ZDLE))!=0)
239: return(result);
240: return zmodem_send_raw(zm, ZRUB1);
241: }
242: break;
243: default:
244: if(zm->escape_ctrl_chars && (c&0x60)==0)
245: return zmodem_send_esc(zm, c);
246: break;
247: }
248: /*
249: * anything that ends here is so normal we might as well transmit it.
250: */
251: return zmodem_send_raw(zm, c);
252: }
253:
254: /**********************************************/
255: /* Output single byte as two hex ASCII digits */
256: /**********************************************/
257: int zmodem_send_hex(zmodem_t* zm, uchar val)
258: {
259: char* xdigit="0123456789abcdef";
260: int result;
261:
262: lprintf(zm,LOG_DEBUG,"send_hex: %02X ",val);
263:
264: if((result=zmodem_send_raw(zm, xdigit[val>>4]))!=0)
265: return result;
266: return zmodem_send_raw(zm, xdigit[val&0xf]);
267: }
268:
269: int zmodem_send_padded_zdle(zmodem_t* zm)
270: {
271: int result;
272:
273: if((result=zmodem_send_raw(zm, ZPAD))!=0)
274: return result;
275: if((result=zmodem_send_raw(zm, ZPAD))!=0)
276: return result;
277: return zmodem_send_raw(zm, ZDLE);
278: }
279:
280: /*
281: * transmit a hex header.
282: * these routines use tx_raw because we're sure that all the
283: * characters are not to be escaped.
284: */
285: int zmodem_send_hex_header(zmodem_t* zm, unsigned char * p)
286: {
287: int i;
288: int result;
289: uchar type=*p;
290: unsigned short int crc;
291:
292: lprintf(zm,LOG_DEBUG,"send_hex_header: %s", chr(type));
293:
294: if((result=zmodem_send_padded_zdle(zm))!=0)
295: return result;
296:
297: if((result=zmodem_send_raw(zm, ZHEX))!=0)
298: return result;
299:
300: /*
301: * initialise the crc
302: */
303:
304: crc = 0;
305:
306: /*
307: * transmit the header
308: */
309:
310: for(i=0;i<HDRLEN;i++) {
311: if((result=zmodem_send_hex(zm, *p))!=0)
312: return result;
313: crc = ucrc16(*p, crc);
314: p++;
315: }
316:
317: /*
318: * update the crc as though it were zero
319: */
320:
321: /*
322: * transmit the crc
323: */
324:
325: if((result=zmodem_send_hex(zm, (uchar)(crc>>8)))!=0)
326: return result;
327: if((result=zmodem_send_hex(zm, (uchar)(crc&0xff)))!=0)
328: return result;
329:
330: /*
331: * end of line sequence
332: */
333:
334: if((result=zmodem_send_raw(zm, '\r'))!=0)
335: return result;
336: if((result=zmodem_send_raw(zm, '\n'))!=0) /* FDSZ sends 0x8a instead of 0x0a */
337: return result;
338:
339: if(type!=ZACK && type!=ZFIN)
340: result=zmodem_send_raw(zm, XON);
341:
342: return(result);
343: }
344:
345: /*
346: * Send ZMODEM binary header hdr
347: */
348:
349: int zmodem_send_bin32_header(zmodem_t* zm, unsigned char * p)
350: {
351: int i;
352: int result;
353: unsigned long crc;
354:
355: lprintf(zm,LOG_DEBUG,"send_bin32_header: %s", chr(*p));
356:
357: if((result=zmodem_send_padded_zdle(zm))!=0)
358: return result;
359:
360: if((result=zmodem_send_raw(zm, ZBIN32))!=0)
361: return result;
362:
363: crc = 0xffffffffL;
364:
365: for(i=0;i<HDRLEN;i++) {
366: crc = ucrc32(*p,crc);
367: if((result=zmodem_tx(zm, *p++))!=0)
368: return result;
369: }
370:
371: crc = ~crc;
372:
373: if((result= zmodem_tx(zm, (uchar)((crc ) & 0xff)))!=0)
374: return result;
375: if((result= zmodem_tx(zm, (uchar)((crc >> 8) & 0xff)))!=0)
376: return result;
377: if((result= zmodem_tx(zm, (uchar)((crc >> 16) & 0xff)))!=0)
378: return result;
379: return zmodem_tx(zm, (uchar)((crc >> 24) & 0xff));
380: }
381:
382: int zmodem_send_bin16_header(zmodem_t* zm, unsigned char * p)
383: {
384: int i;
385: int result;
386: unsigned int crc;
387:
388: lprintf(zm,LOG_DEBUG,"send_bin16_header: %s", chr(*p));
389:
390: if((result=zmodem_send_padded_zdle(zm))!=0)
391: return result;
392:
393: if((result=zmodem_send_raw(zm, ZBIN))!=0)
394: return result;
395:
396: crc = 0;
397:
398: for(i=0;i<HDRLEN;i++) {
399: crc = ucrc16(*p,crc);
400: if((result=zmodem_tx(zm, *p++))!=0)
401: return result;
402: }
403:
404: if((result= zmodem_tx(zm, (uchar)(crc >> 8)))!=0)
405: return result;
406: return zmodem_tx(zm, (uchar)(crc&0xff));
407: }
408:
409:
410: /*
411: * transmit a header using either hex 16 bit crc or binary 32 bit crc
412: * depending on the receivers capabilities
413: * we dont bother with variable length headers. I dont really see their
414: * advantage and they would clutter the code unneccesarily
415: */
416:
417: int zmodem_send_bin_header(zmodem_t* zm, unsigned char * p)
418: {
419: if(zm->can_fcs_32 && !zm->want_fcs_16)
420: return zmodem_send_bin32_header(zm, p);
421: return zmodem_send_bin16_header(zm, p);
422: }
423:
424: /*
425: * data subpacket transmission
426: */
427:
428: int zmodem_send_data32(zmodem_t* zm, uchar subpkt_type, unsigned char * p, size_t l)
429: {
430: int result;
431: unsigned long crc;
432:
433: lprintf(zm,LOG_DEBUG,"send_data32: %s (%u bytes)", chr(subpkt_type), l);
434:
435: crc = 0xffffffffl;
436:
437: while(l > 0) {
438: crc = ucrc32(*p,crc);
439: if((result=zmodem_tx(zm, *p++))!=0)
440: return result;
441: l--;
442: }
443:
444: crc = ucrc32(subpkt_type, crc);
445:
446: if((result=zmodem_send_raw(zm, ZDLE))!=0)
447: return result;
448: if((result=zmodem_send_raw(zm, subpkt_type))!=0)
449: return result;
450:
451: crc = ~crc;
452:
453: if((result= zmodem_tx(zm, (uchar) ((crc ) & 0xff)))!=0)
454: return result;
455: if((result= zmodem_tx(zm, (uchar) ((crc >> 8 ) & 0xff)))!=0)
456: return result;
457: if((result= zmodem_tx(zm, (uchar) ((crc >> 16) & 0xff)))!=0)
458: return result;
459: return zmodem_tx(zm, (uchar) ((crc >> 24) & 0xff));
460: }
461:
462: int zmodem_send_data16(zmodem_t* zm, uchar subpkt_type,unsigned char * p, size_t l)
463: {
464: int result;
465: unsigned short crc;
466:
467: lprintf(zm,LOG_DEBUG,"send_data16: %s (%u bytes)", chr(subpkt_type), l);
468:
469: crc = 0;
470:
471: while(l > 0) {
472: crc = ucrc16(*p,crc);
473: if((result=zmodem_tx(zm, *p++))!=0)
474: return result;
475: l--;
476: }
477:
478: crc = ucrc16(subpkt_type,crc);
479:
480: if((result=zmodem_send_raw(zm, ZDLE))!=0)
481: return result;
482: if((result=zmodem_send_raw(zm, subpkt_type))!=0)
483: return result;
484:
485: if((result= zmodem_tx(zm, (uchar)(crc >> 8)))!=0)
486: return result;
487: return zmodem_tx(zm, (uchar)(crc&0xff));
488: }
489:
490: /*
491: * send a data subpacket using crc 16 or crc 32 as desired by the receiver
492: */
493:
494: int zmodem_send_data(zmodem_t* zm, uchar subpkt_type, unsigned char * p, size_t l)
495: {
496: int result;
497:
498: if(!zm->want_fcs_16 && zm->can_fcs_32) {
499: if((result=zmodem_send_data32(zm, subpkt_type,p,l))!=0)
500: return result;
501: }
502: else {
503: if((result=zmodem_send_data16(zm, subpkt_type,p,l))!=0)
504: return result;
505: }
506:
507: if(subpkt_type == ZCRCW)
508: result=zmodem_send_raw(zm, XON);
509:
510: return result;
511: }
512:
513: int zmodem_send_pos_header(zmodem_t* zm, int type, long pos, BOOL hex)
514: {
515: uchar header[5];
516:
517: header[0] = type;
518: header[ZP0] = (uchar) (pos & 0xff);
519: header[ZP1] = (uchar)((pos >> 8) & 0xff);
520: header[ZP2] = (uchar)((pos >> 16) & 0xff);
521: header[ZP3] = (uchar)((pos >> 24) & 0xff);
522:
523: if(hex)
524: return zmodem_send_hex_header(zm, header);
525: else
526: return zmodem_send_bin_header(zm, header);
527: }
528:
529: int zmodem_send_ack(zmodem_t* zm, long pos)
530: {
531: return zmodem_send_pos_header(zm, ZACK, pos, /* Hex? */ TRUE);
532: }
533:
534: int zmodem_send_nak(zmodem_t* zm)
535: {
536: return zmodem_send_pos_header(zm, ZNAK, 0, /* Hex? */ TRUE);
537: }
538:
539: int zmodem_send_zfin(zmodem_t* zm)
540: {
541: unsigned char zfin_header[] = { ZFIN, 0, 0, 0, 0 };
542:
543: return zmodem_send_hex_header(zm,zfin_header);
544: }
545:
546: int zmodem_abort_receive(zmodem_t* zm)
547: {
548: lprintf(zm,LOG_WARNING,"Aborting receive");
549: return zmodem_send_pos_header(zm, ZABORT, 0, /* Hex? */ TRUE);
550: }
551:
552: int zmodem_send_znak(zmodem_t* zm)
553: {
554: return zmodem_send_pos_header(zm, ZNAK, zm->ack_file_pos, /* Hex? */ TRUE);
555: }
556:
557: int zmodem_send_zskip(zmodem_t* zm)
558: {
559: return zmodem_send_pos_header(zm, ZSKIP, 0L, /* Hex? */ TRUE);
560: }
561:
562: int zmodem_send_zeof(zmodem_t* zm)
563: {
564: return zmodem_send_pos_header(zm, ZEOF, zm->current_file_size, /* Hex? */ TRUE);
565: }
566:
567:
568: /*
569: * rx_raw ; receive a single byte from the line.
570: * reads as many are available and then processes them one at a time
571: * check the data stream for 5 consecutive CAN characters;
572: * and if you see them abort. this saves a lot of clutter in
573: * the rest of the code; even though it is a very strange place
574: * for an exit. (but that was wat session abort was all about.)
575: */
576:
577: int zmodem_recv_raw(zmodem_t* zm)
578: {
579: int c;
580:
581: if((c=zm->recv_byte(zm->cbdata,zm->recv_timeout)) < 0)
582: return(TIMEOUT);
583:
584: if(c == CAN) {
585: zm->n_cans++;
586: if(zm->n_cans == 5) {
587: zm->cancelled=TRUE;
588: lprintf(zm,LOG_WARNING,"recv_raw: Cancelled remotely");
589: /* return(TIMEOUT); removed June-12-2005 */
590: }
591: }
592: else {
593: zm->n_cans = 0;
594: }
595:
596: return c;
597: }
598:
599: /*
600: * rx; receive a single byte undoing any escaping at the
601: * sending site. this bit looks like a mess. sorry for that
602: * but there seems to be no other way without incurring a lot
603: * of overhead. at least like this the path for a normal character
604: * is relatively short.
605: */
606:
607: int zmodem_rx(zmodem_t* zm)
608: {
609: int c;
610:
611: /*
612: * outer loop for ever so for sure something valid
613: * will come in; a timeout will occur or a session abort
614: * will be received.
615: */
616:
617: while(is_connected(zm)) {
618:
619: while(TRUE) {
620: if((c = zmodem_recv_raw(zm)) < 0)
621: return(c);
622:
623: switch (c) {
624: case ZDLE:
625: break;
626: case XON:
627: case XON|0x80:
628: case XOFF:
629: case XOFF|0x80:
630: continue;
631: default:
632: /*
633: * if all control characters should be escaped and
634: * this one wasnt then its spurious and should be dropped.
635: */
636: if(zm->escape_ctrl_chars && (c & 0x60) == 0) {
637: continue;
638: }
639: /*
640: * normal character; return it.
641: */
642: return c;
643: }
644: break;
645: }
646:
647: /*
648: * ZDLE encoded sequence or session abort.
649: * (or something illegal; then back to the top)
650: */
651:
652: while(TRUE) {
653: if((c = zmodem_recv_raw(zm)) < 0)
654: return(c);
655:
656: if(c == XON || c == (XON|0x80) || c == XOFF || c == (XOFF|0x80) || c == ZDLE) {
657: /*
658: * these can be dropped.
659: */
660: continue;
661: }
662:
663: switch (c) {
664: /*
665: * these four are really nasty.
666: * for convenience we just change them into
667: * special characters by setting a bit outside the
668: * first 8. that way they can be recognized and still
669: * be processed as characters by the rest of the code.
670: */
671: case ZCRCE:
672: case ZCRCG:
673: case ZCRCQ:
674: case ZCRCW:
675: lprintf(zm,LOG_DEBUG,"rx: encoding data subpacket type: %s"
676: ,chr(c));
677: return (c | ZDLEESC);
678: case ZRUB0:
679: return 0x7f;
680: case ZRUB1:
681: return 0xff;
682: default:
683: if(zm->escape_ctrl_chars && (c & 0x60) == 0) {
684: /*
685: * a not escaped control character; probably
686: * something from a network. just drop it.
687: */
688: continue;
689: }
690: /*
691: * legitimate escape sequence.
692: * rebuild the orignal and return it.
693: */
694: if((c & 0x60) == 0x40) {
695: return c ^ 0x40;
696: }
697: lprintf(zm,LOG_WARNING,"rx: illegal sequence: ZDLE %s"
698: ,chr(c));
699: break;
700: }
701: break;
702: }
703: }
704:
705: /*
706: * not reached.
707: */
708:
709: return 0;
710: }
711:
712: /*
713: * receive a data subpacket as dictated by the last received header.
714: * return 2 with correct packet and end of frame
715: * return 1 with correct packet frame continues
716: * return 0 with incorrect frame.
717: * return TIMEOUT with a timeout
718: * if an acknowledgement is requested it is generated automatically
719: * here.
720: */
721:
722: /*
723: * data subpacket reception
724: */
725:
726: int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigned* l)
727: {
728: int c;
729: unsigned long rxd_crc;
730: unsigned long crc;
731: int subpkt_type;
732:
733: lprintf(zm,LOG_DEBUG,"recv_data32");
734:
735: crc = 0xffffffffl;
736:
737: do {
738: c = zmodem_rx(zm);
739:
740: if(c == TIMEOUT) {
741: return TIMEOUT;
742: }
743: if(c < 0x100 && *l < maxlen) {
744: crc = ucrc32(c,crc);
745: *p++ = c;
746: (*l)++;
747: continue;
748: }
749: } while(c < 0x100);
750:
751: subpkt_type = c & 0xff;
752:
753: crc = ucrc32(subpkt_type, crc);
754:
755: crc = ~crc;
756:
757: rxd_crc = zmodem_rx(zm);
758: rxd_crc |= zmodem_rx(zm) << 8;
759: rxd_crc |= zmodem_rx(zm) << 16;
760: rxd_crc |= zmodem_rx(zm) << 24;
761:
762: if(rxd_crc != crc) {
763: lprintf(zm,LOG_WARNING,"CRC32 ERROR (%08lX, expected: %08lX) Bytes=%u, subpacket-type=%s"
764: ,rxd_crc, crc, *l, chr(subpkt_type));
765: return FALSE;
766: }
767: lprintf(zm,LOG_DEBUG,"GOOD CRC32: %08lX (Bytes=%u, subpacket-type=%s)"
768: ,crc, *l, chr(subpkt_type));
769:
770: zm->ack_file_pos += *l;
771:
772: return subpkt_type;
773: }
774:
775: int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen, unsigned* l)
776: {
777: int c;
778: int subpkt_type;
779: unsigned short crc;
780: unsigned short rxd_crc;
781:
782: lprintf(zm,LOG_DEBUG,"recv_data16");
783:
784: crc = 0;
785:
786: do {
787: c = zmodem_rx(zm);
788:
789: if(c == TIMEOUT) {
790: return TIMEOUT;
791: }
792: if(c < 0x100 && *l < maxlen) {
793: crc = ucrc16(c,crc);
794: *p++ = c;
795: (*l)++;
796: }
797: } while(c < 0x100);
798:
799: subpkt_type = c & 0xff;
800:
801: crc = ucrc16(subpkt_type,crc);
802:
803: rxd_crc = zmodem_rx(zm) << 8;
804: rxd_crc |= zmodem_rx(zm);
805:
806: if(rxd_crc != crc) {
807: lprintf(zm,LOG_WARNING,"CRC16 ERROR (%04hX, expected: %04hX) Bytes=%d"
808: ,rxd_crc, crc, *l);
809: return FALSE;
810: }
811: lprintf(zm,LOG_DEBUG,"GOOD CRC16: %04hX (Bytes=%d)", crc, *l);
812:
813: zm->ack_file_pos += *l;
814:
815: return subpkt_type;
816: }
817:
818: int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l, BOOL ack)
819: {
820: int subpkt_type;
821: unsigned n=0;
822:
823: if(l==NULL)
824: l=&n;
825:
826: lprintf(zm,LOG_DEBUG,"recv_data (%u-bit)", zm->receive_32bit_data ? 32:16);
827:
828: /*
829: * receive the right type of frame
830: */
831:
832: *l = 0;
833:
834: if(zm->receive_32bit_data) {
835: subpkt_type = zmodem_recv_data32(zm, p, maxlen, l);
836: }
837: else {
838: subpkt_type = zmodem_recv_data16(zm, p, maxlen, l);
839: }
840:
841: if(subpkt_type==FALSE)
842: return(FALSE);
843:
844: if(subpkt_type==TIMEOUT)
845: return(TIMEOUT);
846:
847: lprintf(zm,LOG_DEBUG,"recv_data received subpacket-type: %s"
848: ,chr(subpkt_type));
849:
850: switch (subpkt_type) {
851: /*
852: * frame continues non-stop
853: */
854: case ZCRCG:
855: return FRAMEOK;
856: /*
857: * frame ends
858: */
859: case ZCRCE:
860: return ENDOFFRAME;
861: /*
862: * frame continues; ZACK expected
863: */
864: case ZCRCQ:
865: if(ack)
866: zmodem_send_ack(zm, zm->ack_file_pos);
867: return FRAMEOK;
868: /*
869: * frame ends; ZACK expected
870: */
871: case ZCRCW:
872: if(ack)
873: zmodem_send_ack(zm, zm->ack_file_pos);
874: return ENDOFFRAME;
875: }
876:
877: lprintf(zm,LOG_WARNING,"Invalid subpacket-type: %s",chr(subpkt_type));
878:
879: return FALSE;
880: }
881:
882: BOOL zmodem_recv_subpacket(zmodem_t* zm, BOOL ack)
883: {
884: int type;
885:
886: type=zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket),NULL,ack);
887: if(type!=FRAMEOK && type!=ENDOFFRAME) {
888: zmodem_send_nak(zm);
889: return(FALSE);
890: }
891:
892: return(TRUE);
893: }
894:
895: int zmodem_recv_nibble(zmodem_t* zm)
896: {
897: int c;
898:
899: c = zmodem_rx(zm);
900:
901: if(c == TIMEOUT) {
902: return c;
903: }
904:
905: if(c > '9') {
906: if(c < 'a' || c > 'f') {
907: /*
908: * illegal hex; different than expected.
909: * we might as well time out.
910: */
911: return TIMEOUT;
912: }
913:
914: c -= 'a' - 10;
915: }
916: else {
917: if(c < '0') {
918: /*
919: * illegal hex; different than expected.
920: * we might as well time out.
921: */
922: return TIMEOUT;
923: }
924: c -= '0';
925: }
926:
927: return c;
928: }
929:
930: int zmodem_recv_hex(zmodem_t* zm)
931: {
932: int n1;
933: int n0;
934: int ret;
935:
936: n1 = zmodem_recv_nibble(zm);
937:
938: if(n1 == TIMEOUT) {
939: return n1;
940: }
941:
942: n0 = zmodem_recv_nibble(zm);
943:
944: if(n0 == TIMEOUT) {
945: return n0;
946: }
947:
948: ret = (n1 << 4) | n0;
949:
950: lprintf(zm,LOG_DEBUG,"recv_hex returning: 0x%02X", ret);
951:
952: return ret;
953: }
954:
955: /*
956: * receive routines for each of the six different styles of header.
957: * each of these leaves zm->rxd_header_len set to 0 if the end result is
958: * not a valid header.
959: */
960:
961: BOOL zmodem_recv_bin16_header(zmodem_t* zm)
962: {
963: int c;
964: int n;
965: unsigned short int crc;
966: unsigned short int rxd_crc;
967:
968: lprintf(zm,LOG_DEBUG,"recv_bin16_header");
969:
970: crc = 0;
971:
972: for(n=0;n<HDRLEN;n++) {
973: c = zmodem_rx(zm);
974: if(c == TIMEOUT) {
975: lprintf(zm,LOG_WARNING,"recv_bin16_header: timeout");
976: return(FALSE);
977: }
978: crc = ucrc16(c,crc);
979: zm->rxd_header[n] = c;
980: }
981:
982: rxd_crc = zmodem_rx(zm) << 8;
983: rxd_crc |= zmodem_rx(zm);
984:
985: if(rxd_crc != crc) {
986: lprintf(zm,LOG_WARNING,"CRC16 ERROR: 0x%hX, expected: 0x%hX", rxd_crc, crc);
987: return(FALSE);
988: }
989: lprintf(zm,LOG_DEBUG,"GOOD CRC16: %04hX", crc);
990:
991: zm->rxd_header_len = 5;
992:
993: return(TRUE);
994: }
995:
996: void zmodem_recv_hex_header(zmodem_t* zm)
997: {
998: int c;
999: int i;
1000: unsigned short int crc = 0;
1001: unsigned short int rxd_crc;
1002:
1003: lprintf(zm,LOG_DEBUG,"recv_hex_header");
1004:
1005: for(i=0;i<HDRLEN;i++) {
1006: c = zmodem_recv_hex(zm);
1007: if(c == TIMEOUT) {
1008: return;
1009: }
1010: crc = ucrc16(c,crc);
1011:
1012: zm->rxd_header[i] = c;
1013: }
1014:
1015: /*
1016: * receive the crc
1017: */
1018:
1019: c = zmodem_recv_hex(zm);
1020:
1021: if(c == TIMEOUT) {
1022: return;
1023: }
1024:
1025: rxd_crc = c << 8;
1026:
1027: c = zmodem_recv_hex(zm);
1028:
1029: if(c == TIMEOUT) {
1030: return;
1031: }
1032:
1033: rxd_crc |= c;
1034:
1035: if(rxd_crc == crc) {
1036: lprintf(zm,LOG_DEBUG,"GOOD CRC16: %04hX", crc);
1037: zm->rxd_header_len = 5;
1038: }
1039: else {
1040: lprintf(zm,LOG_WARNING,"CRC16 ERROR: 0x%hX, expected: 0x%hX", rxd_crc, crc);
1041: }
1042:
1043: /*
1044: * drop the end of line sequence after a hex header
1045: */
1046: c = zmodem_rx(zm);
1047: if(c == '\r') {
1048: /*
1049: * both are expected with CR
1050: */
1051: zmodem_rx(zm); /* drop LF */
1052: }
1053: }
1054:
1055: BOOL zmodem_recv_bin32_header(zmodem_t* zm)
1056: {
1057: int c;
1058: int n;
1059: unsigned long crc;
1060: unsigned long rxd_crc;
1061:
1062: lprintf(zm,LOG_DEBUG,"recv_bin32_header");
1063:
1064: crc = 0xffffffffL;
1065:
1066: for(n=0;n<HDRLEN;n++) {
1067: c = zmodem_rx(zm);
1068: if(c == TIMEOUT) {
1069: return(TRUE);
1070: }
1071: crc = ucrc32(c,crc);
1072: zm->rxd_header[n] = c;
1073: }
1074:
1075: crc = ~crc;
1076:
1077: rxd_crc = zmodem_rx(zm);
1078: rxd_crc |= zmodem_rx(zm) << 8;
1079: rxd_crc |= zmodem_rx(zm) << 16;
1080: rxd_crc |= zmodem_rx(zm) << 24;
1081:
1082: if(rxd_crc != crc) {
1083: lprintf(zm,LOG_WARNING,"CRC32 ERROR (%08lX, expected: %08lX)"
1084: ,rxd_crc, crc);
1085: return(FALSE);
1086: }
1087: lprintf(zm,LOG_DEBUG,"GOOD CRC32: %08lX", crc);
1088:
1089: zm->rxd_header_len = 5;
1090: return(TRUE);
1091: }
1092:
1093: /*
1094: * receive any style header
1095: * if the errors flag is set than whenever an invalid header packet is
1096: * received INVHDR will be returned. otherwise we wait for a good header
1097: * also; a flag (receive_32bit_data) will be set to indicate whether data
1098: * packets following this header will have 16 or 32 bit data attached.
1099: * variable headers are not implemented.
1100: */
1101:
1102: int zmodem_recv_header_raw(zmodem_t* zm, int errors)
1103: {
1104: int c;
1105: int frame_type;
1106:
1107: lprintf(zm,LOG_DEBUG,"recv_header_raw");
1108:
1109: zm->rxd_header_len = 0;
1110:
1111: do {
1112: do {
1113: if((c = zmodem_recv_raw(zm)) < 0)
1114: return(c);
1115: if(is_cancelled(zm))
1116: return(ZCAN);
1117: } while(c != ZPAD);
1118:
1119: if((c = zmodem_recv_raw(zm)) < 0)
1120: return(c);
1121:
1122: if(c == ZPAD) {
1123: if((c = zmodem_recv_raw(zm)) < 0)
1124: return(c);
1125: }
1126:
1127: /*
1128: * spurious ZPAD check
1129: */
1130:
1131: if(c != ZDLE) {
1132: lprintf(zm,LOG_WARNING,"recv_header_raw: Expected ZDLE, received: %s"
1133: ,chr(c));
1134: continue;
1135: }
1136:
1137: /*
1138: * now read the header style
1139: */
1140:
1141: c = zmodem_rx(zm);
1142:
1143: if(c == TIMEOUT) {
1144: lprintf(zm,LOG_WARNING,"recv_header_raw: TIMEOUT");
1145: return c;
1146: }
1147:
1148: switch (c) {
1149: case ZBIN:
1150: zmodem_recv_bin16_header(zm);
1151: zm->receive_32bit_data = FALSE;
1152: break;
1153: case ZHEX:
1154: zmodem_recv_hex_header(zm);
1155: zm->receive_32bit_data = FALSE;
1156: break;
1157: case ZBIN32:
1158: zmodem_recv_bin32_header(zm);
1159: zm->receive_32bit_data = TRUE;
1160: break;
1161: default:
1162: /*
1163: * unrecognized header style
1164: */
1165: lprintf(zm,LOG_ERR,"recv_header_raw: UNRECOGNIZED header style: %s"
1166: ,chr(c));
1167: if(errors) {
1168: return INVHDR;
1169: }
1170:
1171: continue;
1172: }
1173: if(errors && zm->rxd_header_len == 0) {
1174: return INVHDR;
1175: }
1176:
1177: } while(zm->rxd_header_len == 0 && !is_cancelled(zm));
1178:
1179: if(is_cancelled(zm))
1180: return(ZCAN);
1181:
1182: /*
1183: * this appears to have been a valid header.
1184: * return its type.
1185: */
1186:
1187: frame_type = zm->rxd_header[0];
1188:
1189: zm->rxd_header_pos = zm->rxd_header[ZP0] | (zm->rxd_header[ZP1] << 8) |
1190: (zm->rxd_header[ZP2] << 16) | (zm->rxd_header[ZP3] << 24);
1191:
1192: switch(frame_type) {
1193: case ZCRC:
1194: zm->crc_request = zm->rxd_header_pos;
1195: break;
1196: case ZDATA:
1197: zm->ack_file_pos = zm->rxd_header_pos;
1198: break;
1199: case ZFILE:
1200: zm->ack_file_pos = 0l;
1201: if(!zmodem_recv_subpacket(zm,/* ack? */FALSE))
1202: frame_type |= BADSUBPKT;
1203: break;
1204: case ZSINIT:
1205: case ZCOMMAND:
1206: if(!zmodem_recv_subpacket(zm,/* ack? */TRUE))
1207: frame_type |= BADSUBPKT;
1208: break;
1209: case ZFREECNT:
1210: zmodem_send_pos_header(zm, ZACK, getfreediskspace(".",1), /* Hex? */ TRUE);
1211: break;
1212: }
1213:
1214: #if 0 /*def _DEBUG */
1215: lprintf(zm,LOG_DEBUG,"recv_header_raw received header type: %s"
1216: ,frame_desc(frame_type));
1217: #endif
1218:
1219: return frame_type;
1220: }
1221:
1222: int zmodem_recv_header(zmodem_t* zm)
1223: {
1224: int ret;
1225:
1226: ret = zmodem_recv_header_raw(zm, FALSE);
1227:
1228: if(ret == TIMEOUT)
1229: lprintf(zm,LOG_WARNING,"recv_header TIMEOUT");
1230: else if(ret == INVHDR)
1231: lprintf(zm,LOG_WARNING,"recv_header detected an invalid header");
1232: else
1233: lprintf(zm,LOG_DEBUG,"recv_header returning: %s (pos=%ld)"
1234: ,frame_desc(ret), zm->rxd_header_pos);
1235:
1236: if(ret==ZCAN)
1237: zm->cancelled=TRUE;
1238:
1239: return ret;
1240: }
1241:
1242: int zmodem_recv_header_and_check(zmodem_t* zm)
1243: {
1244: int type;
1245:
1246: while(is_connected(zm)) {
1247: type = zmodem_recv_header_raw(zm,TRUE);
1248:
1249: if(type != INVHDR && (type&BADSUBPKT) == 0) {
1250: break;
1251: }
1252:
1253: zmodem_send_znak(zm);
1254: }
1255:
1256: return type;
1257: }
1258:
1259: BOOL zmodem_get_crc(zmodem_t* zm, long length, ulong* crc)
1260: {
1261: zmodem_send_pos_header(zm,ZCRC,length,TRUE);
1262: if(!zmodem_data_waiting(zm,zm->crc_timeout*1000))
1263: return(FALSE);
1264: if(zmodem_recv_header(zm)!=ZCRC)
1265: return(FALSE);
1266: if(crc!=NULL)
1267: *crc = zm->crc_request;
1268: return(TRUE);
1269: }
1270:
1271: void zmodem_parse_zrinit(zmodem_t* zm)
1272: {
1273: zm->can_full_duplex = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANFDX);
1274: zm->can_overlap_io = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANOVIO);
1275: zm->can_break = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANBRK);
1276: zm->can_fcs_32 = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_CANFC32);
1277: zm->escape_ctrl_chars = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_ESCCTL);
1278: zm->escape_8th_bit = INT_TO_BOOL(zm->rxd_header[ZF0] & ZF0_ESC8);
1279:
1280: lprintf(zm,LOG_INFO,"Receiver requested mode (0x%02X):\r\n"
1281: "%s-duplex, %s overlap I/O, CRC-%u, Escape: %s"
1282: ,zm->rxd_header[ZF0]
1283: ,zm->can_full_duplex ? "Full" : "Half"
1284: ,zm->can_overlap_io ? "Can" : "Cannot"
1285: ,zm->can_fcs_32 ? 32 : 16
1286: ,zm->escape_ctrl_chars ? "ALL" : "Normal"
1287: );
1288:
1289: if((zm->recv_bufsize = (zm->rxd_header[ZP0] | zm->rxd_header[ZP1]<<8)) != 0)
1290: lprintf(zm,LOG_INFO,"Receiver specified buffer size of: %u", zm->recv_bufsize);
1291: }
1292:
1293: int zmodem_get_zrinit(zmodem_t* zm)
1294: {
1295: unsigned char zrqinit_header[] = { ZRQINIT, /* ZF3: */0, 0, 0, /* ZF0: */0 };
1296: /* Note: sz/dsz/fdsz sends 0x80 in ZF3 because it supports var-length headers. */
1297: /* We do not, so we send 0x00, resulting in a CRC-16 value of 0x0000 as well. */
1298:
1299: zmodem_send_raw(zm,'r');
1300: zmodem_send_raw(zm,'z');
1301: zmodem_send_raw(zm,'\r');
1302: zmodem_send_hex_header(zm,zrqinit_header);
1303:
1304: if(!zmodem_data_waiting(zm,zm->init_timeout*1000))
1305: return(TIMEOUT);
1306: return zmodem_recv_header(zm);
1307: }
1308:
1309: int zmodem_send_zrinit(zmodem_t* zm)
1310: {
1311: unsigned char zrinit_header[] = { ZRINIT, 0, 0, 0, 0 };
1312:
1313: zrinit_header[ZF0] = ZF0_CANFDX;
1314:
1315: if(!zm->no_streaming)
1316: zrinit_header[ZF0] |= ZF0_CANOVIO;
1317:
1318: if(zm->can_break)
1319: zrinit_header[ZF0] |= ZF0_CANBRK;
1320:
1321: if(!zm->want_fcs_16)
1322: zrinit_header[ZF0] |= ZF0_CANFC32;
1323:
1324: if(zm->escape_ctrl_chars)
1325: zrinit_header[ZF0] |= ZF0_ESCCTL;
1326:
1327: if(zm->escape_8th_bit)
1328: zrinit_header[ZF0] |= ZF0_ESC8;
1329:
1330: if(zm->no_streaming && zm->recv_bufsize==0)
1331: zm->recv_bufsize = sizeof(zm->rx_data_subpacket);
1332:
1333: zrinit_header[ZP0] = zm->recv_bufsize & 0xff;
1334: zrinit_header[ZP1] = zm->recv_bufsize >> 8;
1335:
1336: return zmodem_send_hex_header(zm, zrinit_header);
1337: }
1338:
1339: int zmodem_get_zfin(zmodem_t* zm)
1340: {
1341: int type;
1342:
1343: zmodem_send_zfin(zm);
1344: do {
1345: type = zmodem_recv_header(zm);
1346: } while(type != ZFIN && type != TIMEOUT && is_connected(zm));
1347:
1348: /*
1349: * these Os are formally required; but they don't do a thing
1350: * unfortunately many programs require them to exit
1351: * (both programs already sent a ZFIN so why bother ?)
1352: */
1353:
1354: if(type != TIMEOUT) {
1355: zmodem_send_raw(zm,'O');
1356: zmodem_send_raw(zm,'O');
1357: }
1358:
1359: return 0;
1360: }
1361:
1362:
1363: /*
1364: * send from the current position in the file
1365: * all the way to end of file or until something goes wrong.
1366: * (ZNAK or ZRPOS received)
1367: * the name is only used to show progress
1368: */
1369:
1370: int zmodem_send_from(zmodem_t* zm, FILE* fp, ulong pos, ulong* sent)
1371: {
1372: size_t n;
1373: uchar type;
1374: unsigned buf_sent=0;
1375:
1376: if(sent!=NULL)
1377: *sent=0;
1378:
1379: fseek(fp,pos,SEEK_SET);
1380:
1381: zmodem_send_pos_header(zm, ZDATA, pos, /* Hex? */ FALSE);
1382:
1383: /*
1384: * send the data in the file
1385: */
1386:
1387: while(is_connected(zm)) {
1388:
1389: /*
1390: * read a block from the file
1391: */
1392:
1393: n = fread(zm->tx_data_subpacket,sizeof(BYTE),zm->block_size,fp);
1394:
1395: if(zm->progress!=NULL)
1396: zm->progress(zm->cbdata, ftell(fp));
1397:
1398: type = ZCRCG;
1399:
1400: /** ZMODEM.DOC:
1401: ZCRCW data subpackets expect a response before the next frame is sent.
1402: If the receiver does not indicate overlapped I/O capability with the
1403: CANOVIO bit, or sets a buffer size, the sender uses the ZCRCW to allow
1404: the receiver to write its buffer before sending more data.
1405: ***/
1406: if(!zm->can_overlap_io || zm->no_streaming
1407: || (zm->recv_bufsize && buf_sent+n>=zm->recv_bufsize)) {
1408: type=ZCRCW;
1409: buf_sent=0;
1410: }
1411:
1412: if((ulong)ftell(fp) >= zm->current_file_size || n==0) /* can't use feof() here! */
1413: type = ZCRCE;
1414:
1415: if(zmodem_send_data(zm, type, zm->tx_data_subpacket, n)!=0)
1416: return(TIMEOUT);
1417:
1418: if(type == ZCRCW || type == ZCRCE) {
1419: int ack;
1420: lprintf(zm,LOG_DEBUG,"Sent end-of-frame (%s sub-packet)", chr(type));
1421:
1422: if(type==ZCRCW) { /* ZACK expected */
1423:
1424: lprintf(zm,LOG_DEBUG,"Waiting for ZACK");
1425: while(is_connected(zm)) {
1426: if((ack = zmodem_recv_header(zm)) != ZACK)
1427: return(ack);
1428:
1429: if(is_cancelled(zm))
1430: return(ZCAN);
1431:
1432: if(zm->rxd_header_pos == (ulong)ftell(fp))
1433: break;
1434: lprintf(zm,LOG_WARNING,"ZACK for incorrect offset (%lu vs %lu)"
1435: ,zm->rxd_header_pos, ftell(fp));
1436: }
1437:
1438: }
1439: }
1440:
1441: if(sent!=NULL)
1442: *sent+=n;
1443:
1444: buf_sent+=n;
1445:
1446: if((ulong)ftell(fp) >= zm->current_file_size) {
1447: lprintf(zm,LOG_DEBUG,"send_from: end of file (%ld)", zm->current_file_size );
1448: return ZACK;
1449: }
1450: if(n==0) {
1451: lprintf(zm,LOG_ERR,"send_from: read error %d at offset %lu"
1452: ,ferror(fp), ftell(fp) );
1453: return ZACK;
1454: }
1455:
1456: /*
1457: * characters from the other side
1458: * check out that header
1459: */
1460:
1461: while(zmodem_data_waiting(zm, zm->consecutive_errors ? 1000:0)
1462: && !is_cancelled(zm) && is_connected(zm)) {
1463: int type;
1464: int c;
1465: lprintf(zm,LOG_DEBUG,"Back-channel traffic detected:");
1466: if((c = zmodem_recv_raw(zm)) < 0)
1467: return(c);
1468: if(c == ZPAD) {
1469: type = zmodem_recv_header(zm);
1470: if(type != TIMEOUT && type != ZACK) {
1471: return type;
1472: }
1473: } else
1474: lprintf(zm,LOG_DEBUG,"Received: %s",chr(c));
1475: }
1476: if(is_cancelled(zm))
1477: return(ZCAN);
1478:
1479: zm->consecutive_errors = 0;
1480:
1481: if(zm->block_size < zm->max_block_size) {
1482: zm->block_size*=2;
1483: if(zm->block_size > zm->max_block_size)
1484: zm->block_size = zm->max_block_size;
1485: }
1486:
1487: if(type == ZCRCW || type == ZCRCE) /* end-of-frame */
1488: zmodem_send_pos_header(zm, ZDATA, ftell(fp), /* Hex? */ FALSE);
1489: }
1490:
1491: lprintf(zm,LOG_DEBUG,"send_from: returning unexpectedly!");
1492:
1493: /*
1494: * end of file reached.
1495: * should receive something... so fake ZACK
1496: */
1497:
1498: return ZACK;
1499: }
1500:
1501: /*
1502: * send a file; returns true when session is aborted.
1503: * (using ZABORT frame)
1504: */
1505:
1506: BOOL zmodem_send_file(zmodem_t* zm, char* fname, FILE* fp, BOOL request_init, time_t* start, ulong* sent)
1507: {
1508: BOOL success=FALSE;
1509: ulong pos=0;
1510: ulong sent_bytes;
1511: struct stat s;
1512: unsigned char * p;
1513: uchar zfile_frame[] = { ZFILE, 0, 0, 0, 0 };
1514: int type;
1515: int i;
1516: unsigned attempts;
1517:
1518: if(zm->block_size == 0)
1519: zm->block_size = ZBLOCKLEN;
1520:
1521: if(zm->block_size < 128)
1522: zm->block_size = 128;
1523:
1524: if(zm->block_size > sizeof(zm->tx_data_subpacket))
1525: zm->block_size = sizeof(zm->tx_data_subpacket);
1526:
1527: if(zm->max_block_size < zm->block_size)
1528: zm->max_block_size = zm->block_size;
1529:
1530: if(zm->max_block_size > sizeof(zm->rx_data_subpacket))
1531: zm->max_block_size = sizeof(zm->rx_data_subpacket);
1532:
1533: if(sent!=NULL)
1534: *sent=0;
1535:
1536: if(start!=NULL)
1537: *start=time(NULL);
1538:
1539: zm->file_skipped=FALSE;
1540:
1541: if(zm->no_streaming)
1542: lprintf(zm,LOG_WARNING,"Streaming disabled");
1543:
1544: if(request_init) {
1545: for(zm->errors=0; zm->errors<=zm->max_errors && !is_cancelled(zm) && is_connected(zm); zm->errors++) {
1546: lprintf(zm,LOG_INFO,"Sending ZRQINIT (%u of %u)"
1547: ,zm->errors+1,zm->max_errors+1);
1548: i = zmodem_get_zrinit(zm);
1549: if(i == ZRINIT) {
1550: zmodem_parse_zrinit(zm);
1551: break;
1552: }
1553: lprintf(zm,LOG_WARNING,"send_file: received header type %s"
1554: ,frame_desc(i));
1555: }
1556: if(zm->errors>=zm->max_errors || is_cancelled(zm))
1557: return(FALSE);
1558: }
1559:
1560: fstat(fileno(fp),&s);
1561: zm->current_file_size = s.st_size;
1562: SAFECOPY(zm->current_file_name, getfname(fname));
1563:
1564: /*
1565: * the file exists. now build the ZFILE frame
1566: */
1567:
1568: /*
1569: * set conversion option
1570: * (not used; always binary)
1571: */
1572:
1573: zfile_frame[ZF0] = ZF0_ZCBIN;
1574:
1575: /*
1576: * management option
1577: */
1578:
1579: if(zm->management_protect) {
1580: zfile_frame[ZF1] = ZF1_ZMPROT;
1581: lprintf(zm,LOG_DEBUG,"send_file: protecting destination");
1582: }
1583: else if(zm->management_clobber) {
1584: zfile_frame[ZF1] = ZF1_ZMCLOB;
1585: lprintf(zm,LOG_DEBUG,"send_file: overwriting destination");
1586: }
1587: else if(zm->management_newer) {
1588: zfile_frame[ZF1] = ZF1_ZMNEW;
1589: lprintf(zm,LOG_DEBUG,"send_file: overwriting destination if newer");
1590: }
1591: else
1592: zfile_frame[ZF1] = ZF1_ZMCRC;
1593:
1594: /*
1595: * transport options
1596: * (just plain normal transfer)
1597: */
1598:
1599: zfile_frame[ZF2] = ZF2_ZTNOR;
1600:
1601: /*
1602: * extended options
1603: */
1604:
1605: zfile_frame[ZF3] = 0;
1606:
1607: /*
1608: * now build the data subpacket with the file name and lots of other
1609: * useful information.
1610: */
1611:
1612: /*
1613: * first enter the name and a 0
1614: */
1615:
1616: p = zm->tx_data_subpacket;
1617:
1618: strcpy(p,getfname(fname));
1619:
1620: p += strlen(p) + 1;
1621:
1622: sprintf(p,"%lu %lo %lo %d %u %lu %d"
1623: ,zm->current_file_size
1624: ,s.st_mtime
1625: ,0 /* file mode */
1626: ,0 /* serial number */
1627: ,zm->files_remaining
1628: ,zm->bytes_remaining
1629: ,0 /* file type */
1630: );
1631:
1632: p += strlen(p) + 1;
1633:
1634: do {
1635: /*
1636: * send the header and the data
1637: */
1638:
1639: lprintf(zm,LOG_DEBUG,"Sending ZFILE header block: '%s'"
1640: ,zm->tx_data_subpacket+strlen(zm->tx_data_subpacket)+1);
1641:
1642: zmodem_send_bin_header(zm,zfile_frame);
1643: zmodem_send_data(zm,ZCRCW,zm->tx_data_subpacket,p - zm->tx_data_subpacket);
1644:
1645: /*
1646: * wait for anything but an ZACK packet
1647: */
1648:
1649: do {
1650: type = zmodem_recv_header(zm);
1651: if(is_cancelled(zm))
1652: return(FALSE);
1653: } while(type == ZACK && is_connected(zm));
1654:
1655: if(!is_connected(zm))
1656: return(FALSE);
1657:
1658: #if 0
1659: lprintf(zm,LOG_INFO,"type : %d",type);
1660: #endif
1661:
1662: if(type == ZSKIP) {
1663: zm->file_skipped=TRUE;
1664: lprintf(zm,LOG_WARNING,"File skipped by receiver");
1665: return(FALSE);
1666: }
1667:
1668: if(type == ZCRC) {
1669: if(zm->crc_request==0)
1670: lprintf(zm,LOG_NOTICE,"Receiver requested CRC of entire file");
1671: else
1672: lprintf(zm,LOG_NOTICE,"Receiver requested CRC of first %lu bytes"
1673: ,zm->crc_request);
1674: zmodem_send_pos_header(zm,ZCRC,fcrc32(fp,zm->crc_request),TRUE);
1675: type = zmodem_recv_header(zm);
1676: }
1677:
1678: } while(type != ZRPOS);
1679:
1680: zm->transfer_start_time = time(NULL);
1681: zm->transfer_start_pos = 0;
1682: if(zm->rxd_header_pos && zm->rxd_header_pos <= zm->current_file_size) {
1683: pos = zm->transfer_start_pos = zm->rxd_header_pos;
1684: lprintf(zm,LOG_INFO,"Starting transfer at offset: %lu (resume)", pos);
1685: }
1686:
1687: if(start!=NULL)
1688: *start=zm->transfer_start_time;
1689:
1690: rewind(fp);
1691: zm->errors = 0;
1692: zm->consecutive_errors = 0;
1693: do {
1694: /*
1695: * and start sending
1696: */
1697:
1698: type = zmodem_send_from(zm, fp, pos, &sent_bytes);
1699:
1700: if(!is_connected(zm))
1701: return(FALSE);
1702:
1703: if(type == ZFERR || type == ZABORT || is_cancelled(zm))
1704: return(FALSE);
1705:
1706: if(sent != NULL)
1707: *sent += sent_bytes;
1708:
1709: pos += sent_bytes;
1710:
1711: if(type == ZACK) /* success */
1712: break;
1713:
1714: lprintf(zm,LOG_ERR,"%s at offset: %lu", chr(type), pos);
1715:
1716: if(zm->block_size == zm->max_block_size && zm->max_block_size > ZBLOCKLEN)
1717: zm->max_block_size /= 2;
1718:
1719: if(zm->block_size > 128)
1720: zm->block_size /= 2;
1721:
1722: zm->errors++;
1723: if(++zm->consecutive_errors > zm->max_errors)
1724: return(FALSE);
1725:
1726: /*
1727: * fetch pos from the ZRPOS header
1728: */
1729:
1730: if(type == ZRPOS) {
1731: if(zm->rxd_header_pos <= zm->current_file_size) {
1732: if(pos != zm->rxd_header_pos) {
1733: pos = zm->rxd_header_pos;
1734: lprintf(zm,LOG_INFO,"Resuming transfer from offset: %lu", pos);
1735: }
1736: } else
1737: lprintf(zm,LOG_WARNING,"Invalid ZRPOS offset: %lu", zm->rxd_header_pos);
1738: }
1739:
1740: } while(type == ZRPOS || type == ZNAK || type==TIMEOUT);
1741:
1742:
1743: lprintf(zm,LOG_INFO,"Finishing transfer on receipt of header: %s", chr(type));
1744: if(sent!=NULL)
1745: lprintf(zm,LOG_DEBUG,"Sent %lu total bytes", *sent);
1746:
1747: if(type==ZACK) {
1748: /*
1749: * file sent. send end of file frame
1750: * and wait for zrinit. if it doesnt come then try again
1751: */
1752:
1753: for(attempts=0;attempts<=zm->max_errors && !is_cancelled(zm) && is_connected(zm);attempts++) {
1754: lprintf(zm,LOG_INFO,"Sending End-of-File (ZEOF) frame (%u of %u)"
1755: ,attempts+1, zm->max_errors+1);
1756: zmodem_send_zeof(zm);
1757: if(zmodem_recv_header(zm)==ZRINIT) {
1758: success=TRUE;
1759: break;
1760: }
1761: }
1762: }
1763: return(success);
1764: }
1765:
1766: int zmodem_recv_files(zmodem_t* zm, const char* download_dir, ulong* bytes_received)
1767: {
1768: char fpath[MAX_PATH+1];
1769: FILE* fp;
1770: long l;
1771: BOOL skip;
1772: ulong b;
1773: ulong crc;
1774: ulong rcrc;
1775: ulong bytes;
1776: ulong kbytes;
1777: ulong start_bytes;
1778: unsigned files_received=0;
1779: time_t t;
1780: unsigned cps;
1781: unsigned timeout;
1782: unsigned errors;
1783:
1784: if(bytes_received!=NULL)
1785: *bytes_received=0;
1786: zm->current_file_num=1;
1787: while(zmodem_recv_init(zm)==ZFILE) {
1788: bytes=zm->current_file_size;
1789: kbytes=bytes/1024;
1790: if(kbytes<1) kbytes=0;
1791: lprintf(zm,LOG_INFO,"Downloading %s (%lu KBytes) via Zmodem", zm->current_file_name, kbytes);
1792:
1793: do { /* try */
1794: skip=TRUE;
1795:
1796: sprintf(fpath,"%s/%s",download_dir,zm->current_file_name);
1797: lprintf(zm,LOG_DEBUG,"fpath=%s",fpath);
1798: if(fexist(fpath)) {
1799: l=flength(fpath);
1800: lprintf(zm,LOG_WARNING,"%s already exists (%lu bytes)",fpath,l);
1801: if(l>=(long)bytes) {
1802: lprintf(zm,LOG_WARNING,"Local file size >= remote file size (%ld)"
1803: ,bytes);
1804: break;
1805: }
1806: if((fp=fopen(fpath,"rb"))==NULL) {
1807: lprintf(zm,LOG_ERR,"Error %d opening %s", errno, fpath);
1808: break;
1809: }
1810: setvbuf(fp,NULL,_IOFBF,0x10000);
1811:
1812: lprintf(zm,LOG_INFO,"Calculating CRC of: %s", fpath);
1813: crc=fcrc32(fp,l);
1814: fclose(fp);
1815: lprintf(zm,LOG_INFO,"CRC of %s (%lu bytes): %08lX"
1816: ,getfname(fpath), l, crc);
1817: lprintf(zm,LOG_INFO,"Requesting CRC of remote file: %s", zm->current_file_name);
1818: if(!zmodem_get_crc(zm,l,&rcrc)) {
1819: lprintf(zm,LOG_ERR,"Failed to get CRC of remote file");
1820: break;
1821: }
1822: if(crc!=rcrc) {
1823: lprintf(zm,LOG_WARNING,"Remote file has different CRC value: %08lX", rcrc);
1824: break;
1825: }
1826: lprintf(zm,LOG_INFO,"Resuming download of %s",fpath);
1827: }
1828:
1829: if((fp=fopen(fpath,"ab"))==NULL) {
1830: lprintf(zm,LOG_ERR,"Error %d opening/creating/appending %s",errno,fpath);
1831: break;
1832: }
1833: start_bytes=filelength(fileno(fp));
1834:
1835: skip=FALSE;
1836: errors=zmodem_recv_file_data(zm,fp,flength(fpath));
1837:
1838: for(;errors<=zm->max_errors && !is_cancelled(zm); errors++) {
1839: if(zmodem_recv_header_and_check(zm))
1840: break;
1841: }
1842: fclose(fp);
1843: l=flength(fpath);
1844: if(errors && l==0) { /* aborted/failed download */
1845: if(remove(fpath)) /* don't save 0-byte file */
1846: lprintf(zm,LOG_ERR,"Error %d removing %s",errno,fpath);
1847: else
1848: lprintf(zm,LOG_INFO,"Deleted 0-byte file %s",fpath);
1849: }
1850: else {
1851: if(l!=(long)bytes) {
1852: lprintf(zm,LOG_WARNING,"Incomplete download (%ld bytes received, expected %lu)"
1853: ,l,bytes);
1854: } else {
1855: if((t=time(NULL)-zm->transfer_start_time)<=0)
1856: t=1;
1857: b=l-start_bytes;
1858: if((cps=b/t)==0)
1859: cps=1;
1860: lprintf(zm,LOG_INFO,"Received %lu bytes successfully (%u CPS)",b,cps);
1861: files_received++;
1862: if(bytes_received!=NULL)
1863: *bytes_received+=b;
1864: }
1865: if(zm->current_file_time)
1866: setfdate(fpath,zm->current_file_time);
1867: }
1868:
1869: } while(0);
1870: /* finally */
1871:
1872: if(skip) {
1873: lprintf(zm,LOG_WARNING,"Skipping file");
1874: zmodem_send_zskip(zm);
1875: }
1876: zm->current_file_num++;
1877: }
1878: if(zm->local_abort)
1879: zmodem_abort_receive(zm);
1880:
1881: /* wait for "over-and-out" */
1882: timeout=zm->recv_timeout;
1883: zm->recv_timeout=2;
1884: if(zmodem_rx(zm)=='O')
1885: zmodem_rx(zm);
1886: zm->recv_timeout=timeout;
1887:
1888: return(files_received);
1889: }
1890:
1891: int zmodem_recv_init(zmodem_t* zm)
1892: {
1893: int type=CAN;
1894: unsigned errors;
1895:
1896: lprintf(zm,LOG_DEBUG,"recv_init");
1897:
1898: #if 0
1899: while(is_connected(zm) && !is_cancelled(zm) && (ch=zm->recv_byte(zm,0))!=NOINP)
1900: lprintf(zm,LOG_DEBUG,"Throwing out received: %s",chr((uchar)ch));
1901: #endif
1902:
1903: for(errors=0; errors<=zm->max_errors && !is_cancelled(zm) && is_connected(zm); errors++) {
1904: lprintf(zm,LOG_DEBUG,"Sending ZRINIT (%u of %u)"
1905: ,errors+1, zm->max_errors+1);
1906: zmodem_send_zrinit(zm);
1907:
1908: type = zmodem_recv_header(zm);
1909:
1910: if(type==TIMEOUT)
1911: continue;
1912:
1913: lprintf(zm,LOG_DEBUG,"Received header: %s",chr(type));
1914:
1915: if(type==ZFILE) {
1916: zmodem_parse_zfile_subpacket(zm);
1917: return(type);
1918: }
1919:
1920: if(type==ZFIN) {
1921: zmodem_send_zfin(zm); /* ACK */
1922: return(type);
1923: }
1924:
1925: lprintf(zm,LOG_WARNING,"Received frame: %s, expected ZFILE or ZFIN"
1926: ,frame_desc(type));
1927: lprintf(zm,LOG_DEBUG,"ZF0=%02X ZF1=%02X ZF2=%02X ZF3=%02X"
1928: ,zm->rxd_header[ZF0],zm->rxd_header[ZF1],zm->rxd_header[ZF2],zm->rxd_header[ZF3]);
1929: }
1930:
1931: return(type);
1932: }
1933:
1934: void zmodem_parse_zfile_subpacket(zmodem_t* zm)
1935: {
1936: int i;
1937: long mode=0;
1938: long serial=-1;
1939:
1940: SAFECOPY(zm->current_file_name,getfname(zm->rx_data_subpacket));
1941:
1942: zm->current_file_size = 0;
1943: zm->current_file_time = 0;
1944: zm->files_remaining = 0;
1945: zm->bytes_remaining = 0;
1946:
1947: i=sscanf(zm->rx_data_subpacket+strlen(zm->rx_data_subpacket)+1,"%lu %lo %lo %lo %lu %lu"
1948: ,&zm->current_file_size /* file size (decimal) */
1949: ,&zm->current_file_time /* file time (octal unix format) */
1950: ,&mode /* file mode */
1951: ,&serial /* program serial number */
1952: ,&zm->files_remaining /* remaining files to be sent */
1953: ,&zm->bytes_remaining /* remaining bytes to be sent */
1954: );
1955:
1956: lprintf(zm,LOG_DEBUG,"Zmodem header (%u fields): %s"
1957: ,i, zm->rx_data_subpacket+strlen(zm->rx_data_subpacket)+1);
1958:
1959: if(!zm->files_remaining)
1960: zm->files_remaining = 1;
1961: if(!zm->bytes_remaining)
1962: zm->bytes_remaining = zm->current_file_size;
1963:
1964: if(!zm->total_files)
1965: zm->total_files = zm->files_remaining;
1966: if(!zm->total_bytes)
1967: zm->total_bytes = zm->bytes_remaining;
1968: }
1969:
1970: /*
1971: * receive file data until the end of the file or until something goes wrong.
1972: * the name is only used to show progress
1973: */
1974:
1975: unsigned zmodem_recv_file_data(zmodem_t* zm, FILE* fp, ulong offset)
1976: {
1977: int i=0;
1978: unsigned errors=0;
1979:
1980: zm->transfer_start_pos=offset;
1981: zm->transfer_start_time=time(NULL);
1982:
1983: fseek(fp,offset,SEEK_SET);
1984:
1985: while(errors<=zm->max_errors && is_connected(zm)
1986: && (ulong)ftell(fp) < zm->current_file_size && !is_cancelled(zm)) {
1987:
1988: if(i!=ENDOFFRAME)
1989: zmodem_send_pos_header(zm, ZRPOS, ftell(fp), /* Hex? */ TRUE);
1990:
1991: if((i = zmodem_recv_file_frame(zm,fp)) == ZEOF)
1992: break;
1993: if(i!=ENDOFFRAME) {
1994: if(i>0)
1995: lprintf(zm,LOG_ERR,"%s at offset: %lu", chr(i), ftell(fp));
1996: errors++;
1997: }
1998: }
1999: return(errors);
2000: }
2001:
2002:
2003: int zmodem_recv_file_frame(zmodem_t* zm, FILE* fp)
2004: {
2005: unsigned n;
2006: int type;
2007:
2008: /*
2009: * wait for a ZDATA header with the right file offset
2010: * or a timeout or a ZFIN
2011: */
2012:
2013: do {
2014: do {
2015: type = zmodem_recv_header(zm);
2016: if (type == TIMEOUT) {
2017: return TIMEOUT;
2018: }
2019: if(is_cancelled(zm))
2020: return(ZCAN);
2021:
2022: } while(type != ZDATA);
2023:
2024: if(zm->rxd_header_pos==(ulong)ftell(fp))
2025: break;
2026: lprintf(zm,LOG_WARNING,"Wrong ZDATA block (%lu vs %lu)", zm->rxd_header_pos, ftell(fp));
2027:
2028: } while(!is_cancelled(zm) && is_connected(zm));
2029:
2030: do {
2031: type = zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket),&n,TRUE);
2032:
2033: /* fprintf(stderr,"packet len %d type %d\n",n,type);
2034: */
2035: if (type == ENDOFFRAME || type == FRAMEOK) {
2036: fwrite(zm->rx_data_subpacket,1,n,fp);
2037: }
2038:
2039: if(type==FRAMEOK)
2040: zm->block_size = n;
2041:
2042: if(zm->progress!=NULL)
2043: zm->progress(zm->cbdata,ftell(fp));
2044:
2045: if(is_cancelled(zm))
2046: return(ZCAN);
2047:
2048: } while(type == FRAMEOK);
2049:
2050: return type;
2051: }
2052:
2053: const char* zmodem_source(void)
2054: {
2055: return(__FILE__);
2056: }
2057:
2058: char* zmodem_ver(char *buf)
2059: {
2060: sscanf("$Revision: 1.71 $", "%*s %s", buf);
2061:
2062: return(buf);
2063: }
2064:
2065: void zmodem_init(zmodem_t* zm, void* cbdata
2066: ,int (*lputs)(void*, int level, const char* str)
2067: ,void (*progress)(void* unused, ulong)
2068: ,int (*send_byte)(void*, uchar ch, unsigned timeout)
2069: ,int (*recv_byte)(void*, unsigned timeout)
2070: ,BOOL (*is_connected)(void*)
2071: ,BOOL (*is_cancelled)(void*)
2072: ,BOOL (*data_waiting)(void*, unsigned timeout))
2073: {
2074: memset(zm,0,sizeof(zmodem_t));
2075:
2076: /* Use sane default values */
2077: zm->init_timeout=10; /* seconds */
2078: zm->send_timeout=15; /* seconds */
2079: zm->recv_timeout=20; /* seconds */
2080: zm->crc_timeout=60; /* seconds */
2081: #if 0
2082: zm->byte_timeout=3; /* seconds */
2083: zm->ack_timeout=10; /* seconds */
2084: #endif
2085: zm->block_size=ZBLOCKLEN;
2086: zm->max_block_size=ZBLOCKLEN;
2087: zm->max_errors=9;
2088:
2089: zm->cbdata=cbdata;
2090: zm->lputs=lputs;
2091: zm->progress=progress;
2092: zm->send_byte=send_byte;
2093: zm->recv_byte=recv_byte;
2094: zm->is_connected=is_connected;
2095: zm->is_cancelled=is_cancelled;
2096: zm->data_waiting=data_waiting;
2097: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.