📄 ecusz.c
字号:
char *numeric_revision = "@(#)ecusz 3.20";#define BUFFERED_WRITE/*+------------------------------------------------------------------------- ecusz.c - X/Y/ZMODEM send program Derived from public domain source by Chuck Forsberg, Omen Technologies Adaptation for ecu 1989 wht@n4hgf.Mt-Park.GA.US Usage: ecusz [-X -Y -Z] [-12+abdefkLlNnquvwy] [-] file ... (Y) = Option applies to YMODEM only (Z) = Option applies to ZMODEM only a (ASCII) change NL to CR/LF b Binary file transfer override f send Full pathname (Y/Z) k Send 1024 byte packets (Y) L N Limit subpacket length to N bytes (Z) l N Limit frame length to N bytes (l>=L) (Z) n send file if source newer (Z) N send file if source newer or longer (Z) o Use 16 bit CRC instead of 32 bit CRC (Z) p Protect existing destination file (Z) r Resume/Recover interrupted file transfer (Z) q Quiet (no progress reports) u Unlink file after transmission w N Window is N bytes (Z) y Yes,overwrite existing file (Z) @file reads a list of filenames from 'file' Defined functions: SIGALRM_handler(sig) bye_bye(sig) cancel_transaction(sig) determine_transaction_time() flushline() get_file_list_name(namep) getinsync(flag) getnak() getzrxinit() log_packet_buffer(buf,len) main(argc,argv) onintr() purgeline() readline(n) readock(timeout,count) report_rcvr_cancelled(place_happened) report_rcvr_skipped() report_send_progress(filepos) report_send_transaction() rewind_file_list() saybibi() send_cancel(error) sendline(ch) sendzsinit() set_file_list(pathc,pathv) substr(str,str2) usage() wcputsec(buf,sectnum,cseclen) wcs(oname) wcsend() wctx(flen) wctxpn(name) xbuf_build(buf,count) xsendline(ch) zbuf_build(buf,count) zsendfdata() zsendfile(buf,blen)--------------------------------------------------------------------------*//*+:EDITS:*//*:09-10-1992-14:00-wht@n4hgf-ECU release 3.20 *//*:09-05-1992-14:26-wht@n4hgf-zrpos_seen was not set 1 on first ZRPOS *//*:08-22-1992-15:39-wht@n4hgf-ECU release 3.20 BETA *//*:08-16-1992-03:08-wht@n4hgf-head off another POSIX plot *//*:08-10-1992-04:01-wht@n4hgf-use init_Nap *//*:07-20-1992-13:39-wht@n4hgf-need hzmsec for nap.c *//*:09-01-1991-14:18-wht@n4hgf2-improve sun flushline *//*:08-29-1991-02:17-wht@n4hgf2-flush "rz" to line before nap *//*:08-28-1991-14:08-wht@n4hgf2-SVR4 cleanup by aega84!lh *//*:07-25-1991-12:59-wht@n4hgf-ECU release 3.10 *//*:02-03-1991-17:27-wht@n4hgf-version number change - see zcurses.c *//*:12-18-1990-21:26-wht@n4hgf-better output control *//*:09-19-1990-19:36-wht@n4hgf-ecu_log_event now gets pid for log from caller *//*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history *//* Error return conditions 255: usage 254: protocol failed (bad line conditions,brain dead remote) 253: curses problem 253: could not open any files 128-192: process terminated with signal==code-128 (64 signals allowed for) signal 0 == program logic error (see cancel_transaction) 127: 127 or more files not transmitted (see ~/.ecu/log) 1-126: count of files not transmitted (see ~/.ecu/log) 0: file transfer completely successful*/char *substr();char *getenv();#include <stdio.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <string.h>#include <fcntl.h>#include "zmodem.h"#include <sys/param.h>extern char *sys_errlist[];extern unsigned short crctab[]; /* wht */extern unsigned long total_data_bytes_xfered; /* zcurses.c */extern int errno;extern int show_window;extern int Rxtimeout; /* Tenths of seconds to wait for something */extern char Rxhdr[4]; /* Received header */extern char Txhdr[4]; /* Transmitted header */extern int Txfcs32; /* TURE means send binary frames with 32 bit FCS */extern long Rxpos; /* Received file position */extern long Txpos; /* Transmitted file position */extern char *frametypes[];extern char Attn[]; /* Attention string rx sends to tx on err */extern char s128[128];#define RETRYMAX 10 /* non-zmodem retry count on block send */#define VMIN_COUNT 2 /* must not exceed 255 */unsigned char vmin_count = VMIN_COUNT;int iofd = 0; /* line io fd */#ifdef BUFFERED_WRITEFILE *iofp;#endif/* * Attention string to be executed by receiver to interrupt streaming data * when an error is detected. A pause (0336) may be needed before the * ^C (03) or after it. */#if defined(READCHECK)char Myattn[] = { 0 };#elsechar Myattn[] = { 03,0336,0 };#endifFILE *in;char *Cmdstr; /* Pointer to the command string */char *bottom_label = (char *)0;char Crcflg;char Lastrx;char Lzconv; /* Local ZMODEM file conversion request */char Lzmanag; /* Local ZMODEM file management request */char Lztrans;char Pathname[PATHLEN];char curr_dir[256];char txbuf[1024];char zconv; /* ZMODEM file conversion request */char zmanag; /* ZMODEM file management request */char ztrans; /* ZMODEM file transport request */int Ascii; /* Add CR's for brain damaged programs */int Cmdack1; /* Rx ACKs command,then do it */int Cmdtries = 11;int Command; /* Send a command,then exit. */int Dontread; /* Don't read the buffer,it's still there */int Dottoslash; /* Change foo.bar.baz to foo/bar/baz */int Exitcode;int Filcnt; /* count of number of files opened */int FilesTotal;int Filesleft;int Fullname; /* transmit full pathname */int Lastn; /* Count of last buffer read or -1 */int Lfseen;int Noeofseen;int Nozmodem;int Optiong; /* no wait for block ACK's */int Quiet; /* overrides logic that would otherwise set verbose */int Rxflags;int SameZrposAgain; /* How many times we've been ZRPOS'd same place (wht) */int Tframlen; /* Override for tx frame length */int Totsecs; /* total number of blocks this file */int Twostop; /* use two stop bits */int Unlinkafter; /* Unlink file after it is sent */int Wantfcs32 = TRUE; /* want to send 32 bit FCS */int Xmodem; /* XMODEM Protocol - don't send pathnames */int Zctlesc; /* Encode control characters */int Zmodem; /* ZMODEM protocol requested by receiver */int Zrwindow = 1400; /* RX window size (controls garbage count) */int blklen=128; /* length of transmitted records */int blklen_original;int blkopt; /* Override value for zmodem blklen */int ecusz_flag = 1;int force_dumbtty;int got_xfer_type;int seen_zrpos;int skip_count; /* skipped files */int errors;int firstsec;int log_packets;int no_files;int npats;long Lastread; /* Beginning offset of last buffer read */long Lastsync; /* Last offset to which we got a ZRPOS */long Lrxpos; /* Receiver's last reported offset */long TotalLeft;long TotalToSend;long bytcnt;long rx_char_count;long this_file_length;long tx_char_count;long initial_filepos; /* initial file position */unsigned Baudrate;unsigned Rxbuflen = 16384; /* Receiver's max buffer length */unsigned Txwcnt; /* Counter used to space ack requests */unsigned Txwindow; /* Control the size of the transmitted window */unsigned Txwspac; /* Spacing between zcrcq requests */unsigned int bad_condx_blklen; /* if <>0,blklen has been reduced (wht) */unsigned int bad_condx_frame_count; /* frame # last SameZrposAgain (wht) */unsigned int this_file_frame_count; /* count of frames sent this file (wht) */#define MAX_PATHS 512char *paths[MAX_PATHS];jmp_buf tohere; /* For the interrupt on RX timeout */jmp_buf intrjmp; /* For the interrupt on RX CAN */int file_list_pathc;int file_list_path_current;char **file_list_pathv;FILE *fpflst = (FILE *)0;void send_cancel();void purgeline();void usage();void saybibi();void determine_transaction_time();void sendline();void xsendline();/*+------------------------------------------------------------------------- log_packet_buffer(buf,len)--------------------------------------------------------------------------*/voidlog_packet_buffer(buf,len)register unsigned char *buf;register int len;{ char xbuf[32]; while(len--) { sprintf(xbuf,"%02x ",*buf++); write(log_packets,xbuf,strlen(xbuf)); } write(log_packets,"\n",1);} /* end of log_packet_buffer *//*+------------------------------------------------------------------------- rewind_file_list()--------------------------------------------------------------------------*/voidrewind_file_list(){ file_list_path_current = 0; if(fpflst) { fclose(fpflst); fpflst = (FILE *)0; }} /* end of rewind_file_list *//*+------------------------------------------------------------------------- set_file_list(pathc,pathv)--------------------------------------------------------------------------*/voidset_file_list(pathc,pathv)int pathc;char **pathv;{ file_list_pathc = pathc; file_list_pathv = pathv; rewind_file_list();} /* end of set_file_list *//*+------------------------------------------------------------------------- get_file_list_name(namep)return 1 if @lst found else 0--------------------------------------------------------------------------*/intget_file_list_name(namep)char **namep;{ register char *cptr; static char name[256];try_fpflst: if(fpflst) { if(fgets(name,sizeof(name),fpflst) != NULL) { name[strlen(name) - 1] = 0; *namep = name; return(1); } fclose(fpflst); fpflst = (FILE *)0; }next_arg: if(file_list_path_current == file_list_pathc) return(0); cptr = file_list_pathv[file_list_path_current++]; if(*cptr != '@') { *namep = cptr; return(1); } cptr++; if((fpflst = fopen(cptr,"r")) == NULL) goto next_arg; goto try_fpflst;} /* end of get_file_list_name *//*+------------------------------------------------------------------------- bye_bye(sig)--------------------------------------------------------------------------*/voidbye_bye(sig)int sig;{ exit(sig+128);} /* end of bye_bye *//*+------------------------------------------------------------------------- cancel_transaction(sig)called by signal interrupt or terminate to clean things up--------------------------------------------------------------------------*/voidcancel_transaction(sig)int sig;{ if(Zmodem) zmputs(Attn); send_cancel(1); mode(0); if(sig >= 0) { sprintf(s128,"ecusz aborted (signal %d)",sig); report_str(s128,0); } report_tx_ind(0); report_rx_ind(0); report_uninit(0); bye_bye(sig);} /* end of cancel_transaction *//*+------------------------------------------------------------------------- onintr() - Called when ZMODEM gets an interrupt (^X)--------------------------------------------------------------------------*/onintr(){ signal(SIGINT,SIG_IGN); report_rx_ind(0); report_tx_ind(0); longjmp(intrjmp,-1);} /* end of onintr *//*+------------------------------------------------------------------------- report_send_transaction()--------------------------------------------------------------------------*/voidreport_send_transaction(){ if(Xmodem) { long blocks = (TotalToSend >> 7) + ((TotalToSend % 128) != 0); long secs = 7 /* slightly worse than average first nak delay */ + (blocks / 5L) /* assume .2 sec ack time */ + ((blocks * (128L + 16L)) / (Baudrate / 10)); if(!secs) secs = 10L; sprintf(s128,"Sending %ld blocks time ~= %ld:%02ld", blocks,secs/60,secs % 60); } else { long min_100 = (FilesTotal * 2L) + (((TotalToSend * 11L)) * 10L) / (Baudrate * 6L); if(!min_100) min_100 = 4L;#if defined(M_I286) /* slower */ else if(Baudrate > 4800) { min_100 *= 13; min_100 /= 9; /* yech ... empirical */ }#endif sprintf(s128, "Total transaction %ld bytes (xfer time ~= %2lu:%02lu)", TotalToSend,min_100 / 100,((min_100 % 100) * 60L) / 100L); } report_transaction(s128);} /* end of report_send_transaction *//*+------------------------------------------------------------------------- report_send_progress(filepos)--------------------------------------------------------------------------*/voidreport_send_progress(filepos)long filepos;{ if(Xmodem) { sprintf(s128,"File %d%% complete", (this_file_length == 0) ? (int)100 : (int)((filepos * 100L) / this_file_length)); } else { sprintf(s128,"This file %d%%, transaction %d%% complete", (this_file_length == 0) ? (int)100 : (int)((filepos * 100L)/this_file_length), (TotalToSend == 0) ? (int)100 : (int)(((total_data_bytes_xfered + filepos) * 100L) / TotalToSend)); } report_str(s128,0); report_txpos(filepos);} /* end of report_send_progress *//*+------------------------------------------------------------------------- report_rcvr_cancelled(place_happened)--------------------------------------------------------------------------*/voidreport_rcvr_cancelled(place_happened)char *place_happened;{ strcpy(s128,"SEND CANCELLED"); report_str(s128 + 5,1);#if defined(LOG_XFER) strcat(s128," ("); strcat(s128,place_happened); strcat(s128,")"); ecu_log_event(getppid(),s128);#endif skip_count++; report_error_count();} /* end of report_rcvr_cancelled *//*+------------------------------------------------------------------------- report_rcvr_skipped()--------------------------------------------------------------------------*/voidreport_rcvr_skipped(){ sprintf(s128,"SEND skipped: %s",Pathname); report_str(s128 + 5,-1);#if defined(LOG_SKIP) ecu_log_event(getppid(),s128);#endif skip_count++; report_error_count(); TotalToSend -= this_file_length; report_send_transaction();} /* end of report_rcvr_skipped *//*+------------------------------------------------------------------------- xsendline(ch)--------------------------------------------------------------------------*/voidxsendline(ch)char ch;{#ifdef BUFFERED_WRITE fputc(ch,iofp);#else write(iofd,&ch,1);#endif ++tx_char_count;} /* end of xsendline *//*+------------------------------------------------------------------------- sendline(ch)--------------------------------------------------------------------------*/voidsendline(ch)char ch;{ xsendline(ch);} /* end of sendline *//*+------------------------------------------------------------------------- flushline() - ensure all queued data to line is on the wire--------------------------------------------------------------------------*/voidflushline(){#if defined(sun)int retries = 50;int outq_count;int old_outq_count = 0;#elsestruct termio tio;#endif#ifdef BUFFERED_WRITE fflush(iofp);#endif#if defined(sun) do { ioctl(iofd,TIOCOUTQ,&outq_count); if(!outq_count) break; if(old_outq_count == outq_count) /* don't hang if flow control lock */ retries--; old_outq_count = outq_count; Nap(50); } while(outq_count && retries);#else ioctl(iofd,TCGETA,(char *)&tio); ioctl(iofd,TCSETAW,(char *)&tio);#endif} /* end of flushline *//*+------------------------------------------------------------------------- main(argc,argv)--------------------------------------------------------------------------*/main(argc,argv)int argc;char **argv;{register char *cp;char **patts = paths;char **gargv = argv;int gargc = argc; signal(SIGINT,bye_bye); signal(SIGTERM,bye_bye);#if defined(SIGSTOP) /* * call Roto-Rooter on POSIX plots */ signal(SIGSTOP,SIG_IGN); signal(SIGTSTP,SIG_IGN); signal(SIGCONT,SIG_IGN); signal(SIGTTIN,SIG_IGN); signal(SIGTTOU,SIG_IGN);#endif get_curr_dir(curr_dir,sizeof(curr_dir)); Rxtimeout = 600; npats=0; if(argc<2) usage(); while(--argc) { cp = *++argv; if(*cp == '-') { cp++; switch(*cp++) { case 'X': got_xfer_type = 1; Xmodem = TRUE; break; case 'Y': got_xfer_type = 1; Nozmodem = TRUE; blklen=1024; break; case 'Z': show_window = 1; got_xfer_type = 1; break; case '+': Lzmanag = ZMAPND; break; case 'a': Lzconv = ZCNL; Ascii = TRUE; break; case 'b': Lzconv = ZCBIN; break; case 'd': ++Dottoslash; /* **** FALL THROUGH TO **** */ case 'f': Fullname=TRUE; break; case ',': log_packets = 1; break; case '@': force_dumbtty = 1; break; case '/': if(--argc < 1) usage(); strcpy(curr_dir,*++argv); break; case '.': if(--argc < 1) usage(); iofd = atoi(*++argv); break; case 'C': if(--argc < 1) usage("no label after -C"); bottom_label = *++argv; break; case 'e': Zctlesc = 1; break; case 'k': blklen=1024; break; case 'L': if(--argc < 1) { usage(); } blkopt = atoi(*++argv); if(blkopt<24 || blkopt>1024) usage(); break; case 'l': if(--argc < 1) { usage(); } Tframlen = atoi(*++argv); if(Tframlen<32 || Tframlen>1024) usage(); break; case 'N': Lzmanag = ZMNEWL; break; case 'n': Lzmanag = ZMNEW; break; case 'o': Wantfcs32 = FALSE; break; case 'p': Lzmanag = ZMPROT; break; case 'r': Lzconv = ZCRESUM; break; case 't': if(--argc < 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -