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

📄 telnet.c

📁 使用BorlandC++4.5编译的一个MUD客户端程序
💻 C
字号:
/* telnet.c: Support telnet protocol */
/* $Id: telnet.c 2.1 1995/10/24 15:46:14 tsurace Release $ */

#include "vt.h"

#define ECHO	01
#define EOR	031
#define GA	0371
#define WILL	0373
#define WONT	0374
#define DO	0375
#define DONT	0376
#define IAC	0377

#ifdef PROTOTYPES
static void handle_echo_option(Unode *);
static void handle_eor_option(Unode *);
static void handle_unsupported_option(Unode *, int);
static void telnet_response(Unode *, int, int);
#else
static void handle_echo_option(), handle_eor_option();
static void handle_unsupported_option(), telnet_response();
#endif

void telnet_state_machine(rmt, c)
	Unode *rmt;
	int c;
{
	String *buf = rmt->Rtelnetbuf;
	char *p;
	int rid;

	if (!c) {
		if (rmt->Rraw && buf->c.l) {
			give_remote(rmt, istr_c(buf->c), 0);
			s_term(buf, 0);
		}
	} else if (!rmt->Riac) {
		switch (c) {
			case IAC:
				rmt->Riac = 1;
				break;
			case '\r':
				if (!rmt->Rraw)
					break;
			case '\n':
				if (!rmt->Rraw) {
					rid = rmt->id;
					give_remote(rmt, istr_c(buf->c), 0);
					if (rid == rmt->id)
						s_term(buf, 0);
					break;
				}
			default:
				s_add(buf, c);
				break;
		}
	} else if (!rmt->Rintent) {
		switch (c) {
			case WILL:
			case WONT:
			case DO:
			case DONT:
				rmt->Rintent = c;
				break;
			case EOR:
				if (!rmt->Reor) {
					rmt->Riac = 0;
					break;
				}
				/* Otherwise fall through. */
			case GA:
				/* Prompt terminator. */
				rid = rmt->id;
				if (rmt->Rraw) {
					p = strrchr(buf->c.s, '\n');
					if (p) {
						p++;
						give_remote(rmt,
						 istr_sl(buf->c.s,
							 p - buf->c.s),
						 0);
						s_delete(buf, 0, p - buf->c.s);
						if (rid != rmt->id)
							break;
					}
				}
				give_remote(rmt, istr_c(buf->c), 1);
				if (rid == rmt->id) {
					s_term(buf, 0);
					rmt->Riac = 0;
				}
				break;
			default:
				rmt->Riac = 0;
				break;
		}
	} else {
		switch(c) {
			case ECHO:
				handle_echo_option(rmt);
				break;
			case EOR:
				handle_eor_option(rmt);
				break;
			default:
				handle_unsupported_option(rmt, c);
				break;
		}
		rmt->Riac = rmt->Rintent = 0;
	}
}

static void handle_echo_option(rmt)
	Unode *rmt;
{
	int mode;

	if ((unsigned char) rmt->Rintent == DO) {
		telnet_response(rmt, WONT, ECHO);
	} else if ((unsigned char) rmt->Rintent != DONT) {
		mode = ((unsigned char) rmt->Rintent == WONT);
		if (rmt->Recho != mode) {
			rmt->Recho = mode;
			telnet_response(rmt, (mode) ? DONT : DO, ECHO);
			update_echo_mode();
		}
	}
}

static void handle_eor_option(rmt)
	Unode *rmt;
{
	int mode;

	if ((unsigned char) rmt->Rintent == DO) {
		telnet_response(rmt, WONT, EOR);
	} else if ((unsigned char) rmt->Rintent != DONT) {
		mode = ((unsigned char) rmt->Rintent == WILL);
		if (rmt->Reor != mode) {
			rmt->Reor = mode;
			telnet_response(rmt, (mode) ? DO : DONT, EOR);
		}
	}
}

static void handle_unsupported_option(rmt, c)
	Unode *rmt;
	int c;
{
	if ((unsigned char) rmt->Rintent == DO)
		telnet_response(rmt, WONT, c);
	else if ((unsigned char) rmt->Rintent == WILL)
		telnet_response(rmt, DONT, c);
}

static void telnet_response(rmt, intent, option)
	Unode *rmt;
	int intent, option;
{
	static char response[3] = { IAC };

	response[1] = intent;
	response[2] = option;
	transmit(rmt, cstr_sl(response, 3));
}

⌨️ 快捷键说明

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