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

📄 sz.c

📁 ZMODEM协议的实现
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif#ifndef READCHECK#ifndef USG#ifndef GENIE			/* Use 1024 byte frames if no sample/interrupt */			if (Rxbuflen < 32 || Rxbuflen > 1024) {				Rxbuflen = 1024;				vfile("Rxbuflen=%d", Rxbuflen);			}#endif#endif#endif			/* Override to force shorter frame length */			if (Rxbuflen && (Rxbuflen>Tframlen) && (Tframlen>=32))				Rxbuflen = Tframlen;			if ( !Rxbuflen && (Tframlen>=32) && (Tframlen<=1024))				Rxbuflen = Tframlen;			vfile("Rxbuflen=%d", Rxbuflen);#ifndef GENIE#ifndef vax11c#ifdef STAT			/* If using a pipe for testing set lower buf len */			fstat(0, &f);			if ((f.st_mode & S_IFMT) != S_IFCHR) {				Rxbuflen = 1024;			}#endif#endif#endif#ifdef BADSEEK#ifdef GENIE			if (Txwindow == 0) {				Txwspac = (Txwindow = 4096)/4;			}#else			if (Txwindow == 0)				Txwindow = TXBSIZE - 1024;			Txwspac = TXBSIZE/4;#endif			Canseek = 0;#endif			/*			 * If input is not a regular file, force ACK's to			 *  prevent running beyond the buffer limits			 */#ifdef STAT			if ( !Command) {				fstat(fileno(in), &f);				if ((f.st_mode & S_IFMT) != S_IFREG) {					Canseek = -1;#ifdef TXBSIZE					Txwindow = TXBSIZE - 1024;					Txwspac = TXBSIZE/4;#else					return ERROR;#endif				}			}#endif			/* Set initial subpacket length */			if (blklen < 1024) {	/* Command line override? */				if (Effbaud > 300)					blklen = 256;				if (Effbaud > 1200)					blklen = 512;				if (Effbaud > 2400)					blklen = 1024;			}			if (Rxbuflen && blklen>Rxbuflen)				blklen = Rxbuflen;			if (blkopt && blklen > blkopt)				blklen = blkopt;#ifdef GENIE			blklen /= 128;  blklen *= 128;			if (blklen < 128)				blklen = 128;#endif			vfile("Rxbuflen=%d blklen=%d", Rxbuflen, blklen);			vfile("Txwindow = %u Txwspac = %d", Txwindow, Txwspac);			if (Lztrans == ZTRLE && (Rxflags & CANRLE))				Txfcs32 = 2;			else				Lztrans = 0;			return (sendzsinit());		case ZCAN:		case TIMEOUT:			return ERROR;		case ZRQINIT:			if (Rxhdr[ZF0] == ZCOMMAND)				continue;		default:			zshhdr(4, ZNAK, Txhdr);			continue;		}	}	return ERROR;}/* Send send-init information */sendzsinit(){	register c;	if (Myattn[0] == '\0' && (!Zctlesc || (Rxflags & TESCCTL)))		return OK;	errors = 0;	for (;;) {		stohdr(0L);#ifdef ALTCANOFF		Txhdr[ALTCOFF] = ALTCANOFF;#endif		if (Zctlesc) {			Txhdr[ZF0] |= TESCCTL; zshhdr(4, ZSINIT, Txhdr);		}		else			zsbhdr(4, ZSINIT, Txhdr);		zsdata(Myattn, ZATTNLEN, ZCRCW);		c = zgethdr(Rxhdr, 1);		switch (c) {		case ZCAN:			return ERROR;		case ZACK:			return OK;		default:			if (++errors > 19)				return ERROR;			continue;		}	}}/* Send file name and related info */zsendfile(buf, blen)char *buf;{	register c;	register UNSL long crc;	long lastcrcrq = -1;	char *p;	for (;;) {		Txhdr[ZF0] = Lzconv;	/* file conversion request */		Txhdr[ZF1] = Lzmanag;	/* file management request */		if (Lskipnocor)			Txhdr[ZF1] |= ZMSKNOLOC;		Txhdr[ZF2] = Lztrans;	/* file transport request */		Txhdr[ZF3] = 0;		zsbhdr(4, ZFILE, Txhdr);		zsdata(buf, blen, ZCRCW);again:		c = zgethdr(Rxhdr, 1);		switch (c) {		case ZRINIT:			while ((c = readline(50)) > 0)				if (c == ZPAD) {					goto again;				}			/* **** FALL THRU TO **** */		default:			continue;		case ZCAN:		case TIMEOUT:		case ZABORT:		case ZFIN:			return ERROR;		case ZCRC:			if (Rxpos != lastcrcrq) {				lastcrcrq = Rxpos;				crc = 0xFFFFFFFFL;				if (Canseek >= 0) {					fseek(in, 0L, 0);					while (((c = getc(in)) != EOF) && --lastcrcrq)						crc = UPDC32(c, crc);					crc = ~crc;					clearerr(in);	/* Clear possible EOF */					lastcrcrq = Rxpos;				}			}			stohdr(crc);			zsbhdr(4, ZCRC, Txhdr);			goto again;		case ZSKIP:			fclose(in); return c;		case ZRPOS:			/*			 * Suppress zcrcw request otherwise triggered by			 * lastyunc==bytcnt			 */#ifdef GENIE			/*			 *  Special case - turn on RLE if not archive, etc.			 *   otherwise turn off RLE unless cmd line specified			 */			if (Rxflags & CANRLE) {		/* RX can do it */				bytcnt = 0;				zfilbuf();				vfile("txbuf012: %x %x %x", txbuf[0], txbuf[1],				  txbuf[2]);				if ((txbuf[0] != 032)	/* .ARC file */				 && (txbuf[0] != 0x1f)	/* .Z file */				 && (txbuf[0] != 0x1c)	/* .LHZ file */				 && strncmp(txbuf, "ZOO", 3)				 && strncmp(txbuf, "GIF", 3)				 && (txbuf[2] != 3))	/* .ZIP file */					Txfcs32 = 2;				else if ( !(Lztrans & ZTRLE))					Txfcs32 = 1;			}			/* GEnie binary can't seek to byte */			if (Binfile) {				Rxpos &= ~127L;			}#endif			if (fseek(in, Rxpos, 0))				return ERROR;			Lastsync = (bytcnt = Txpos = Lrxpos = Rxpos) -1;			return zsendfdata();		}	}}/* Send the data in the file */zsendfdata(){	register c, e, n;	register newcnt;	register long tcount = 0;	int junkcount;		/* Counts garbage chars received by TX */	static int tleft = 6;	/* Counter for test mode */	junkcount = 0;	Beenhereb4 = FALSE;somemore:	if (setjmp(intrjmp)) {waitack:		junkcount = 0;		c = getinsync(0);gotack:		switch (c) {		default:		case ZCAN:			fclose(in);			return ERROR;		case ZSKIP:			fclose(in);			return c;		case ZACK:		case ZRPOS:			break;		case ZRINIT:			return OK;		}#ifdef READCHECK		/*		 * If the reverse channel can be tested for data,		 *  this logic may be used to detect error packets		 *  sent by the receiver, in place of setjmp/longjmp		 *  rdchk(fd) returns non 0 if a character is available		 */		while (rdchk(0)) {#ifdef EATSIT			switch (checked)#else			switch (readline(1))#endif			{			case CAN:			case ZPAD:				c = getinsync(1);				goto gotack;			case XOFF:		/* Wait a while for an XON */			case XOFF|0200:				readline(100);			}		}#endif	}	if ( !Fromcu)		signal(SIGINT, onintr);	newcnt = Rxbuflen;	Txwcnt = 0;	stohdr(Txpos);	zsbhdr(4, ZDATA, Txhdr);	/*	 * Special testing mode.  This should force receiver to Attn,ZRPOS	 *  many times.  Each time the signal should be caught, causing the	 *  file to be started over from the beginning.	 */	if (Test) {		if ( --tleft)			while (tcount < 20000) {				printf(qbf); fflush(stdout);				tcount += strlen(qbf);#ifdef READCHECK				while (rdchk(0)) {#ifdef EATSIT					switch (checked)#else					switch (readline(1))#endif					{					case CAN:					case ZPAD:#ifdef TCFLSH						ioctl(0, TCFLSH, 1);#endif						goto waitack;					case XOFF:	/* Wait for XON */					case XOFF|0200:						readline(100);					}				}#endif			}		signal(SIGINT, SIG_IGN); canit();		sleep(3); purgeline(); mode(0);		printf("\nsz: Tcount = %ld\n", tcount);		if (tleft) {			printf("ERROR: Interrupts Not Caught\n");			exit(1);		}		exit(SS_NORMAL);	}	do {		n = zfilbuf();		if (Eofseen)			e = ZCRCE;		else if (junkcount > 3)			e = ZCRCW;		else if (bytcnt == Lastsync)			e = ZCRCW;		else if (Rxbuflen && (newcnt -= n) <= 0)			e = ZCRCW;		else if (Txwindow && (Txwcnt += n) >= Txwspac) {			Txwcnt = 0;  e = ZCRCQ;		} else			e = ZCRCG;		if (Verbose>1)			fprintf(stderr, "\r%7ld ZMODEM%s    ",			  Txpos, Crc32t?" CRC-32":"");		zsdata(txbuf, n, e);		bytcnt = Txpos += n;		if (e == ZCRCW)			goto waitack;#ifdef READCHECK		/*		 * If the reverse channel can be tested for data,		 *  this logic may be used to detect error packets		 *  sent by the receiver, in place of setjmp/longjmp		 *  rdchk(fd) returns non 0 if a character is available		 */		fflush(stdout);		while (rdchk(0)) {#ifdef EATSIT			switch (checked)#else			switch (readline(1))#endif			{			case CAN:			case ZPAD:				c = getinsync(1);				if (c == ZACK)					break;#ifdef TCFLSH				ioctl(0, TCFLSH, 1);#endif				/* zcrce - dinna wanna starta ping-pong game */				zsdata(txbuf, 0, ZCRCE);				goto gotack;			case XOFF:		/* Wait a while for an XON */			case XOFF|0200:				readline(100);			default:				++junkcount;			}		}#endif	/* READCHECK */		if (Txwindow) {			while ((tcount = (Txpos - Lrxpos)) >= Txwindow) {				vfile("%ld window >= %u", tcount, Txwindow);				if (e != ZCRCQ)					zsdata(txbuf, 0, e = ZCRCQ);				c = getinsync(1);				if (c != ZACK) {#ifdef TCFLSH					ioctl(0, TCFLSH, 1);#endif					zsdata(txbuf, 0, ZCRCE);					goto gotack;				}			}			vfile("window = %ld", tcount);		}	} while (!Eofseen);	if ( !Fromcu)		signal(SIGINT, SIG_IGN);	for (;;) {		stohdr(Txpos);		zsbhdr(4, ZEOF, Txhdr);		switch (getinsync(0)) {		case ZACK:			continue;		case ZRPOS:			goto somemore;		case ZRINIT:			return OK;		case ZSKIP:			fclose(in);			return c;		default:			fclose(in);			return ERROR;		}	}}/* * Respond to receiver's complaint, get back in sync with receiver */getinsync(flag){	register c;	for (;;) {		if (Test) {			printf("\r\n\n\n***** Signal Caught *****\r\n");			Rxpos = 0; c = ZRPOS;		} else			c = zgethdr(Rxhdr, 0);		switch (c) {		case ZCAN:		case ZABORT:		case ZFIN:		case TIMEOUT:			return ERROR;		case ZRPOS:			/* ************************************* */			/*  If sending to a buffered modem, you  */			/*   might send a break at this point to */			/*   dump the modem's buffer.		 */			clearerr(in);	/* In case file EOF seen */			if (fseek(in, Rxpos, 0))				return ERROR;			Eofseen = 0;			bytcnt = Lrxpos = Txpos = Rxpos;#ifndef GENIE			if (Lastsync == Rxpos) {				if (++Beenhereb4 > 4)					if (blklen > 32)						blklen /= 2;			}#endif			Lastsync = Rxpos;			return c;		case ZACK:			Lrxpos = Rxpos;			if (flag || Txpos == Rxpos)				return ZACK;			continue;		case ZRINIT:		case ZSKIP:			fclose(in);			return c;		case ERROR:		default:			zsbhdr(4, ZNAK, Txhdr);			continue;		}	}}/* Say "bibi" to the receiver, try to do it cleanly */saybibi(){	for (;;) {		stohdr(0L);		/* CAF Was zsbhdr - minor change */		zshhdr(4, ZFIN, Txhdr);	/*  to make debugging easier */		switch (zgethdr(Rxhdr, 0)) {		case ZFIN:			sendline('O'); sendline('O'); flushmo();		case ZCAN:		case TIMEOUT:			return;		}	}}/* Local screen character display function */bttyout(c){	if (Verbose)		putc(c, stderr);}/* Send command and related info */zsendcmd(buf, blen)char *buf;{	register c;	long cmdnum;#ifdef GENIE	cmdnum = 69;#else	cmdnum = getpid();#endif	errors = 0;	for (;;) {		stohdr(cmdnum);		Txhdr[ZF0] = Cmdack1;		zsbhdr(4, ZCOMMAND, Txhdr);		zsdata(buf, blen, ZCRCW);listen:		Rxtimeout = 100;		/* Ten second wait for resp. */		Usevhdrs = 0;		/* Allow rx to send fixed len headers */		c = zgethdr(Rxhdr, 1);		switch (c) {		case ZRINIT:			goto listen;	/* CAF 8-21-87 */		case ERROR:		case GCOUNT:		case TIMEOUT:			if (++errors > Cmdtries)				return ERROR;			continue;		case ZCAN:		case ZABORT:		case ZFIN:		case ZSKIP:		case ZRPOS:			return ERROR;		default:			if (++errors > 20)				return ERROR;			continue;		case ZCOMPL:			Exitcode = Rxpos;			saybibi();			return OK;		case ZRQINIT:#ifdef vax11c		/* YAMP :== Yet Another Missing Primitive */			return ERROR;#else			vfile("******** RZ *******");			system("rz");			vfile("******** SZ *******");			goto listen;#endif		}	}}/* * If called as sb use YMODEM protocol */chkinvok(s)char *s;{	register char *p;	p = s;	while (*p == '-')		s = ++p;	while (*p)		if (*p++ == '/')			s = p;	if (*s == 'v') {		Verbose=1; ++s;	}	Progname = s;	if (s[0]=='s' && s[1]=='b') {		Nozmodem = TRUE; blklen=1024;	}	if (s[0]=='s' && s[1]=='x') {		Modem2 = TRUE;	}}#ifdef STATcountem(argc, argv)register char **argv;{	register c;	struct stat f;	for (Totalleft = 0, Filesleft = 0; --argc >=0; ++argv) {		f.st_size = -1;		if (Verbose>2) {			fprintf(stderr, "\nCountem: %03d %s ", argc, *argv);			fflush(stderr);		}		if (access(*argv, 04) >= 0 && stat(*argv, &f) >= 0) {			c = f.st_mode & S_IFMT;			if (c != S_IFDIR && c != S_IFBLK) {				++Filesleft;  Totalleft += f.st_size;			}		}		if (Verbose>2)			fprintf(stderr, " %ld", f.st_size);	}	if (Verbose>2)		fprintf(stderr, "\ncountem: Total %d %ld\n",		  Filesleft, Totalleft);}#elsecountem(argc, argv)register char **argv;{	register c;	register char *p;	long size;	for (Totalleft = 0, Filesleft = 0; --argc >=0; ++argv) {		size = -1;		if (Verbose>2) {			fprintf(stderr, "\nCountem: %03d %s ", argc, *argv);			fflush(stderr);		}		++Filesleft;  #ifdef XARGSFILE		/* Look for file length in third colon sep field */		for (p = *argv; *p; ++p) {			if (*p == ':') {				for (++p; *p; ++p) {					if (*p == ':') {						++p;						size = atol(p);						Totalleft += size;						break;					}				}			break;			}		}#endif		if (Verbose>2)			fprintf(stderr, " %ld", size);	}	if (Verbose>2)		fprintf(stderr, "\ncountem: Total %d %ld\n",		  Filesleft, Totalleft);}#endifchartest(m){	register n;	mode(m);	printf("\r\n\nCharacter Transparency Test Mode %d\r\n", m);	printf("If Pro-YAM/ZCOMM is not displaying ^M hit ALT-V NOW.\r\n");	printf("Hit Enter.\021");  fflush(stdout);	readline(500);	for (n = 0; n < 256; ++n) {		if (!(n%8))			printf("\r\n");		printf("%02x ", n);  fflush(stdout);		sendline(n);	flushmo();		printf("  ");  fflush(stdout);		if (n == 127) {			printf("Hit Enter.\021");  fflush(stdout);			readline(500);			printf("\r\n");  fflush(stdout);		}	}	printf("\021\r\nEnter Characters, echo is in hex.\r\n");	printf("Hit SPACE or pause 40 seconds for exit.\r\n");	while (n != TIMEOUT && n != ' ') {		n = readline(400);		printf("%02x\r\n", n);		fflush(stdout);	}	printf("\r\nMode %d character transparency test ends.\r\n", m);	fflush(stdout);}/* End of sz.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -