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

📄 lsz.c

📁 Debian Linux下的通讯程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		case ZRPOS:			/*			 * Suppress zcrcw request otherwise triggered by			 * lastyunc==bytcnt			 */#ifdef HAVE_MMAP			if (!mm_addr)#endif			if (Rxpos && fseek(in, Rxpos, 0))				return ERROR;			bytcnt = Txpos = Rxpos;			Lastsync = 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 */	long last_txpos=0;	long last_bps=0;	long not_printed=0;	static long total_sent=0;#ifdef HAVE_MMAP	{		struct stat st;		if (fstat(fileno(in),&st)==0)		{			mm_size=st.st_size;	    		mm_addr = mmap (0, mm_size, PROT_READ, 	    			MAP_SHARED, fileno(in), 0);	    		if ((caddr_t) mm_addr==(caddr_t) -1)	    			mm_addr=NULL;	    		else {	    			fclose(in);	    			in=NULL;	    		}		}	}#endif	Lrxpos = 0;	junkcount = 0;	Beenhereb4 = 0;somemore:	if (setjmp(intrjmp)) {waitack:		junkcount = 0;		c = getinsync(0);gotack:		switch (c) {		default:		case ZCAN:			if (in)				fclose(in);			return ERROR;		case ZSKIP:			if (in)				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(fdes) returns non 0 if a character is available		 */		while (rdchk(iofd)) {#ifdef READCHECK_READS			switch (checked)#else			switch (readline(1))#endif			{			case CAN:			case ZPAD:				c = getinsync(1);				goto gotack;			case XOFF:		/* Wait a while for an XON */#ifndef linux			case XOFF|0200:#endif				readline(100);			}		}#endif	}#ifndef linux	if ( !Fromcu)		signal(SIGINT, onintr);#endif	newcnt = Rxbuflen;	Txwcnt = 0;	stohdr(Txpos);	zsbhdr(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(iofd)) {#ifdef READCHECK_READS					switch (checked)#else					switch (readline(1))#endif					{					case CAN:					case ZPAD:#ifdef TCFLSH						ioctl(iofd, TCFLSH, 1);#endif						goto waitack;					case XOFF:	/* Wait for XON */#ifndef linux					case XOFF|0200:#endif						readline(100);					}				}#endif			}		signal(SIGINT, SIG_IGN); canit();		sleep(3); purgeline(); mode(0);		printf("\nlsz: Tcount = %ld\n", tcount);		if (tleft) {			printf("ERROR: Interrupts Not Caught\n");			exit(1);		}		exit(SS_NORMAL);	}	do {#ifdef NEW_ERROR		int old=blklen;		blklen=calc_blklen(total_sent);		total_sent+=blklen+OVERHEAD;		if (Verbose >2 && blklen!=old)			fprintf(stderr,"blklen now %ld\n",blklen);#endif#ifdef HAVE_MMAP		if (mm_addr) {			if (Txpos+blklen<mm_size) 				n=blklen;			else {				n=mm_size-Txpos;				Eofseen=1;			}		} else #endif		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			&& (not_printed > 5 || Txpos > last_bps / 2 + last_txpos)) {			int minleft =  0;			int secleft =  0;			last_bps=(Txpos/timing(0));			if (last_bps > 0) {				minleft =  (Filesize-Txpos)/last_bps/60;				secleft =  ((Filesize-Txpos)/last_bps)%60;			}			fprintf(stderr, "\rBytes Sent:%7ld/%7ld   BPS:%-6d ETA %02d:%02d  ",			 Txpos, Filesize, last_bps, minleft, secleft);			last_txpos=Txpos;		} else if (Verbose)			not_printed++;#ifdef HAVE_MMAP		if (mm_addr)			zsdata(mm_addr+Txpos,n,e);		else#endif		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(fdes) returns non 0 if a character is available		 */		fflush(stdout);		while (rdchk(iofd)) {#ifdef READCHECK_READS			switch (checked)#else			switch (readline(1))#endif			{			case CAN:			case ZPAD:				c = getinsync(1);				if (c == ZACK)					break;#ifdef TCFLSH				ioctl(iofd, TCFLSH, 1);#endif				/* zcrce - dinna wanna starta ping-pong game */				zsdata(txbuf, 0, ZCRCE);				goto gotack;			case XOFF:		/* Wait a while for an XON */#ifndef linux			case XOFF|0200:#endif				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(iofd, TCFLSH, 1);#endif					zsdata(txbuf, 0, ZCRCE);					goto gotack;				}			}			vfile("window = %ld", tcount);		}	} while (!Eofseen);	if (Verbose > 1)		fprintf(stderr, "\rBytes Sent:%7ld   BPS:%-6d                       \n",		Filesize,last_bps);	if ( !Fromcu)		signal(SIGINT, SIG_IGN);	for (;;) {		stohdr(Txpos);		zsbhdr(ZEOF, Txhdr);		switch (getinsync(0)) {		case ZACK:			continue;		case ZRPOS:			goto somemore;		case ZRINIT:			return OK;		case ZSKIP:			if (in)				fclose(in);			return c;		default:			if (in)				fclose(in);			return ERROR;		}	}}#ifdef NEW_ERRORintcalc_blklen(long total_sent){	static long total_bytes=0;	static int calcs_done=0;	static long last_error_count=0;	static int last_blklen=0;	static long last_bytes_per_error=0;	long best_bytes=0;	long best_size=0;	long bytes_per_error;	long d;	int i;	if (total_bytes==0)	{		/* called from countem */		total_bytes=total_sent;		return 0;	}	/* it's not good to calc blklen too early */	if (calcs_done++ < 5) {		if (error_count && start_blklen >1024)			return last_blklen=1024;		else 			last_blklen/=2;		return last_blklen=start_blklen;	}	if (!error_count) {		/* that's fine */		if (start_blklen==max_blklen)			return start_blklen;		bytes_per_error=LONG_MAX;		goto calcit;	}	if (error_count!=last_error_count) {		/* the last block was bad. shorten blocks until one block is		 * ok. this is because very often many errors come in an		 * short period */		if (error_count & 2)		{			last_blklen/=2;			if (last_blklen < 32)				last_blklen = 32;			else if (last_blklen > 512)				last_blklen=512;			if (Verbose > 3)				fprintf(stderr,"calc_blklen: reduced to %d due to error\n",					last_blklen);			last_error_count=error_count;			last_bytes_per_error=0; /* force recalc */		}		return last_blklen;	}	bytes_per_error=total_sent / error_count;		/* we do not get told about every error! 		 * from my experience the value is ok */	bytes_per_error/=2;	/* there has to be a margin */	if (bytes_per_error<100)		bytes_per_error=100;	/* be nice to the poor machine and do the complicated things not	 * too often	 */	if (last_bytes_per_error>bytes_per_error)		d=last_bytes_per_error-bytes_per_error;	else		d=bytes_per_error-last_bytes_per_error;	if (d<4)	{		if (Verbose > 3)		{			fprintf(stderr,"calc_blklen: returned old value %d due to low bpe diff\n",				last_blklen);			fprintf(stderr,"calc_blklen: old %ld, new %ld, d %ld\n",				last_bytes_per_error,bytes_per_error,d );		}		return last_blklen;	}	last_bytes_per_error=bytes_per_error;calcit:	if (Verbose > 3)		fprintf(stderr,"calc_blklen: calc total_bytes=%ld, bpe=%ld\n",			total_bytes,bytes_per_error);	for (i=32;i<=max_blklen;i*=2) {		long ok; /* some many ok blocks do we need */		long failed; /* and that's the number of blocks not transmitted ok */		long transmitted;		ok=total_bytes / i + 1;		failed=((long) i + OVERHEAD) * ok / bytes_per_error;		transmitted=ok * ((long) i+OVERHEAD)  			+ failed * ((long) i+OVERHEAD+OVER_ERR);		if (Verbose > 4)			fprintf(stderr,"calc_blklen: blklen %d, ok %ld, failed %ld -> %ld\n",				i,ok,failed,transmitted);		if (transmitted < best_bytes || !best_bytes)		{			best_bytes=transmitted;			best_size=i;		}	}	if (best_size > 2*last_blklen)		best_size=2*last_blklen;	last_blklen=best_size;	if (Verbose > 3)		fprintf(stderr,"calc_blklen: returned %d as best\n",			last_blklen);	return last_blklen;}#endif/* * 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 */#ifdef HAVE_MMAP			if (!mm_addr)#endif			if (fseek(in, Rxpos, 0))				return ERROR;			Eofseen = 0;			bytcnt = Lrxpos = Txpos = Rxpos;			if (Lastsync == Rxpos) {#ifndef NEW_ERROR				if (++Beenhereb4 > 4)					if (blklen > 32)					{						blklen /= 2;						if (Verbose > 1) {							fprintf(stderr,"\rFalldown to %ld blklen\r\n",								blklen);						}					}#else				error_count++;#endif			}			Lastsync = Rxpos-1;			return c;		case ZACK:			Lrxpos = Rxpos;			if (flag || Txpos == Rxpos)				return ZACK;			continue;		case ZRINIT:		case ZSKIP:			if (in)				fclose(in);			return c;		case ERROR:		default:#ifdef NEW_ERROR				error_count++;#endif			zsbhdr(ZNAK, Txhdr);			continue;		}	}}/* Say "bibi" to the receiver, try to do it cleanly */saybibi(){	for (;;) {		stohdr(0L);		/* CAF Was zsbhdr - minor change */		zshhdr(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;	cmdnum = getpid();	errors = 0;	for (;;) {		stohdr(cmdnum);		Txhdr[ZF0] = Cmdack1;		zsbhdr(ZCOMMAND, Txhdr);		zsdata(buf, blen, ZCRCW);listen:		Rxtimeout = 100;		/* Ten second wait for resp. */		c = zgethdr(Rxhdr, 1);		switch (c) {		case ZRINIT:			goto listen;	/* CAF 8-21-87 */		case ERROR:		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:			vfile("******** RZ *******");			system("rz");			vfile("******** SZ *******");			goto listen;		}	}}/* * If called as lsb 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')		|| (s[0]=='l' && s[1]=='s' && s[2]=='b')) {		Nozmodem = TRUE; blklen=1024;	}	if ((s[0]=='s' && s[1]=='x')		|| (s[0]=='l' && s[1]=='s' && s[2]=='x')) {		Modem2 = TRUE;	}}countem(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", (long) f.st_size);	}	if (Verbose>2)		fprintf(stderr, "\ncountem: Total %d %ld\n",		  Filesleft, Totalleft);#ifdef NEW_ERROR	calc_blklen(Totalleft);#endif}chartest(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 lsz.c */

⌨️ 快捷键说明

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