⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sz.c

📁 ZMODEM协议的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -