📄 telnet.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 + -