📄 zmodem.c
字号:
case GOTCRCG: case GOTCRCQ: case GOTCRCW: crc = updcrc(((d=c)&0377),crc); if((c = zdlread()) & ~0377) goto crcfoo; crc = updcrc(c,crc); if((c = zdlread()) & ~0377) goto crcfoo; crc = updcrc(c,crc); if(crc & 0xFFFF) { report_str(badcrc,0); report_rx_ind(0); return(ERROR); } Rxcount = length - (end - buf); report_rxblklen(Rxcount); sprintf(s128,#ifdef SHOW_ZHDR_TYPE "D16 %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 Cancelled",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 = updcrc(c,crc); } report_str("Data subpacket too long",0); report_rx_ind(0); return(ERROR);}/* * Read a ZMODEM header to hdr,either binary or hex. * eflag controls local display of non zmodem characters: * 0: no display * 1: display printing characters only * 2: display all non ZMODEM characters * On success,set Zmodem to 1,set Rxpos and return type of header. * Otherwise return negative on error. * Return ERROR instantly if ZCRCW sequence,for fast error recovery. */intzgethdr(hdr,eflag)char *hdr;int eflag;{register int c,n,cancount;#ifdef SHOW_ZHDR_TYPEchar *hdrtyp = "?";#endif report_rx_ind(1); n = Zrwindow + Baudrate; /* Max bytes before start of frame */ Rxframeind = Rxtype = 0;startover: cancount = 5;again: /* Return immediate ERROR if ZCRCW sequence seen */ switch(c = readline(Rxtimeout)) { case RCDO: case TIMEOUT: goto fifi; case CAN:gotcan: if(--cancount <= 0) { c = ZCAN; goto fifi; } switch(c = readline(1)) { case TIMEOUT: goto again; case ZCRCW: c = ERROR; /* **** FALL THRU TO **** */ case RCDO: goto fifi; default: break; case CAN: if(--cancount <= 0) { c = ZCAN; goto fifi; } goto again; } /* **** FALL THRU TO **** */ default:agn2: if( --n == 0) { report_str("Garbage count exceeded",1); report_last_rxhdr("Noise",0); report_rx_ind(0); return(ERROR); } goto startover; case ZPAD|0200: /* This is what we want. */ case ZPAD: /* This is what we want. */ evenp = c & 0200; break; } cancount = 5;splat: switch(c = noxrd7()) { case ZPAD: goto splat; case RCDO: case TIMEOUT: goto fifi; default: goto agn2; case ZDLE: /* This is what we want. */ break; } switch(c = noxrd7()) { case RCDO: case TIMEOUT: goto fifi; case ZBIN: Rxframeind = ZBIN; Crc32 = FALSE; c = zrbhdr(hdr); break; case ZBIN32: Crc32 = Rxframeind = ZBIN32; c = zrbhdr32(hdr); break; case ZHEX: Rxframeind = ZHEX; Crc32 = FALSE; c = zrhhdr(hdr); break; case CAN: goto gotcan; default: goto agn2; } Rxpos = hdr[ZP3] & 0377; Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0377); Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0377); Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0377);fifi: switch(c) { case GOTCAN: c = ZCAN; /* **** FALL THRU TO **** */ case ZNAK: case ZCAN: case ERROR: case TIMEOUT: case RCDO: sprintf(s128,"Got %s",frametypes[c+FTOFFSET]); report_str(s128,0); /* **** FALL THRU TO **** */ default:#ifdef SHOW_ZHDR_TYPE switch(Rxframeind) { case ZBIN: hdrtyp = "B16"; break; case ZBIN32: hdrtyp = "B32"; break; case ZHEX: hdrtyp = "HEX"; break; } if(c >= -3 && c <= FRTYPES) sprintf(s128,"%s %s %ld",hdrtyp,frametypes[c+FTOFFSET],Rxpos); else sprintf(s128,"%s 0x%02x? %ld",hdrtyp,c,Rxpos);#else if(c >= -3 && c <= FRTYPES) sprintf(s128,"hdr %s %ld",frametypes[c+FTOFFSET],Rxpos); else sprintf(s128,"hdr 0x%02x? %ld",c,Rxpos);#endif report_last_rxhdr(s128,0); } report_rx_ind(0); return(c);}/* Receive a binary style header (type and position) */intzrbhdr(hdr)register char *hdr;{ register int c,n; register unsigned short crc; if((c = zdlread()) & ~0377) return(c); Rxtype = c; crc = updcrc(c,0); for(n=4; --n >= 0; ++hdr) { if((c = zdlread()) & ~0377) return(c); crc = updcrc(c,crc); *hdr = c; } if((c = zdlread()) & ~0377) return(c); crc = updcrc(c,crc); if((c = zdlread()) & ~0377) return(c); crc = updcrc(c,crc); if(crc & 0xFFFF) { if(evenp) report_str(masked,1); report_str(badcrc,0); return(ERROR); }#if defined(ZMODEM) Protocol = ZMODEM;#endif Zmodem = 1; return(Rxtype);}/* Receive a binary style header (type and position) with 32 bit FCS */intzrbhdr32(hdr)register char *hdr;{ register int c,n; register UNSL long crc; if((c = zdlread()) & ~0377) return(c); Rxtype = c; crc = 0xFFFFFFFFL; crc = UPDC32(c,crc); for(n=4; --n >= 0; ++hdr) { if((c = zdlread()) & ~0377) return(c); crc = UPDC32(c,crc); *hdr = c; } for(n=4; --n >= 0;) { if((c = zdlread()) & ~0377) return(c); crc = UPDC32(c,crc); } if(crc != 0xDEBB20E3) { if(evenp) report_str(masked,1); report_str(badcrc,0); return(ERROR); }#if defined(ZMODEM) Protocol = ZMODEM;#endif Zmodem = 1; return(Rxtype);}/* Receive a hex style header (type and position) */intzrhhdr(hdr)char *hdr;{ register int c; register unsigned short crc; register int n; if((c = zgethex()) < 0) return(c); Rxtype = c; crc = updcrc(c,0); for(n=4; --n >= 0; ++hdr) { if((c = zgethex()) < 0) return(c); crc = updcrc(c,crc); *hdr = c; } if((c = zgethex()) < 0) return(c); crc = updcrc(c,crc); if((c = zgethex()) < 0) return(c); crc = updcrc(c,crc); if(crc & 0xFFFF) { report_str(badcrc,0); return(ERROR); } if(readline(1) == '\r') /* Throw away possible cr/lf */ readline(1);#if defined(ZMODEM) Protocol = ZMODEM;#endif Zmodem = 1; return(Rxtype);}/* Decode two lower case hex digits into an 8 bit byte value */intzgeth1(){ register int c,n; if((c = noxrd7()) < 0) return(c); n = c - '0'; if(n > 9) n -= ('a' - ':'); if(n & ~0xF) return(ERROR); if((c = noxrd7()) < 0) return(c); c -= '0'; if(c > 9) c -= ('a' - ':'); if(c & ~0xF) return(ERROR); c += (n<<4); return(c);}intzgethex(){ return(zgeth1());}/* * Read a byte,checking for ZMODEM escape encoding * including CAN*5 which represents a quick abort */intzdlread(){ register int c;again: /* Quick check for non control characters */ if((c = readline(Rxtimeout)) & 0140) return(c); switch(c) { case ZDLE: break; case 023: case 0223: case 021: case 0221: goto again; default: if(Zctlesc && !(c & 0140)) { goto again; } return(c); }again2: if((c = readline(Rxtimeout)) < 0) return(c); if(c == CAN && (c = readline(Rxtimeout)) < 0) return(c); if(c == CAN && (c = readline(Rxtimeout)) < 0) return(c); if(c == CAN && (c = readline(Rxtimeout)) < 0) return(c); switch(c) { case CAN: return(GOTCAN); case ZCRCE: case ZCRCG: case ZCRCQ: case ZCRCW: return(c | GOTOR); case ZRUB0: return(0177); case ZRUB1: return(0377); case 023: case 0223: case 021: case 0221: goto again2; default: if(Zctlesc && ! (c & 0140)) { goto again2; } if((c & 0140) == 0100) return(c ^ 0100); break; } sprintf(s128,"Bad escape sequence %x",c); report_str(s128,0); return(ERROR);}/* * Read a character from the modem line with timeout. * Eat parity,XON and XOFF characters. */intnoxrd7(){ register int c; for(;;) { if((c = readline(Rxtimeout)) < 0) return(c); switch(c &= 0177) { case XON: case XOFF: continue; default: if(Zctlesc && !(c & 0140)) continue; case '\r': case '\n': case ZDLE: return(c); } }}/* Store long integer pos in Txhdr */voidstohdr(pos)long pos;{ Txhdr[ZP0] = pos; Txhdr[ZP1] = pos>>8; Txhdr[ZP2] = pos>>16; Txhdr[ZP3] = pos>>24;}/* Recover a long integer from a header */longrclhdr(hdr)register char *hdr;{ register long l; l = (hdr[ZP3] & 0377); l = (l << 8) | (hdr[ZP2] & 0377); l = (l << 8) | (hdr[ZP1] & 0377); l = (l << 8) | (hdr[ZP0] & 0377); return(l);}/* end of zmodem.c *//* vi: set tabstop=4 shiftwidth=4: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -