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

📄 ttn.c

📁 操作系统源代码
💻 C
字号:
/*ttn.c*/#ifndef _POSIX_SOURCE#define _POSIX_SOURCE 1#endif#include <sys/types.h>#include <sys/ioctl.h>#include <assert.h>#include <errno.h>#include <fcntl.h>#include <termios.h>#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <net/hton.h>#include <net/netlib.h>#include <net/gen/in.h>#include <net/gen/inet.h>#include <net/gen/netdb.h>#include <net/gen/tcp.h>#include <net/gen/tcp_io.h>#include "ttn.h"#if __STDC__#define PROTOTYPE(func,args) func args#else#define PROTOTYPE(func,args) func()#endifPROTOTYPE (int main, (int argc, char *argv[]) );static int do_read(int fd, char *buf, unsigned len);static void screen(void);static void keyboard (void);static int process_opt (char *bp, int count);static void do_option (int optsrt);static void dont_option (int optsrt);static void will_option (int optsrt);static void wont_option (int optsrt);static int writeall (int fd, char *buffer, int buf_size);static int sb_termtype (char *sb, int count);#if DEBUG#define where() (fprintf(stderr, "%s %d:", __FILE__, __LINE__))#endifstatic char *prog_name;static tcp_fd;static char *term_env;main(argc, argv)int argc;char *argv[];{	struct hostent *hostent;	struct servent *servent;	ipaddr_t host;	tcpport_t port;	int pid, ppid;	nwio_tcpconf_t tcpconf;	int result, count;	nwio_tcpcl_t tcpconnopt;	char buffer[1024];	struct termios termios;	char *tcp_device;	prog_name= argv[0];	if (argc <2 || argc>3)	{		fprintf(stderr, "Usage: %s host <port>\r\n", argv[0]);		exit(1);	}	hostent= gethostbyname(argv[1]);	if (!hostent)	{		host= inet_addr(argv[1]);		if (host == -1)		{			fprintf(stderr, "%s: unknown host (%s)\r\n",				argv[0], argv[1]);			exit(1);		}	}	else		host= *(ipaddr_t *)(hostent->h_addr);	if (argc < 3)		port= htons(TCPPORT_TELNET);	else	{		servent= getservbyname (argv[2], "tcp");		if (!servent)		{			port= htons(strtol (argv[2], (char **)0, 0));			if (!port)			{				fprintf(stderr, "%s: unknown port (%s)\r\n",					argv[0], argv[2]);				exit(1);			}		}		else			port= (tcpport_t)(servent->s_port);	}	printf("connecting to %s %u\r\n", inet_ntoa(host), ntohs(port));	tcp_device= getenv("TCP_DEVICE");	if (tcp_device == NULL)		tcp_device= TCP_DEVICE;	tcp_fd= open (tcp_device, O_RDWR);	if (tcp_fd<0)	{		perror ("unable to open /dev/tcp");		exit(1);	}	tcpconf.nwtc_flags= NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;	tcpconf.nwtc_remaddr= host;	tcpconf.nwtc_remport= port;	result= ioctl (tcp_fd, NWIOSTCPCONF, &tcpconf);	if (result<0)	{		perror ("unable to NWIOSTCPCONF");		exit(1);	}	tcpconnopt.nwtcl_flags= 0;	while(1)	{		result= ioctl (tcp_fd, NWIOTCPCONN, &tcpconnopt);		if (result < 0 && errno == EAGAIN)		{			fprintf(stderr,"%s: got EAGAIN, sleeping(1s)\r\n",				prog_name);			sleep(1);		} else			break;	}	if (result<0)	{		perror ("unable to NWIOTCPCONN");		exit(1);	}	printf("Connected\r\n");	ppid= getpid();	pid= fork();	switch(pid)	{	case 0:		keyboard();#if DEBUGfprintf(stderr, "killing %d with %d\r\n", ppid, SIGKILL);#endif		kill(ppid, SIGKILL);		break;	case -1:		fprintf(stderr, "%s: fork failed: %s\r\n", argv[0],			strerror(errno));		exit(1);		break;	default:		tcgetattr(0, &termios);		screen();#if DEBUGfprintf(stderr, "killing %d with %d\r\n", pid, SIGKILL);#endif		kill(pid, SIGKILL);		tcsetattr(0, TCSANOW, &termios);		break;	}}static int do_read(fd, buf, len)int fd;char *buf;unsigned len;{#if __minix_vmd	nwio_tcpopt_t tcpopt;	int count;	for (;;)	{		count= read (fd, buf, len);		if (count <0)		{			if (errno == EURG || errno == ENOURG)			{				/* Toggle urgent mode. */				tcpopt.nwto_flags= errno == EURG ?					NWTO_RCV_URG : NWTO_RCV_NOTURG;				if (ioctl(tcp_fd, NWIOSTCPOPT, &tcpopt) == -1)				{					return -1;				}				continue;			}			return -1;		}		return count;	}#else	return read(fd, buf, len);#endif}static void screen(){	char buffer[1024], *bp, *iacptr;	int count, optsize;	for (;;)	{		count= do_read (tcp_fd, buffer, sizeof(buffer));#if DEBUG && 0 { where(); fprintf(stderr, "read %d bytes\r\n", count); }#endif		if (count <0)		{			perror ("read");			return;		}		if (!count)			return;		bp= buffer;		do		{			iacptr= memchr (bp, IAC, count);			if (!iacptr)			{				write(1, bp, count);				count= 0;			}			if (iacptr && iacptr>bp)			{#if DEBUG  { where(); fprintf(stderr, "iacptr-bp= %d\r\n", iacptr-bp); }#endif				write(1, bp, iacptr-bp);				count -= (iacptr-bp);				bp= iacptr;				continue;			}			if (iacptr)			{assert (iacptr == bp);				optsize= process_opt(bp, count);#if DEBUG && 0 { where(); fprintf(stderr, "process_opt(...)= %d\r\n", optsize); }#endif				if (optsize<0)					return;assert (optsize);				bp += optsize;				count -= optsize;			}		} while (count);	}}static void keyboard(){	nwio_tcpatt_t nwio_tcpatt;	char buffer[1024];	int result;	int count;	nwio_tcpatt.nwta_flags= 0;	for (;;)	{		count= read (0, buffer, sizeof(buffer));		if (count<0)		{			fprintf(stderr, "%s: read: %s\r\n", prog_name,			strerror(errno));			return;		}		if (!count)			return;#if DEBUG && 0 { where(); fprintf(stderr, "writing %d bytes\r\n", count); }#endif		count= write(tcp_fd, buffer, count);#if 0		if (buffer[0] == '\r')			write(tcp_fd, "\n", 1);#endif		if (count<0)		{			perror("write");			return;		}		if (!count)			return;	}}#define next_char(var) \	if (offset<count) { (var) = bp[offset++]; } \	else if (do_read(tcp_fd, (char *)&(var), 1) <= 0) \	{ perror ("read"); return -1; }static int process_opt (char *bp, int count){	unsigned char iac, command, optsrt, sb_command;	int offset, result;	;#if DEBUG && 0 { where(); fprintf(stderr, "process_opt(bp= 0x%x, count= %d)\r\n",	bp, count); }#endif	offset= 0;assert (count);	next_char(iac);assert (iac == IAC);	next_char(command);	switch(command)	{	case IAC_NOP:		break;	case IAC_DataMark:fprintf(stderr, "got a DataMark\r\n");		break;	case IAC_BRK:fprintf(stderr, "got a BRK\r\n");		break;	case IAC_IP:fprintf(stderr, "got a IP\r\n");		break;	case IAC_AO:fprintf(stderr, "got a AO\r\n");		break;	case IAC_AYT:fprintf(stderr, "got a AYT\r\n");		break;	case IAC_EC:fprintf(stderr, "got a EC\r\n");		break;	case IAC_EL:fprintf(stderr, "got a EL\r\n");		break;	case IAC_GA:fprintf(stderr, "got a GA\r\n");		break;	case IAC_SB:		next_char(sb_command);		switch (sb_command)		{		case OPT_TERMTYPE:#if DEBUG && 0fprintf(stderr, "got SB TERMINAL-TYPE\r\n");#endif			result= sb_termtype(bp+offset, count-offset);			if (result<0)				return result;			else				return result+offset;		default:fprintf(stderr, "got an unknown SB (skiping)\r\n");			for (;;)			{				next_char(iac);				if (iac != IAC)					continue;				next_char(optsrt);				if (optsrt == IAC)					continue;if (optsrt != IAC_SE)	fprintf(stderr, "got IAC %d\r\n", optsrt);				break;			}		}		break;	case IAC_WILL:		next_char(optsrt);		will_option(optsrt);		break;	case IAC_WONT:		next_char(optsrt);		wont_option(optsrt);		break;	case IAC_DO:		next_char(optsrt);		do_option(optsrt);		break;	case IAC_DONT:		next_char(optsrt);		dont_option(optsrt);		break;	case IAC:fprintf(stderr, "got a IAC\r\n");		break;	default:fprintf(stderr, "got unknown command (%d)\r\n", command);	}	return offset;}static void do_option (int optsrt){	unsigned char reply[3], *rp;	int count, result;	switch (optsrt)	{	case OPT_TERMTYPE:		if (WILL_terminal_type)			return;		if (!WILL_terminal_type_allowed)		{			reply[0]= IAC;			reply[1]= IAC_WONT;			reply[2]= optsrt;		}		else		{			WILL_terminal_type= TRUE;			term_env= getenv("TERM");			if (!term_env)				term_env= "unknown";			reply[0]= IAC;			reply[1]= IAC_WILL;			reply[2]= optsrt;		}		break;	default:#if DEBUG { where(); fprintf(stderr, "got a DO (%d)\r\n", optsrt); }#endif#if DEBUG { where(); fprintf(stderr, "WONT (%d)\r\n", optsrt); }#endif		reply[0]= IAC;		reply[1]= IAC_WONT;		reply[2]= optsrt;		break;	}	result= writeall(tcp_fd, (char *)reply, 3);	if (result<0)		perror("write");}static void will_option (int optsrt){	unsigned char reply[3], *rp;	int count, result;	switch (optsrt)	{	case OPT_ECHO:		if (DO_echo)			break;		if (!DO_echo_allowed)		{			reply[0]= IAC;			reply[1]= IAC_DONT;			reply[2]= optsrt;		}		else		{			struct termios termios;			tcgetattr(0, &termios);			termios.c_iflag &= ~(ICRNL|IGNCR|INLCR|IXON|IXOFF);			termios.c_oflag &= ~(OPOST);			termios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG);			tcsetattr(0, TCSANOW, &termios);			DO_echo= TRUE;			reply[0]= IAC;			reply[1]= IAC_DO;			reply[2]= optsrt;		}		result= writeall(tcp_fd, (char *)reply, 3);		if (result<0)			perror("write");		break;	case OPT_SUPP_GA:		if (DO_suppress_go_ahead)			break;		if (!DO_suppress_go_ahead_allowed)		{			reply[0]= IAC;			reply[1]= IAC_DONT;			reply[2]= optsrt;		}		else		{			DO_suppress_go_ahead= TRUE;			reply[0]= IAC;			reply[1]= IAC_DO;			reply[2]= optsrt;		}		result= writeall(tcp_fd, (char *)reply, 3);		if (result<0)			perror("write");		break;	default:#if DEBUG { where(); fprintf(stderr, "got a WILL (%d)\r\n", optsrt); }#endif#if DEBUG { where(); fprintf(stderr, "DONT (%d)\r\n", optsrt); }#endif		reply[0]= IAC;		reply[1]= IAC_DONT;		reply[2]= optsrt;		result= writeall(tcp_fd, (char *)reply, 3);		if (result<0)			perror("write");		break;	}}static int writeall (fd, buffer, buf_size)int fd;char *buffer;int buf_size;{	int result;	while (buf_size)	{		result= write (fd, buffer, buf_size);		if (result <= 0)			return -1;assert (result <= buf_size);		buffer += result;		buf_size -= result;	}	return 0;}static void dont_option (int optsrt){	unsigned char reply[3], *rp;	int count, result;	switch (optsrt)	{	default:#if DEBUG { where(); fprintf(stderr, "got a DONT (%d)\r\n", optsrt); }#endif		break;	}}static void wont_option (int optsrt){	unsigned char reply[3], *rp;	int count, result;	switch (optsrt)	{	default:#if DEBUG { where(); fprintf(stderr, "got a WONT (%d)\r\n", optsrt); }#endif		break;	}}static int sb_termtype (char *bp, int count){	unsigned char command, iac, optsrt;	unsigned char buffer[4];	int offset, result;	offset= 0;	next_char(command);	if (command == TERMTYPE_SEND)	{		buffer[0]= IAC;		buffer[1]= IAC_SB;		buffer[2]= OPT_TERMTYPE;		buffer[3]= TERMTYPE_IS;		result= writeall(tcp_fd, (char *)buffer,4);		if (result<0)			return result;		count= strlen(term_env);		if (!count)		{			term_env= "unknown";			count= strlen(term_env);		}		result= writeall(tcp_fd, term_env, count);		if (result<0)			return result;		buffer[0]= IAC;		buffer[1]= IAC_SE;		result= writeall(tcp_fd, (char *)buffer,2);		if (result<0)			return result;	}	else	{#if DEBUG where();#endif		fprintf(stderr, "got an unknown command (skipping)\r\n");	}	for (;;)	{		next_char(iac);		if (iac != IAC)			continue;		next_char(optsrt);		if (optsrt == IAC)			continue;		if (optsrt != IAC_SE)		{#if DEBUG where();#endif			fprintf(stderr, "got IAC %d\r\n", optsrt);		}		break;	}	return offset;}

⌨️ 快捷键说明

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