Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396/////////////////////////////////////////////////////////////////////////////////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: tnclass.cpp//// Contents: telnet object definition//// Product: telnet//// Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu>// July 12, 1998 Paul Brannan// June 15, 1998 Paul Brannan// May 14, 1998 Paul Brannan// 5.April.1997 jbj@nounname.com// 14.Sept.1996 jbj@nounname.com// Version 2.0/////////////////////////////////////////////////////////////////////////////////
#include "precomp.h"
// Mingw32 needs these (Paul Brannan 9/4/98)#ifndef ICON_SMALL#define ICON_SMALL 0#endif#ifndef ICON_BIG#define ICON_BIG 1#endif
// Ioannou Dec. 8, 1998#ifdef __BORLANDC__#ifndef WM_SETICON#define WM_SETICON STM_SETICON#endif#endif
// DoInit() - performs initialization that is common to both the// constructors (Paul Brannan 6/15/98)void Telnet::DoInit() { Socket = INVALID_SOCKET; bConnected = 0; bNetPaused = 1; bNetFinished = 1; bNetFinish = 0; hThread = 0; // Sam Robertson 12/7/98 hProcess = 0;
WSADATA WsaData;
// Set the title telSetConsoleTitle("No Connection");
// Change the icon hConsoleWindow = TelnetGetConsoleWindow(); iconChange = SetIcon(hConsoleWindow, 0, &oldBIcon, &oldSIcon, ini.get_startdir());
if (WSAStartup(MAKEWORD(1, 1), &WsaData)) { DWORD dwLastError = GetLastError(); printm(0, FALSE, MSG_ERROR, "WSAStartup()"); printm(0, TRUE, dwLastError); bWinsockUp = 0; return; } bWinsockUp = 1;
// Get keyfile (Paul Brannan 5/12/98) const char *keyfile = ini.get_keyfile();
// This should be changed later to use the Tnerror routines // This has been done (Paul Brannan 6/5/98) if(LoadKeyMap( keyfile, ini.get_default_config()) != 1) // printf("Error loading keymap.\n"); printm(0, FALSE, MSG_ERRKEYMAP);}
Telnet::Telnet():MapLoader(KeyTrans, Charmap),Console(GetStdHandle(STD_OUTPUT_HANDLE)),TelHandler(Network, Console, Parser),ThreadParams(TelHandler),Clipboard(TelnetGetConsoleWindow(), Network),Mouse(Clipboard),Scroller(Mouse, ini.get_scroll_size()),Parser(Console, KeyTrans, Scroller, Network, Charmap) { DoInit();}
Telnet::Telnet(const char * szHost1, const char *strPort1):MapLoader(KeyTrans, Charmap),Console(GetStdHandle(STD_OUTPUT_HANDLE)),TelHandler(Network, Console, Parser),ThreadParams(TelHandler),Clipboard(TelnetGetConsoleWindow(), Network),Mouse(Clipboard),Scroller(Mouse, ini.get_scroll_size()),Parser(Console, KeyTrans, Scroller, Network, Charmap) { DoInit(); Open( szHost1, strPort1);}
Telnet::~Telnet(){ if (bWinsockUp){ if(bConnected) Close(); WSACleanup(); }
// Paul Brannan 8/10/98 if(iconChange) { ResetIcon(hConsoleWindow, oldBIcon, oldSIcon); }
}
// changed from char * to const char * (Paul Brannan 5/12/98)int Telnet::LoadKeyMap(const char * file, const char * name){ // printf("Loading %s from %s.\n", name ,file); printm(0, FALSE, MSG_KEYMAP, name, file); return MapLoader.Load(file,name);}
void Telnet::DisplayKeyMap(){ // display available keymaps MapLoader.Display();};
int Telnet::SwitchKeyMap(int to) { // switch to selected keymap int ret = KeyTrans.SwitchTo(to); switch(ret) { case -1: printm(0, FALSE, MSG_KEYNOKEYMAPS); break; case 0: printm(0, FALSE, MSG_KEYBADMAP); break; case 1: printm(0, FALSE, MSG_KEYMAPSWITCHED); break; } return ret;};
int Telnet::Open(const char *szHost1, const char *strPort1){ if (bWinsockUp && !bConnected){ telSetConsoleTitle(szHost1);
strncpy (szHost,szHost1, 127); strncpy(strPort, strPort1, sizeof(strPort));
// Determine whether to pipe to an executable or use our own sockets // (Paul Brannan March 18, 1999) const char *netpipe; if(*(netpipe=ini.get_netpipe())) { PROCESS_INFORMATION pi; HANDLE hInWrite, hOutRead, hErrRead; if(!CreateHiddenConsoleProcess(netpipe, &pi, &hInWrite, &hOutRead, &hErrRead)) { printm(0, FALSE, MSG_ERRPIPE); return TNNOCON; } Network.SetPipe(hOutRead, hInWrite); hProcess = pi.hProcess; } else { Socket = Connect(); if (Socket == INVALID_SOCKET) { printm(0, FALSE, GetLastError()); return TNNOCON; } Network.SetSocket(Socket); SetLocalAddress(Socket); }
bNetFinish = 0; bConnected = 1; ThreadParams.p.bNetPaused = &bNetPaused; ThreadParams.p.bNetFinish = &bNetFinish; ThreadParams.p.bNetFinished = &bNetFinished; ThreadParams.p.hExit = CreateEvent(0, TRUE, FALSE, ""); ThreadParams.p.hPause = CreateEvent(0, FALSE, FALSE, ""); ThreadParams.p.hUnPause = CreateEvent(0, FALSE, FALSE, ""); DWORD idThread;
// Disable Ctrl-break (PB 5/14/98); // Fixed (Thomas Briggs 8/17/98) if(ini.get_disable_break() || ini.get_control_break_as_c()) SetConsoleCtrlHandler(ControlEventHandler, TRUE);
hThread = CreateThread(0, 0, telProcessNetwork, (LPVOID)&ThreadParams, 0, &idThread); // This helps the display thread a little (Paul Brannan 8/3/98) SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); return Resume(); } else if(bWinsockUp && bConnected) { printm (0, FALSE, MSG_ALREADYCONNECTED, szHost); }
return TNNOCON; // cannot do winsock stuff or already connected}
// There seems to be a bug with MSVC's optimization. This turns them off// for these two functions.// (Paul Brannan 5/14/98)#ifdef _MSC_VER#pragma optimize("", off)#endif
int Telnet::Close() { Console.sync(); switch(Network.get_net_type()) { case TN_NETSOCKET: if(Socket != INVALID_SOCKET) closesocket(Socket); Socket = INVALID_SOCKET; break; case TN_NETPIPE: if(hProcess != 0) { TerminateProcess(hProcess, 0); CloseHandle(hProcess); hProcess = 0; } break; }
// Enable Ctrl-break (PB 5/14/98); // Ioannou : this must be FALSE if(ini.get_disable_break()) SetConsoleCtrlHandler(NULL, FALSE);
if (hThread) CloseHandle(hThread); // Paul Brannan 8/11/98 hThread = NULL; // Daniel Straub 11/12/98
SetEvent(ThreadParams.p.hUnPause); bNetFinish = 1; while (!bNetFinished) Sleep (0); // give up our time slice- this lets our connection thread // finish itself, so we don't hang -crn@ozemail.com.au telSetConsoleTitle("No Connection"); bConnected = 0; return 1;}
int Telnet::Resume(){ int i; if (bConnected) { Console.sync(); for(;;){ SetEvent(ThreadParams.p.hUnPause); i = telProcessConsole(&ThreadParams.p, KeyTrans, Console, Network, Mouse, Clipboard, hThread); if (i) bConnected = 1; else bConnected = 0; ResetEvent(ThreadParams.p.hUnPause); SetEvent(ThreadParams.p.hPause); while (!bNetPaused) Sleep (0); // give up our time slice- this lets our connection thread // unpause itself, so we don't hang -crn@ozemail.com.au switch (i){ case TNNOCON: Close(); return TNDONE; case TNPROMPT: return TNPROMPT; case TNSCROLLBACK: Scroller.ScrollBack(); break; case TNSPAWN: NewProcess(); } } } return TNNOCON;}
// Turn optimization back on (Paul Brannan 5/12/98)#ifdef _MSC_VER#pragma optimize("", on)#endif
// The scrollback functions have been moved to TScroll.cpp// (Paul Brannan 6/15/98)SOCKET Telnet::Connect(){ SOCKET Socket1 = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN SockAddr; SockAddr.sin_family = AF_INET; SockAddr.sin_addr.s_addr = inet_addr(szHost);
// determine the port correctly -crn@ozemail.com.au 15/12/98 SERVENT *sp; sp = getservbyname (strPort, "tcp"); if (sp == NULL) { if (isdigit (*(strPort))) SockAddr.sin_port = htons(atoi(strPort)); else { printm(0, FALSE, MSG_NOSERVICE, strPort); return INVALID_SOCKET; } } else SockAddr.sin_port = sp->s_port; ///
// Were we given host name? if (SockAddr.sin_addr.s_addr == INADDR_NONE) {
// Resolve host name to IP address. printm(0, FALSE, MSG_RESOLVING, szHost); hostent* pHostEnt = gethostbyname(szHost); if (!pHostEnt) return INVALID_SOCKET; printit("\n");
SockAddr.sin_addr.s_addr = *(DWORD*)pHostEnt->h_addr; }
// Print a message telling the user the IP we are connecting to // (Paul Brannan 5/14/98) char ss_b1[4], ss_b2[4], ss_b3[4], ss_b4[4], ss_b5[12]; itoa(SockAddr.sin_addr.S_un.S_un_b.s_b1, ss_b1, 10); itoa(SockAddr.sin_addr.S_un.S_un_b.s_b2, ss_b2, 10); itoa(SockAddr.sin_addr.S_un.S_un_b.s_b3, ss_b3, 10); itoa(SockAddr.sin_addr.S_un.S_un_b.s_b4, ss_b4, 10); itoa(ntohs(SockAddr.sin_port), ss_b5, 10); printm(0, FALSE, MSG_TRYING, ss_b1, ss_b2, ss_b3, ss_b4, ss_b5);
if (connect(Socket1, (sockaddr*)&SockAddr, sizeof(SockAddr))) return INVALID_SOCKET;
char esc[2]; esc [0] = ini.get_escape_key(); esc [1] = 0; printm(0, FALSE, MSG_CONNECTED, szHost, esc);
return Socket1;}
void Telnet::telSetConsoleTitle(const char * szHost1){ char szTitle[128] = "Telnet - "; strcat(szTitle, szHost1); if(ini.get_set_title()) SetConsoleTitle(szTitle);}
void Telnet::NewProcess() { char cmd_line[MAX_PATH*2]; PROCESS_INFORMATION pi;
strcpy(cmd_line, ini.get_startdir()); strcat(cmd_line, ini.get_exename()); // Thomas Briggs 12/7/98
if(!SpawnProcess(cmd_line, &pi)) printm(0, FALSE, MSG_NOSPAWN);}
void Telnet::SetLocalAddress(SOCKET s) { SOCKADDR_IN SockAddr; int size = sizeof(SOCKADDR_IN); memset(&SockAddr, 0, sizeof(SockAddr)); SockAddr.sin_family = AF_INET;
getsockname(Network.GetSocket(), (sockaddr*)&SockAddr, &size); char ss_b1[4], ss_b2[4], ss_b3[4], ss_b4[4]; itoa(SockAddr.sin_addr.S_un.S_un_b.s_b1, ss_b1, 10); itoa(SockAddr.sin_addr.S_un.S_un_b.s_b2, ss_b2, 10); itoa(SockAddr.sin_addr.S_un.S_un_b.s_b3, ss_b3, 10); itoa(SockAddr.sin_addr.S_un.S_un_b.s_b4, ss_b4, 10);
char addr[40]; strcpy(addr, ss_b1); strcat(addr, "."); strcat(addr, ss_b2); strcat(addr, "."); strcat(addr, ss_b3); strcat(addr, "."); strcat(addr, ss_b4); strcat(addr, ":0.0");
Network.SetLocalAddress(addr);}