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