📄 ecusz.c
字号:
{ usage(); } Rxtimeout = atoi(*++argv); if(Rxtimeout<10 || Rxtimeout>1000) usage(); break; case 'u': ++Unlinkafter; break; case 'w': if(--argc < 1) { usage(); } Txwindow = atoi(*++argv); if(Txwindow < 256) Txwindow = 256; Txwindow = (Txwindow/64) * 64; Txwspac = Txwindow/4; if(blkopt > Txwspac || (!blkopt && Txwspac < 1024)) blkopt = Txwspac; break; case 'y': Lzmanag = ZMCLOB; break; default: usage(); } } else if(argc > 0) { if(npats < MAX_PATHS) { npats++; *patts++ = cp; } else { printf("too many filenames to send\n"); exit(255); } } } if(!got_xfer_type || !iofd) { printf("can only be run by ecu\n"); exit(255); } if(determine_output_mode()) { setbuf(stdout,NULL); setbuf(stderr,NULL); } if(npats < 1 && !Command) usage(); set_file_list(npats,paths); sprintf(s128,"%s",numeric_revision + 4); if(log_packets) { char log_packets_name[64]; FILE *ftmp; int iargv; sprintf(log_packets_name,"/tmp/sz%05d.plog",getpid()); unlink(log_packets_name); ftmp = fopen(log_packets_name,"w"); fclose(ftmp); log_packets = open(log_packets_name,O_WRONLY,0644); if(log_packets < 0) log_packets = 0; else { write(log_packets,"exec: ",6); for(iargv = 0; iargv < gargc; iargv++) { write(log_packets,gargv[iargv],strlen(gargv[iargv])); write(log_packets," ",1); } write(log_packets,"\n",1); } } /* * learn tick rate for various timers */ init_Nap(); report_init(s128); mode(1); if(signal(SIGINT,cancel_transaction) == SIG_IGN) signal(SIGINT,SIG_IGN); else signal(SIGINT,cancel_transaction); signal(SIGTERM,cancel_transaction); report_str("calculating transaction time",-1); determine_transaction_time();#ifdef BUFFERED_WRITE iofp = fdopen(iofd,"w");#endif if(!Xmodem) { TotalToSend = TotalLeft; report_send_transaction(); report_str("starting remote receiver",-1); report_last_txhdr("begin transfer",0); if(!Nozmodem) write(iofd,"rz\r",3); else /* wht -- why not? */ write(iofd,"rb\r",3); /* wht */ flushline(); Nap(750L); report_str("",-1); if(!Nozmodem) { stohdr(0L); zshhdr(ZRQINIT,Txhdr); } } else { report_str("",-1); report_last_txhdr("begin transfer",0); } if(wcsend()==ERROR) { Exitcode=254; /*wht was 0200 */ send_cancel(1); } mode(0); report_uninit(0); if(no_files) Exitcode = 253; exit(Exitcode ? Exitcode : (skip_count > 127) ? 127 : skip_count); /*NOTREACHED*/} /* end of main *//*+------------------------------------------------------------------------- wcsend(argc,argp) -- send group of files--------------------------------------------------------------------------*/intwcsend(){ char *name; Crcflg=FALSE; firstsec=TRUE; bytcnt = -1; rewind_file_list(); while(get_file_list_name(&name)) { Totsecs = 0; if(wcs(name)==ERROR) return(ERROR); } Totsecs = 0; if(Filcnt==0) { /* bitch if we couldn't open ANY files */ send_cancel(1); strcpy(s128,"SEND cannot open any requested files"); report_str(s128 + 5,1);#if defined(LOG_XFER) ecu_log_event(getppid(),s128);#endif sleep(2); /* allow time for other rz to get ready */ no_files = 1; return(ERROR); /* ... then cancel */ } if(Zmodem) saybibi(); else if(!Xmodem) wctxpn(""); return(OK);}/*+------------------------------------------------------------------------- wcs(oname) -- send a file--------------------------------------------------------------------------*/intwcs(oname)char *oname;{register c;struct stat f; strcpy(Pathname,oname); /* global copy of name */ if((in=fopen(oname,"r"))==NULL) { sprintf(s128,"SEND %s: %s",sys_errlist[errno],oname);#if defined(LOG_XFER) ecu_log_event(getppid(),s128);#endif report_str(s128 + 5,1); skip_count++; report_error_count(); return(OK); /* pass over it,there may be others */ } seen_zrpos = 0; ++Noeofseen; Lastread = 0; Lastn = -1; Dontread = FALSE; /* Check for directory or block special files */ fstat(fileno(in),&f); c = f.st_mode & S_IFMT; if(c == S_IFDIR || c == S_IFBLK) { sprintf(s128,"SEND %s: %s", (c == S_IFDIR) ? "directory" : "block device",oname); report_str(s128 + 5,1);#if defined(LOG_SKIP) ecu_log_event(getppid(),s128);#endif skip_count++; report_error_count(); fclose(in); return(OK); } f.st_mode &= ~(S_ISUID | S_ISGID); Filcnt++; report_file_send_open(oname,&f); this_file_length = f.st_size; report_send_progress(0L); switch(wctxpn(Pathname)) { case ERROR: sprintf(s128,"SEND protocol failure: %s",oname); report_str(s128 + 5,1);#if defined(LOG_XFER) ecu_log_event(getppid(),s128);#endif skip_count++; report_error_count(); report_file_close(2); fclose(in); return(ERROR); case ZSKIP: report_rcvr_skipped(); return(OK); } if(!Zmodem && wctx(f.st_size)==ERROR) return(ERROR); if(Unlinkafter) unlink(oname); return(0);}/*+------------------------------------------------------------------------- wctxpn(name)generate and transmit pathname block consisting of pathname (nullterminated), file length,mode time and file mode in octal asprovided by the Unix fstat call. N.B.: modifies the passedname,may extend it!--------------------------------------------------------------------------*/intwctxpn(name)char *name;{ register char *p,*q; char name2[PATHLEN]; struct stat f; if(Xmodem) { if((in!=stdin) && *name && fstat(fileno(in),&f)!= -1) { TotalToSend = f.st_size; report_protocol_type("XMODEM"); report_send_transaction(); report_xfer_mode((Ascii) ? "ASCII" : "BINARY"); report_last_txhdr("Waiting on NAK",0); } return(OK); } if(!Zmodem) { report_last_txhdr("START PENDING",0); if(getnak()) { report_str("Timeout on pathname nak",1); return(ERROR); } } q = (char *) 0; if(Dottoslash) { /* change . to . */ for(p=name; *p; ++p) { if(*p == '/') q = p; else if(*p == '.') *(q=p) = '/'; } if(q && strlen(++q) > (unsigned)8) { /* If name>8 chars */ q += 8; /* make it .ext */ strcpy(name2,q); /* save excess of name */ *q = '.'; strcpy(++q,name2); /* add it back */ } } for(p=name,q=txbuf ; *p; ) if((*q++ = *p++) == '/' && !Fullname) q = txbuf; *q++ = 0; p=q; while(q < (txbuf + 1024)) *q++ = 0; if(!Ascii && (in != stdin) && *name && !fstat(fileno(in),&f)) sprintf(p,"%lu %lo %o 0 %d %ld",f.st_size,f.st_mtime, f.st_mode &= ~(S_ISUID | S_ISGID), Filesleft,TotalLeft); report_xfer_mode((Lzconv == ZCNL) ? "ASCII" : "BINARY"); TotalLeft -= f.st_size; if(--Filesleft <= 0) TotalLeft = 0; if(TotalLeft < 0) TotalLeft = 0; /* force 1k blocks if name won't fit in 128 byte block */ if(txbuf[125]) blklen=1024; else { /* A little goodie for IMP/KMD */ txbuf[127] = (f.st_size + 127) >>7; txbuf[126] = (f.st_size + 127) >>15; } if(Zmodem) return(zsendfile(txbuf,1+strlen(p)+(p-txbuf))); report_protocol_type("YMODEM"); if(wcputsec(txbuf,0,128)==ERROR) return(ERROR); return(OK);} /* end of wctxpn *//*+------------------------------------------------------------------------- getnak()--------------------------------------------------------------------------*/intgetnak(){ register firstch; Lastrx = 0; for(;;) { switch(firstch = readock(50,1)) { case ZPAD: if(getzrxinit()) return(ERROR); Ascii = 0; /* Receiver does the conversion */ return(FALSE); case TIMEOUT: report_str("Timeout",1); return(TRUE); case WANTG:#if defined(MODE2OK) mode(2); /* Set cbreak,XON/XOFF,etc. */#endif Optiong = TRUE; blklen=1024; case WANTCRC: Crcflg = TRUE; case NAK: return(FALSE); case CAN: if((firstch = readock(20,1)) == CAN && Lastrx == CAN) return(TRUE); default: break; } Lastrx = firstch; } /*NOTREACHED*/} /* end of getnak *//*+------------------------------------------------------------------------- wctx(flen)--------------------------------------------------------------------------*/wctx(flen)long flen;{ register int thisblklen; register int firstch; register int sectnum; register int attempts; long charssent; charssent = 0; firstsec=TRUE; thisblklen = blklen; report_txblklen(blklen); attempts = 8; while(((firstch = readock(Rxtimeout,2)) != NAK) && (firstch != WANTCRC) && (firstch != WANTG) && (firstch != TIMEOUT) && (firstch != CAN)) { if(!--attempts) { report_str("bad start stimulus",1); send_cancel(1); return(ERROR); } } if(firstch==CAN) { report_str("receiver CAN",1); return(ERROR); } if((firstch==WANTCRC) || (firstch==WANTG)) Crcflg=TRUE; report_protocol_crc_type((Crcflg) ? ((firstch== WANTG) ? "/CRC-g" : "/CRC") : "/CHK"); sectnum=0; for(;;) { if(flen <= (charssent + 896L)) { thisblklen = 128; report_txblklen(thisblklen); } if(!xbuf_build(txbuf,thisblklen)) break; if(wcputsec(txbuf,++sectnum,thisblklen)==ERROR) return(ERROR); charssent += thisblklen; } /* file transfer completed */ report_file_byte_io(this_file_length - initial_filepos); report_file_close(0); fclose(in);#if defined(LOG_XFER) sprintf(s128,"SEND success: %s",Pathname); ecu_log_event(getppid(),s128);#endif attempts=0; do { purgeline(); sendline(EOT); flushline(); report_last_txhdr("EOT",0); ++attempts; } while((firstch=(readock(Rxtimeout,1)) != ACK) && attempts < RETRYMAX); if(attempts == RETRYMAX) { report_str("No ACK on EOT",1); return(ERROR); } else return(OK);}/*+------------------------------------------------------------------------- wcputsec(buf,sectnum,cseclen)--------------------------------------------------------------------------*/intwcputsec(buf,sectnum,cseclen)unsigned char *buf;int sectnum;int cseclen; /* data length of this block to send */{ register int checksum; register int wcj; register unsigned char *cp; unsigned short oldcrc; int firstch; int attempts; firstch=0; /* part of logic to detect CAN CAN */ sprintf(s128,"Sending block %d",sectnum); report_last_txhdr(s128,0); if(log_packets) { log_packet_buffer(buf,cseclen); } for(attempts=0; attempts <= RETRYMAX; attempts++) { Lastrx= firstch; sendline(cseclen == 1024 ? STX : SOH); sendline(sectnum); sendline(-sectnum - 1); oldcrc=checksum=0; for(wcj = cseclen,cp = buf; --wcj >= 0; ) { sendline(*cp); oldcrc=updcrc(*cp,oldcrc); checksum += *cp++; } if(Crcflg) { oldcrc=updcrc(0,updcrc(0,oldcrc)); sendline((int)(oldcrc >> 8)); sendline((int)(oldcrc & 0xFF)); } else sendline(checksum); flushline(); if(Optiong) { firstsec = FALSE; return(OK); } firstch = readock(Rxtimeout,(Noeofseen&§num) ? 2:1);gotnak: switch(firstch) { case CAN: if(Lastrx == CAN) {cancan: report_last_rxhdr("CAN",1); return(ERROR); } break; case TIMEOUT: report_last_rxhdr("Timeout",1); continue; case WANTCRC: if(firstsec) Crcflg = TRUE; case NAK: report_last_rxhdr("NAK",1); continue; case ACK: report_last_rxhdr("ACK",0); firstsec=FALSE; Totsecs += (cseclen>>7); return(OK); case ERROR: report_last_rxhdr("Noise",0); break; default: sprintf(s128,"0x%02x ???",firstch); report_last_rxhdr(s128,1); break; } for(;;) { Lastrx = firstch; if((firstch = readock(Rxtimeout,2)) == TIMEOUT) break; if(firstch == NAK || firstch == WANTCRC) goto gotnak; if(firstch == CAN && Lastrx == CAN) goto cancan; } } report_str("retry count exceeded",1); return(ERROR);} /* end of wcputsec *//*+------------------------------------------------------------------------- xbuf_build(buf,count) fill buf with count chars padding with ^Z for CPM and DOS--------------------------------------------------------------------------*/xbuf_build(buf,count)register char *buf;int count;{ register c,m; long lseek(); long X_txpos = lseek(fileno(in),0L,1); char diag_str[64]; report_send_progress(X_txpos); if( !Ascii) { m = read(fileno(in),buf,count); if(log_packets) { sprintf(diag_str,"read rtnd %d of %d",m,count); report_str(diag_str,1); } if(m <= 0) return(0); while(m < count) buf[m++] = 032; return(count); } m=count; if(Lfseen) { *buf++ = 012; --m; Lfseen = 0; } while((c=fgetc(in))!=EOF) { if(c == 012) { *buf++ = 015; if(--m == 0) { Lfseen = TRUE; break; } } *buf++ =c; if(--m == 0) break; } if(m==count) return(0); else while(--m>=0) *buf++ = CPMEOF; return(count);} /* end of xbuf_build *//*+------------------------------------------------------------------------- zbuf_build(buf,count) - fill buf with count chars --------------------------------------------------------------------------*/intzbuf_build(buf,count)register char *buf;int count;{ register c,m; m=count; while((c=fgetc(in))!=EOF) { *buf++ =c; if(--m == 0) break; } return(count - m);} /* end of zbuf_build *//*+------------------------------------------------------------------------- SIGALRM_handler(sig)--------------------------------------------------------------------------*/SIGTYPESIGALRM_handler(sig)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -