📄 lrz.c
字号:
/* * Totalitarian Communist pathname processing */checkpath(name)char *name;{ if (Restricted) { if (fopen(name, "r") != NULL) { canit(); fprintf(stderr, "\r\nlrz: %s exists\n", name); bibi(-1); } /* restrict pathnames to current tree or uucppublic */ if ( strstr(name, "../")#ifdef PUBDIR || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR)))#endif ) { canit(); fprintf(stderr,"\r\nlrz:\tSecurity Violation\r\n"); bibi(-1); } if (Restricted > 1) { if (name[0]=='.' || strstr(name,"/.")) { canit(); fprintf(stderr,"\r\nlrz:\tSecurity Violation\r\n"); bibi(-1); } } }}/* * Initialize for Zmodem receive attempt, try to activate Zmodem sender * Handles ZSINIT frame * Return ZFILE if Zmodem filename received, -1 on error, * ZCOMPL if transaction finished, else 0 */tryz(){ register c, n; register cmdzack1flg; if (Nozmodem) /* Check for "rb" program name */ return 0; for (n=Zmodem?15:5; --n>=0; ) { /* Set buffer length (0) and capability flags */#ifdef SEGMENTS stohdr(SEGMENTS*MAX_BLOCK);#else stohdr(0L);#endif#ifdef CANBREAK Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;#else Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO;#endif#ifdef ENABLE_TIMESYNC if (timesync_flag) Txhdr[ZF1] |= ZF1_TIMESYNC;#endif if (Zctlesc) Txhdr[ZF0] |= TESCCTL; /* TESCCTL == ESCCTL */ zshhdr(tryzhdrtype, Txhdr); if (tryzhdrtype == ZSKIP) /* Don't skip too far */ tryzhdrtype = ZRINIT; /* CAF 8-21-87 */again: switch (zgethdr(Rxhdr, 0)) { case ZRQINIT: continue; case ZEOF: continue; case TIMEOUT: continue; case ZFILE: zconv = Rxhdr[ZF0]; zmanag = Rxhdr[ZF1]; ztrans = Rxhdr[ZF2]; tryzhdrtype = ZRINIT; c = zrdata(secbuf, MAX_BLOCK); mode(3); if (c == GOTCRCW) return ZFILE; zshhdr(ZNAK, Txhdr); goto again; case ZSINIT: Zctlesc = TESCCTL & Rxhdr[ZF0]; if (zrdata(Attn, ZATTNLEN) == GOTCRCW) { stohdr(1L); zshhdr(ZACK, Txhdr); goto again; } zshhdr(ZNAK, Txhdr); goto again; case ZFREECNT: stohdr(getfree()); zshhdr(ZACK, Txhdr); goto again; case ZCOMMAND: cmdzack1flg = Rxhdr[ZF0]; if (zrdata(secbuf, MAX_BLOCK) == GOTCRCW) { if (Verbose) { fprintf(stderr,"lrz: remote requested command\n"); fprintf(stderr,"lrz: %s\n",secbuf); } if (!allow_remote_commands) { if (Verbose) fprintf(stderr,"lrz: not executed\n"); zshhdr(ZCOMPL, Txhdr); return ZCOMPL; } if (cmdzack1flg & ZCACK1) stohdr(0L); else stohdr((long)sys2(secbuf)); purgeline(); /* dump impatient questions */ do { zshhdr(ZCOMPL, Txhdr); } while (++errors<20 && zgethdr(Rxhdr,1) != ZFIN); ackbibi(); if (cmdzack1flg & ZCACK1) exec2(secbuf); return ZCOMPL; } zshhdr(ZNAK, Txhdr); goto again; case ZCOMPL: goto again; default: continue; case ZFIN: ackbibi(); return ZCOMPL; case ZCAN: return ERROR; } } return 0;}/* * Receive 1 or more files with ZMODEM protocol */rzfiles(){ register c; for (;;) { switch (c = rzfile()) { case ZEOF: case ZSKIP: switch (tryz()) { case ZCOMPL: return OK; default: return ERROR; case ZFILE: break; } continue; default: return c; case ERROR: return ERROR; } }}/* * Receive a file with ZMODEM protocol * Assumes file name frame is in secbuf */rzfile(){ register c, n; long last_rxbytes=0; long last_bps=0; long not_printed=0; Eofseen=FALSE; n = 20; rxbytes = 0l; if (procheader(secbuf) == ERROR) { return (tryzhdrtype = ZSKIP); } for (;;) {#ifdef SEGMENTS chinseg = 0;#endif stohdr(rxbytes); zshhdr(ZRPOS, Txhdr);nxthdr: switch (c = zgethdr(Rxhdr, 0)) { default: vfile("lrzfile: zgethdr returned %d", c); return ERROR; case ZNAK: case TIMEOUT:#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif if ( --n < 0) { vfile("lrzfile: zgethdr returned %d", c); return ERROR; } case ZFILE: zrdata(secbuf, MAX_BLOCK); continue; case ZEOF:#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif if (rclhdr(Rxhdr) != rxbytes) { /* * Ignore eof if it's at wrong place - force * a timeout because the eof might have gone * out before we sent our zrpos. */ errors = 0; goto nxthdr; } if (Verbose>1) { int minleft = 0; int secleft = 0; last_bps=(rxbytes/timing(0)); if (last_bps > 0) { minleft = (Bytesleft-rxbytes)/last_bps/60; secleft = ((Bytesleft-rxbytes)/last_bps)%60; } fprintf(stderr, "\rBytes Received: %7ld/%7ld BPS:%-6ld \r\n", rxbytes, Bytesleft, last_bps, minleft, secleft); } if (closeit()) { tryzhdrtype = ZFERR; vfile("lrzfile: closeit returned <> 0"); return ERROR; } vfile("lrzfile: normal EOF"); return c; case ERROR: /* Too much garbage in header search error */#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif if ( --n < 0) { vfile("lrzfile: zgethdr returned %d", c); return ERROR; } zmputs(Attn); continue; case ZSKIP:#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif closeit(); vfile("lrzfile: Sender SKIPPED file"); return c; case ZDATA: if (rclhdr(Rxhdr) != rxbytes) { if ( --n < 0) { return ERROR; }#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif zmputs(Attn); continue; }moredata: if (Verbose>1 && (not_printed > 7 || rxbytes > last_bps / 2 + last_rxbytes)) { int minleft = 0; int secleft = 0; last_bps=(rxbytes/timing(0)); if (last_bps > 0) { minleft = (Bytesleft-rxbytes)/last_bps/60; secleft = ((Bytesleft-rxbytes)/last_bps)%60; } fprintf(stderr, "\rBytes Received: %7ld/%7ld BPS:%-6ld ETA %02d:%02d ", rxbytes, Bytesleft, last_bps, minleft, secleft); last_rxbytes=rxbytes; not_printed=0; } else if (Verbose) not_printed++;#ifdef SEGMENTS if (chinseg >= (MAX_BLOCK * SEGMENTS)) { putsec(secbuf, chinseg); chinseg = 0; } switch (c = zrdata(secbuf+chinseg, MAX_BLOCK))#else switch (c = zrdata(secbuf, MAX_BLOCK))#endif { case ZCAN:#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif vfile("lrzfile: zgethdr returned %d", c); return ERROR; case ERROR: /* CRC error */#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif if ( --n < 0) { vfile("lrzfile: zgethdr returned %d", c); return ERROR; } zmputs(Attn); continue; case TIMEOUT:#ifdef SEGMENTS putsec(secbuf, chinseg); chinseg = 0;#endif if ( --n < 0) { vfile("lrzfile: zgethdr returned %d", c); return ERROR; } continue; case GOTCRCW: n = 20;#ifdef SEGMENTS chinseg += Rxcount; putsec(secbuf, chinseg); chinseg = 0;#else putsec(secbuf, Rxcount);#endif rxbytes += Rxcount; stohdr(rxbytes); zshhdr(ZACK, Txhdr); sendline(XON); goto nxthdr; case GOTCRCQ: n = 20;#ifdef SEGMENTS chinseg += Rxcount;#else putsec(secbuf, Rxcount);#endif rxbytes += Rxcount; stohdr(rxbytes); zshhdr(ZACK, Txhdr); goto moredata; case GOTCRCG: n = 20;#ifdef SEGMENTS chinseg += Rxcount;#else putsec(secbuf, Rxcount);#endif rxbytes += Rxcount; goto moredata; case GOTCRCE: n = 20;#ifdef SEGMENTS chinseg += Rxcount;#else putsec(secbuf, Rxcount);#endif rxbytes += Rxcount; goto nxthdr; } } }}/* * Send a string to the modem, processing for \336 (sleep 1 sec) * and \335 (break signal) */zmputs(s)char *s;{ char *p; while (s && *s) { p=strpbrk(s,"\335\336"); if (!p) { write(1,s,strlen(s)); return; } if (p!=s) { write(1,s,p-s); s=p; } if (*p=='\336') sleep(1); else sendbrk(); p++; }}/* * Close the receive dataset, return OK or ERROR */closeit(){ time_t time(); if (Topipe) { if (pclose(fout)) { return ERROR; } return OK; } if (fclose(fout)) { fprintf(stderr, "file close error: %s\n",strerror(errno)); /* this may be any sort of error, including random data corruption */ unlink(Pathname); return ERROR; } if (Modtime) { timep[0] = time(NULL); timep[1] = Modtime; utime(Pathname, timep); } if ((Filemode&S_IFMT) == S_IFREG) chmod(Pathname, (07777 & Filemode)); return OK;}/* * Ack a ZFIN packet, let byegones be byegones */ackbibi(){ register n; vfile("ackbibi:"); Readnum = 1; stohdr(0L); for (n=3; --n>=0; ) { purgeline(); zshhdr(ZFIN, Txhdr); switch (readline(100)) { case 'O': readline(1); /* Discard 2nd 'O' */ vfile("ackbibi complete"); return; case RCDO: return; case TIMEOUT: default: break; } }}/* * Local console output simulation */bttyout(c){ if (Verbose || Fromcu) putc(c, stderr);}/* * Strip leading ! if present, do shell escape. */sys2(s)register char *s;{ if (*s == '!') ++s; return system(s);}/* * Strip leading ! if present, do exec. */exec2(s)register char *s;{ if (*s == '!') ++s; mode(0); execl("/bin/sh", "sh", "-c", s);}/* End of lrz.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -