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

📄 tty.c

📁 使用Modem发送网上传呼
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	-*- mode: c; mode: fold -*-	*//*{{{	includes */# include	"config.h"# include	<stdio.h># include	<stdlib.h># include	<stdarg.h># include	<ctype.h># include	<unistd.h># include	<fcntl.h># include	<string.h># include	<termios.h># include	<errno.h># include	<signal.h># include	<sys/time.h># include	<sys/types.h># include	<sys/stat.h># if		HAVE_SYS_SELECT_H# include	<sys/select.h># endif		/* HAVE_SYS_SELECT_H */# if		HAVE_SYS_SYSMACROS_H# include	<sys/sysmacros.h># elif		HAVE_SYS_MKDEV_H# include	<sys/mkdev.h># else		/* ! HAVE_SYS_SYSMACROS_H && ! HAVE_SYS_MKDEV_H */# define	major(xx)	(((xx) >> 8) & 0xff)# define	minor(xx)	((xx) & 0xff)# endif		/* HAVE_SYS_SYSMACROS_H || HAVE_SYS_MKDEV_H */# include	"pager.h"/*}}}*//*{{{	statics and typedefs */static struct {	int	speed;	speed_t	tok;}	stab[] = {	{	   300,	B300	},	{	  1200,	B1200	},	{	  2400,	B2400	},	{	  4800,	B4800	},	{	  9600,	B9600	},	{	 19200,	B19200	},	{	 38400,	B38400	},# ifdef		B57600	{	 57600,	B57600	},# endif		/* B57600 */# ifdef		B115200	{	115200, B115200	},# endif		/* B115200 */# ifdef		B230400	{	230400, B230400	},# endif		/* B230400 */# ifdef		B460800	{	460800, B460800	},# endif		/* B460800 */	{	-1,	B9600	}};static char	*lckmth[] = {	"ascii",	"binary",	"lower",	"upper",	"sysv4",	"timeout",	NULL};typedef struct {# ifndef	NDEBUG# define	MAGIC		MKMAGIC ('t', 't', 'y', '\0')	long		magic;# endif		/* NDEBUG */	char		*lck;	char		*device;	struct termios	tty, sav;	int		fd;	string_t	*line;	char		*sep;	void		(*callback) (void *, string_t *, char_t, void *);	void		*data;	Bool		suspend;}	serial;typedef struct _expect {	int	idx;	char	*str;	int	pos;	int	len;	struct _expect		*next;}	expect;/*}}}*//*{{{	support routines */static char *mkprint (char *str, int len){	static char	*buf = NULL;	static int	size = 0;	int		n;	char		ch;	char		extra;	char		*ptr;	if (len >= size) {		size = len + 128;		if (! (buf = Realloc (buf, size + 2)))			return NULL;	}	extra = '\0';	for (n = 0; len > 0; ++str, --len) {		if (n + 8 >= size) {			size += 128;			if (! (buf = Realloc (buf, size + 2)))				break;		}		ch = *str;		if (ch & 0x80) {			buf[n++] = '<';			buf[n++] = 'M';			buf[n++] = '-';			ch &= 0x7f;			extra = '>';		}		switch (ch) {		case '\x00':	ptr = "<nul>";	break;		case '\x01':	ptr = "<soh>";	break;		case '\x02':	ptr = "<stx>";	break;		case '\x03':	ptr = "<etx>";	break;		case '\x04':	ptr = "<eot>";	break;		case '\x05':	ptr = "<enq>";	break;		case '\x06':	ptr = "<ack>";	break;		case '\x07':	ptr = "<bel>";	break;		case '\x08':	ptr = "<bs>";	break;		case '\x09':	ptr = "<ht>";	break;		case '\x0a':	ptr = "<lf>";	break;		case '\x0b':	ptr = "<vt>";	break;		case '\x0c':	ptr = "<ff>";	break;		case '\x0d':	ptr = "<cr>";	break;		case '\x0e':	ptr = "<so>";	break;		case '\x0f':	ptr = "<si>";	break;		case '\x10':	ptr = "<dle>";	break;		case '\x11':	ptr = "<dc1>";	break;		case '\x12':	ptr = "<dc2>";	break;		case '\x13':	ptr = "<dc3>";	break;		case '\x14':	ptr = "<dc4>";	break;		case '\x15':	ptr = "<nak>";	break;		case '\x16':	ptr = "<syn>";	break;		case '\x17':	ptr = "<etb>";	break;		case '\x18':	ptr = "<can>";	break;		case '\x19':	ptr = "<em>";	break;		case '\x1a':	ptr = "<sub>";	break;		case '\x1b':	ptr = "<esc>";	break;		case '\x1c':	ptr = "<fs>";	break;		case '\x1d':	ptr = "<gs>";	break;		case '\x1e':	ptr = "<rs>";	break;		case '\x1f':	ptr = "<us>";	break;		case '\x7f':	ptr = "<del>";	break;		default:			ptr = NULL;			buf[n++] = ch;			break;		}		if (ptr)			while (*ptr)				buf[n++] = *ptr++;		if (extra) {			buf[n++] = extra;			extra = '\0';		}	}	if (buf)		buf[n] = '\0';	return buf;}static inline voidmsleep (int msec){	struct timeval	tv;	if (msec > 0) {		do {			tv.tv_sec = msec / 1000;			tv.tv_usec = (msec % 1000) * 1000;			errno = 0;		}	while ((select (0, NULL, NULL, NULL, & tv) < 0) && (errno == EINTR));	}}static inline intdata_ready (int fd, int *msec){	int		ret = 0;	struct timeval	tv;	fd_set		fset;		FD_ZERO (& fset);	FD_SET (fd, & fset);	tv.tv_sec = *msec / 1000;	tv.tv_usec = (*msec % 1000) * 1000;	if (((ret = select (fd + 1, & fset, NULL, NULL, & tv)) > 0) && FD_ISSET (fd, & fset)) {		*msec = tv.tv_sec * 1000 + (tv.tv_usec / 1000);		return 1;	}	return ret;}static Booldo_lock (serial *s, char *dev, char *prefix, char *method){	Bool		binary;	Bool		lower, upper;	Bool		sysv4;	int		tout;	struct stat	st;	char		*ptr, *sav, *val;	int		len;	char		*bdev;	int		fd;	char		buf[32];	int		n, m;	pid_t		pid;	s -> lck = NULL;	if (prefix) {		binary = False;		lower = False;		upper = False;		sysv4 = False;		tout = 0;		if (method && (method = strdup (method))) {			for (ptr = method; *ptr; ) {				sav = ptr;				ptr = skipch (ptr, ',');				val = skipch (sav, '=');				len = strlen (sav);				for (n = 0; lckmth[n]; ++n)					if (! strncmp (lckmth[n], sav, len))						break;				switch (n) {				case 0:		/* ascii */					binary = False;					break;				case 1:		/* binary */					binary = True;					break;				case 2:		/* lower */					lower = True;					upper = False;					break;				case 3:		/* upper */					lower = False;					upper = True;					break;				case 4:		/* sysv4 */					sysv4 = True;					break;				case 5:		/* timeout */					tout = atoi (val);					break;				}			}			free (method);		}		if (sysv4) {			bdev = NULL;			if ((stat (dev, & st) != -1) && S_ISCHR (st.st_mode) && (bdev = malloc (96)))				sprintf (bdev, "%03d.%03d.%03d", major (st.st_dev), major (st.st_rdev), minor (st.st_rdev));		} else {			if (bdev = strrchr (dev, '/'))				++bdev;			else				bdev = dev;			bdev = strdup (bdev);		}		len = strlen (prefix);		if (bdev && (s -> lck = malloc (len + strlen (bdev) + 4))) {			sprintf (s -> lck, "%s%s", prefix, bdev);			free (bdev);			if (upper || lower) {				ptr = s -> lck + len;				while (*ptr) {					if (lower)						*ptr = tolower (*ptr);					else if (upper)						*ptr = toupper (*ptr);					++ptr;				}			}			do {				for (n = 0; n < 2; ++n) {					if ((fd = open (s -> lck, O_CREAT | O_EXCL | O_WRONLY, 0600)) != -1)						break;					if ((! n) && ((fd = open (s -> lck, O_RDONLY)) != -1)) {						pid = 0;						if (binary) {							if (read (fd, & pid, sizeof (pid)) != sizeof (pid))								pid = 0;						} else {							if ((m = read (fd, buf, sizeof (buf) - 1)) > 1) {								buf[m - 1] = '\0';								pid = (int) atoi (buf);							}						}						close (fd);						fd = -1;						if ((pid > 0) && (kill (pid, 0) < 0) && (errno == ESRCH))							unlink (s -> lck);						else							break;					}				}				if ((fd < 0) && (tout > 0))					sleep (1);			}	while ((fd < 0) && (tout-- > 0));			if (fd != -1) {				pid = getpid ();				if (binary)					write (fd, & pid, sizeof (pid));				else {					sprintf (buf, "%10d\n", (int) pid);					write (fd, buf, strlen (buf));				}# if		HAVE_FCHMOD								fchmod (fd, 0644);# else		/* HAVE_FCHMOD */				chmod (s -> lck, 0644);# endif		/* HAVE_FCHMOD */# if		HAVE_FCHOWN								fchown (fd, geteuid (), getegid ());# else		/* HAVE_FCHOWN */				chown (s -> lck, geteuid (), getegid ());# endif		/* HAVE_FCHOWN */				close (fd);			} else {				free (s -> lck);				s -> lck = NULL;				return False;			}		} else {			if (bdev)				free (bdev);			return False;		}	}	return True;}static voiddo_unlock (serial *s){	if (s -> lck) {		unlink (s -> lck);		free (s -> lck);		s -> lck = NULL;	}}/*}}}*//*{{{	open/close/reopen */void *tty_open (char *dev, char *lckprefix, char *lckmethod){	serial	*s;	int	n;		if (s = (serial *) malloc (sizeof (serial))) {# ifndef	NDEBUG		s -> magic = MAGIC;# endif		/* NDEBUG */		if (do_lock (s, dev, lckprefix, lckmethod)) {			if ((s -> fd = open (dev, O_RDWR)) != -1) {				n = tcgetattr (s -> fd, & s -> sav);				if ((n < 0) || (! (s -> device = strdup (dev)))) {					close (s -> fd);					do_unlock (s);					free (s);					s = NULL;				} else {					s -> tty = s -> sav;					s -> line = NULL;					s -> sep = NULL;					s -> callback = NULL;					s -> data = NULL;					s -> suspend = False;				}			} else {				do_unlock (s);				free (s);				s = NULL;			}		} else {			free (s);			s = NULL;		}	}	return s;}void *tty_close (void *sp){	serial	*s = (serial *) sp;	MCHK (s);	if (s) {		if (s -> fd != -1) {			tcsetattr (s -> fd, TCSANOW, & s -> sav);			close (s -> fd);		}		do_unlock (s);		if (s -> device)			free (s -> device);		if (s -> sep)			free (s -> sep);		if (s -> line)			sfree (s -> line);		free (s);	}	return NULL;}Booltty_reopen (void *sp, int msec){	serial	*s = (serial *) sp;	MCHK (s);	if (s -> fd != -1) {		close (s -> fd);		if (msec > 0)			msleep (msec);		s -> fd = -1;	}	if (s -> device && ((s -> fd = open (s -> device, O_RDWR)) != -1))		tcsetattr (s -> fd, TCSANOW, & s -> tty);	return s -> fd != -1 ? True : False;}/*}}}*//*{{{	hangup, get fd */voidtty_hangup (void *sp, int msec){	serial		*s = (serial *) sp;	struct termios	tmp;	MCHK (s);	V (2, ("[Hangup] "));	if (s && (s -> fd != -1)) {		tmp = s -> tty;		cfsetispeed (& tmp, B0);		cfsetospeed (& tmp, B0);		if (tcsetattr (s -> fd, TCSANOW, & tmp) != -1) {			msleep (msec);			tcsetattr (s -> fd, TCSANOW, & s -> tty);		}		tty_reopen (s, msec);	}	V (2, ("\n"));}inttty_fd (void *sp){	serial	*s = (serial *) sp;		MCHK (s);	return s ? s -> fd : -1;}/*}}}*//*{{{	configuration */inttty_setup (void *sp, Bool raw, Bool modem, int speed, int bpb, int sb, char par){	serial	*s = (serial *) sp;	int	n;	MCHK (s);	if ((! s) || (s -> fd < 0))		return -1;	if ((bpb < 5) || (bpb > 8) ||	    ((sb != 1) && (sb != 2)) ||	    ((par != 'n') && (par != 'e') && (par != 'o')))		return -1;	for (n = 0; stab[n].speed > 0; ++n)		if (stab[n].speed == speed)			break;	if (stab[n].speed < 0)		return -1;	if (raw) {		s -> tty.c_iflag &= ~(IGNCR | ICRNL | INLCR | ISTRIP | IXON | IXOFF);		s -> tty.c_iflag |= IGNBRK;		s -> tty.c_oflag = 0;		s -> tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG);# ifdef		CRTSCTS# ifdef		sun		/* SunOS 4.x needs RTSCTS off if carrier detect is on */		/* but there is no carrier present (fkk) */		s -> tty.c_cflag &= ~CRTSCTS;# else		/* sun */		s -> tty.c_cflag |= CRTSCTS;# endif		/* sun */# endif		/* CRTSCTS */		s -> tty.c_cc[VMIN] = 0;		s -> tty.c_cc[VTIME] = 0;	} else {		s -> tty = s -> sav;		s -> tty.c_lflag |= ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG;	}	if (modem) {# if	0				s -> tty.c_cflag &= ~CLOCAL;# else		s -> tty.c_cflag |= CLOCAL;# endif				s -> tty.c_cflag |= HUPCL;	} else {		s -> tty.c_cflag |= CLOCAL;		s -> tty.c_cflag &= ~HUPCL;	}	cfsetispeed (& s -> tty, stab[n].tok);	cfsetospeed (& s -> tty, stab[n].tok);	s -> tty.c_cflag &= ~(CSIZE);	s -> tty.c_cflag |= CREAD;	switch (sb) {	default:	case 1:	s -> tty.c_cflag &= ~CSTOPB;	break;	case 2:	s -> tty.c_cflag |= CSTOPB;	break;	}	switch (bpb) {	case 5:	s -> tty.c_cflag |= CS5;	break;	case 6:	s -> tty.c_cflag |= CS6;	break;	case 7:	s -> tty.c_cflag |= CS7;	break;	default:	case 8:	s -> tty.c_cflag |= CS8;	break;	}	switch (par) {	default:	case 'n':		s -> tty.c_cflag &= ~PARENB;		break;	case 'e':		s -> tty.c_cflag &= ~PARODD;		s -> tty.c_cflag |= PARENB;		break;	case 'o':		s -> tty.c_cflag |= PARENB | PARODD;		break;	}	return tcsetattr (s -> fd, TCSANOW, & s -> tty) < 0 ? -1 : 0;}/*}}}*//*{{{	callback */voidtty_set_line_callback (void *sp, void (*func) (void *, string_t *, char_t, void *), char *sep, void *data){	serial	*s = (serial *) sp;		MCHK (s);	if (s) {		if (! (s -> callback = func)) {			if (s -> line)				s -> line = sfree (s -> line);			if (s -> sep) {				free (s -> sep);				s -> sep = NULL;			}			s -> data = NULL;		} else {

⌨️ 快捷键说明

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