📄 ecurz.c
字号:
/*+------------------------------------------------------------------------- cancel_transaction(can_code)called by signal interrupt or terminate to clean things up--------------------------------------------------------------------------*/voidcancel_transaction(can_code)int can_code;{ purgeline(); if(Zmodem) zmputs(Attn); send_cancel(1); mode(0); if(can_code >= 0) { sprintf(s128,"ecurz aborted (signal %d)",can_code); report_str(s128,0); } report_tx_ind(0); report_rx_ind(0); report_uninit(0); bye_bye(can_code);} /* end of cancel_transaction *//*+------------------------------------------------------------------------- sendline(c) - send a character to DCE--------------------------------------------------------------------------*/voidsendline(c)char c;{ write(iofd,&c,1); ++tx_char_count;} /* end of sendline *//*+------------------------------------------------------------------------- xsendline(c)--------------------------------------------------------------------------*/voidxsendline(c)int c;{ sendline(c);} /* end of xsendline *//*+------------------------------------------------------------------------- flushline()--------------------------------------------------------------------------*/voidflushline(){} /* end of flushline *//*+------------------------------------------------------------------------- purgeline() - purge the modem input queue of all characters--------------------------------------------------------------------------*/voidpurgeline(){ Lleft = 0;#if defined(TCFLSH) ioctl(iofd,TCFLSH,0);#else lseek(iofd,0L,2);#endif} /* end of purgeline *//*+------------------------------------------------------------------------- wcreceive(argc,argp)--------------------------------------------------------------------------*/wcreceive(argc,argp)int argc;char **argp;{ register c; if(Batch || argc==0) { Crcflg=1; c=tryz(); if(Zmodem) { report_protocol_type("ZMODEM"); report_protocol_crc_type((Crc32) ? "/CRC32" : "/CRC16"); } if(c) { if(c == ZCOMPL) return(OK); if(c == ERROR) goto FAIL; c = rzfiles(); if(c) goto FAIL; } else { report_protocol_type("YMODEM"); report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK"); for(;;) { if(wcrxpn(secbuf)== ERROR) goto FAIL; if(secbuf[0]==0) return(OK); if(procheader(secbuf) == ERROR) goto FAIL; report_str("Receiving data",0); if(wcrx()==ERROR) goto FAIL; } } } else { report_protocol_type("XMODEM"); report_protocol_crc_type((Crcflg) ? "/CRC" : "/CHK"); Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L; procheader(""); strcpy(Pathname,*argp); if(!(fout=our_fopen(Pathname,"w"))) { sprintf(s128,"%-0.64s: %-0.40s",Pathname,sys_errlist[errno]); report_str(s128,1); ecu_log_event(getppid(),s128); goto FAIL; } ++Filcnt; report_file_rcv_started(Pathname,0L,Modtime,(unsigned short)Filemode); this_file_length = 0; report_rxpos(0L); report_str("Receiving data",0); if(wcrx()==ERROR) goto FAIL; } return(OK);FAIL: send_cancel(1); if(fout) { fflush(fout); fstat(fileno(fout),&fout_stat); report_file_byte_io((long)fout_stat.st_size - initial_filepos); report_file_close(0); fclose(fout); fout = (FILE *)0; } return(ERROR);} /* end of wcreceive *//*+------------------------------------------------------------------------- wcgetsec(rxbuf,maxtime) Wcgetsec fetches a Ward Christensen type sector. Returns sector number encountered or ERROR if valid sector not received, or CAN CAN received or WCEOT if eot sector time is timeout for first char,set to 4 seconds thereafter. NO ACK IS SENT IF SECTOR IS RECEIVED OK. Caller must do that when he is good and ready to get next sector.--------------------------------------------------------------------------*/unsigned intwcgetsec(rxbuf,maxtime)char *rxbuf;int maxtime;{ register unsigned int firstch; register unsigned short oldcrc; register unsigned char checksum; register wcj; register char *p; int sectcurr; for(Lastrx=errors=0; errors<RETRYMAX; errors++) { firstch=readline(maxtime); if((firstch == STX) || (firstch == SOH)) { oldBlklen = Blklen; if(firstch == STX) Blklen=1024; else Blklen=128; if(oldBlklen != Blklen) report_rxblklen(Blklen); sectcurr=readline(1); if((sectcurr + (oldcrc=readline(1))) == 0xFF) { oldcrc=checksum=0; for(p = rxbuf,wcj = Blklen; --wcj >= 0; ) { if((int)(firstch=readline(1)) < 0) goto bilge; oldcrc=updcrc(firstch,oldcrc); checksum += (*p++ = firstch); } if((int)(firstch=readline(1)) < 0) goto bilge; if(Crcflg) { oldcrc=updcrc(firstch,oldcrc); if((int)(firstch=readline(1)) < 0) goto bilge; oldcrc=updcrc(firstch,oldcrc); if(oldcrc) { sprintf(s128,"CRC error = 0x%04x",oldcrc); report_str(s128,1); } else { Firstsec=0; return(sectcurr); } } else if((checksum-firstch)==0) { Firstsec=0; return(sectcurr); } else report_str("checksum error",1); } else { report_last_txhdr("Noise",0); sprintf(s128,"Sector garbled 0x%x 0x%x",sectcurr,oldcrc); report_str(s128,1); } } /* make sure eot really is eot and not just mixmash */#if defined(NFGVMIN) else if(firstch==EOT && readline(1)==TIMEOUT) return(WCEOT);#else else if(firstch==EOT && Lleft==0) return(WCEOT);#endif else if(firstch==EOT) { report_str("Noisy EOT",2); } else if(firstch==CAN) { if(Lastrx==CAN) { report_str("Sender CANcelled",1); report_last_rxhdr("CAN",1); return(ERROR); } else { Lastrx=CAN; continue; } } else if(firstch==TIMEOUT) { if(Firstsec) goto humbug;bilge: report_str("Timeout",1); } else { sprintf(s128,"Got 0x%02x sector header",firstch); report_str(s128,1); }humbug: Lastrx=0; while(readline(1)!=TIMEOUT) ; if(Firstsec) { sendline(Crcflg?WANTCRC:NAK); report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0); Lleft=0; /* Do read next time ... */ } else { maxtime=40; sendline(NAK); report_last_txhdr("NAK",1); Lleft=0; /* Do read next time ... */ } } /* try to stop the bubble machine. */ send_cancel(1); return(ERROR);} /* end of wcgetsec *//*+------------------------------------------------------------------------- wcrxpn(rpn) Fetch a pathname from the other end. Length is indeterminate as long as less than Blklen. During YMODEM xfers, a null string represents no more files.--------------------------------------------------------------------------*/wcrxpn(rpn)char *rpn; /* receive a pathname */{ register c;#if defined(NFGVMIN) readline(1);#else purgeline();#endifet_tu: Firstsec=1; Eofseen=0; sendline(Crcflg?WANTCRC:NAK); report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0); Lleft=0; /* Do read next time ... */ while((c = wcgetsec(rpn,100)) != 0) { if(c == WCEOT) { sprintf(s128,"Pathname fetch returned %d",c); report_str(s128,1); sendline(ACK); report_last_txhdr("ACK",0); Lleft=0; /* Do read next time ... */ readline(1); goto et_tu; } return(ERROR); } sendline(ACK); report_last_txhdr("ACK",0); return(OK);} /* end of wcrxpn *//*+------------------------------------------------------------------------- report_receive_progress(pos)--------------------------------------------------------------------------*/voidreport_receive_progress(pos)long pos;{ report_rxpos(pos); if(this_file_length != 0) { sprintf(s128,"Receiving data (%u%% complete)", (int)((unsigned long)pos * (unsigned long)100) / this_file_length); report_str(s128,0); }} /* end of report_receive_progress *//*+------------------------------------------------------------------------- write_sec_to_disk(buf,n) Putsec writes the n characters of buf to receive file fout. If not in binary mode, carriage returns, and all characters starting with CPMEOF are discarded.--------------------------------------------------------------------------*/write_sec_to_disk(buf,n)char *buf;register n;{ register char *p; if(!n) return(OK); if(Thisbinary) { for(p=buf; --n>=0; ) fputc( *p++,fout); } else { if(Eofseen) return(OK); for(p=buf; --n>=0; ++p ) { if( *p == '\r') continue; if(*p == CPMEOF) { Eofseen=1; fflush(fout); fstat(fileno(fout),&fout_stat); report_rxpos(fout_stat.st_size); return(OK); } fputc(*p,fout); } } if(!Zmodem) { fflush(fout); fstat(fileno(fout),&fout_stat); report_rxpos(fout_stat.st_size); } return(OK);} /* end of write_sec_to_disk *//*+------------------------------------------------------------------------- wcrx() - receive an X/YMODEM sector Adapted from CMODEM13.C,written by Jack M. Wierda and Roderick W. Hart--------------------------------------------------------------------------*/intwcrx(){ register unsigned int sectnum,sectcurr; register unsigned char sendchar; int cblklen; /* bytes to dump this block */ Firstsec=1; sectnum=0; Eofseen=0; sendchar=Crcflg ? WANTCRC : NAK; report_last_txhdr(Crcflg ? "WANTCRC" : "NAK",0); for(;;) { sendline(sendchar); /* send it now,we're ready! */ if(sendchar == ACK) report_last_txhdr("ACK",0); Lleft=0; /* Do read next time ... */ sectcurr=wcgetsec(secbuf,(sectnum&0177)?50:130); sprintf(s128,"Block %d received",sectnum); report_last_rxhdr(s128,0); fstat(fileno(fout),&fout_stat); report_rxpos(fout_stat.st_size); if(sectcurr == (sectnum+1 & 0xFF)) { sectnum++; cblklen = Bytesleft>Blklen ? Blklen : Bytesleft; if(write_sec_to_disk(secbuf,cblklen) == ERROR) return(ERROR); if((Bytesleft-=cblklen) < 0) Bytesleft = 0; sendchar=ACK; } else if(sectcurr == sectnum) { report_str("Received duplicate Sector",-1); sendchar = ACK; } else if(sectcurr == WCEOT) { if(close_and_report()) return(ERROR); sendline(ACK); report_last_txhdr("ACK",0); Lleft=0; /* Do read next time ... */ return(OK); } else if(sectcurr==ERROR) return(ERROR); else { report_str( "Sync Error",1); return(ERROR); } }} /* end of wcrx *//*+------------------------------------------------------------------------- readline(timeout) read one or more characters timeout is in tenths of seconds--------------------------------------------------------------------------*/readline(timeout)int timeout;{ VOLATILE int n; static unsigned char *cdq; /* pointer for removing chars from linbuf */ if(--Lleft >= 0) return(*cdq++); n = timeout/10; if(n < 2) n = 3; if(setjmp(tohere)) { Lleft = 0; return(TIMEOUT); } signal(SIGALRM,SIGALRM_handler); alarm(n); Lleft = read(iofd,(char *)(cdq = linbuf),Readnum); alarm(0); rx_char_count += Lleft; if(Lleft < 1) return(TIMEOUT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -