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

📄 remote.c

📁 Unix下的MUD客户端程序
💻 C
字号:
/* remote.c: Handle I/O to remote */#include "vt.h"#include <errno.h>#include <sys/uio.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#ifdef PROTOTYPESstatic int get_in_addr(char *, struct in_addr *);static void receive_input(Unode *rmt);#elsestatic void receive_input();#endif#ifndef FD_ZEROtypedef struct fd_set_tag {	long masks[9];} DESCR_MASK;#define FD_SET(n, p)   ((p)->masks[(n) / 32] |=	 (1 << ((n) % 32)))#define FD_CLR(n, p)   ((p)->masks[(n) / 32] &= ~(1 << ((n) % 32)))#define FD_ISSET(n, p) ((p)->masks[(n) / 32] &	 (1 << ((n) % 32)))#define FD_ZERO(p)     bzero((p), sizeof(*(p)))#elsetypedef fd_set DESCR_MASK;#endif#define INBUF_SIZE 1024extern int errno, sys_nerr;extern unsigned long inet_addr();Unode rmt_ring;				/* Dummy node for remotes ring */Unode *cur_rmt = NULL;			/* Remote being processed      */String kin;void init_rmt(){	rmt_ring.next = rmt_ring.prev = &rmt_ring;	rmt_ring.dummy = 1;}static int get_in_addr(name, addr)	char *name;	struct in_addr *addr;{	struct hostent *hostent;	if (isdigit(*name)) {		addr->s_addr = inet_addr(name);		return addr->s_addr != -1;	}	hostent = gethostbyname(name);	if (!hostent)		return 0;	bcopy(hostent->h_addr, (char *) addr, sizeof(struct in_addr));	return 1;}Unode *new_rmt(addr, port)	char *addr;	int port;{	struct sockaddr_in saddr;	struct in_addr hostaddr;	int fd;	Unode *rmt; 	saddr.sin_family = AF_INET;	saddr.sin_port = htons(port);	if (!get_in_addr(addr, &hostaddr)) {		vtc_errmsg = "Couldn't find host";		return NULL;	}	vtc_errmsg = NULL;	bcopy(&hostaddr, &saddr.sin_addr, sizeof(struct in_addr));	fd = socket(AF_INET, SOCK_STREAM, 0);	if (fd < 0)		return NULL;	if (connect(fd, &saddr, sizeof(struct sockaddr_in)) < 0) {		close(fd);		return NULL;	}#ifdef FNDELAY	fcntl(fd, F_SETFL, FNDELAY);#endif	rmt = unalloc();	rmt->Raddr = vtstrdup(addr);	rmt->Rport = port;	rmt->Rfd = fd;	rmt->Rbuf = New(String);	*rmt->Rbuf = empty_string;	rmt->Rtelnetbuf = New(String);	*rmt->Rtelnetbuf = empty_string;	rmt->Rwin = NULL;	rmt->Rnetread = NULL;	rmt->Rpromptread = NULL;	rmt->Rrstack = NULL;	rmt->Robj = NULL;	rmt->Rback = rmt->Rbusy = rmt->Rraw = 0;	rmt->Riac = rmt->Rintent = 0;	rmt->Recho = 1;	rmt->Rdisconnected = 0;	rmt->prev = rmt_ring.prev;	rmt->next = &rmt_ring;	rmt_ring.prev = rmt_ring.prev->next = rmt;	return rmt;}void disconnect(rmt)	Unode *rmt;{	Func *func;	Unode *old_rmt;	int ormt_id;	if (rmt->Rdisconnected)		return;	rmt->Rdisconnected = 1;	func = find_func("disconnect_hook");	if (func && func->cmd) {		old_rmt = cur_rmt;		if (cur_rmt)			ormt_id = cur_rmt->id;		cur_rmt = rmt;		run_prog(func->cmd);		cur_rmt = old_rmt && ormt_id == old_rmt->id ? old_rmt : NULL;	}	if (rmt->Rwin) {		rmt->Rwin->Wrmt = NULL;		update_echo_mode();	}	close(rmt->Rfd);	s_free(rmt->Rbuf);	Discard(rmt->Rbuf, String);	rmt->prev->next = rmt->next;	rmt->next->prev = rmt->prev;	if (cur_rmt == rmt)		cur_rmt = NULL;	destroy_pointers(rmt->frefs);	break_pipe(rmt->Rrstack);	discard_unode(rmt);}static void receive_input(rmt)	Unode *rmt;{	int count;	char block[INBUF_SIZE + 1];	do		count = recv(rmt->Rfd, block, INBUF_SIZE, 0);	while (count == -1 && (errno == EINTR || errno == EWOULDBLOCK));	if (count <= 0) {		vtc_errflag = 1;		vtc_errmsg = count ? NULL				   : "Connection closed by foreign host";		disconnect(rmt);		return;	}	block[count] = '\0';	s_acat(rmt->Rbuf, block);	rmt->Rinbuf = 1;}int io_check(sec, usec)	long sec, usec;{	struct timeval tv, *tvp;	DESCR_MASK readers, except;	int count, nfd, fd;	Unode *rp, *next;	char block[INBUF_SIZE + 1];	if (sec == -1) {		tvp = NULL;	} else {		tv.tv_sec = sec;		tv.tv_usec = usec;		tvp = &tv;	}	FD_ZERO(&readers);	FD_ZERO(&except);	FD_SET(0, &readers);	nfd = 1;	for (rp = rmt_ring.next; !rp->dummy; rp = rp->next) {		if ((rp->Rwin || rp->Rback) && !rp->Rbusy) {			fd = rp->Rfd;			FD_SET(fd, &readers);			if (nfd <= fd)				nfd = fd + 1;		}	}	count = select(nfd, &readers, (DESCR_MASK *) NULL, &except, tvp);	if (count == 0 || count == -1 && errno == EINTR)		return 0;	if (count == -1)		operror("select", NULL);	for (rp = rmt_ring.next; !rp->dummy; rp = next) {		next = rp->next;		if ((rp->Rwin || rp->Rback) && !rp->Rbusy) {			if (FD_ISSET(rp->Rfd, &readers))				receive_input(rp);		}	}	if (FD_ISSET(0, &readers)) {		do			count = read(0, block, INBUF_SIZE);		while (count == -1 && errno == EINTR);		s_cat(&kin, cstr_sl(block, count));	}	return 1;}int transmit(rmt, cstr)	Unode *rmt;	Cstr cstr;{	int written;	if (rmt->Rdisconnected)		return -1;	while (cstr.l > 0) {		written = send(rmt->Rfd, cstr.s, cstr.l, 0);		if (written == -1) {			if (errno == EWOULDBLOCK) {				sleep(1);				continue;			}			vtc_errflag = 1;			vtc_errmsg = NULL;			disconnect(rmt);			return -1;		}		cstr.s += written;		cstr.l -= written;		if (cstr.l)			sleep(1);	}	return 0;}int input_waiting(fd)	int fd;{	struct timeval tv;	DESCR_MASK readers;	tv.tv_sec = tv.tv_usec = 0;	FD_ZERO(&readers);	FD_SET(fd, &readers);	return select(fd + 1, &readers, (DESCR_MASK *) NULL,		      (DESCR_MASK *) NULL, &tv);}int process_remote_text(rmt)	Unode *rmt;{	int rid = rmt->id;	char *s;	for (s = rmt->Rbuf->c.s; *s; s++) {		if (!(rmt->Rwin || rmt->Rback) || rmt->Rbusy) {			s_cpy(rmt->Rbuf, cstr_sl(s, rmt->Rbuf->c.l -				(s - rmt->Rbuf->c.s)));			telnet_state_machine(rmt, 0);			return 1;		}		rmt->Rinbuf = (s[1] != 0);		telnet_state_machine(rmt, (unsigned char) *s);		if (rmt->id != rid)			return 0;	}	telnet_state_machine(rmt, 0);	s_term(rmt->Rbuf, 0);	rmt->Rinbuf = (rmt->Rbuf->c.l != 0);	return 1;}void give_remote(rmt, is, isgoahead)	Unode *rmt;	Istr *is;	int isgoahead;{	Func *func;	is->refs++;	if (rmt->Rrstack && !isgoahead) {		resume_istr(&rmt->Rrstack, is);	} else {		func = (isgoahead) ? rmt->Rpromptread : rmt->Rnetread;		if (func) {			run_prog_istr(func->cmd, is, NULL, rmt);		} else {			output(rmt->Rwin, is->rs->str.c.s);			if (!isgoahead)				output(rmt->Rwin, "\n");		}	}	dec_ref_istr(is);}

⌨️ 快捷键说明

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