tnclass.cpp
上传用户:tigerk9
上传日期:2020-03-10
资源大小:237k
文件大小:11k
源码类别:

Telnet客户端

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //Telnet Win32 : an ANSI telnet client.
  3. //Copyright (C) 1998  Paul Brannan
  4. //Copyright (C) 1998  I.Ioannou
  5. //Copyright (C) 1997  Brad Johnson
  6. //
  7. //This program is free software; you can redistribute it and/or
  8. //modify it under the terms of the GNU General Public License
  9. //as published by the Free Software Foundation; either version 2
  10. //of the License, or (at your option) any later version.
  11. //
  12. //This program is distributed in the hope that it will be useful,
  13. //but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. //GNU General Public License for more details.
  16. //
  17. //You should have received a copy of the GNU General Public License
  18. //along with this program; if not, write to the Free Software
  19. //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. //
  21. //I.Ioannou
  22. //roryt@hol.gr
  23. //
  24. ///////////////////////////////////////////////////////////////////////////
  25. ///////////////////////////////////////////////////////////////////////////////
  26. //
  27. // Module: tnclass.cpp
  28. //
  29. // Contents: telnet object definition
  30. //
  31. // Product: telnet
  32. //
  33. // Revisions: August 30, 1998 Paul Brannan <pbranna@clemson.edu>
  34. //            July 12, 1998 Paul Brannan
  35. //            June 15, 1998 Paul Brannan
  36. //            May 14, 1998 Paul Brannan
  37. //            5.April.1997 jbj@nounname.com
  38. //            14.Sept.1996 jbj@nounname.com
  39. //            Version 2.0
  40. //
  41. ///////////////////////////////////////////////////////////////////////////////
  42. #include <stdlib.h>
  43. #include <string.h>
  44. #include "tnclass.h"
  45. #include "tnmisc.h"
  46. // Mingw32 needs these (Paul Brannan 9/4/98)
  47. #ifndef ICON_SMALL
  48. #define ICON_SMALL 0
  49. #endif
  50. #ifndef ICON_BIG
  51. #define ICON_BIG 1
  52. #endif
  53. // Ioannou Dec. 8, 1998
  54. #ifdef __BORLANDC__
  55. #ifndef WM_SETICON
  56. #define WM_SETICON STM_SETICON
  57. #endif
  58. #endif
  59. // DoInit() - performs initialization that is common to both the
  60. // constructors (Paul Brannan 6/15/98)
  61. void Telnet::DoInit() {
  62. Socket = INVALID_SOCKET;
  63. bConnected = 0;
  64. bNetPaused = 1;
  65. bNetFinished = 1;
  66. bNetFinish = 0;
  67. hThread = 0; // Sam Robertson 12/7/98
  68. hProcess = 0;
  69. WSADATA WsaData;
  70. // Set the title
  71. telSetConsoleTitle("No Connection");
  72. // Change the icon
  73. hConsoleWindow = GetConsoleWindow();
  74. iconChange = SetIcon(hConsoleWindow, 0, &oldBIcon, &oldSIcon, ini.get_startdir());
  75. if (WSAStartup(MAKEWORD(1, 1), &WsaData)) {
  76. DWORD dwLastError = GetLastError();
  77. printm(0, FALSE, MSG_ERROR, "WSAStartup()");
  78. printm(0, TRUE, dwLastError);
  79. bWinsockUp = 0;
  80. return;
  81. }
  82. bWinsockUp = 1;
  83. // Get keyfile (Paul Brannan 5/12/98)
  84. const char *keyfile = ini.get_keyfile();
  85. // This should be changed later to use the Tnerror routines
  86. // This has been done (Paul Brannan 6/5/98)
  87. if(LoadKeyMap( keyfile, ini.get_default_config()) != 1)
  88. // printf("Error loading keymap.n");
  89. printm(0, FALSE, MSG_ERRKEYMAP);
  90. }
  91. Telnet::Telnet():
  92. MapLoader(KeyTrans, Charmap),
  93. Console(GetStdHandle(STD_OUTPUT_HANDLE)),
  94. TelHandler(Network, Console, Parser),
  95. ThreadParams(TelHandler),
  96. Clipboard(GetConsoleWindow(), Network),
  97. Mouse(Clipboard),
  98. Scroller(Mouse, ini.get_scroll_size()),
  99. Parser(Console, KeyTrans, Scroller, Network, Charmap) {
  100. DoInit();
  101. }
  102. Telnet::Telnet(const char * szHost1, const char *strPort1):
  103. MapLoader(KeyTrans, Charmap),
  104. Console(GetStdHandle(STD_OUTPUT_HANDLE)),
  105. TelHandler(Network, Console, Parser),
  106. ThreadParams(TelHandler),
  107. Clipboard(GetConsoleWindow(), Network),
  108. Mouse(Clipboard),
  109. Scroller(Mouse, ini.get_scroll_size()),
  110. Parser(Console, KeyTrans, Scroller, Network, Charmap) {
  111. DoInit();
  112. Open( szHost1, strPort1);
  113. }
  114. Telnet::~Telnet(){
  115. if (bWinsockUp){
  116. if(bConnected) Close();
  117. WSACleanup();
  118. }
  119. // Paul Brannan 8/10/98
  120. if(iconChange) {
  121. ResetIcon(hConsoleWindow, oldBIcon, oldSIcon);
  122. }
  123. }
  124. // changed from char * to const char * (Paul Brannan 5/12/98)
  125. int Telnet::LoadKeyMap(const char * file, const char * name){
  126. // printf("Loading %s from %s.n", name ,file);
  127. printm(0, FALSE, MSG_KEYMAP, name, file);
  128. return MapLoader.Load(file,name);
  129. }
  130. void Telnet::DisplayKeyMap(){ // display available keymaps
  131. MapLoader.Display();
  132. };
  133. int  Telnet::SwitchKeyMap(int to) { // switch to selected keymap
  134. int ret = KeyTrans.SwitchTo(to);
  135. switch(ret) {
  136. case -1: printm(0, FALSE, MSG_KEYNOKEYMAPS); break;
  137. case 0: printm(0, FALSE, MSG_KEYBADMAP); break;
  138. case 1: printm(0, FALSE, MSG_KEYMAPSWITCHED); break;
  139. }
  140. return ret;
  141. };
  142. int Telnet::Open(const char *szHost1, const char *strPort1){
  143. if (bWinsockUp && !bConnected){
  144. telSetConsoleTitle(szHost1);
  145. strncpy (szHost,szHost1, 127);
  146. strncpy(strPort, strPort1, sizeof(strPort));
  147. // Determine whether to pipe to an executable or use our own sockets
  148. // (Paul Brannan March 18, 1999)
  149. const char *netpipe;
  150. if(*(netpipe=ini.get_netpipe())) {
  151. PROCESS_INFORMATION pi;
  152. HANDLE hInWrite, hOutRead, hErrRead;
  153. if(!CreateHiddenConsoleProcess(netpipe, &pi, &hInWrite,
  154. &hOutRead, &hErrRead)) {
  155. printm(0, FALSE, MSG_ERRPIPE);
  156. return TNNOCON;
  157. }
  158. Network.SetPipe(hOutRead, hInWrite);
  159. hProcess = pi.hProcess;
  160. } else {
  161. Socket = Connect();
  162. if (Socket == INVALID_SOCKET) {
  163. printm(0, FALSE, GetLastError());
  164. return TNNOCON;
  165. }
  166. Network.SetSocket(Socket);
  167. SetLocalAddress(Socket);
  168. }
  169. bNetFinish = 0;
  170. bConnected = 1;
  171. ThreadParams.p.bNetPaused = &bNetPaused;
  172. ThreadParams.p.bNetFinish = &bNetFinish;
  173. ThreadParams.p.bNetFinished = &bNetFinished;
  174. ThreadParams.p.hExit = CreateEvent(0, TRUE, FALSE, "");
  175. ThreadParams.p.hPause = CreateEvent(0, FALSE, FALSE, "");
  176. ThreadParams.p.hUnPause = CreateEvent(0, FALSE, FALSE, "");
  177. DWORD idThread;
  178. // Disable Ctrl-break (PB 5/14/98);
  179. // Fixed (Thomas Briggs 8/17/98)
  180.         if(ini.get_disable_break() || ini.get_control_break_as_c())
  181. SetConsoleCtrlHandler(ControlEventHandler, TRUE);
  182. hThread = CreateThread(0, 0,
  183. (LPTHREAD_START_ROUTINE) telProcessNetwork,
  184. (LPVOID)&ThreadParams, 0, &idThread);
  185. // This helps the display thread a little (Paul Brannan 8/3/98)
  186. SetThreadPriority(hThread, THREAD_PRIORITY_ABOVE_NORMAL);
  187. return Resume();
  188. } else if(bWinsockUp && bConnected) {
  189. printm (0, FALSE, MSG_ALREADYCONNECTED, szHost);
  190. }
  191.  
  192. return TNNOCON; // cannot do winsock stuff or already connected
  193. }
  194. // There seems to be a bug with MSVC's optimization.  This turns them off
  195. // for these two functions.
  196. // (Paul Brannan 5/14/98)
  197. #ifdef _MSC_VER
  198. #pragma optimize("", off)
  199. #endif
  200. int Telnet::Close() {
  201. Console.sync();
  202. switch(Network.get_net_type()) {
  203. case TN_NETSOCKET:
  204. if(Socket != INVALID_SOCKET) closesocket(Socket);
  205. Socket = INVALID_SOCKET;
  206. break;
  207. case TN_NETPIPE:
  208. if(hProcess != 0) {
  209. TerminateProcess(hProcess, 0);
  210. CloseHandle(hProcess);
  211. hProcess = 0;
  212. }
  213. break;
  214. }
  215. // Enable Ctrl-break (PB 5/14/98);
  216. // Ioannou : this must be FALSE
  217.     if(ini.get_disable_break()) SetConsoleCtrlHandler(NULL, FALSE);
  218. if (hThread) CloseHandle(hThread); // Paul Brannan 8/11/98
  219. hThread = NULL; // Daniel Straub 11/12/98
  220. SetEvent(ThreadParams.p.hUnPause);
  221. bNetFinish = 1;
  222. while (!bNetFinished)
  223. Sleep (0); // give up our time slice- this lets our connection thread
  224. // finish itself, so we don't hang -crn@ozemail.com.au
  225. telSetConsoleTitle("No Connection");
  226. bConnected = 0;
  227. return 1;
  228. }
  229. int Telnet::Resume(){
  230. int i;
  231. if (bConnected) {
  232. Console.sync();
  233. for(;;){
  234. SetEvent(ThreadParams.p.hUnPause);
  235. i = telProcessConsole(&ThreadParams.p, KeyTrans, Console,
  236. Network, Mouse, Clipboard, hThread);
  237. if (i) bConnected = 1;
  238. else bConnected = 0;
  239. ResetEvent(ThreadParams.p.hUnPause);
  240. SetEvent(ThreadParams.p.hPause);
  241. while (!bNetPaused)
  242. Sleep (0); // give up our time slice- this lets our connection thread
  243. // unpause itself, so we don't hang -crn@ozemail.com.au
  244. switch (i){
  245. case TNNOCON:
  246. Close();
  247. return TNDONE;
  248. case TNPROMPT:
  249. return TNPROMPT;
  250. case TNSCROLLBACK:
  251. Scroller.ScrollBack();
  252. break;
  253. case TNSPAWN:
  254. NewProcess();
  255. }
  256. }
  257. }
  258. return TNNOCON;
  259. }
  260. // Turn optimization back on (Paul Brannan 5/12/98)
  261. #ifdef _MSC_VER
  262. #pragma optimize("", on)
  263. #endif
  264. // The scrollback functions have been moved to TScroll.cpp
  265. // (Paul Brannan 6/15/98)
  266. SOCKET Telnet::Connect()
  267. {
  268. SOCKET Socket1 = socket(AF_INET, SOCK_STREAM, 0);
  269. SOCKADDR_IN SockAddr;
  270. SockAddr.sin_family = AF_INET;
  271. SockAddr.sin_addr.s_addr = inet_addr(szHost);
  272. // determine the port correctly -crn@ozemail.com.au 15/12/98
  273. SERVENT *sp;
  274. sp = getservbyname (strPort, "tcp");
  275. if (sp == NULL) {
  276. if (isdigit (*(strPort)))
  277. SockAddr.sin_port = htons(atoi(strPort));
  278. else {
  279. printm(0, FALSE, MSG_NOSERVICE, strPort);
  280. return INVALID_SOCKET;
  281. }
  282. } else
  283. SockAddr.sin_port = sp->s_port;
  284. ///
  285. // Were we given host name?
  286. if (SockAddr.sin_addr.s_addr == INADDR_NONE) {
  287. // Resolve host name to IP address.
  288. printm(0, FALSE, MSG_RESOLVING, szHost);
  289. hostent* pHostEnt = gethostbyname(szHost);
  290. if (!pHostEnt)
  291. return INVALID_SOCKET;
  292. printit("n");
  293. SockAddr.sin_addr.s_addr = *(DWORD*)pHostEnt->h_addr;
  294. }
  295. // Print a message telling the user the IP we are connecting to
  296. // (Paul Brannan 5/14/98)
  297. char ss_b1[4], ss_b2[4], ss_b3[4], ss_b4[4], ss_b5[12];
  298. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b1, ss_b1, 10);
  299. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b2, ss_b2, 10);
  300. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b3, ss_b3, 10);
  301. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b4, ss_b4, 10);
  302. itoa(ntohs(SockAddr.sin_port), ss_b5, 10);
  303. printm(0, FALSE, MSG_TRYING, ss_b1, ss_b2, ss_b3, ss_b4, ss_b5);
  304. if (connect(Socket1, (sockaddr*)&SockAddr, sizeof(SockAddr)))
  305. return INVALID_SOCKET;
  306. char esc[2];
  307. esc [0] = ini.get_escape_key();
  308. esc [1] = 0;
  309. printm(0, FALSE, MSG_CONNECTED, szHost, esc);
  310. return Socket1;
  311. }
  312. void Telnet::telSetConsoleTitle(const char * szHost1)
  313. {
  314. char szTitle[128] = "Telnet - ";
  315. strcat(szTitle, szHost1);
  316. if(ini.get_set_title()) SetConsoleTitle(szTitle);
  317. }
  318. void Telnet::NewProcess() {
  319. char cmd_line[MAX_PATH*2];
  320. PROCESS_INFORMATION pi;
  321. strcpy(cmd_line, ini.get_startdir());
  322. strcat(cmd_line, ini.get_exename()); // Thomas Briggs 12/7/98
  323. if(!SpawnProcess(cmd_line, &pi)) printm(0, FALSE, MSG_NOSPAWN);
  324. }
  325. void Telnet::SetLocalAddress(SOCKET s) {
  326. SOCKADDR_IN SockAddr;
  327. int size = sizeof(SOCKADDR_IN);
  328. memset(&SockAddr, 0, sizeof(SockAddr));
  329. SockAddr.sin_family = AF_INET;
  330. getsockname(Network.GetSocket(), (sockaddr*)&SockAddr, &size);
  331. char ss_b1[4], ss_b2[4], ss_b3[4], ss_b4[4];
  332. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b1, ss_b1, 10);
  333. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b2, ss_b2, 10);
  334. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b3, ss_b3, 10);
  335. itoa(SockAddr.sin_addr.S_un.S_un_b.s_b4, ss_b4, 10);
  336. char addr[40];
  337. strcpy(addr, ss_b1);
  338. strcat(addr, ".");
  339. strcat(addr, ss_b2);
  340. strcat(addr, ".");
  341. strcat(addr, ss_b3);
  342. strcat(addr, ".");
  343. strcat(addr, ss_b4);
  344. strcat(addr, ":0.0");
  345. Network.SetLocalAddress(addr);
  346. }