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