ttelhndl.cpp
来自「一个类似windows」· C++ 代码 · 共 549 行 · 第 1/2 页
CPP
549 行
///////////////////////////////////////////////////////////////////////////////
//Telnet Win32 : an ANSI telnet client.
//Copyright (C) 1998 Paul Brannan
//Copyright (C) 1998 I.Ioannou
//Copyright (C) 1997 Brad Johnson
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//I.Ioannou
//roryt@hol.gr
//
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
//
// Module: ttelhndl.cpp
//
// Contents: Telnet Handler
//
// Product: telnet
//
// Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu>
// June 15, 1998 pbranna@clemson.edu (Paul Brannan)
//
// This is code originally from tnnet.cpp and ansiprsr.cpp
//
///////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include "ttelhndl.h"
#include "telnet.h"
#include "tnconfig.h"
#include "tparams.h"
int naws_string(char *buf, int width, int height);
// This helps make the code more readable (Paul Brannan 1/1/99)
#ifdef DEBUG_TELOPT
#define TELOPT_PRINTD(x) printit(x);
#define TELOPT_PRINTD2(x,n) { \
static char buf[20]; \
printit(s); \
printit(" "); \
itoa(d, buf, 10); \
printit(buf); \
printit("\n"); \
}
#else
#define TELOPT_PRINTD(x) ;
#define TELOPT_PRINTD2(x,n) ;
#endif
// A new print function for debugging (Paul Brannan 5/15/98)
#ifdef DEBUG_TELOPT
void TTelnetHandler::print_telopt(const char *s, int d) {
static char buf[20];
printit(s);
printit(" ");
itoa(d, buf, 10);
printit(buf);
printit("\n");
}
#endif
TTelnetHandler::TTelnetHandler(TNetwork &RefNetwork, TConsole &RefConsole,
TParser &RefParser):
Network(RefNetwork), Console(RefConsole), Parser(RefParser) {
init();
// Paul Brannan 9/13/98
dwBuffer = ini.get_buffer_size();
szBuffer = new char [dwBuffer];
Network.SetNawsFunc(NULL);
}
void TTelnetHandler::init() {
iTermSet = 0;
bInBinaryRx = 0;
bInBinaryTx = 0;
bInEchoTx = 0;
bInEchoRx = 0;
Network.set_local_echo(1);
}
TTelnetHandler::~TTelnetHandler() {
delete[] szBuffer;
}
int TTelnetHandler::escapeIAC(char *buf, int length){
// The size of buffer must be greater than 2 * length to ensure no memory
// out of bounds errors. The 0xff is escaped into 0xff 0xff.
char * temp;
temp = new char [length * 2];
int current=0;
for (int x=0; x < length; x++){
if (buf[x] == (signed char)IAC)
temp[current++]=(char)IAC;
temp[current++]=buf[x];
}
memcpy( buf, temp, current);
delete [] temp;
return current;
}
// This lets us get rid of all the printf's (Paul Brannan 5/15/98)
void TTelnetHandler::SendIAC(char c) {
static char buf[2] = {IAC};
buf[1] = c;
Network.WriteString(buf, 2);
}
void TTelnetHandler::SendIAC(char c1, char c2) {
static char buf[3] = {IAC};
buf[1] = c1; buf[2] = c2;
Network.WriteString(buf, 3);
}
void TTelnetHandler::SendIACParams(char c) {
static char buf[2];
buf[0] = c;
static int length = escapeIAC(buf, 1);
Network.WriteString(buf, length);
}
void TTelnetHandler::SendIACParams(char c1, char c2) {
static char buf[4];
buf[0] = c1; buf[1] = c2;
static int length = escapeIAC(buf, 2);
Network.WriteString(buf, length);
}
int naws_string(char *b, int width, int height) {
int l = 0;
unsigned char *buf = (unsigned char *)b;
union {
char szResponse[2];
int n;
};
buf[l++] = IAC;
buf[l++] = SB;
buf[l++] = TELOPT_NAWS;
n = width;
buf[l] = szResponse[1];
if(buf[l-1] == IAC) buf[l++] = IAC;
buf[l++] = szResponse[0];
if(buf[l-1] == IAC) buf[l++] = IAC;
n = height;
buf[l++] = szResponse[1];
if(buf[l-1] == IAC) buf[l++] = IAC;
buf[l++] = szResponse[0];
if(buf[l-1] == IAC) buf[l++] = IAC;
buf[l++] = IAC;
buf[l++] = SE;
return l;
}
// Ioannou 29 May 1998 : Something strange happens with
// Borland compiler at this point when it passes the arguments
// to SendIACParams. It always sends 80 lines to the server !!!
// There seems to be a bug with optimization (the disassemble shows
// that it uses an address plus 0xa than the right one).
// This turns them off for this point.
#ifdef __BORLANDC__
#pragma -O-
#endif
// Removed old printf code that was commented out to clean this function
// up a bit (Paul brannan 6/15/98)
char* TTelnetHandler::ParseIAC(char* pszBuffer, char* pszBufferEnd)
{
// int n,l;
// char szResponse[40];
// Ioannou 29 May 1998 : I prefer the union redefinitions
// than the typecasting (used with them from Pascal and Cobol :-) )
// FIX ME !!!! Shall we use the winsock routines instead ?
union {
char szResponse[2];
int n;
};
// Added support for user-defined term name (Paul Brannan 5/13/98)
#define LASTTERM 4
const char *pszTerms[] = {ini.get_term(), "ANSI","DEC-VT100","DEC-VT52","UNKNOWN"};
if(!iTermSet && (pszTerms[0] == 0 || *pszTerms[0] == 0)) iTermSet++;
if (pszBuffer + 2 < pszBufferEnd) {
switch ((unsigned char)pszBuffer[1]) {
///////////////// DO ////////////////////
case DO:
{
switch (pszBuffer[2]){
case TELOPT_BINARY:
TELOPT_PRINTD("RCVD DO TELOPT_BINARY\n");
if (!bInBinaryRx){
SendIAC(WILL, TELOPT_BINARY);
bInBinaryRx = 1;
TELOPT_PRINTD("SENT WILL TELOPT_BINARY\n");
}
break;
case TELOPT_ECHO:
// we shouldn't echo for the server! (Paul Brannan 5/30/98)
TELOPT_PRINTD2("RCVD DO TELOPT_ECHO", pszBuffer[2]);
SendIAC(WONT, TELOPT_ECHO);
TELOPT_PRINTD("SENT WONT TELOPT_ECHO\n");
break;
case TELOPT_TTYPE:
TELOPT_PRINTD("RCVD DO TELOPT_TTYPE\n");
SendIAC(WILL, TELOPT_TTYPE);
TELOPT_PRINTD("SENT WILL TELOPT_TTYPE\n");
break;
case TELOPT_NAWS:
TELOPT_PRINTD("RCVD DO TELOPT_NAWS\n");
SendIAC(WILL, TELOPT_NAWS);
SendIAC(SB, TELOPT_NAWS);
Network.SetNawsFunc(naws_string);
n = Console.GetWidth();
SendIACParams(szResponse[1],szResponse [0]);
n = Console.GetHeight();
SendIACParams(szResponse[1],szResponse[0]);
SendIAC(SE);
TELOPT_PRINTD("SENT WILL TELOPT_NAWS\n");
break;
case TELOPT_XDISPLOC:
TELOPT_PRINTD("RCVD DO TELOPT_XDISPLOC\n");
SendIAC(WILL, TELOPT_XDISPLOC);
TELOPT_PRINTD("SENT WILL TELOPT_XDISPLOC\n");
printit("Retrieving IP...");
break;
default:
TELOPT_PRINTD2("RCVD DO", pszBuffer[2]);
SendIAC(WONT, pszBuffer[2]);
TELOPT_PRINTD2("SENT WONT", pszBuffer[2]);
break;
}
if (pszBuffer + 2 < pszBufferEnd)
pszBuffer += 3;
break;
}
///////////////// WILL ////////////////////
case WILL:
{
switch ((unsigned char)pszBuffer[2]){
case TELOPT_BINARY:
TELOPT_PRINTD("RCVD WILL TELOPT_BINARY\n");
if (!bInBinaryTx){
SendIAC(DO, TELOPT_BINARY);
bInBinaryTx = 1;
TELOPT_PRINTD("SENT DO TELOPT_BINARY\n");
}
break;
case TELOPT_ECHO:
TELOPT_PRINTD2("RCVD WILL TELOPT_ECHO", pszBuffer[2]);
if(!bInEchoRx) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?