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

📄 rbsb.c

📁 通讯程序源码
💻 C
字号:
/* * *  Rev 10-30-91 *  This file contains Unix specific code for setting terminal modes, *  very little is specific to ZMODEM or YMODEM per se (that code is in *  sz.c and rz.c).  The CRC-16 routines used by XMODEM, YMODEM, and ZMODEM *  are also in this file, a fast table driven macro version * *	V7/BSD HACKERS:  SEE NOTES UNDER mode(2) !!! * *   This file is #included so the main file can set parameters such as HOWMANY. *   See the main files (rz.c/sz.c) for compile instructions. */#ifdef V7#include <sys/types.h>#include <sys/stat.h>#define STAT#include <sgtty.h>#define OS "V7/BSD"#define ROPMODE "r"#ifdef LLITOUTlong Locmode;		/* Saved "local mode" for 4.x BSD "new driver" */long Locbit = LLITOUT;	/* Bit SUPPOSED to disable output translations */#include <strings.h>#endif#endif#ifndef OS#ifndef USG#define USG#endif#endif#ifdef USG#include <sys/types.h>#include <sys/stat.h>#define STAT#include <termio.h>#define OS "SYS III/V"#define ROPMODE "r"#define MODE2OK#include <string.h>#endif#ifdef T6K#include <sys/ioctl.h>		/* JPRadley: for the Tandy 6000 */#endif#include <setjmp.h>#if HOWMANY  > 255Howmany must be 255 or less#endif /* *  Some systems (Venix, Coherent, Regulus) may not support tty raw mode *  read(2) the same way as Unix. ONEREAD must be defined to force one *  character reads for these systems. Added 7-01-84 CAF */#define sendline(c) putc(c & 0377, Ttystream)#define xsendline(c) putc(c, Ttystream)FILE *Ttystream;int Tty;char linbuf[HOWMANY];char xXbuf[BUFSIZ];int Lleft=0;		/* number of characters in linbuf */jmp_buf tohere;		/* For the interrupt on RX timeout */#ifdef ONEREAD/* Sorry, Regulus and some others don't work right in raw mode! */int Readnum = 1;	/* Number of bytes to ask for in read() from modem */#elseint Readnum = HOWMANY;	/* Number of bytes to ask for in read() from modem */#endifint Verbose=0;struct {	unsigned baudr;	int speedcode;} speeds[] = {	110,	B110,	300,	B300,	600,	B600,	1200,	B1200,	2400,	B2400,	4800,	B4800,	9600,	B9600,	19200,	EXTA,	38400,	EXTB,	0,};int Twostop;		/* Use two stop bits *//* *  The following uses an external rdchk() routine if available, *  otherwise defines the function for BSD or fakes it for SYSV. */#ifndef READCHECK#ifdef FIONREAD#define READCHECK/* *  Return non 0 iff something to read from io descriptor f */rdchk(f){	static long lf;	ioctl(f, FIONREAD, &lf);	return ((int) lf);}#else		/* FIONREAD */#ifdef SV#define READCHECK#include <fcntl.h>int checked = 0;/* * Nonblocking I/O is a bit different in System V, Release 2 *  Note: this rdchk vsn throws away a byte, OK for ZMODEM *  sender because protocol design anticipates this problem. */#define EATSITrdchk(f){	int lf, savestat;	static char bchecked;	savestat = fcntl(f, F_GETFL) ;	fcntl(f, F_SETFL, savestat | O_NDELAY) ;	lf = read(f, &bchecked, 1) ;	fcntl(f, F_SETFL, savestat) ;	checked = bchecked & 0377;	/* force unsigned byte */	return(lf) ;}#endif#endif#endifstatic unsignedgetspeed(code){	register n;	for (n=0; speeds[n].baudr; ++n)		if (speeds[n].speedcode == code)			return speeds[n].baudr;	return 38400;	/* Assume fifo if ioctl failed */}#ifdef ICANONstruct termio oldtty, tty;#elsestruct sgttyb oldtty, tty;struct tchars oldtch, tch;#endif/* * mode(n) *  3: save old tty stat, set raw mode with flow control *  2: set XON/XOFF for sb/sz with ZMODEM or YMODEM-g *  1: save old tty stat, set raw mode  *  0: restore original tty mode */mode(n){	static did0 = FALSE;	vfile("mode:%d", n);	switch(n) {#ifdef USG	case 2:		/* Un-raw mode used by sz, sb when -g detected */		if(!did0)			(void) ioctl(Tty, TCGETA, &oldtty);		tty = oldtty;		tty.c_iflag = BRKINT|IXON;		tty.c_oflag = 0;	/* Transparent output */		tty.c_cflag &= ~(PARENB|HUPCL);		/* Disable parity */		tty.c_cflag |= (CREAD|CS8);	/* Set character size = 8 */		if (Twostop)			tty.c_cflag |= CSTOPB;	/* Set two stop bits */#ifdef READCHECK		tty.c_lflag = Zmodem ? 0 : ISIG;		tty.c_cc[VINTR] = Zmodem ? -1:030;	/* Interrupt char */#else		tty.c_lflag = ISIG;		tty.c_cc[VINTR] = Zmodem ? 03:030;	/* Interrupt char */#endif		tty.c_cc[VQUIT] = -1;			/* Quit char */#ifdef NFGVMIN		tty.c_cc[VMIN] = 1;#else		tty.c_cc[VMIN] = 3;	 /* This many chars satisfies reads */#endif		tty.c_cc[VTIME] = 1;	/* or in this many tenths of seconds */		(void) ioctl(Tty, TCSETAW, &tty);		did0 = TRUE;		return OK;	case 1:	case 3:		if(!did0)			(void) ioctl(Tty, TCGETA, &oldtty);		tty = oldtty;		tty.c_iflag = n==3 ? (IGNBRK|IXOFF) : IGNBRK;		 /* No echo, crlf mapping, INTR, QUIT, delays, no erase/kill */		tty.c_lflag &= ~(ECHO | ICANON | ISIG);		tty.c_oflag = 0;	/* Transparent output */		tty.c_cflag &= ~PARENB;	/* Same baud rate, disable parity */		tty.c_cflag |= CS8;	/* Set character size = 8 */		if (Twostop)			tty.c_cflag |= CSTOPB;	/* Set two stop bits */#ifdef NFGVMIN		tty.c_cc[VMIN] = 1; /* This many chars satisfies reads */#else		tty.c_cc[VMIN] = HOWMANY; /* This many chars satisfies reads */#endif		tty.c_cc[VTIME] = 1;	/* or in this many tenths of seconds */		(void) ioctl(Tty, TCSETAW, &tty);		did0 = TRUE;		Effbaud = Baudrate = getspeed(tty.c_cflag & CBAUD);		return OK;#endif#ifdef V7	/*	 *  NOTE: this should transmit all 8 bits and at the same time	 *   respond to XOFF/XON flow control.  If no FIONREAD or other	 *   rdchk() alternative, also must respond to INTRRUPT char	 *   This doesn't work with V7.  It should work with LLITOUT,	 *   but LLITOUT was broken on the machine I tried it on.	 */	case 2:		/* Un-raw mode used by sz, sb when -g detected */		if(!did0) {			ioctl(Tty, TIOCEXCL, 0);			ioctl(Tty, TIOCGETP, &oldtty);			ioctl(Tty, TIOCGETC, &oldtch);#ifdef LLITOUT			ioctl(Tty, TIOCLGET, &Locmode);#endif		}		tty = oldtty;		tch = oldtch;#ifdef READCHECK		tch.t_intrc = Zmodem ? -1:030;	/* Interrupt char */#else		tch.t_intrc = Zmodem ? 03:030;	/* Interrupt char */#endif		tty.sg_flags |= (ODDP|EVENP|CBREAK);		tty.sg_flags &= ~(ALLDELAY|CRMOD|ECHO|LCASE);		ioctl(Tty, TIOCSETP, &tty);		ioctl(Tty, TIOCSETC, &tch);#ifdef LLITOUT		ioctl(Tty, TIOCLBIS, &Locbit);#endif		bibi(99);	/* un-raw doesn't work w/o lit out */		did0 = TRUE;		return OK;	case 1:	case 3:		if(!did0) {			ioctl(Tty, TIOCEXCL, 0);			ioctl(Tty, TIOCGETP, &oldtty);			ioctl(Tty, TIOCGETC, &oldtch);#ifdef LLITOUT			ioctl(Tty, TIOCLGET, &Locmode);#endif		}		tty = oldtty;		tty.sg_flags |= (RAW|TANDEM);		tty.sg_flags &= ~ECHO;		ioctl(Tty, TIOCSETP, &tty);		did0 = TRUE;		Effbaud = Baudrate = getspeed(tty.sg_ospeed);		return OK;#endif	case 0:		if(!did0)			return ERROR;#ifdef USG		(void) ioctl(Tty, TCSBRK, 1);	/* Wait for output to drain */		(void) ioctl(Tty, TCFLSH, 1);	/* Flush input queue */		(void) ioctl(Tty, TCSETAW, &oldtty);	/* Restore modes */		(void) ioctl(Tty, TCXONC,1);	/* Restart output */#endif#ifdef V7		ioctl(Tty, TIOCSETP, &oldtty);		ioctl(Tty, TIOCSETC, &oldtch);		ioctl(Tty, TIOCNXCL, 0);#ifdef LLITOUT		ioctl(Tty, TIOCLSET, &Locmode);#endif#endif		return OK;	default:		return ERROR;	}}sendbrk(){#ifdef V7#ifdef TIOCSBRK#define CANBREAK	sleep(1);	ioctl(Tty, TIOCSBRK, 0);	sleep(1);	ioctl(Tty, TIOCCBRK, 0);#endif#endif#ifdef USG#define CANBREAK	ioctl(Tty, TCSBRK, 0);#endif}/* Initialize tty device for serial file xfer */inittty(){#if 0	Tty = open("/dev/tty", 2);	if (Tty < 0) {		perror("/dev/tty");  exit(2);	}	Ttystream = fdopen(Tty, "w");#else	Ttystream = fdopen(1, "w");#endif	setbuf(Ttystream, xXbuf);		}flushmoc(){	fflush(Ttystream);}flushmo(){	fflush(Ttystream);}/* * This version of readline is reasoably well suited for * reading many characters. * * timeout is in tenths of seconds */void alrm(){	longjmp(tohere, -1);}readline(timeout)int timeout;{	register n;	static char *cdq;	/* pointer for removing chars from linbuf */	if (--Lleft >= 0) {		if (Verbose > 8) {			fprintf(stderr, "%02x ", *cdq&0377);		}		return (*cdq++ & 0377);	}	n = timeout/10;	if (n < 2)		n = 3;	if (Verbose > 5)		fprintf(stderr, "Calling read: alarm=%d  Readnum=%d ",		  n, Readnum);	if (setjmp(tohere)) {#ifdef TIOCFLUSH/*		ioctl(Tty, TIOCFLUSH, 0); */#endif		Lleft = 0;		if (Verbose>1)			fprintf(stderr, "Readline:TIMEOUT\n");		return TIMEOUT;	}	signal(SIGALRM, alrm); alarm(n);	errno = 0;	Lleft=read(Tty, cdq=linbuf, Readnum);	alarm(0);	if (Verbose > 5) {		fprintf(stderr, "Read returned %d bytes errno=%d\n",		  Lleft, errno);	}	if (Lleft < 1)		return TIMEOUT;	--Lleft;	if (Verbose > 8) {		fprintf(stderr, "%02x ", *cdq&0377);	}	return (*cdq++ & 0377);}/* * Purge the modem input queue of all characters */purgeline(){	Lleft = 0;#ifdef USG	ioctl(Tty, TCFLSH, 0);#else	lseek(Tty, 0L, 2);#endif}/* send cancel string to get the other end to shut up */canit(){	static char canistr[] = {	 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0	};	zmputs(canistr);	Lleft=0;	/* Do read next time ... */}/* * Send a string to the modem, processing for \336 (sleep 1 sec) *   and \335 (break signal) */zmputs(s)char *s;{	register c;	while (*s) {		switch (c = *s++) {		case '\336':			sleep(1); continue;		case '\335':			sendbrk(); continue;		default:			sendline(c);		}	}	flushmo();}/* VARARGS1 */vfile(f, a, b, c, d)char *f;long a, b, c, d;{	if (Verbose > 2) {		fprintf(stderr, f, a, b, c, d);		fprintf(stderr, "\n");	}}/* End of rbsb.c */

⌨️ 快捷键说明

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