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