?? sz.c
字號:
in=fopen(name, "r"); if (in==NULL) { ++errcnt; return OK; /* pass over it, there may be others */ } BEofseen = Eofseen = 0; vpos = 0; /* Check for directory */ fstat(fileno(in), &f);#ifdef POSIX if (S_ISDIR(f.st_mode))#else c = f.st_mode & S_IFMT; if (c == S_IFDIR || c == S_IFBLK)#endif { fclose(in); return OK; } ++Filcnt; switch (wctxpn(name)) { case ZSKIP: case ZFERR: return OK; case OK: break; default: return ERROR; } if (!Zmodem && wctx(f.st_size)) return ERROR; if (Unlinkafter) unlink(oname); return 0;}/* * generate and transmit pathname block consisting of * pathname (null terminated), * file length, mode time and file mode in octal * as provided by the Unix fstat call. * N.B.: modifies the passed name, may extend it! */wctxpn(name)char *name;{ register char *p, *q; char name2[PATHLEN]; struct stat f; vfile("wctxpn: %s", name); if (Modem2) { if (*name && fstat(fileno(in), &f)!= -1) { fprintf(stderr, "Sending %s, %ld XMODEM blocks. ", name, (127+f.st_size)>>7); } printf("Start your local XMODEM receive. "); fflush(stdout); return OK; } zperr2("Awaiting pathname nak for %s", *name?name:"<END>"); if ( !Zmodem) if (getnak()) 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) > 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 (*name) { if (fstat(fileno(in), &f)!= -1) sprintf(p, "%lu %lo %o 3 %d %ld", f.st_size, f.st_mtime, f.st_mode, Filesleft, Totalleft); Totalleft -= f.st_size; } if (--Filesleft <= 0) Filesleft = 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; } vfile("wctxpn: %s", p); if (Zmodem) return zsendfile(txbuf, 1+strlen(p)+(p-txbuf)); if (wcputsec(txbuf, 0, 128)==ERROR) return ERROR; return OK;}getnak(){ register firstch; Lastrx = 0; for (;;) { switch (firstch = readline(800)) { case ZPAD: if (getzrxinit()) return ERROR; return FALSE; case TIMEOUT: sprintf(endmsg, "Timeout waiting for ZRINIT"); return TRUE; case WANTG:#ifdef 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 = readline(20)) == CAN && Lastrx == CAN) { sprintf(endmsg, "Got CAN waiting to send file"); return TRUE; } default: break; } Lastrx = firstch; }}wctx(flen)long flen;{ register int thisblklen; register int sectnum, attempts, firstch; long charssent; charssent = 0; firstsec=TRUE; thisblklen = blklen; vfile("wctx:file length=%ld", flen); while ((firstch=readline(Rxtimeout))!=NAK && firstch != WANTCRC && firstch != WANTG && firstch!=TIMEOUT && firstch!=CAN) ; if (firstch==CAN) { zperr1("Receiver CANcelled"); return ERROR; } if (firstch==WANTCRC) Crcflg=TRUE; if (firstch==WANTG) Crcflg=TRUE; sectnum=0; for (;;) { if (flen <= (charssent + 896L)) thisblklen = 128; if ( !filbuf(txbuf, thisblklen)) break; if (wcputsec(txbuf, ++sectnum, thisblklen)==ERROR) return ERROR; charssent += thisblklen; } fclose(in); attempts=0; do { purgeline(); sendline(EOT); flushmo(); ++attempts; } while ((firstch=(readline(Rxtimeout)) != ACK) && attempts < RETRYMAX); if (attempts == RETRYMAX) { zperr1("No ACK on EOT"); return ERROR; } else return OK;}wcputsec(buf, sectnum, cseclen)char *buf;int sectnum;int cseclen; /* data length of this sector to send */{ register checksum, wcj; register char *cp; unsigned oldcrc; int firstch; int attempts; firstch=0; /* part of logic to detect CAN CAN */ if (Verbose>1) fprintf(stderr, "Sector %3d %2dk\n", 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(Rxtimeout);gotnak: switch (firstch) { case CAN: if(Lastrx == CAN) {cancan: zperr1("Cancelled"); return ERROR; } break; case TIMEOUT: zperr1("Timeout on sector ACK"); continue; case WANTCRC: if (firstsec) Crcflg = TRUE; case NAK: zperr1("NAK on sector"); continue; case ACK: firstsec=FALSE; Totsecs += (cseclen>>7); return OK; case ERROR: zperr1("Got burst for sector ACK"); break; default: zperr2("Got %02x for sector ACK", firstch); break; } for (;;) { Lastrx = firstch; if ((firstch = readline(Rxtimeout)) == TIMEOUT) break; if (firstch == NAK || firstch == WANTCRC) goto gotnak; if (firstch == CAN && Lastrx == CAN) goto cancan; } } zperr1("Retry Count Exceeded"); return ERROR;}/* fill buf with count chars padding with ^Z for CPM */filbuf(buf, count)register char *buf;{ register m; m = read(fileno(in), buf, count); if (m <= 0) return 0; while (m < count) buf[m++] = 032; return count;}/* Fill buffer with blklen chars */zfilbuf(){ int n;#ifdef TXBSIZE vfile("zfilbuf: bytcnt =%lu vpos=%lu blklen=%d", bytcnt, vpos, blklen); /* We assume request is within buffer, or just beyond */ txbuf = Txb + (bytcnt & TXBMASK); if (vpos <= bytcnt) { n = fread(txbuf, 1, blklen, in); vpos += n; if (n < blklen) Eofseen = 1; vfile("zfilbuf: n=%d vpos=%lu Eofseen=%d", n, vpos, Eofseen); return n; } if (vpos >= (bytcnt+blklen)) return blklen; /* May be a short block if crash recovery etc. */ Eofseen = BEofseen; return (vpos - bytcnt);#else n = fread(txbuf, 1, blklen, in); if (n < blklen) { Eofseen = 1; vfile("zfilbuf: n=%d vpos=%lu Eofseen=%d", n, vpos, Eofseen); } return n;#endif}#ifdef TXBSIZE/* Replacement for brain damaged fseek function. Returns 0==success */fooseek(fptr, pos, whence)FILE *fptr;long pos;{ long m, n; vfile("fooseek: pos =%lu vpos=%lu Canseek=%d", pos, vpos, Canseek); /* Seek offset < current buffer */ if (pos < (vpos -TXBSIZE +1024)) { BEofseen = 0; if (Canseek > 0) { vpos = pos & ~TXBMASK; if (vpos > pos) vpos -= TXBSIZE; vfile("seek to vpos=%ld", vpos); if (fseek(fptr, vpos, 0)) return 1; } else if (Canseek == 0) { vfile("seek to 00000"); if (fseek(fptr, vpos = 0L, 0)) return 1; } else return 1; while (vpos < pos) { n = fread(Txb, (size_t)1, (size_t)TXBSIZE, fptr); vpos += n; vfile("n=%d vpos=%ld", n, vpos); if (n < TXBSIZE) { BEofseen = 1; break; } } vfile("vpos=%ld", vpos); return 0; } /* Seek offset > current buffer (Crash Recovery, etc.) */ if (pos > vpos) { if (Canseek) if (fseek(fptr, vpos = (pos & ~TXBMASK), 0)) return 1; while (vpos <= pos) { txbuf = Txb + (vpos & TXBMASK); m = TXBSIZE - (vpos & TXBMASK); vfile("m=%ld vpos=%ld", m,vpos); n = fread(txbuf, (size_t)1, (size_t)m, fptr); vfile("n=%ld vpos=%ld", n,vpos); vpos += n; vfile("bo=%d m=%ld vpos=%ld", txbuf-Txb,m,vpos); if (n < m) { BEofseen = 1; break; } } return 0; } /* Seek offset is within current buffer */ vfile("within buffer: vpos=%ld", vpos); return 0;}#define fseek fooseek#endif/* * substr(string, token) searches for token in string s * returns pointer to token within string if found, NULL otherwise */char *substr(s, t)register char *s,*t;{ register char *ss,*tt; /* search for first char of token */ for (ss=s; *s; s++) if (*s == *t) /* compare token with substring */ for (ss=s,tt=t; ;) { if (*tt == 0) return s; if (*ss++ != *tt++) break; } return NULL;}char *usinfo[] = { "Send Files and Commands with ZMODEM/YMODEM/XMODEM Protocol\n", "Usage: sz [-+abcdefgklLnNuvwxyYZ] [-] file ...", "\t zcommand [-egv] COMMAND", "\t zcommandi [-egv] COMMAND", "\t sb [-adfkuv] [-] file ...", "\t sx [-akuv] [-] file", ""};usage(){ char **pp; fprintf(stderr, "\n%s %s for %s by Chuck Forsberg, Omen Technology INC\n", Progname, VERSION, OS); fprintf(stderr, "\t\t\042The High Reliability Software\042\n"); for (pp=usinfo; **pp; ++pp) fprintf(stderr, "%s\n", *pp); fprintf(stderr,"\nCopyright (c) 1997 Omen Technology INC All Rights Reserved\n"); fprintf(stderr, "See sz.doc and README for option descriptions and licensing information.\n\n"); fprintf(stderr, "This program is designed to talk to terminal programs,\nnot to be called by one.\n"); exit(3);}/* * Get the receiver's init parameters */getzrxinit(){ register n; struct stat f; for (n=10; --n>=0; ) { switch (zgethdr(Rxhdr)) { case ZCHALLENGE: /* Echo receiver's challenge numbr */ stohdr(Rxpos); zshhdr(4, ZACK, Txhdr); continue; case ZCOMMAND: /* They didn't see out ZRQINIT */ stohdr(0L); zshhdr(4, ZRQINIT, Txhdr); continue; case ZRINIT: if (Rxhlen==4 && (Rxhdr[ZF1] & ZRQNVH)) { stohdr(0x80L); /* Show we can var header */ zshhdr(4, ZRQINIT, Txhdr); continue; } Rxflags = 0377 & Rxhdr[ZF0];#if COMPL Usevhdrs = 1;#else Usevhdrs = Rxhdr[ZF1] & CANVHDR;#endif Txfcs32 = (Wantfcs32 && (Rxflags & CANFC32)); Zctlesc |= Rxflags & TESCCTL; if (Rxhdr[ZF1] & ZRRQQQ) /* Escape ctrls */ initzsendmsk(Rxhdr+ZRPXQQ); Rxbuflen = (0377 & Rxhdr[ZP0])+((0377 & Rxhdr[ZP1])<<8); if ( !(Rxflags & CANFDX)) Txwindow = 0; vfile("Rxbuflen=%d Tframlen=%ld", Rxbuflen, Tframlen); signal(SIGINT, SIG_IGN);#ifdef MODE2OK mode(2); /* Set cbreak, XON/XOFF, etc. */#endif#ifndef READCHECK#ifndef USG /* Use 1024 byte frames if no sample/interrupt */ if (Rxbuflen < 32 || Rxbuflen > 1024) { Rxbuflen = 1024; vfile("Rxbuflen=%d", Rxbuflen); }#endif#endif /* Override to force shorter frame length */ if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32)) Rxbuflen = Tframlen; if ( !Rxbuflen && (Tframlen>=32)) Rxbuflen = Tframlen; vfile("Rxbuflen=%d", Rxbuflen); /* * If input is not a regular file, force ACK's to * prevent running beyond the buffer limits */ if ( !Command) { fstat(fileno(in), &f); if (#ifdef POSIX !S_ISREG(f.st_mode)#else (f.st_mode & S_IFMT) != S_IFREG#endif ) { Canseek = -1; f.st_size = 0; f.st_mtime = 0;#ifdef TXBSIZE Txwindow = TXBSIZE - 1024; Txwspac = TXBSIZE/4;#else sprintf(endmsg, "Can't seek on input"); return ERROR;#endif } } /* 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 (Baudrate < 300) 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); if (Lztrans == ZTRLE && (Rxflags & CANRLE)) Txfcs32 = 2; else Lztrans = 0; return (sendzsinit()); case ZCAN: case TIMEOUT: return ERROR; case ZRQINIT: if (Rxhdr[ZF0] == ZCOMMAND) continue; default: zshhdr(4, ZNAK, Txhdr); continue; } } return ERROR;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -