📄 lsz.c
字号:
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_requested) return zsendfile(zi,txbuf, 1+strlen(p)+(p-txbuf)); if (wcputsec(txbuf, 0, 128)==ERROR) { vfile("wcputsec failed"); DO_SYSLOG((LOG_INFO, "%s/%s: wcputsec failed", shortname,protname())); return ERROR; } return OK;}static int getnak(void){ int firstch; int tries=0; Lastrx = 0; for (;;) { tries++; switch (firstch = READLINE_PF(100)) { case ZPAD: if (getzrxinit()) return ERROR; Ascii = 0; /* Receiver does the conversion */ return FALSE; case TIMEOUT: /* 30 seconds are enough */ if (tries==3) { zperr(_("Timeout on pathname")); return TRUE; } /* don't send a second ZRQINIT _directly_ after the * first one. Never send more then 4 ZRQINIT, because * omen rz stops if it saw 5 of them */ if ((zrqinits_sent>1 || tries>1) && zrqinits_sent<4) { /* if we already sent a ZRQINIT we are using zmodem * protocol and may send further ZRQINITs */ stohdr(0L); zshhdr(ZRQINIT, Txhdr); zrqinits_sent++; } continue; case WANTG: io_mode(io_mode_fd,2); /* Set cbreak, XON/XOFF, etc. */ Optiong = TRUE; blklen=1024; case WANTCRC: Crcflg = TRUE; case NAK: return FALSE; case CAN: if ((firstch = READLINE_PF(20)) == CAN && Lastrx == CAN) return TRUE; default: break; } Lastrx = firstch; }}static int wctx(struct zm_fileinfo *zi){ register size_t thisblklen; register int sectnum, attempts, firstch; firstsec=TRUE; thisblklen = blklen; vfile("wctx:file length=%ld", (long) zi->bytes_total); while ((firstch=READLINE_PF(Rxtimeout))!=NAK && firstch != WANTCRC && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN) ; if (firstch==CAN) { zperr(_("Receiver Cancelled")); return ERROR; } if (firstch==WANTCRC) Crcflg=TRUE; if (firstch==WANTG) Crcflg=TRUE; sectnum=0; for (;;) { if (zi->bytes_total <= (zi->bytes_sent + 896L)) thisblklen = 128; if ( !filbuf(txbuf, thisblklen)) break; if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR) return ERROR; zi->bytes_sent += thisblklen; } fclose(input_f); attempts=0; do { purgeline(io_mode_fd); sendline(EOT); flushmo(); ++attempts; } while ((firstch=(READLINE_PF(Rxtimeout)) != ACK) && attempts < RETRYMAX); if (attempts == RETRYMAX) { zperr(_("No ACK on EOT")); return ERROR; } else return OK;}static int wcputsec(char *buf, int sectnum, size_t cseclen){ int checksum, wcj; char *cp; unsigned oldcrc; int firstch; int attempts; firstch=0; /* part of logic to detect CAN CAN */ if (Verbose>1) { vchar('\r'); if (protocol==ZM_XMODEM) { vstringf(_("Xmodem sectors/kbytes sent: %3d/%2dk"), Totsecs, Totsecs/8 ); } else { vstringf(_("Ymodem sectors/kbytes sent: %3d/%2dk"), Totsecs, Totsecs/8 ); } } 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((0377& *cp), oldcrc); checksum += *cp++; } if (Crcflg) { oldcrc=updcrc(0,updcrc(0,oldcrc)); sendline((int)oldcrc>>8); sendline((int)oldcrc); } else sendline(checksum); flushmo(); if (Optiong) { firstsec = FALSE; return OK; } firstch = READLINE_PF(Rxtimeout);gotnak: switch (firstch) { case CAN: if(Lastrx == CAN) {cancan: zperr(_("Cancelled")); return ERROR; } break; case TIMEOUT: zperr(_("Timeout on sector ACK")); continue; case WANTCRC: if (firstsec) Crcflg = TRUE; case NAK: zperr(_("NAK on sector")); continue; case ACK: firstsec=FALSE; Totsecs += (cseclen>>7); return OK; case ERROR: zperr(_("Got burst for sector ACK")); break; default: zperr(_("Got %02x for sector ACK"), firstch); break; } for (;;) { Lastrx = firstch; if ((firstch = READLINE_PF(Rxtimeout)) == TIMEOUT) break; if (firstch == NAK || firstch == WANTCRC) goto gotnak; if (firstch == CAN && Lastrx == CAN) goto cancan; } } zperr(_("Retry Count Exceeded")); return ERROR;}/* fill buf with count chars padding with ^Z for CPM */static size_t filbuf(char *buf, size_t count){ int c; size_t m; if ( !Ascii) { m = read(fileno(input_f), buf, count); if (m <= 0) return 0; while (m < count) buf[m++] = 032; return count; } m=count; if (Lfseen) { *buf++ = 012; --m; Lfseen = 0; } while ((c=getc(input_f))!=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;}/* Fill buffer with blklen chars */static size_tzfilbuf (struct zm_fileinfo *zi){ size_t n; n = fread (txbuf, 1, blklen, input_f); if (n < blklen) zi->eof_seen = 1; else { /* save one empty paket in case file ends ob blklen boundary */ int c = getc(input_f); if (c != EOF || !feof(input_f)) ungetc(c, input_f); else zi->eof_seen = 1; } return n;}static voidusage1 (int exitcode){ usage (exitcode, NULL);}static voidusage(int exitcode, const char *what){ FILE *f=stdout; if (exitcode) { if (what) fprintf(stderr, "%s: %s\n",program_name,what); fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); exit(exitcode); } fprintf(f, _("%s version %s\n"), program_name, VERSION); fprintf(f,_("Usage: %s [options] file ...\n"), program_name); fprintf(f,_(" or: %s [options] -{c|i} COMMAND\n"),program_name); fputs(_("Send file(s) with ZMODEM/YMODEM/XMODEM protocol\n"),f); fputs(_( " (X) = option applies to XMODEM only\n" " (Y) = option applies to YMODEM only\n" " (Z) = option applies to ZMODEM only\n" ),f); /* splitted into two halves for really bad compilers */ fputs(_(" -+, --append append to existing destination file (Z)\n"" -2, --twostop use 2 stop bits\n"" -4, --try-4k go up to 4K blocksize\n"" --start-4k start with 4K blocksize (doesn't try 8)\n"" -8, --try-8k go up to 8K blocksize\n"" --start-8k start with 8K blocksize\n"" -a, --ascii ASCII transfer (change CR/LF to LF)\n"" -b, --binary binary transfer\n"" -B, --bufsize N buffer N bytes (N==auto: buffer whole file)\n"" -c, --command COMMAND execute remote command COMMAND (Z)\n"" -C, --command-tries N try N times to execute a command (Z)\n"" -d, --dot-to-slash change '.' to '/' in pathnames (Y/Z)\n"" --delay-startup N sleep N seconds before doing anything\n"" -e, --escape escape all control characters (Z)\n"" -E, --rename force receiver to rename files it already has\n"" -f, --full-path send full pathname (Y/Z)\n"" -i, --immediate-command CMD send remote CMD, return immediately (Z)\n"" -h, --help print this usage message\n"" -k, --1k send 1024 byte packets (X)\n"" -L, --packetlen N limit subpacket length to N bytes (Z)\n"" -l, --framelen N limit frame length to N bytes (l>=L) (Z)\n"" -m, --min-bps N stop transmission if BPS below N\n"" -M, --min-bps-time N for at least N seconds (default: 120)\n" ),f); fputs(_(" -n, --newer send file if source newer (Z)\n"" -N, --newer-or-longer send file if source newer or longer (Z)\n"" -o, --16-bit-crc use 16 bit CRC instead of 32 bit CRC (Z)\n"" -O, --disable-timeouts disable timeout code, wait forever\n"" -p, --protect protect existing destination file (Z)\n"" -r, --resume resume interrupted file transfer (Z)\n"" -R, --restricted restricted, more secure mode\n"" -q, --quiet quiet (no progress reports)\n"" -s, --stop-at {HH:MM|+N} stop transmission at HH:MM or in N seconds\n"" --tcp build a TCP connection to transmit files\n"" --tcp-server open socket, wait for connection\n"" -u, --unlink unlink file after transmission\n"" -U, --unrestrict turn off restricted mode (if allowed to)\n"" -v, --verbose be verbose, provide debugging information\n"" -w, --windowsize N Window is N bytes (Z)\n"" -X, --xmodem use XMODEM protocol\n"" -y, --overwrite overwrite existing files\n"" -Y, --overwrite-or-skip overwrite existing files, else skip\n"" --ymodem use YMODEM protocol\n"" -Z, --zmodem use ZMODEM protocol\n""\n""short options use the same arguments as the long ones\n" ),f); exit(exitcode);}/* * Get the receiver's init parameters */static int getzrxinit(void){ static int dont_send_zrqinit=1; int old_timeout=Rxtimeout; int n; struct stat f; size_t rxpos; int timeouts=0; Rxtimeout=100; /* 10 seconds */ /* XXX purgeline(io_mode_fd); this makes _real_ trouble. why? -- uwe */ for (n=10; --n>=0; ) { /* we might need to send another zrqinit in case the first is * lost. But *not* if getting here for the first time - in * this case we might just get a ZRINIT for our first ZRQINIT. * Never send more then 4 ZRQINIT, because * omen rz stops if it saw 5 of them. */ if (zrqinits_sent<4 && n!=10 && !dont_send_zrqinit) { zrqinits_sent++; stohdr(0L); zshhdr(ZRQINIT, Txhdr); } dont_send_zrqinit=0; switch (zgethdr(Rxhdr, 1,&rxpos)) { case ZCHALLENGE: /* Echo receiver's challenge numbr */ stohdr(rxpos); zshhdr(ZACK, Txhdr); continue; case ZCOMMAND: /* They didn't see our ZRQINIT */ /* ??? Since when does a receiver send ZCOMMAND? -- uwe */ continue; case ZRINIT: Rxflags = 0377 & Rxhdr[ZF0]; Rxflags2 = 0377 & Rxhdr[ZF1]; Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32)); { int old=Zctlesc; Zctlesc |= Rxflags & TESCCTL; /* update table - was initialised to not escape */ if (Zctlesc && !old) zsendline_init(); } Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8); if ( !(Rxflags & CANFDX)) Txwindow = 0; vfile("Rxbuflen=%d Tframlen=%d", Rxbuflen, Tframlen); if ( play_with_sigint) signal(SIGINT, SIG_IGN); io_mode(io_mode_fd,2); /* Set cbreak, XON/XOFF, etc. */#ifndef READCHECK /* Use MAX_BLOCK byte frames if no sample/interrupt */ if (Rxbuflen < 32 || Rxbuflen > MAX_BLOCK) { Rxbuflen = MAX_BLOCK; vfile("Rxbuflen=%d", Rxbuflen); }#endif /* Override to force shorter frame length */ if (Tframlen && Rxbuflen > Tframlen) Rxbuflen = Tframlen; if ( !Rxbuflen) Rxbuflen = 1024; vfile("Rxbuflen=%d", Rxbuflen); /* If using a pipe for testing set lower buf len */ fstat(0, &f);#if defined(S_ISCHR) if (! (S_ISCHR(f.st_mode))) {#else if ((f.st_mode & S_IFMT) != S_IFCHR) {#endif Rxbuflen = MAX_BLOCK; } /* * If input is not a regular file, force ACK's to * prevent running beyond the buffer limits */ if ( !command_mode) { fstat(fileno(input_f), &f);#if defined(S_ISREG) if (!(S_ISREG(f.st_mode))) {#else if ((f.st_mode & S_IFMT) != S_IFREG) {#endif Canseek = -1; /* return ERROR; */ } } /* Set initial subpacket length */ if (blklen < 1024) { /* Command line override? */ if (Baudrate > 300) blklen = 256; if (Baudrate > 1200) blklen = 512; if (Baudrate > 2400) blklen = 1024; } if (Rxbuflen && blklen>Rxbuflen) blklen = Rxbuflen; if (blkopt && blklen > blkopt) blklen = blkopt; vfile("Rxbuflen=%d blklen=%d", Rxbuflen, blklen); vfile("Txwindow = %u Txwspac = %d", Txwindow, Txwspac); Rxtimeout=old_timeout; return (sendzsinit()); case ZCAN: case TIMEOUT: if (timeouts++==0) continue; /* force one other ZRQINIT to be sent */ return ERROR; case ZRQINIT: if (Rxhdr[ZF0] == ZCOMMAND) continue; default: zshhdr(ZNAK, Txhdr); continue; } } return ERROR;}/* Send send-init information */static int sendzsinit(void){ int 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,NULL); switch (c) { case ZCAN: return ERROR; case ZACK: return OK; default: if (++errors > 19) return ERROR; continue; } }}/* Send file name and related info */static int zsendfile(struct zm_fileinfo *zi, const char *buf, size_t blen){ int c; unsigned long crc; size_t rxpos; /* we are going to send a ZFILE. There cannot be much useful * stuff in the line right now (*except* ZCAN?). */#if 0 purgeline(io_mode_fd); /* might possibly fix stefan glasers problems */#endif for (;;) { Txhdr[ZF0] = Lzconv; /* file conversion request */ Txhdr[ZF1] = Lzmanag; /* file management request */ if (Lskipnocor) Txhdr[ZF1] |= ZF1_ZMSKNOLOC; Txhdr[ZF2] = Lztrans; /* file transport request */ Txhdr[ZF3] = 0; zsbhdr(ZFILE, Txhdr); ZSDATA(buf, blen, ZCRCW);again: c = zgethdr(Rxhdr, 1, &rxpos); switch (c) { case ZRINIT: while ((c = READLINE_PF(50)) > 0) if (c == ZPAD) { goto again; } /* **** FALL THRU TO **** */ default: continue; case ZRQINIT: /* remote site is sender! */ if (Verbose) vstringf(_("got ZRQINIT")); DO_SYSLOG((LOG_INFO, "%s/%s: got ZRQINIT - sz talks to sz", shortname,protname())); return ERROR; case ZCAN: if (Verbose) vstringf(_("got ZCAN")); DO_SYSLOG((LOG_INFO, "%s/%s: got ZCAN - receiver canceled", shortname,protname())); return ERROR; case TIMEOUT: DO_SYSLOG((LOG_INFO, "%s/%s: got TIMEOUT", shortname,protname())); return ERROR; case ZABORT: DO_SYSLOG((LOG_INFO, "%s/%s: got ZABORT", shortname,protname())); return ERROR; case ZFIN: DO_SYSLOG((LOG_INFO, "%s/%s: got ZFIN", shortname,protname())); return ERROR; case ZCRC: crc = 0xFFFFFFFFL;#ifdef HAVE_MMAP if (use_mmap && !mm_addr) { struct stat st; if (fstat (fileno (input_f), &st) == 0) { mm_size = st.st_size; mm_addr = mmap (0, mm_size, PROT_READ, MAP_SHARED, fileno (input_f), 0); if ((caddr_t) mm_addr == (caddr_t) - 1) mm_addr = NULL; else { fclose (input_f); input_f = NULL; } } } if (mm_addr) { size_t i; size_t count; char *p=mm_addr; count=(rxpos < mm_size && rxpos > 0)? rxpos: mm_size; for (i=0;i<count;i++,p++) { crc = UPDC32(*p, crc); } crc = ~crc; } else#endif if (Canseek >= 0) { if (rxpos==0) { struct stat st; if (0==fstat(fileno(input_f),&st)) { rxpos=st.st_size; } else rxpos=-1; } while (rxpos-- && ((c = getc(input_f)) != EOF)) crc = UPDC32(c, crc); crc = ~crc; clearerr(input_f); /* Clear EOF */ fseek(input_f, 0L, 0); } stohdr(crc); zsbhdr(ZCRC, Txhdr); goto again; case ZSKIP: if (input_f) fclose(input_f);#ifdef HAVE_MMAP else if (mm_addr) { munmap(mm_addr,mm_size); mm_addr=NULL; }#endif vfile("receiver skipped"); DO_SYSLOG((LOG_INFO, "%s/%s: receiver skipped", shortname, protname())); return c; case ZRPOS: /* * Suppress zcrcw request otherwise triggered by * lastsync==bytcnt */#ifdef HAVE_MMAP if (!mm_addr)#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -