📄 crzsz.sh
字号:
wcgetsec(rxbuf, maxtime)char *rxbuf;int maxtime;{X register checksum, wcj, firstch;X register unsigned short oldcrc;X register char *p;X int sectcurr;XX for (Lastrx=errors=0; errors<RETRYMAX; errors++) {XX if ((firstch=readline(maxtime))==STX) {X Blklen=1024; goto get2;X }X if (firstch==SOH) {X Blklen=128;get2:X sectcurr=readline(1);X if ((sectcurr+(oldcrc=readline(1)))==0377) {X oldcrc=checksum=0;X for (p=rxbuf,wcj=Blklen; --wcj>=0; ) {X if ((firstch=readline(1)) < 0)X goto bilge;X oldcrc=updcrc(firstch, oldcrc);X checksum += (*p++ = firstch);X }X if ((firstch=readline(1)) < 0)X goto bilge;X if (Crcflg) {X oldcrc=updcrc(firstch, oldcrc);X if ((firstch=readline(1)) < 0)X goto bilge;X oldcrc=updcrc(firstch, oldcrc);X if (oldcrc & 0xFFFF)X zperr1( "CRC");X else {X Firstsec=FALSE;X return sectcurr;X }X }X else if (((checksum-firstch)&0377)==0) {X Firstsec=FALSE;X return sectcurr;X }X elseX zperr1( "Checksum");X }X elseX zperr1("Sector number garbled");X }X /* make sure eot really is eot and not just mixmash */X else if (firstch==EOT && Lleft==0)X return WCEOT;X else if (firstch==CAN) {X if (Lastrx==CAN) {X zperr1( "Sender CANcelled");X return ERROR;X } else {X Lastrx=CAN;X continue;X }X }X else if (firstch==TIMEOUT) {X if (Firstsec)X goto humbug;bilge:X zperr1( "TIMEOUT");X }X elseX zperr1( "Got 0%o sector header", firstch);Xhumbug:X Lastrx=0;X while(readline(1)!=TIMEOUT)X ;X if (Firstsec) {X sendline(Crcflg?WANTCRC:NAK); flushmo();X Lleft=0; /* Do read next time ... */X } else {X maxtime=40; sendline(NAK); flushmo();X Lleft=0; /* Do read next time ... */X }X }X /* try to stop the bubble machine. */X canit();X return ERROR;}XX/*X * Process incoming file information headerX * Returns 0 for success, other codes for errorsX * or skip conditions.X */procheader(name)char *name;{X register char *openmode, *p;X static dummy;X struct stat f;XX /* set default parameters and overrides */X openmode = "w";X Thisbinary = (!Rxascii) || Rxbinary;X if (zconv == ZCBIN && Lzconv != ZCRESUM)X Lzconv = zconv; /* Remote Binary override */X if (Lzconv)X zconv = Lzconv;X if (Lzmanag)X zmanag = Lzmanag;XX /*X * Process ZMODEM remote file management requestsX */X if (!Rxbinary && zconv == ZCNL) /* Remote ASCII override */X Thisbinary = 0;X if (zconv == ZCBIN) /* Remote Binary override */X Thisbinary = TRUE;X else if (zmanag == ZMAPND)X openmode = "a";XX Bytesleft = DEFBYTL; Filemode = 0; Modtime = 0L;XX if (!name || !*name)X return 0;XX p = name + 1 + strlen(name);X if (*p) { /* file coming from Unix or DOS system */X sscanf(p, "%ld%lo%o%lo%d%ld%d%d",X &Bytesleft, &Modtime, &Filemode,X &dummy, &Filesleft, &Totalleft, &dummy, &dummy);X if (Filemode & UNIXFILE)X ++Thisbinary;X fprintf(stderr, "Incoming: %s %ld bytes\n", name, Bytesleft);X }XXX else { /* File coming from CP/M system */X for (p=name; *p; ++p) /* change / to _ */X if ( *p == '/')X *p = '_';XX if ( *--p == '.') /* zap trailing period */X *p = 0;X }XX strcpy(Pathname, name);XX if (*name && stat(name, &f)!= -1) {X zmanag &= ZMMASK;X if (zmanag==ZMPROT)X goto skipfile;X vfile("Current %s is %ld %lo", name, f.st_size, f.st_mtime);X if (Thisbinary && zconv==ZCRESUM) {X rxbytes = f.st_size & ~511;X if (Bytesleft < rxbytes) {X rxbytes = 0; goto doopen;X } elseX openit(name, "r+");X if ( !fout)X return ZFERR;X if (fseek(fout, rxbytes, 0)) {X closeit();X return ZFERR;X }X vfile("Crash recovery at %ld", rxbytes);X return 0;X }X switch (zmanag & ZMMASK) {X case ZMNEWL:X if (Bytesleft > f.st_size)X goto doopen;X case ZMNEW:X if ((f.st_mtime+1) >= Modtime)X goto skipfile;X goto doopen;X case ZMCLOB:X case ZMAPND:X goto doopen;X default:X goto skipfile;X }X } else if (zmanag & ZMSKNOLOC) {skipfile:X fprintf(stderr, "Skipping %s\n", name);X return ZSKIP;X }doopen:X openit(name, openmode);#ifdef MDX if ( !fout)X if (make_dirs(name))X openit(name, openmode);#endifX if ( !fout)X return ZFERR;X return 0;}Xopenit(name, openmode)char *name, *openmode;{X if (strcmp(name, "-"))X fout = fopen(name, openmode);X else if (isatty(1))X fout = fopen("stdout", "a");X elseX fout = stdout;}X#ifdef MD/*X * Directory-creating routines from Public Domain TAR by John GilmoreX */X/*X * After a file/link/symlink/dir creation has failed, see ifX * it's because some required directory was not present, and ifX * so, create all required dirs.X */make_dirs(pathname)register char *pathname;{X register char *p; /* Points into path */X int madeone = 0; /* Did we do anything yet? */X int save_errno = errno; /* Remember caller's errno */XX if (errno != ENOENT)X return 0; /* Not our problem */XX for (p = strchr(pathname, '/'); p != NULL; p = strchr(p+1, '/')) {X /* Avoid mkdir of empty string, if leading or double '/' */X if (p == pathname || p[-1] == '/')X continue;X /* Avoid mkdir where last part of path is '.' */X if (p[-1] == '.' && (p == pathname+1 || p[-2] == '/'))X continue;X *p = 0; /* Truncate the path there */X if ( !mkdir(pathname, 0777)) { /* Try to create it as a dir */X vfile("Made directory %s\n", pathname);X madeone++; /* Remember if we made one */X *p = '/';X continue;X }X *p = '/';X if (errno == EEXIST) /* Directory already exists */X continue;X /*X * Some other error in the mkdir. We return to the caller.X */X break;X }X errno = save_errno; /* Restore caller's errno */X return madeone; /* Tell them to retry if we made one */}X#if (MD != 2)#define TERM_SIGNAL(status) ((status) & 0x7F)#define TERM_COREDUMP(status) (((status) & 0x80) != 0)#define TERM_VALUE(status) ((status) >> 8)/*X * Make a directory. Compatible with the mkdir() system call on 4.2BSD.X */mkdir(dpath, dmode)char *dpath;int dmode;{X int cpid, status;X struct stat statbuf;XX if (stat(dpath,&statbuf) == 0) {X errno = EEXIST; /* Stat worked, so it already exists */X return -1;X }XX /* If stat fails for a reason other than non-existence, return error */X if (errno != ENOENT) return -1; XX switch (cpid = fork()) {XX case -1: /* Error in fork() */X return(-1); /* Errno is set already */XX case 0: /* Child process */X /*X * Cheap hack to set mode of new directory. Since thisX * child process is going away anyway, we zap its umask.X * FIXME, this won't suffice to set SUID, SGID, etc. on thisX * directory. Does anybody care?X */X status = umask(0); /* Get current umask */X status = umask(status | (0777 & ~dmode)); /* Set for mkdir */X execl("/bin/mkdir", "mkdir", dpath, (char *)0);X _exit(2); /* Can't exec /bin/mkdir */X X default: /* Parent process */X while (cpid != wait(&status)) ; /* Wait for kid to finish */X }XX if (TERM_SIGNAL(status) != 0 || TERM_VALUE(status) != 0) {X errno = EIO; /* We don't know why, but */X return -1; /* /bin/mkdir failed */X }XX return 0;}#endif /* MD != 2 */#endif /* MD */X/*X * Putsec writes the n characters of buf to receive file fout.X * If not in binary mode, carriage returns, and all charactersX * starting with CPMEOF are discarded.X */putsec(buf, n)char *buf;register n;{X register char *p;XX if (n == 0)X return OK;X if (Thisbinary) {X for (p=buf; --n>=0; )X putc( *p++, fout);X }X else {X if (Eofseen)X return OK;X for (p=buf; --n>=0; ++p ) {X if ( *p == '\r')X continue;X if (*p == CPMEOF) {X Eofseen=TRUE; return OK;X }X putc(*p ,fout);X }X }X return OK;}X/*X * substr(string, token) searches for token in string sX * returns pointer to token within string if found, NULL otherwiseX */char *substr(s, t)register char *s,*t;{X register char *ss,*tt;X /* search for first char of token */X for (ss=s; *s; s++)X if (*s == *t)X /* compare token with substring */X for (ss=s,tt=t; ;) {X if (*tt == 0)X return s;X if (*ss++ != *tt++)X break;X }X return NULL;}XX/*X * If called as rb use YMODEM protocol, etc.X */chkinvok(s)char *s;{X register char *p;XX p = s;X while (*p == '-')X s = ++p;X while (*p)X if (*p++ == '/')X s = p;X Progname = s++;X if (s[0]=='r' && s[1]=='z')X Batch = TRUE;X if (s[0]=='r' && s[1]=='b')X Batch = Nozmodem = TRUE;}X/*X * Ack a ZFIN packet, let byegones be byegonesX */voidackbibi(){X register n;XX vfile("ackbibi:");X Readnum = 1;X stohdr(0L);X for (n=3; --n>=0; ) {X purgeline();X zshhdr(4,ZFIN, Txhdr);X switch (readline(100)) {X case 'O':X readline(1); /* Discard 2nd 'O' */X vfile("ackbibi complete");X return;X case RCDO:X return;X case TIMEOUT:X default:X break;X }X }}XX/*X * Initialize for Zmodem receive attempt, try to activate Zmodem senderX * Handles ZSINIT frameX * Return ZFILE if Zmodem filename received, -1 on error,X * ZCOMPL if transaction finished, else 0X */tryz(){X register c, n;X register cmdzack1flg;XX if (Nozmodem) /* Check for "rb" program name */X return 0;XXX for (n=15; --n>=0; ) {X /* Set buffer length (0) and capability flags */#ifdef SEGMENTSX stohdr(SEGMENTS*1024L);#elseX stohdr(0L);#endif#ifdef CANBREAKX Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;#elseX Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;#endifX if (Zctlesc)X Txhdr[ZF0] |= TESCCTL;X Txhdr[ZF0] |= CANRLE;X Txhdr[ZF1] = CANVHDR;X /* tryzhdrtype may == ZRINIT */X zshhdr(4,tryzhdrtype, Txhdr);X if (tryzhdrtype == ZSKIP) /* Don't skip too far */X tryzhdrtype = ZRINIT; /* CAF 8-21-87 */again:X switch (zgethdr(Rxhdr)) {X case ZRQINIT:X if (Rxhdr[ZF3] & 0x80)X Usevhdrs = 1; /* we can var header */X continue;X case ZEOF:X continue;X case TIMEOUT:X continue;X case ZFILE:X zconv = Rxhdr[ZF0];X zmanag = Rxhdr[ZF1];X ztrans = Rxhdr[ZF2];X if (Rxhdr[ZF3] & ZCANVHDR)X Usevhdrs = TRUE;X tryzhdrtype = ZRINIT;X c = zrdata(secbuf, 1024);X if (c == GOTCRCW)X return ZFILE;X zshhdr(4,ZNAK, Txhdr);X goto again;X case ZSINIT:X Zctlesc = TESCCTL & Rxhdr[ZF0];X if (zrdata(Attn, ZATTNLEN) == GOTCRCW) {X stohdr(1L);X zshhdr(4,ZACK, Txhdr);X goto again;X }X zshhdr(4,ZNAK, Txhdr);X goto again;X case ZFREECNT:X stohdr(getfree());X zshhdr(4,ZACK, Txhdr);X goto again;X case ZCOMMAND:X cmdzack1flg = Rxhdr[ZF0];X if (zrdata(secbuf, 1024) == GOTCRCW) {X void exec2();XX if (cmdzack1flg & ZCACK1)X stohdr(0L);X elseX stohdr((long)sys2(secbuf));X purgeline(); /* dump impatient questions */X do {X zshhdr(4,ZCOMPL, Txhdr);X }X while (++errors<20 && zgethdr(Rxhdr) != ZFIN);X ackbibi();X if (cmdzack1flg & ZCACK1)X exec2(secbuf);X return ZCOMPL;X }X zshhdr(4,ZNAK, Txhdr); goto again;X case ZCOMPL:X goto again;X default:X continue;X case ZFIN:X ackbibi(); return ZCOMPL;X case ZCAN:X return ERROR;X }X }X return 0;}X/*X * Receive 1 or more files with ZMODEM protocolX */rzfiles(){X register c;XX for (;;) {X switch (c = rzfile()) {X case ZEOF:X case ZSKIP:X case ZFERR:X switch (tryz()) {X case ZCOMPL:X return OK;X default:X return ERROR;X case ZFILE:X break;X }X continue;X default:X return c;X case ERROR:X return ERROR;X }X }X /* NOTREACHED */}X/*X * Receive a file with ZMODEM protocol
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -