📄 sz.c
字号:
#define VERSION "sz 3.03 5-09-89"#define PUBDIR "/usr/spool/uucppublic"/*% cc -compat -M2 -Ox -K -i -DTXBSIZE=16384 -DNFGVMIN -DREADCHECK sz.c -lx -o sz; size sz/*% cc -Zi -DXX -DNFGVMIN -DREADCHECK sz.c -lx -o xsz; size xsz<-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 BADSEEK 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 * * This version implements ZMODEM Run Length Encoding, Comparision, * and variable length headers. These features were not funded * by the original Telenet development contract. This software, * including these features, may be freely used for non * commercial and educational purposes. This software may also * be freely used to support file transfer operations to or from * licensed Omen Technology products. Contact Omen Technology * for licensing for other uses. Any programs which use part or * all of this software must be provided in source form with this * notice intact except by written permission from Omen * Technology Incorporated. * * Omen Technology Inc FAX: 503-621-3745 * Post Office Box 4681 * Portland OR 97208 * * Previous versions of this program (not containing the extensions * listed above) remain in the public domain. * * This code is made available in the hope it will be useful, * BUT WITHOUT ANY WARRANTY OF ANY KIND OR LIABILITY FOR ANY * DAMAGES OF ANY KIND. * * 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 */#ifdef XX#define XARGSFILE "args"long Thisflen;#endifchar *substr(), *getenv();#ifdef vax11c#define STATIC#define BADSEEK#define TXBSIZE 32768 /* Must be power of two, < MAXINT */#include <types.h>#include <stat.h>#define STAT#define LOGFILE "szlog.tmp"#include <stdio.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <errno.h>#define OS "VMS"#define ROPMODE "r"#define READCHECK#define BUFWRITEextern int errno;#define SS_NORMAL SS$_NORMAL#define xsendline(c) sendline(c)#ifndef PROGNAME#define PROGNAME "sz"#endif#else /* vax11c */#ifdef GENIE#define STATIC static#define LOGFILE "szlog"#define BADSEEK#define TXBSIZE 32768 /* Must be power of two, < MAXINT */#define OS "GEnie"#define SS_NORMAL 0#include <stdio.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <errno.h>#include <stdlib.h>#include <fildes.h>FILDES fdes;extern int errno;int Binfile;long Thisflen;#define sendline(c) putchar(c & 0377)#define xsendline(c) putchar(c)#else /* GENIE */#define LOGFILE "/tmp/szlog"#define SS_NORMAL 0#include <stdio.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <errno.h>extern int errno;#define STATIC#define sendline(c) putchar(c & 0377)#define xsendline(c) putchar(c)#endif#endif#define PATHLEN 256#define OK 0#define FALSE 0#ifdef TRUE#undef TRUE#endif#define TRUE 1#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 GCOUNT (-4)#define RETRYMAX 10#define HOWMANY 2STATIC int Zmodem=0; /* ZMODEM protocol requested by receiver */unsigned Baudrate=4800; /* Default, set by first mode() call */STATIC unsigned Effbaud = 4800;STATIC unsigned Txwindow; /* Control the size of the transmitted window */STATIC unsigned Txwspac; /* Spacing between zcrcq requests */STATIC unsigned Txwcnt; /* Counter used to space ack requests */STATIC long Lrxpos; /* Receiver's last reported offset */STATIC int errors;#ifdef vax11c#include "vrzsz.c" /* most of the system dependent stuff here */#else#ifdef GENIE#include "genie.c" /* most of the system dependent stuff here */#else#include "rbsb.c" /* most of the system dependent stuff here */#ifdef XX#undef STAT#endif#endif#endif#include "crctab.c"STATIC int Filesleft;STATIC 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 READCHECKSTATIC char Myattn[] = { 0 };#else#ifdef USGSTATIC char Myattn[] = { 03, 0336, 0 };#else#ifndef GENIESTATIC char Myattn[] = { 0 };#endif#endif#endifFILE *in;#ifdef BADSEEKSTATIC int Canseek = 0; /* 1: Can seek 0: only rewind -1: neither (pipe) */#ifndef TXBSIZE#define TXBSIZE 16384 /* Must be power of two, < MAXINT */#endif#elseSTATIC int Canseek = 1; /* 1: Can seek 0: only rewind -1: neither (pipe) */#endif#ifdef TXBSIZE#define TXBMASK (TXBSIZE-1)STATIC char Txb[TXBSIZE]; /* Circular buffer for file reads */STATIC char *txbuf = Txb; /* Pointer to current file segment */#elseSTATIC char txbuf[1024];#endifSTATIC long vpos = 0; /* Number of bytes read from file */STATIC char Lastrx;STATIC char Crcflg;STATIC int Verbose=0;STATIC int Modem2=0; /* XMODEM Protocol - don't send pathnames */STATIC int Restricted=0; /* restricted; no /.. or ../ in filenames */STATIC int Quiet=0; /* overrides logic that would otherwise set verbose */STATIC int Ascii=0; /* Add CR's for brain damaged programs */STATIC int Fullname=0; /* transmit full pathname */STATIC int Unlinkafter=0; /* Unlink file after it is sent */STATIC int Dottoslash=0; /* Change foo.bar.baz to foo/bar/baz */STATIC int firstsec;STATIC int errcnt=0; /* number of files unreadable */STATIC int blklen=128; /* length of transmitted records */STATIC int Optiong; /* Let it rip no wait for sector ACK's */STATIC int Eofseen; /* EOF seen on input set by zfilbuf */STATIC int BEofseen; /* EOF seen on input set by fooseek */STATIC int Totsecs; /* total number of sectors this file */STATIC int Filcnt=0; /* count of number of files opened */STATIC int Lfseen=0;STATIC unsigned Rxbuflen = 16384; /* Receiver's max buffer length */STATIC int Tframlen = 0; /* Override for tx frame length */STATIC int blkopt=0; /* Override value for zmodem blklen */STATIC int Rxflags = 0;STATIC long bytcnt;STATIC int Wantfcs32 = TRUE; /* want to send 32 bit FCS */STATIC char Lzconv; /* Local ZMODEM file conversion request */STATIC char Lzmanag; /* Local ZMODEM file management request */STATIC int Lskipnocor;STATIC char Lztrans;STATIC int Command; /* Send a command, then exit. */STATIC char *Cmdstr; /* Pointer to the command string */STATIC int Cmdtries = 11;STATIC int Cmdack1; /* Rx ACKs command, then do it */STATIC int Exitcode;STATIC int Test; /* 1= Force receiver to send Attn, etc with qbf. */ /* 2= Character transparency test */STATIC char *qbf= "The quick brown fox jumped over the lazy dog's back 1234567890\r\n";STATIC long Lastsync; /* Last offset to which we got a ZRPOS */STATIC int Beenhereb4; /* How many times we've been ZRPOS'd same place */STATIC jmp_buf tohere; /* For the interrupt on RX timeout */STATIC jmp_buf intrjmp; /* For the interrupt on RX CAN */#ifdef XARGSFILEchar *mystrsave(s)char *s;{ register char *p; char *malloc(); if (p = malloc(strlen(s)+1) ) { strcpy(p, s); return p; } fprintf(stderr, "No memory for mystrsave!\n"); exit(1);}/* Remove (presumably) terminating CR and/or LF from string */uncrlf(s)register char *s;{ for ( ; *s; ++s) switch (*s) { case '\r': case '\n': *s = 0; return; }}#endif/* called by signal interrupt or terminate to clean things up */bibi(n){ canit(); fflush(stdout); mode(0); fprintf(stderr, "sz: caught signal %d; exiting\n", n);#ifndef GENIE if (n == SIGQUIT) abort();#endif if (n == 99) fprintf(stderr, "mode(2) in rbsb.c not implemented!!\n"); cucheck(); exit(128+n);}/* Called when ZMODEM gets an interrupt (^X) */onintr(){ signal(SIGINT, SIG_IGN); longjmp(intrjmp, -1);}STATIC int Zctlesc; /* Encode control characters */STATIC int Nozmodem = 0; /* If invoked as "sb" */STATIC char *Progname = "sz";STATIC int Zrwindow = 1400; /* RX window size (controls garbage count) */#include "zm.c"#include "zmr.c"#ifdef XARGSFILE#define XARGSMAX 256char *xargv[XARGSMAX+1];#endifmain(argc, argv)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();#ifdef vax11c chkinvok(PROGNAME);#else chkinvok(argv[0]);#endif 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': if (Lzconv == ZCRESUM) Lzmanag = (Lzmanag & ZMMASK) | ZMCRC; Lzconv = ZCRESUM; break; 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; case 'Z': case 'z': Lztrans = ZTRLE; break; default: usage(); } } } else if ( !npats && argc>0) { if (argv[0][0]) { npats=argc; patts=argv; } } } 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, NULL); } if (Fromcu && !Quiet) { if (Verbose == 0) Verbose = 2; } vfile("%s %s for %s\n", Progname, VERSION, OS);#ifdef XARGSFILE vfile("npats=%d *patts=%s", npats, *patts); if (npats == 1 && !strcmp(XARGSFILE, *patts)) { in = fopen(XARGSFILE, "r"); if (!in) { printf(stderr, "Can't open / control file!\n"); exit(2); } for (npats=0,argv=patts=xargv; npats<XARGSMAX; ++npats,++argv) { if (fgets(txbuf, 1024, in) <= 0) break; uncrlf(txbuf); *argv = mystrsave(txbuf); } fclose(in); }#endif mode(1);#ifdef GENIE signal(SIGINT, SIG_IGN);#else if (signal(SIGINT, bibi) == SIG_IGN) { signal(SIGINT, SIG_IGN); signal(SIGKILL, SIG_IGN); } else { signal(SIGINT, bibi); signal(SIGKILL, bibi); }#endif#ifdef SIGQUIT if ( !Fromcu) signal(SIGQUIT, SIG_IGN);#endif#ifdef SIGTERM signal(SIGTERM, bibi);#endif if ( !Modem2) { if (!Nozmodem) { printf("rz\r"); fflush(stdout); } countem(npats, patts); if (!Nozmodem) { stohdr(0L); if (Command) Txhdr[ZF0] = ZCOMMAND; zshhdr(4, 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); } exit(SS_NORMAL); /*NOTREACHED*/}wcsend(argc, argp)char *argp[];{ register n; Crcflg=FALSE; firstsec=TRUE; bytcnt = -1; if (Nozmodem) { printf("Start your YMODEM receive. "); fflush(stdout); } 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 (!Nozmodem && !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;}wcs(oname)char *oname;{ register c; register char *p, *q;#ifdef STAT struct stat f;#endif char name[PATHLEN]; strcpy(name, oname);#ifdef XARGSFILE /* Parse GEniename:REALname:length pathname syntax */ Thisflen = -1; for (p = oname; *p; ++p) { if (*p == ':') { *p++ = 0; q = p; for (++p; *p; ++p) { if (*p == ':') { *p++ = 0; Thisflen = atol(p); break; } } strcpy(name, q); break; } }#endif#ifdef GENIE _describe(oname,&fdes); /* An undocumented goodie */ if (fdes.type_file == 1) { /* Fortran Sequential Binary */ Binfile = 1; in = fopen(oname,"rB"); } else if (fdes.type_file == 0) { /* Ascii */ Binfile = 0; in = fopen(oname,"r"); } else { /* not a SL filetype */ fprintf(stderr, "\nUnknown file type %d\n",fdes.type_file); ++errcnt; return OK; /* pass over it, there may be others */ }#else 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; } } in=fopen(oname, ROPMODE);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -