📄 sz.c
字号:
#define VERSION "sz 2.12 05-29-88"#define PUBDIR "/usr/spool/uucppublic"/*% cc -compat -M2 -Ox -K -i -DTXBSIZE=16384 -DNFGVMIN -DREADCHECK sz.c -lx -o sz; size sz Following is used for testing, might not be reasonable for production<-xtx-*> cc -Osal -DTXBSIZE=32768 -DSV sz.c -lx -o $B/sz; size $B/sz **************************************************************************** * * sz.c By Chuck Forsberg, Omen Technology INC * **************************************************************************** * * Typical Unix/Xenix/Clone compiles: * * cc -O sz.c -o sz USG (SYS III/V) Unix * cc -O -DSV sz.c -o sz Sys V Release 2 with non-blocking input * Define to allow reverse channel checking * cc -O -DV7 sz.c -o sz Unix Version 7, 2.8 - 4.3 BSD * * cc -O -K -i -DNFGVMIN -DREADCHECK sz.c -lx -o sz Classic Xenix * * ln sz sb **** All versions **** * ln sz sx **** All versions **** * **************************************************************************** * * Typical VMS compile and install sequence: * * define LNK$LIBRARY SYS$LIBRARY:VAXCRTL.OLB * cc sz.c * cc vvmodem.c * link sz,vvmodem * sz :== $disk$user2:[username.subdir]sz.exe * * If you feel adventureous, remove the #define BADSYNC line * immediately following the #ifdef vax11c line! Some VMS * systems know how to fseek, some don't. * **************************************************************************** * * * A program for Unix to send files and commands to computers running * Professional-YAM, PowerCom, YAM, IMP, or programs supporting Y/XMODEM. * * Sz uses buffered I/O to greatly reduce CPU time compared to UMODEM. * * USG UNIX (3.0) ioctl conventions courtesy Jeff Martin * * 2.1x hacks to avoid VMS fseek() bogosity, allow input from pipe * -DBADSEEK -DTXBSIZE=32768 * 2.x has mods for VMS flavor * * 1.34 implements tx backchannel garbage count and ZCRCW after ZRPOS * in accordance with the 7-31-87 ZMODEM Protocol Description */#include <sys/types.h>#ifdef vax11c#define BADSEEK#define TXBSIZE 32768 /* Must be power of two, < MAXINT */#include <types.h>#include <stat.h>#define LOGFILE "szlog.tmp"#define OS "VMS"#define READCHECK#define BUFWRITE#define iofdextern int errno;#define SS_NORMAL SS$_NORMAL#define xsendline(c) sendline(c)#else /* vax11c */#define SS_NORMAL 0#define LOGFILE "/tmp/szlog"#define sendline(c) putchar((c) & 0377)#define xsendline(c) putchar(c)#endif#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <utime.h>#include <stdio.h>#define PATHLEN 256#define OK 0#define FALSE 0#define TRUE 1#undef ERROR#define ERROR (-1)/* Ward Christensen / CP/M parameters - Don't change these! */#define ENQ 005#define CAN ('X'&037)#define XOFF ('s'&037)#define XON ('q'&037)#define SOH 1#define STX 2#define EOT 4#define ACK 6#define NAK 025#define CPMEOF 032#define WANTCRC 0103 /* send C not NAK to get crc not checksum */#define WANTG 0107 /* Send G not NAK to get nonstop batch xmsn */#define TIMEOUT (-2)#define RCDO (-3)#define RETRYMAX 10#define HOWMANY 2int Zmodem=0; /* ZMODEM protocol requested by receiver */unsigned Baudrate=2400; /* Default, should be set by first mode() call */unsigned Txwindow; /* Control the size of the transmitted window */unsigned Txwspac; /* Spacing between zcrcq requests */unsigned Txwcnt; /* Counter used to space ack requests */long Lrxpos; /* Receiver's last reported offset */int errors;#ifdef vax11c#include "vrzsz.c" /* most of the system dependent stuff here */#else#include "rbsb.c" /* most of the system dependent stuff here */#endif#include "crctab.c"int Filesleft;long Totalleft;/* * Attention string to be executed by receiver to interrupt streaming data * when an error is detected. A pause (0336) may be needed before the * ^C (03) or after it. */#ifdef READCHECKchar Myattn[] = { 0 };#else#ifdef USGchar Myattn[] = { 03, 0336, 0 };#elsechar Myattn[] = { 0 };#endif#endifFILE *in;#ifdef BADSEEKint Canseek = 0; /* 1: Can seek 0: only rewind -1: neither (pipe) */#ifndef TXBSIZE#define TXBSIZE 16384 /* Must be power of two, < MAXINT */#endif#elseint Canseek = 1; /* 1: Can seek 0: only rewind -1: neither (pipe) */#endif#ifdef TXBSIZE#define TXBMASK (TXBSIZE-1)char Txb[TXBSIZE]; /* Circular buffer for file reads */char *txbuf = Txb; /* Pointer to current file segment */#elsechar txbuf[1024];#endiflong vpos = 0; /* Number of bytes read from file */char Lastrx;char Crcflg;int Verbose=0;int Modem2=0; /* XMODEM Protocol - don't send pathnames */int Restricted=0; /* restricted; no /.. or ../ in filenames */int Quiet=0; /* overrides logic that would otherwise set verbose */int Ascii=0; /* Add CR's for brain damaged programs */int Fullname=0; /* transmit full pathname */int Unlinkafter=0; /* Unlink file after it is sent */int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */int firstsec;int errcnt=0; /* number of files unreadable */int blklen=128; /* length of transmitted records */int Optiong; /* Let it rip no wait for sector ACK's */int Eofseen; /* EOF seen on input set by zfilbuf */int BEofseen; /* EOF seen on input set by fooseek */int Totsecs; /* total number of sectors this file */int Filcnt=0; /* count of number of files opened */int Lfseen=0;unsigned Rxbuflen = 16384; /* Receiver's max buffer length */int Tframlen = 0; /* Override for tx frame length */int blkopt=0; /* Override value for zmodem blklen */int Rxflags = 0;long bytcnt;int Wantfcs32 = TRUE; /* want to send 32 bit FCS */char Lzconv; /* Local ZMODEM file conversion request */char Lzmanag; /* Local ZMODEM file management request */int Lskipnocor;char Lztrans;char zconv; /* ZMODEM file conversion request */char zmanag; /* ZMODEM file management request */char ztrans; /* ZMODEM file transport request */int Command; /* Send a command, then exit. */char *Cmdstr; /* Pointer to the command string */int Cmdtries = 11;int Cmdack1; /* Rx ACKs command, then do it */int Exitcode = 0;int Test; /* 1= Force receiver to send Attn, etc with qbf. */ /* 2= Character transparency test */char *qbf="The quick brown fox jumped over the lazy dog's back 1234567890\r\n";long Lastsync; /* Last offset to which we got a ZRPOS */int Beenhereb4; /* How many times we've been ZRPOS'd same place */jmp_buf tohere; /* For the interrupt on RX timeout */jmp_buf intrjmp; /* For the interrupt on RX CAN */_PROTOTYPE(void onintr , (int sig ));_PROTOTYPE(int main , (int argc , char *argv []));_PROTOTYPE(int wcsend , (int argc , char *argp []));_PROTOTYPE(int wcs , (char *oname ));_PROTOTYPE(int wctxpn , (char *name ));_PROTOTYPE(int getnak , (void));_PROTOTYPE(int wctx , (long flen ));_PROTOTYPE(int wcputsec , (char *buf , int sectnum , int cseclen ));_PROTOTYPE(int filbuf , (char *buf , int count ));_PROTOTYPE(int zfilbuf , (void));_PROTOTYPE(int fooseek , (FILE *fptr , long pos , int whence ));_PROTOTYPE(void alrm , (int sig ));_PROTOTYPE(int readline , (int timeout ));_PROTOTYPE(void flushmo , (void));_PROTOTYPE(void purgeline , (void));_PROTOTYPE(void canit , (void));void zperr();_PROTOTYPE(char *substr , (char *s , char *t ));_PROTOTYPE(int usage , (void));_PROTOTYPE(int getzrxinit , (void));_PROTOTYPE(int sendzsinit , (void));_PROTOTYPE(int zsendfile , (char *buf , int blen ));_PROTOTYPE(int zsendfdata , (void));_PROTOTYPE(int getinsync , (int flag ));_PROTOTYPE(void saybibi , (void));_PROTOTYPE(void bttyout , (int c ));_PROTOTYPE(int zsendcmd , (char *buf , int blen ));_PROTOTYPE(void chkinvok , (char *s ));_PROTOTYPE(void countem , (int argc , char **argv ));_PROTOTYPE(void chartest , (int m ));/* called by signal interrupt or terminate to clean things up */void bibi(n)int n;{ canit(); fflush(stdout); mode(0); fprintf(stderr, "sz: caught signal %d; exiting\n", n); if (n == SIGQUIT) abort(); if (n == 99) fprintf(stderr, "mode(2) in rbsb.c not implemented!!\n"); cucheck(); exit(128+n);}/* Called when ZMODEM gets an interrupt (^X) */void onintr(sig)int sig;{ signal(SIGINT, SIG_IGN); longjmp(intrjmp, -1);}int Zctlesc; /* Encode control characters */int Nozmodem = 0; /* If invoked as "sb" */char *Progname = "sz";int Zrwindow = 1400; /* RX window size (controls garbage count) */#include "zm.c"int main(argc, argv)int argc;char *argv[];{ register char *cp; register npats; int dm; char **patts; static char xXbuf[BUFSIZ]; if ((cp = getenv("ZNULLS")) && *cp) Znulls = atoi(cp); if ((cp=getenv("SHELL")) && (substr(cp, "rsh") || substr(cp, "rksh"))) Restricted=TRUE; from_cu(); chkinvok(argv[0]); Rxtimeout = 600; npats=0; if (argc<2) usage(); setbuf(stdout, xXbuf); while (--argc) { cp = *++argv; if (*cp++ == '-' && *cp) { while ( *cp) { switch(*cp++) { case '\\': *cp = toupper(*cp); continue; case '+': Lzmanag = ZMAPND; break;#ifdef CSTOPB case '2': Twostop = TRUE; break;#endif case 'a': Lzconv = ZCNL; Ascii = TRUE; break; case 'b': Lzconv = ZCBIN; break; case 'C': if (--argc < 1) { usage(); } Cmdtries = atoi(*++argv); break; case 'i': Cmdack1 = ZCACK1; /* **** FALL THROUGH TO **** */ case 'c': if (--argc != 1) { usage(); } Command = TRUE; Cmdstr = *++argv; break; case 'd': ++Dottoslash; /* **** FALL THROUGH TO **** */ case 'f': Fullname=TRUE; break; case 'e': Zctlesc = 1; break; case 'k': blklen=1024; break; case 'L': if (--argc < 1) { usage(); } blkopt = atoi(*++argv); if (blkopt<24 || blkopt>1024) usage(); break; case 'l': if (--argc < 1) { usage(); } Tframlen = atoi(*++argv); if (Tframlen<32 || Tframlen>1024) usage(); break; case 'N': Lzmanag = ZMNEWL; break; case 'n': Lzmanag = ZMNEW; break; case 'o': Wantfcs32 = FALSE; break; case 'p': Lzmanag = ZMPROT; break; case 'r': Lzconv = ZCRESUM; case 'q': Quiet=TRUE; Verbose=0; break; case 't': if (--argc < 1) { usage(); } Rxtimeout = atoi(*++argv); if (Rxtimeout<10 || Rxtimeout>1000) usage(); break; case 'T': if (++Test > 1) { chartest(1); chartest(2); mode(0); exit(0); } break;#ifndef vax11c case 'u': ++Unlinkafter; break;#endif case 'v': ++Verbose; 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 'X': ++Modem2; break; case 'Y': Lskipnocor = TRUE; /* **** FALLL THROUGH TO **** */ case 'y': Lzmanag = ZMCLOB; break; default: usage(); } } } else if ( !npats && argc>0) { if (argv[0][0]) { npats=argc; patts=argv;#ifndef vax11c if ( !strcmp(*patts, "-")) iofd = 1;#endif } } } if (npats < 1 && !Command && !Test) usage(); if (Verbose) { if (freopen(LOGFILE, "a", stderr)==NULL) { printf("Can't open log file %s\n",LOGFILE); exit(0200); } setbuf(stderr, (char *)NULL); } if (Fromcu && !Quiet) { if (Verbose == 0) Verbose = 2; } vfile("%s %s for %s\n", Progname, VERSION, OS); mode(1); if (signal(SIGINT, bibi) == SIG_IGN) { signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN); } else { signal(SIGINT, bibi); signal(SIGKILL, bibi); } if ( !Fromcu) signal(SIGQUIT, SIG_IGN); signal(SIGTERM, bibi); if ( !Modem2) { if (!Nozmodem) { printf("rz\r"); fflush(stdout); } countem(npats, patts); if (!Nozmodem) { stohdr(0L); if (Command) Txhdr[ZF0] = ZCOMMAND; zshhdr(ZRQINIT, Txhdr); } } fflush(stdout); if (Command) { if (getzrxinit()) { Exitcode=0200; canit(); } else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) { Exitcode=0200; canit(); } } else if (wcsend(npats, patts)==ERROR) { Exitcode=0200; canit(); } fflush(stdout); mode(0); dm = ((errcnt != 0) | Exitcode); if (dm) { cucheck(); exit(dm); } putc('\n',stderr); exit(SS_NORMAL); /*NOTREACHED*/}int wcsend(argc, argp)int argc;char *argp[];{ register int n; Crcflg=FALSE; firstsec=TRUE; bytcnt = -1; for (n=0; n<argc; ++n) { Totsecs = 0; if (wcs(argp[n])==ERROR) return ERROR; } Totsecs = 0; if (Filcnt==0) { /* bitch if we couldn't open ANY files */ if ( !Modem2) { Command = TRUE; Cmdstr = "echo \"sz: Can't open any requested files\""; if (getnak()) { Exitcode=0200; canit(); } if (!Zmodem) canit(); else if (zsendcmd(Cmdstr, 1+strlen(Cmdstr))) { Exitcode=0200; canit(); } Exitcode = 1; return OK; } canit(); fprintf(stderr,"\r\nCan't open any requested files.\r\n"); return ERROR; } if (Zmodem) saybibi(); else if ( !Modem2) wctxpn(""); return OK;}int wcs(oname)char *oname;{ register c; register char *p; struct stat f; char name[PATHLEN]; strcpy(name, oname); if (Restricted) { /* restrict pathnames to current tree or uucppublic */ if ( substr(name, "../") || (name[0]== '/' && strncmp(name, PUBDIR, strlen(PUBDIR))) ) { canit(); fprintf(stderr,"\r\nsz:\tSecurity Violation\r\n"); return ERROR; } } if ( !strcmp(oname, "-")) { if ((p = getenv("ONAME")) && *p) strcpy(name, p); else sprintf(name, "s%d.sz", getpid()); in = stdin; } else if ((in=fopen(oname, "r"))==NULL) { ++errcnt; return OK; /* pass over it, there may be others */ } BEofseen = Eofseen = 0; vpos = 0; /* Check for directory or block special files */ fstat(fileno(in), &f); c = f.st_mode & S_IFMT; if (c == S_IFDIR || c == S_IFBLK) { fclose(in); return OK; } ++Filcnt; switch (wctxpn(name)) { case ERROR: return ERROR; case ZSKIP: return OK; } if (!Zmodem && wctx(f.st_size)==ERROR) return ERROR;#ifndef vax11c if (Unlinkafter) unlink(oname);#endif return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -