📄 zmodem.c
字号:
#if defined(WHT) && !defined(SHOW_ZHDR_TYPE)#define SHOW_ZHDR_TYPE#endif/*+------------------------------------------------------------------------- zmodem.c - ZMODEM protocol primitives based on code by Chuck Forsberg Defined functions: noxrd7() rclhdr(hdr) stohdr(pos) zdlread() zgeth1() zgethdr(hdr,eflag) zgethex() zputhex(c) zrbhdr(hdr) zrbhdr32(hdr) zrdat32(buf,length) zrdata(buf,length) zrhhdr(hdr) zsbh32(type,hdr) zsbhdr(type,hdr) zsda32(buf,length,frameend) zsdata(buf,length,frameend) zsendline(c) zshhdr(type,hdr)--------------------------------------------------------------------------*//*+:EDITS:*//*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 *//*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA *//*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 *//*:08-14-1990-20:41-wht@n4hgf-ecu3.00-flush old edit history */#include "zmodem.h" /* wht */extern char s128[]; /* wht */extern int Zctlesc; /* wht */extern int Zmodem; /* wht */extern long cr3tab[]; /* wht */extern unsigned Baudrate; /* wht */extern unsigned short crctab[]; /* wht */int Rxtimeout = 100; /* Tenths of seconds to wait for something */#if !defined(UNSL)#define UNSL#endifstatic lastsent; /* Last char we sent */static evenp; /* Even parity seen on header *//* Globals used by ZMODEM functions */char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */char Rxhdr[4]; /* Received header */char Txhdr[4]; /* Transmitted header */int Crc32; /* Display flag indicating 32 bit CRC being received */int Crc32t; /* Display flag indicating 32 bit CRC being sent */int Rxcount; /* Count of data bytes received */int Rxframeind; /* ZBIN ZBIN32,or ZHEX type of frame received */int Rxtype; /* Type of header received */int Txfcs32; /* TURE means send binary frames with 32 bit FCS */int Zrwindow; /* RX window size (controls garbage count) */long Rxpos; /* Received file position */long Txpos; /* Transmitted file position */char *frametypes[] = { "Carrier Lost", /* -3 */ "TIMEOUT", /* -2 */ "ERROR", /* -1 *//* #define FTOFFSET 3 moved to zmodem.h */ "ZRQINIT", "ZRINIT", "ZSINIT", "ZACK ", "ZFILE", "ZSKIP", "ZNAK ", "ZABORT", "ZFIN ", "ZRPOS", "ZDATA", "ZEOF ", "ZFERR", "ZCRC ", "ZCHALLENGE", "ZCOMPL", "ZCAN ", "ZFREECNT", "ZCOMMAND", "ZSTDERR", "xxxxx"#define FRTYPES 22 /* Total number of frame types in this array */ /* not including psuedo negative entries */};/* * Send character c with ZMODEM escape sequence encoding. * Escape XON,XOFF. Escape CR following @ (Telenet net escape) */voidzsendline(c)int c;{ /* Quick check for non control characters */ if(c & 0140) xsendline(lastsent = c); else { switch(c &= 0377) { case ZDLE: xsendline(ZDLE); xsendline(lastsent = (c ^= 0100)); break; case 015: case 0215: if(!Zctlesc && (lastsent & 0177) != '@') goto sendit; /* **** FALL THRU TO **** */ case 020: case 021: case 023: case 0220: case 0221: case 0223: xsendline(ZDLE); c ^= 0100;sendit: xsendline(lastsent = c); break; default: if(Zctlesc && ! (c & 0140)) { xsendline(ZDLE); c ^= 0100; } xsendline(lastsent = c); } }}static char masked[] = "8 bit transparent path required";static char badcrc[] = "Bad CRC";/* Send ZMODEM CRC-32 binary header hdr of type type */voidzsbh32(type,hdr)int type;register char *hdr;{ register int n; register UNSL long crc; sprintf(s128,#ifdef SHOW_ZHDR_TYPE "B32 %s %ld",#else "hdr %s %ld",#endif frametypes[type+FTOFFSET],rclhdr(hdr)); report_last_txhdr(s128,0); report_tx_ind(1); xsendline(ZBIN32); zsendline(type); crc = 0xFFFFFFFFL; crc = UPDC32(type,crc); for(n=4; --n >= 0; ++hdr) { crc = UPDC32((0377 & *hdr),crc); zsendline(*hdr); } crc = ~crc; for(n=4; --n >= 0;) { zsendline((int)crc); crc >>= 8; } report_tx_ind(0);}/* Send ZMODEM binary header hdr of type type */voidzsbhdr(type,hdr)int type;register unsigned char *hdr;{ register int n; register unsigned crc; xsendline(ZPAD); xsendline(ZDLE); if(Crc32t=Txfcs32) zsbh32(type,hdr); else { sprintf(s128,#ifdef SHOW_ZHDR_TYPE "B16 %s %ld",#else "hdr %s %ld",#endif frametypes[type+FTOFFSET],rclhdr(hdr)); report_last_txhdr(s128,0); report_tx_ind(1); xsendline(ZBIN); zsendline(type); crc = updcrc(type,0); for(n=4; --n >= 0; ++hdr) { zsendline(*hdr); crc = updcrc(*hdr,crc); } crc = updcrc(0,updcrc(0,crc)); zsendline(crc>>8); zsendline(crc); report_tx_ind(0); } if(type != ZDATA) flushline();}/* * Send binary array buf of length length,with ending ZDLE sequence frameend */static char *Zendnames[] = { "ZCRCE","ZCRCG","ZCRCQ","ZCRCW"};voidzsda32(buf,length,frameend)register char *buf;int length;int frameend;{ register int c; register UNSL long crc; sprintf(s128,#ifdef SHOW_ZHDR_TYPE "D32 %s %d",#else "data %s %d",#endif Zendnames[frameend-ZCRCE&3],length); report_last_txhdr(s128,0); report_tx_ind(1); crc = 0xFFFFFFFFL; for(;--length >= 0; ++buf) { c = *buf & 0377; if(c & 0140) xsendline(lastsent = c); else zsendline(c); crc = UPDC32(c,crc); } xsendline(ZDLE); xsendline(frameend); crc = UPDC32(frameend,crc); crc = ~crc; for(length=4; --length >= 0;) { zsendline((int)crc); crc >>= 8; } report_tx_ind(0);}voidzsdata(buf,length,frameend)register unsigned char *buf;int length;int frameend;{ register unsigned short crc; if(Crc32t) zsda32(buf,length,frameend); else { sprintf(s128,#ifdef SHOW_ZHDR_TYPE "D16 %s %d",#else "data %s %d",#endif Zendnames[frameend-ZCRCE&3],length); report_last_txhdr(s128,0); report_tx_ind(1); crc = 0; for(;--length >= 0; ++buf) { zsendline(*buf); crc = updcrc(*buf,crc); } xsendline(ZDLE); xsendline(frameend); crc = updcrc(frameend,crc); crc = updcrc(0,updcrc(0,crc)); zsendline(crc>>8); zsendline(crc); report_tx_ind(0); } if(frameend == ZCRCW) { xsendline(XON); flushline(); }}/* Send a byte as two hex digits */voidzputhex(c)register int c;{ static char digits[] = "0123456789abcdef"; sendline(digits[(c&0xF0)>>4]); sendline(digits[(c)&0xF]);}voidzshhdr(type,hdr)int type;register unsigned char *hdr;{ register int n; register unsigned short crc; sprintf(s128,#ifdef SHOW_ZHDR_TYPE "HEX %s %ld",#else "hdr %s %ld",#endif frametypes[type+FTOFFSET],rclhdr(hdr)); report_last_txhdr(s128,0); report_tx_ind(1); sendline(ZPAD); sendline(ZPAD); sendline(ZDLE); sendline(ZHEX); zputhex(type); Crc32t = 0; crc = updcrc(type,0); for(n=4; --n >= 0; ++hdr) { zputhex(*hdr); crc = updcrc(*hdr,crc);/* crc = updcrc((0377 & *hdr),crc); original - wht */ } crc = updcrc(0,updcrc(0,crc)); zputhex(crc>>8); zputhex(crc); /* Make it printable on remote machine */ sendline(015); sendline(012); /* * Uncork the remote in case a fake XOFF has stopped data flow */ if(type != ZFIN && type != ZACK) sendline(021); flushline(); report_tx_ind(0);}/* * Receive array buf of max length with ending ZDLE sequence * and CRC. Returns the ending character or error code. * NB: On errors may store length+1 bytes! */intzrdat32(buf,length)register char *buf;int length;{ register int c; register UNSL long crc; register char *end; register int d; report_rx_ind(1); crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length; while(buf <= end) { if((c = zdlread()) & ~0377) {crcfoo: switch(c) { case GOTCRCE: case GOTCRCG: case GOTCRCQ: case GOTCRCW: d = c; c &= 0377; crc = UPDC32(c,crc); if((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c,crc); if((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c,crc); if((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c,crc); if((c = zdlread()) & ~0377) goto crcfoo; crc = UPDC32(c,crc); if(crc != 0xDEBB20E3) { report_str(badcrc,0); report_rx_ind(0); return(ERROR); } Rxcount = length - (end - buf); report_rxblklen(Rxcount); sprintf(s128,#ifdef SHOW_ZHDR_TYPE "D32 %s %d",#else "data %s %d",#endif Zendnames[d-GOTCRCE&3],Rxcount); report_last_rxhdr(s128,0); report_rx_ind(0); return(d); case GOTCAN: report_str("Sender Canceled",1); report_rx_ind(0); return(ZCAN); case TIMEOUT: report_str("TIMEOUT",0); report_rx_ind(0); return(c); default: report_str("Bad data subpacket",0); report_rx_ind(0); return(c); } } *buf++ = c; crc = UPDC32(c,crc); } report_str("Data subpacket too long",0); report_rx_ind(0); return(ERROR);}intzrdata(buf,length)register char *buf;int length;{ register int c; register unsigned short crc; register char *end; register int d; if(Rxframeind == ZBIN32) return(zrdat32(buf,length)); report_rx_ind(1); crc = Rxcount = 0; end = buf + length; while(buf <= end) { if((c = zdlread()) & ~0377) {crcfoo: switch(c) { case GOTCRCE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -