Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentnclass.cpp
Go to the documentation of this file.
00001 00002 //Telnet Win32 : an ANSI telnet client. 00003 //Copyright (C) 1998 Paul Brannan 00004 //Copyright (C) 1998 I.Ioannou 00005 //Copyright (C) 1997 Brad Johnson 00006 // 00007 //This program is free software; you can redistribute it and/or 00008 //modify it under the terms of the GNU General Public License 00009 //as published by the Free Software Foundation; either version 2 00010 //of the License, or (at your option) any later version. 00011 // 00012 //This program is distributed in the hope that it will be useful, 00013 //but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 //GNU General Public License for more details. 00016 // 00017 //You should have received a copy of the GNU General Public License 00018 //along with this program; if not, write to the Free Software 00019 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 // 00021 //I.Ioannou 00022 //roryt@hol.gr 00023 // 00025 00027 // 00028 // Module: tnclass.cpp 00029 // 00030 // Contents: telnet object definition 00031 // 00032 // Product: telnet 00033 // 00034 // Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu> 00035 // July 12, 1998 Paul Brannan 00036 // June 15, 1998 Paul Brannan 00037 // May 14, 1998 Paul Brannan 00038 // 5.April.1997 jbj@nounname.com 00039 // 14.Sept.1996 jbj@nounname.com 00040 // Version 2.0 00041 // 00043 00044 #include "precomp.h" 00045 00046 // Mingw32 needs these (Paul Brannan 9/4/98) 00047 #ifndef ICON_SMALL 00048 #define ICON_SMALL 0 00049 #endif 00050 #ifndef ICON_BIG 00051 #define ICON_BIG 1 00052 #endif 00053 00054 // Ioannou Dec. 8, 1998 00055 #ifdef __BORLANDC__ 00056 #ifndef WM_SETICON 00057 #define WM_SETICON STM_SETICON 00058 #endif 00059 #endif 00060 00061 // DoInit() - performs initialization that is common to both the 00062 // constructors (Paul Brannan 6/15/98) 00063 void Telnet::DoInit() { 00064 Socket = INVALID_SOCKET; 00065 bConnected = 0; 00066 bNetPaused = 1; 00067 bNetFinished = 1; 00068 bNetFinish = 0; 00069 hThread = 0; // Sam Robertson 12/7/98 00070 hProcess = 0; 00071 00072 WSADATA WsaData; 00073 00074 // Set the title 00075 telSetConsoleTitle("No Connection"); 00076 00077 // Change the icon 00078 hConsoleWindow = TelnetGetConsoleWindow(); 00079 iconChange = SetIcon(hConsoleWindow, 0, &oldBIcon, &oldSIcon, ini.get_startdir()); 00080 00081 if (WSAStartup(MAKEWORD(1, 1), &WsaData)) { 00082 DWORD dwLastError = GetLastError(); 00083 printm(0, FALSE, MSG_ERROR, "WSAStartup()"); 00084 printm(0, TRUE, dwLastError); 00085 bWinsockUp = 0; 00086 return; 00087 } 00088 bWinsockUp = 1; 00089 00090 // Get keyfile (Paul Brannan 5/12/98) 00091 const char *keyfile = ini.get_keyfile(); 00092 00093 // This should be changed later to use the Tnerror routines 00094 // This has been done (Paul Brannan 6/5/98) 00095 if(LoadKeyMap( keyfile, ini.get_default_config()) != 1) 00096 // printf("Error loading keymap.\n"); 00097 printm(0, FALSE, MSG_ERRKEYMAP); 00098 } 00099 00100 Telnet::Telnet(): 00101 MapLoader(KeyTrans, Charmap), 00102 Console(GetStdHandle(STD_OUTPUT_HANDLE)), 00103 TelHandler(Network, Console, Parser), 00104 ThreadParams(TelHandler), 00105 Clipboard(TelnetGetConsoleWindow(), Network), 00106 Mouse(Clipboard), 00107 Scroller(Mouse, ini.get_scroll_size()), 00108 Parser(Console, KeyTrans, Scroller, Network, Charmap) { 00109 DoInit(); 00110 } 00111 00112 Telnet::Telnet(const char * szHost1, const char *strPort1): 00113 MapLoader(KeyTrans, Charmap), 00114 Console(GetStdHandle(STD_OUTPUT_HANDLE)), 00115 TelHandler(Network, Console, Parser), 00116 ThreadParams(TelHandler), 00117 Clipboard(TelnetGetConsoleWindow(), Network), 00118 Mouse(Clipboard), 00119 Scroller(Mouse, ini.get_scroll_size()), 00120 Parser(Console, KeyTrans, Scroller, Network, Charmap) { 00121 DoInit(); 00122 Open( szHost1, strPort1); 00123 } 00124 00125 Telnet::~Telnet(){ 00126 if (bWinsockUp){ 00127 if(bConnected) Close(); 00128 WSACleanup(); 00129 } 00130 00131 // Paul Brannan 8/10/98 00132 if(iconChange) { 00133 ResetIcon(hConsoleWindow, oldBIcon, oldSIcon); 00134 } 00135 00136 } 00137 00138 // changed from char * to const char * (Paul Brannan 5/12/98) 00139 int Telnet::LoadKeyMap(const char * file, const char * name){ 00140 // printf("Loading %s from %s.\n", name ,file); 00141 printm(0, FALSE, MSG_KEYMAP, name, file); 00142 return MapLoader.Load(file,name); 00143 } 00144 00145 void Telnet::DisplayKeyMap(){ // display available keymaps 00146 MapLoader.Display(); 00147 }; 00148 00149 int Telnet::SwitchKeyMap(int to) { // switch to selected keymap 00150 int ret = KeyTrans.SwitchTo(to); 00151 switch(ret) { 00152 case -1: printm(0, FALSE, MSG_KEYNOKEYMAPS); break; 00153 case 0: printm(0, FALSE, MSG_KEYBADMAP); break; 00154 case 1: printm(0, FALSE, MSG_KEYMAPSWITCHED); break; 00155 } 00156 return ret; 00157 }; 00158 00159 00160 int Telnet::Open(const char *szHost1, const char *strPort1){ 00161 if (bWinsockUp && !bConnected){ 00162 telSetConsoleTitle(szHost1); 00163 00164 strncpy (szHost,szHost1, 127); 00165 strncpy(strPort, strPort1, sizeof(strPort)); 00166 00167 // Determine whether to pipe to an executable or use our own sockets 00168 // (Paul Brannan March 18, 1999) 00169 const char *netpipe; 00170 if(*(netpipe=ini.get_netpipe())) { 00171 PROCESS_INFORMATION pi; 00172 HANDLE hInWrite, hOutRead, hErrRead; 00173 if(!CreateHiddenConsoleProcess(netpipe, &pi, &hInWrite, 00174 &hOutRead, &hErrRead)) { 00175 printm(0, FALSE, MSG_ERRPIPE); 00176 return TNNOCON; 00177 } 00178 Network.SetPipe(hOutRead, hInWrite); 00179 hProcess = pi.hProcess; 00180 } else { 00181 Socket = Connect(); 00182 if (Socket == INVALID_SOCKET) { 00183 printm(0, FALSE, GetLastError()); 00184 return TNNOCON; 00185 } 00186 Network.SetSocket(Socket); 00187 SetLocalAddress(Socket); 00188 } 00189 00190 bNetFinish = 0; 00191 bConnected = 1; 00192 ThreadParams.p.bNetPaused = &bNetPaused; 00193 ThreadParams.p.bNetFinish = &bNetFinish; 00194 ThreadParams.p.bNetFinished = &bNetFinished; 00195 ThreadParams.p.hExit = CreateEvent(0, TRUE, FALSE, ""); 00196 ThreadParams.p.hPause = CreateEvent(0, FALSE, FALSE, ""); 00197 ThreadParams.p.hUnPause = CreateEvent(0, FALSE, FALSE, ""); 00198 DWORD idThread; 00199 00200 // Disable Ctrl-break (PB 5/14/98); 00201 // Fixed (Thomas Briggs 8/17/98) 00202 if(ini.get_disable_break() || ini.get_control_break_as_c()) 00203 SetConsoleCtrlHandler(ControlEventHandler, TRUE); 00204 00205 hThread = CreateThread(0, 0, 00206 telProcessNetwork, 00207 (LPVOID)&ThreadParams, 0, &idThread); 00208 // This helps the display thread a little (Paul Brannan 8/3/98) 00209 SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL); 00210 return Resume(); 00211 } else if(bWinsockUp && bConnected) { 00212 printm (0, FALSE, MSG_ALREADYCONNECTED, szHost); 00213 } 00214 00215 return TNNOCON; // cannot do winsock stuff or already connected 00216 } 00217 00218 // There seems to be a bug with MSVC's optimization. This turns them off 00219 // for these two functions. 00220 // (Paul Brannan 5/14/98) 00221 #ifdef _MSC_VER 00222 #pragma optimize("", off) 00223 #endif 00224 00225 00226 int Telnet::Close() { 00227 Console.sync(); 00228 switch(Network.get_net_type()) { 00229 case TN_NETSOCKET: 00230 if(Socket != INVALID_SOCKET) closesocket(Socket); 00231 Socket = INVALID_SOCKET; 00232 break; 00233 case TN_NETPIPE: 00234 if(hProcess != 0) { 00235 TerminateProcess(hProcess, 0); 00236 CloseHandle(hProcess); 00237 hProcess = 0; 00238 } 00239 break; 00240 } 00241 00242 // Enable Ctrl-break (PB 5/14/98); 00243 // Ioannou : this must be FALSE 00244 if(ini.get_disable_break()) SetConsoleCtrlHandler(NULL, FALSE); 00245 00246 if (hThread) CloseHandle(hThread); // Paul Brannan 8/11/98 00247 hThread = NULL; // Daniel Straub 11/12/98 00248 00249 SetEvent(ThreadParams.p.hUnPause); 00250 bNetFinish = 1; 00251 while (!bNetFinished) 00252 Sleep (0); // give up our time slice- this lets our connection thread 00253 // finish itself, so we don't hang -crn@ozemail.com.au 00254 telSetConsoleTitle("No Connection"); 00255 bConnected = 0; 00256 return 1; 00257 } 00258 00259 int Telnet::Resume(){ 00260 int i; 00261 if (bConnected) { 00262 Console.sync(); 00263 for(;;){ 00264 SetEvent(ThreadParams.p.hUnPause); 00265 i = telProcessConsole(&ThreadParams.p, KeyTrans, Console, 00266 Network, Mouse, Clipboard, hThread); 00267 if (i) bConnected = 1; 00268 else bConnected = 0; 00269 ResetEvent(ThreadParams.p.hUnPause); 00270 SetEvent(ThreadParams.p.hPause); 00271 while (!bNetPaused) 00272 Sleep (0); // give up our time slice- this lets our connection thread 00273 // unpause itself, so we don't hang -crn@ozemail.com.au 00274 switch (i){ 00275 case TNNOCON: 00276 Close(); 00277 return TNDONE; 00278 case TNPROMPT: 00279 return TNPROMPT; 00280 case TNSCROLLBACK: 00281 Scroller.ScrollBack(); 00282 break; 00283 case TNSPAWN: 00284 NewProcess(); 00285 } 00286 } 00287 } 00288 return TNNOCON; 00289 } 00290 00291 // Turn optimization back on (Paul Brannan 5/12/98) 00292 #ifdef _MSC_VER 00293 #pragma optimize("", on) 00294 #endif 00295 00296 // The scrollback functions have been moved to TScroll.cpp 00297 // (Paul Brannan 6/15/98) 00298 SOCKET Telnet::Connect() 00299 { 00300 SOCKET Socket1 = socket(AF_INET, SOCK_STREAM, 0); 00301 SOCKADDR_IN SockAddr; 00302 SockAddr.sin_family = AF_INET; 00303 SockAddr.sin_addr.s_addr = inet_addr(szHost); 00304 00305 // determine the port correctly -crn@ozemail.com.au 15/12/98 00306 SERVENT *sp; 00307 sp = getservbyname (strPort, "tcp"); 00308 if (sp == NULL) { 00309 if (isdigit (*(strPort))) 00310 SockAddr.sin_port = htons(atoi(strPort)); 00311 else { 00312 printm(0, FALSE, MSG_NOSERVICE, strPort); 00313 return INVALID_SOCKET; 00314 } 00315 } else 00316 SockAddr.sin_port = sp->s_port; 00318 00319 // Were we given host name? 00320 if (SockAddr.sin_addr.s_addr == INADDR_NONE) { 00321 00322 // Resolve host name to IP address. 00323 printm(0, FALSE, MSG_RESOLVING, szHost); 00324 hostent* pHostEnt = gethostbyname(szHost); 00325 if (!pHostEnt) 00326 return INVALID_SOCKET; 00327 printit("\n"); 00328 00329 SockAddr.sin_addr.s_addr = *(DWORD*)pHostEnt->h_addr; 00330 } 00331 00332 // Print a message telling the user the IP we are connecting to 00333 // (Paul Brannan 5/14/98) 00334 char ss_b1[4], ss_b2[4], ss_b3[4], ss_b4[4], ss_b5[12]; 00335 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b1, ss_b1, 10); 00336 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b2, ss_b2, 10); 00337 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b3, ss_b3, 10); 00338 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b4, ss_b4, 10); 00339 itoa(ntohs(SockAddr.sin_port), ss_b5, 10); 00340 printm(0, FALSE, MSG_TRYING, ss_b1, ss_b2, ss_b3, ss_b4, ss_b5); 00341 00342 if (connect(Socket1, (sockaddr*)&SockAddr, sizeof(SockAddr))) 00343 return INVALID_SOCKET; 00344 00345 char esc[2]; 00346 esc [0] = ini.get_escape_key(); 00347 esc [1] = 0; 00348 printm(0, FALSE, MSG_CONNECTED, szHost, esc); 00349 00350 return Socket1; 00351 } 00352 00353 void Telnet::telSetConsoleTitle(const char * szHost1) 00354 { 00355 char szTitle[128] = "Telnet - "; 00356 strcat(szTitle, szHost1); 00357 if(ini.get_set_title()) SetConsoleTitle(szTitle); 00358 } 00359 00360 void Telnet::NewProcess() { 00361 char cmd_line[MAX_PATH*2]; 00362 PROCESS_INFORMATION pi; 00363 00364 strcpy(cmd_line, ini.get_startdir()); 00365 strcat(cmd_line, ini.get_exename()); // Thomas Briggs 12/7/98 00366 00367 if(!SpawnProcess(cmd_line, &pi)) printm(0, FALSE, MSG_NOSPAWN); 00368 } 00369 00370 void Telnet::SetLocalAddress(SOCKET s) { 00371 SOCKADDR_IN SockAddr; 00372 int size = sizeof(SOCKADDR_IN); 00373 memset(&SockAddr, 0, sizeof(SockAddr)); 00374 SockAddr.sin_family = AF_INET; 00375 00376 getsockname(Network.GetSocket(), (sockaddr*)&SockAddr, &size); 00377 char ss_b1[4], ss_b2[4], ss_b3[4], ss_b4[4]; 00378 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b1, ss_b1, 10); 00379 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b2, ss_b2, 10); 00380 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b3, ss_b3, 10); 00381 itoa(SockAddr.sin_addr.S_un.S_un_b.s_b4, ss_b4, 10); 00382 00383 char addr[40]; 00384 strcpy(addr, ss_b1); 00385 strcat(addr, "."); 00386 strcat(addr, ss_b2); 00387 strcat(addr, "."); 00388 strcat(addr, ss_b3); 00389 strcat(addr, "."); 00390 strcat(addr, ss_b4); 00391 strcat(addr, ":0.0"); 00392 00393 Network.SetLocalAddress(addr); 00394 } 00395 Generated on Sun May 27 2012 04:17:17 for ReactOS by
1.7.6.1
|