📄 ecusz.c
字号:
int sig;{ report_rx_ind(0); report_tx_ind(0); longjmp(tohere,-1);} /* end of SIGALRM_handler *//*+------------------------------------------------------------------------- readock(timeout,count)timeout is in tenths of seconds reads character(s) from filedescriptor 'fd' read 'count' characters, (1 <= count <= 3) if more thanone received, return ERROR unless all are CAN normal response is NAK,ACK, CAN, G or C--------------------------------------------------------------------------*/intreadock(timeout,count)int timeout;int count;{ VOLATILE int c; static char byt[5]; if(setjmp(tohere)) { report_str("TIMEOUT",1); return(TIMEOUT); } c = timeout / 10; if(c < 2) c = 2; signal(SIGALRM,SIGALRM_handler); alarm(c); c = read(iofd,byt,count); alarm(0); if(c < 1) return(TIMEOUT); rx_char_count += c; if(c == 1) return(byt[0] & 0xFF); while(c) { if(byt[--c] != CAN) return(ERROR); } return(CAN);} /* end of readock *//*+------------------------------------------------------------------------- readline(n)--------------------------------------------------------------------------*/intreadline(n)int n;{ return(readock(n,1));} /* end of readline *//*+------------------------------------------------------------------------- purgeline()--------------------------------------------------------------------------*/voidpurgeline(){ ioctl(iofd,TCFLSH,0);} /* end of purgeline *//*+------------------------------------------------------------------------- send_cancel(error) - send cancel to remote--------------------------------------------------------------------------*/voidsend_cancel(error)int error;{ static char canistr[] = { 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0 }; register char *cptr = canistr; report_last_txhdr("^X CAN",!!error); while(*cptr) sendline(*cptr++); flushline();} /* end of send_cancel *//*+------------------------------------------------------------------------- substr(str,str2) - searches for str2 in string str--------------------------------------------------------------------------*/char *substr(str,str2)register char *str;register char *str2;{ register char *sptr; register char *ssptr; for(sptr = str; *str; str++) { if(*str == *str2) { sptr = str; ssptr = str2; while(1) { if(*ssptr == 0) return(str); if(*sptr++ != *ssptr++) break; } } } return(NULL);} /* end of substr *//*+------------------------------------------------------------------------- usage()--------------------------------------------------------------------------*/voidusage(){ exit(255);} /* end of usage *//*+------------------------------------------------------------------------- getzrxinit() - Get the receiver's init parameters--------------------------------------------------------------------------*/intgetzrxinit(){ register n; struct stat f; for(n=10; --n>=0; ) { switch(zgethdr(Rxhdr,1)) { case ZCHALLENGE: /* Echo receiver's challenge numbr */ stohdr(Rxpos); zshhdr(ZACK,Txhdr); continue; case ZCOMMAND: /* They didn't see out ZRQINIT */ stohdr(0L); zshhdr(ZRQINIT,Txhdr); continue; case ZRINIT: Rxflags = 0377 & Rxhdr[ZF0]; Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32)); report_protocol_type("ZMODEM"); report_protocol_crc_type((Txfcs32) ? "/CRC32" : "/CRC16"); Zctlesc |= Rxflags & TESCCTL; Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8); if( !(Rxflags & CANFDX)) Txwindow = 0;#if defined(MODE2OK) mode(2); /* Set cbreak,XON/XOFF,etc. */#endif#if !defined(READCHECK) /* Use 1024 byte frames if no sample/interrupt */ if(Rxbuflen < 32 || Rxbuflen > 1024) { Rxbuflen = 1024; }#endif /* Override to force shorter frame length */ if(Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32)) Rxbuflen = Tframlen; if( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024)) Rxbuflen = Tframlen; /* If using a pipe for testing set lower buf len */ fstat(iofd,&f); if((f.st_mode & S_IFMT) != S_IFCHR && (Rxbuflen == 0 || Rxbuflen > 4096)) Rxbuflen = 4096; sprintf(s128,"Remote: CRC32 %c duplex %c", (Rxflags & CANFC32) ? 'y' : 'n', (Rxflags & CANFDX) ? 'y' : 'n'); if(Rxbuflen) sprintf(&s128[strlen(s128)]," buflen %u",Rxbuflen); else strcat(s128," continuous stream y"); report_str(s128,2); /* * If input is not a regular file,force ACK's each 1024 * (A smarter strategey could be used here ...) */ if( !Command) { fstat(fileno(in),&f); if(((f.st_mode & S_IFMT) != S_IFREG) && (Rxbuflen == 0 || Rxbuflen > 1024)) Rxbuflen = 1024; } if(Baudrate > 300) /* Set initial subpacket len */ blklen = 256; if(Baudrate > 1200) blklen = 512; if(Baudrate >= 2400) /* original code had > 2400 here ****/ blklen = 1024; if(Rxbuflen && blklen>Rxbuflen) blklen = Rxbuflen; if(blkopt && blklen > blkopt) blklen = blkopt; blklen_original = blklen; report_txblklen(blklen); return(sendzsinit()); case ZCAN: case TIMEOUT: return(ERROR); case ZRQINIT: if(Rxhdr[ZF0] == ZCOMMAND) continue; default: zshhdr(ZNAK,Txhdr); continue; } } return(ERROR);} /* end of getzrxinit *//*+------------------------------------------------------------------------- sendzsinit() - send send-init information--------------------------------------------------------------------------*/sendzsinit(){ register c; if(Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL))) return(OK); errors = 0; for(;;) { stohdr(0L); if(Zctlesc) { Txhdr[ZF0] |= TESCCTL; zshhdr(ZSINIT,Txhdr); } else zsbhdr(ZSINIT,Txhdr); zsdata(Myattn,1+strlen(Myattn),ZCRCW); c = zgethdr(Rxhdr,1); switch(c) { case ZCAN: return(ERROR); case ZACK: return(OK); default: if(++errors > 19) return(ERROR); continue; } }} /* end of sendzsinit *//*+------------------------------------------------------------------------- zsendfile(buf,blen) - send file name & info--------------------------------------------------------------------------*/zsendfile(buf,blen)char *buf;int blen;{ register c; for(;;) { blklen = blklen_original; report_txblklen(blklen); Txhdr[ZF0] = Lzconv; /* file conversion request */ Txhdr[ZF1] = Lzmanag; /* file management request */ Txhdr[ZF2] = Lztrans; /* file transport request */ Txhdr[ZF3] = 0; zsbhdr(ZFILE,Txhdr); zsdata(buf,blen,ZCRCW);again: c = zgethdr(Rxhdr,1); switch(c) { case ZRINIT: while((c = readline(50)) > 0) if(c == ZPAD) { goto again; } /* **** FALL THRU TO **** */ default: continue; case ZCAN: case TIMEOUT: case ZABORT: case ZFIN: return(ERROR); case ZSKIP: report_file_close(3); fclose(in); return(c); case ZRPOS: if(!seen_zrpos) initial_filepos = Rxpos; seen_zrpos = 1; /* * Suppress zcrcw request otherwise triggered by * lastyunc==bytcnt */ Lastsync = (bytcnt = Txpos = Rxpos) -1; fseek(in,Rxpos,0); Dontread = FALSE; report_send_progress(Txpos); return(zsendfdata()); } }} /* end of zsendfile *//*+------------------------------------------------------------------------- zsendfdata() - send data in the file--------------------------------------------------------------------------*/zsendfdata(){ VOLATILE int c = 0,e,n; VOLATILE int newcnt; VOLATILE int long tcount = 0; VOLATILE int junkcount; /* Counts garbage chars received by TX */ VOLATILE int err; Lrxpos = 0; junkcount = 0; SameZrposAgain = FALSE; /* variable was named Beenhereb4 (wht) */ this_file_frame_count = 0; /* we've sent no frames (wht) */somemore: if(setjmp(intrjmp)) {waitack: junkcount = 0; c = getinsync(0);gotack: switch(c) { default: case ZCAN: report_rcvr_cancelled("zfdata-1"); report_file_close(4); fclose(in); return(ERROR); case ZSKIP: report_file_close(5); fclose(in); return(c); case ZACK: case ZRPOS: if(!seen_zrpos) initial_filepos = Rxpos; seen_zrpos = 1; break; case ZRINIT: return(OK); }#if defined(READCHECK) /* * If the reverse channel can be tested for data, * this logic may be used to detect error packets * sent by the receiver, in place of setjmp/longjmp * rdchk(fdes) returns non 0 if a character is available */ while(rdchk(iofd)) { switch(readline(1)) { case CAN: case ZPAD: c = getinsync(1); goto gotack; case XOFF: /* Wait a while for an XON */ case XOFF|0200: readline(100); } }#endif } newcnt = Rxbuflen; Txwcnt = 0; stohdr(Txpos); zsbhdr(ZDATA,Txhdr); do { if(Dontread) { n = Lastn; } else { n = zbuf_build(txbuf,blklen); Lastread = Txpos; Lastn = n; } Dontread = FALSE; if(n < blklen) e = ZCRCE; else if(junkcount > 3) e = ZCRCW; else if(bytcnt == Lastsync) e = ZCRCW; else if(Rxbuflen && (newcnt -= n) <= 0) e = ZCRCW; else if(Txwindow && (Txwcnt += n) >= Txwspac) { Txwcnt = 0; e = ZCRCQ; } else e = ZCRCG; zsdata(txbuf,n,e); this_file_frame_count++; /* wht */ if(bad_condx_blklen) /* wht */ { /* if we have sent four frames since last ZRPOS to same pos (wht)*/ if((this_file_frame_count - bad_condx_frame_count) > 4) /*wht*/ { if(blklen == bad_condx_blklen) bad_condx_blklen = 0; else { blklen *= 2; report_txblklen(blklen); } SameZrposAgain = 0; } } bytcnt = Txpos += n; report_send_progress(Txpos); if(e == ZCRCW) goto waitack;#if defined(READCHECK) /* * If the reverse channel can be tested for data, * this logic may be used to detect error packets * sent by the receiver,in place of setjmp/longjmp * rdchk(fdes) returns non 0 if a character is available */ while(rdchk(iofd)) { switch(readline(1)) { case CAN: case ZPAD: c = getinsync(1); if(c == ZACK) break;#if defined(TCFLSH) ioctl(iofd,TCFLSH,1);#endif /* zcrce - dinna wanna starta ping-pong game */ zsdata(txbuf,0,ZCRCE); goto gotack; case XOFF: /* Wait a while for an XON */ case XOFF|0200: readline(100); default: ++junkcount; } }#endif /* READCHECK */ if(Txwindow) { while((tcount = Txpos - Lrxpos) >= Txwindow) { if(e != ZCRCQ) zsdata(txbuf,0,e = ZCRCQ); c = getinsync(1); if(c != ZACK) {#if defined(TCFLSH) ioctl(iofd,TCFLSH,1);#endif zsdata(txbuf,0,ZCRCE); goto gotack; } } } } while(n == blklen); for(;;) { stohdr(Txpos); zsbhdr(ZEOF,Txhdr); switch(err = getinsync(0)) { case ZACK: continue; case ZRPOS: if(!seen_zrpos) initial_filepos = Rxpos; seen_zrpos = 1; goto somemore; case ZRINIT: return(OK); case ZSKIP: report_file_close(6); fclose(in); return(c); default: sprintf(s128,"SEND protocol sync error 0x%04x: %s",err,Pathname); ecu_log_event(getppid(),s128); /* always log this */ report_str(s128 + 5,1); skip_count++; report_error_count(); report_file_byte_io(this_file_length - initial_filepos); report_file_close(7); fclose(in); return(ERROR); } }} /* end of zsendfdata *//*+------------------------------------------------------------------------- getinsync(flag) - get back in sync with receiver--------------------------------------------------------------------------*/intgetinsync(flag)int flag;{ register c; for(;;) { switch(c = zgethdr(Rxhdr,0)) { case ZCAN: case ZABORT: case ZFIN: case TIMEOUT: sprintf(s128,"Receiver %s",frametypes[c+FTOFFSET]); report_str(s128,1); return(ERROR); case ZRPOS: report_str("Receiver ZRPOS",1); if(!seen_zrpos) initial_filepos = Rxpos; seen_zrpos = 1; /* ************************************* */ /* If sending to a modem buffer,you */ /* might send a break at this point to */ /* dump the modem's buffer. */ /* ************************************* */ if(Lastn >= 0 && Lastread == Rxpos) { Dontread = TRUE; } else { clearerr(in); /* In case file EOF seen */ fseek(in,Rxpos,0); } bytcnt = Lrxpos = Txpos = Rxpos; if(Lastsync == Rxpos) /* wht - original code */ { /* wht - original code */ /* save frame count at time of each occurrence (wht) */ bad_condx_frame_count = this_file_frame_count; /* wht */ /* save block length at time of error (wht) */ if(++SameZrposAgain > 4) /* wht - original code */ { /* wht */ if(bad_condx_blklen == 0) /* wht */ bad_condx_blklen = blklen; /* wht */ if(blklen > 256) /* wht - 32->256 */ { blklen /= 2; /* wht - original code */ report_txblklen(blklen); } } /* wht */ } /* wht - original code */ Lastsync = Rxpos; report_send_progress(Txpos); return(c); case ZACK: report_str("",-1); Lrxpos = Rxpos; if(flag || Txpos == Rxpos) return(ZACK); continue; case ZRINIT: report_str("",-1);#if defined(LOG_XFER) sprintf(s128,"SEND success: %s",Pathname); ecu_log_event(getppid(),s128);#endif case ZSKIP: report_file_byte_io(this_file_length); report_file_close(0); fclose(in); return(c); case ERROR: default: report_str("Sending ZNAK",0); zsbhdr(ZNAK,Txhdr); continue; } }} /* end of getinsync *//*+------------------------------------------------------------------------- saybibi() - Say "bibi" to the receiver, try to do it cleanly--------------------------------------------------------------------------*/voidsaybibi(){ for(;;) { stohdr(0L); /* CAF Was zsbhdr - minor change */ zshhdr(ZFIN,Txhdr); /* to make debugging easier */ switch(zgethdr(Rxhdr,0)) { case ZFIN: sendline('O'); sendline('O'); flushline(); case ZCAN: case TIMEOUT: return; } }} /* end of saybibi *//*+------------------------------------------------------------------------- determine_transaction_time()--------------------------------------------------------------------------*/voiddetermine_transaction_time(){register c;struct stat f;char *name; rewind_file_list(); TotalLeft = 0; Filesleft = 0; while(get_file_list_name(&name)) { f.st_size = -1; if((access(name,04) >= 0) && (stat(name,&f) >= 0)) { c = f.st_mode & S_IFMT; if(c != S_IFDIR && c != S_IFBLK) { ++Filesleft; TotalLeft += f.st_size; } } } FilesTotal = Filesleft; rewind_file_list();} /* end of determine_transaction_time *//* vi: set tabstop=4 shiftwidth=4: *//* end of ecusz.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -