]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/l_net/l_net_wins.c
q3map2 is now waring free
[xonotic/netradiant.git] / libs / l_net / l_net_wins.c
1 /*
2 Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant 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 GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 //===========================================================================
23 //
24 // Name:         l_net_wins.c
25 // Function:     WinSock
26 // Programmer:   MrElusive
27 // Last update:  -
28 // Tab Size:     3
29 // Notes:
30 //===========================================================================
31
32 #include <windows.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include "l_net.h"
37 #include "l_net_wins.h"
38 //#include <winsock.h>
39 //#include "mpdosock.h"
40
41 #define WinError WinPrint
42
43 #define qtrue   1
44 #define qfalse  0
45
46 typedef struct tag_error_struct
47 {
48     int     errnum;
49     LPSTR   errstr;
50 } ERROR_STRUCT;
51
52 #define NET_NAMELEN                     64
53
54 char my_tcpip_address[NET_NAMELEN];
55
56 #define DEFAULTnet_hostport     26000
57
58 #define MAXHOSTNAMELEN          256
59
60 static int net_acceptsocket = -1;               // socket for fielding new connections
61 static int net_controlsocket;
62 static int net_hostport;                                // udp port number for acceptsocket
63 static int net_broadcastsocket = 0;
64 //static qboolean ifbcastinit = qfalse;
65 static struct sockaddr_s broadcastaddr;
66
67 static unsigned long myAddr;
68
69 WSADATA winsockdata;
70
71 ERROR_STRUCT errlist[] = {
72     {WSAEINTR,           "WSAEINTR - Interrupted"},
73     {WSAEBADF,           "WSAEBADF - Bad file number"},
74     {WSAEFAULT,          "WSAEFAULT - Bad address"},
75     {WSAEINVAL,          "WSAEINVAL - Invalid argument"},
76     {WSAEMFILE,          "WSAEMFILE - Too many open files"},
77
78 /*
79 *    Windows Sockets definitions of regular Berkeley error constants
80 */
81
82     {WSAEWOULDBLOCK,     "WSAEWOULDBLOCK - Socket marked as non-blocking"},
83     {WSAEINPROGRESS,     "WSAEINPROGRESS - Blocking call in progress"},
84     {WSAEALREADY,        "WSAEALREADY - Command already completed"},
85     {WSAENOTSOCK,        "WSAENOTSOCK - Descriptor is not a socket"},
86     {WSAEDESTADDRREQ,    "WSAEDESTADDRREQ - Destination address required"},
87     {WSAEMSGSIZE,        "WSAEMSGSIZE - Data size too large"},
88     {WSAEPROTOTYPE,      "WSAEPROTOTYPE - Protocol is of wrong type for this socket"},
89     {WSAENOPROTOOPT,     "WSAENOPROTOOPT - Protocol option not supported for this socket type"},
90     {WSAEPROTONOSUPPORT, "WSAEPROTONOSUPPORT - Protocol is not supported"},
91     {WSAESOCKTNOSUPPORT, "WSAESOCKTNOSUPPORT - Socket type not supported by this address family"},
92     {WSAEOPNOTSUPP,      "WSAEOPNOTSUPP - Option not supported"},
93     {WSAEPFNOSUPPORT,    "WSAEPFNOSUPPORT - "},
94     {WSAEAFNOSUPPORT,    "WSAEAFNOSUPPORT - Address family not supported by this protocol"},
95     {WSAEADDRINUSE,      "WSAEADDRINUSE - Address is in use"},
96     {WSAEADDRNOTAVAIL,   "WSAEADDRNOTAVAIL - Address not available from local machine"},
97     {WSAENETDOWN,        "WSAENETDOWN - Network subsystem is down"},
98     {WSAENETUNREACH,     "WSAENETUNREACH - Network cannot be reached"},
99     {WSAENETRESET,       "WSAENETRESET - Connection has been dropped"},
100     {WSAECONNABORTED,    "WSAECONNABORTED - Connection aborted"},
101     {WSAECONNRESET,      "WSAECONNRESET - Connection reset"},
102     {WSAENOBUFS,         "WSAENOBUFS - No buffer space available"},
103     {WSAEISCONN,         "WSAEISCONN - Socket is already connected"},
104     {WSAENOTCONN,        "WSAENOTCONN - Socket is not connected"},
105     {WSAESHUTDOWN,       "WSAESHUTDOWN - Socket has been shut down"},
106     {WSAETOOMANYREFS,    "WSAETOOMANYREFS - Too many references"},
107     {WSAETIMEDOUT,       "WSAETIMEDOUT - Command timed out"},
108     {WSAECONNREFUSED,    "WSAECONNREFUSED - Connection refused"},
109     {WSAELOOP,           "WSAELOOP - "},
110     {WSAENAMETOOLONG,    "WSAENAMETOOLONG - "},
111     {WSAEHOSTDOWN,       "WSAEHOSTDOWN - Host is down"},
112     {WSAEHOSTUNREACH,    "WSAEHOSTUNREACH - "},
113     {WSAENOTEMPTY,       "WSAENOTEMPTY - "},
114     {WSAEPROCLIM,        "WSAEPROCLIM - "},
115     {WSAEUSERS,          "WSAEUSERS - "},
116     {WSAEDQUOT,          "WSAEDQUOT - "},
117     {WSAESTALE,          "WSAESTALE - "},
118     {WSAEREMOTE,         "WSAEREMOTE - "},
119
120 /*
121 *    Extended Windows Sockets error constant definitions
122 */
123
124     {WSASYSNOTREADY,     "WSASYSNOTREADY - Network subsystem not ready"},
125     {WSAVERNOTSUPPORTED, "WSAVERNOTSUPPORTED - Version not supported"},
126     {WSANOTINITIALISED,  "WSANOTINITIALISED - WSAStartup() has not been successfully called"},
127
128 /*
129 *    Other error constants.
130 */
131
132     {WSAHOST_NOT_FOUND,  "WSAHOST_NOT_FOUND - Host not found"},
133     {WSATRY_AGAIN,       "WSATRY_AGAIN - Host not found or SERVERFAIL"},
134     {WSANO_RECOVERY,     "WSANO_RECOVERY - Non-recoverable error"},
135     {WSANO_DATA,         "WSANO_DATA - (or WSANO_ADDRESS) - No data record of requested type"},
136     {-1,                 NULL}
137 };
138
139 //===========================================================================
140 //
141 // Parameter:                           -
142 // Returns:                                     -
143 // Changes Globals:             -
144 //===========================================================================
145 const char *WINS_ErrorMessage(int error)
146 {
147     int search = 0;
148
149     if (!error) return "No error occurred";
150
151          for (search = 0; errlist[search].errstr; search++)
152          {
153                 if (error == errlist[search].errnum)
154                                 return errlist[search].errstr;
155          } //end for
156
157     return "Unknown error";
158 } //end of the function WINS_ErrorMessage
159 //===========================================================================
160 //
161 // Parameter:                           -
162 // Returns:                                     -
163 // Changes Globals:             -
164 //===========================================================================
165 int WINS_Init(void)
166 {
167         int             i;
168         struct hostent *local;
169         char    buff[MAXHOSTNAMELEN];
170         struct sockaddr_s addr;
171         char    *p;
172         int             r;
173         WORD    wVersionRequested; 
174
175         wVersionRequested = MAKEWORD(1, 1);
176
177         r = WSAStartup (wVersionRequested, &winsockdata);
178
179         if (r)
180         {
181                 WinPrint("Winsock initialization failed.\n");
182                 return -1;
183         }
184
185         /*
186         i = COM_CheckParm ("-udpport");
187         if (i == 0)*/
188                 net_hostport = DEFAULTnet_hostport;
189         /*
190         else if (i < com_argc-1)
191                 net_hostport = Q_atoi (com_argv[i+1]);
192         else
193                 Sys_Error ("WINS_Init: you must specify a number after -udpport");
194         */
195
196         // determine my name & address
197         gethostname(buff, MAXHOSTNAMELEN);
198         local = gethostbyname(buff);
199         myAddr = *(int *)local->h_addr_list[0];
200
201         // if the quake hostname isn't set, set it to the machine name
202 //      if (Q_strcmp(hostname.string, "UNNAMED") == 0)
203         {
204                 // see if it's a text IP address (well, close enough)
205                 for (p = buff; *p; p++)
206                         if ((*p < '0' || *p > '9') && *p != '.')
207                                 break;
208
209                 // if it is a real name, strip off the domain; we only want the host
210                 if (*p)
211                 {
212                         for (i = 0; i < 15; i++)
213                                 if (buff[i] == '.')
214                                         break;
215                         buff[i] = 0;
216                 }
217 //              Cvar_Set ("hostname", buff);
218         }
219
220         if ((net_controlsocket = WINS_OpenSocket (0)) == -1)
221                 WinError("WINS_Init: Unable to open control socket\n");
222
223         ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
224         ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
225         ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((u_short)net_hostport);
226
227         WINS_GetSocketAddr (net_controlsocket, &addr);
228         strcpy(my_tcpip_address,  WINS_AddrToString (&addr));
229         p = strrchr (my_tcpip_address, ':');
230         if (p) *p = 0;
231         WinPrint("Winsock Initialized\n");
232
233         return net_controlsocket;
234 } //end of the function WINS_Init
235 //===========================================================================
236 //
237 // Parameter:                           -
238 // Returns:                                     -
239 // Changes Globals:             -
240 //===========================================================================
241 char *WINS_MyAddress(void)
242 {
243         return my_tcpip_address;
244 } //end of the function WINS_MyAddress
245 //===========================================================================
246 //
247 // Parameter:                           -
248 // Returns:                                     -
249 // Changes Globals:             -
250 //===========================================================================
251 void WINS_Shutdown(void)
252 {
253         //WINS_Listen(0);
254         WINS_CloseSocket(net_controlsocket);
255         WSACleanup();
256         //
257         //WinPrint("Winsock Shutdown\n");
258 } //end of the function WINS_Shutdown
259 //===========================================================================
260 //
261 // Parameter:                           -
262 // Returns:                                     -
263 // Changes Globals:             -
264 //===========================================================================
265 /*
266 void WINS_Listen(int state)
267 {
268         // enable listening
269         if (state)
270         {
271                 if (net_acceptsocket != -1)
272                         return;
273                 if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1)
274                         WinError ("WINS_Listen: Unable to open accept socket\n");
275                 return;
276         }
277
278         // disable listening
279         if (net_acceptsocket == -1)
280                 return;
281         WINS_CloseSocket (net_acceptsocket);
282         net_acceptsocket = -1;
283 } //end of the function WINS_Listen*/
284 //===========================================================================
285 //
286 // Parameter:                           -
287 // Returns:                                     -
288 // Changes Globals:             -
289 //===========================================================================
290 int WINS_OpenSocket(int port)
291 {
292         int newsocket;
293         struct sockaddr_in address;
294         u_long _true = 1;
295
296         if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
297         {
298                 WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
299                 return -1;
300         } //end if
301
302         if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
303         {
304                 WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
305                 closesocket(newsocket);
306                 return -1;
307         } //end if
308
309         memset((char *) &address, 0, sizeof(address));
310         address.sin_family = AF_INET;
311         address.sin_addr.s_addr = INADDR_ANY;
312         address.sin_port = htons((u_short)port);
313         if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
314         {
315                 WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
316                 closesocket(newsocket);
317                 return -1;
318         } //end if
319
320         return newsocket;
321 } //end of the function WINS_OpenSocket
322 //===========================================================================
323 //
324 // Parameter:                           -
325 // Returns:                                     -
326 // Changes Globals:             -
327 //===========================================================================
328 int WINS_OpenReliableSocket(int port)
329 {
330         int newsocket;
331         struct sockaddr_in address;
332         BOOL _true = 0xFFFFFFFF;
333
334         //IPPROTO_TCP
335         //
336         if ((newsocket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
337         {
338                 WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
339                 return -1;
340         } //end if
341
342         memset((char *) &address, 0, sizeof(address));
343         address.sin_family = AF_INET;
344         address.sin_addr.s_addr = htonl(INADDR_ANY);
345         address.sin_port = htons((u_short)port);
346         if (bind(newsocket, (void *)&address, sizeof(address)) == -1)
347         {
348                 WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
349                 closesocket(newsocket);
350                 return -1;
351         } //end if
352
353   //
354         if (setsockopt(newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof(int)) == SOCKET_ERROR)
355         {
356                 WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
357                 WinPrint("setsockopt error\n");
358         } //end if
359
360         return newsocket;
361 } //end of the function WINS_OpenReliableSocket
362 //===========================================================================
363 //
364 // Parameter:                           -
365 // Returns:                                     -
366 // Changes Globals:             -
367 //===========================================================================
368 int WINS_Listen(int socket)
369 {
370         u_long _true = 1;
371
372         if (ioctlsocket(socket, FIONBIO, &_true) == -1)
373         {
374                 WinPrint("WINS_Listen: %s\n", WINS_ErrorMessage(WSAGetLastError()));
375                 return -1;
376         } //end if
377         if (listen(socket, SOMAXCONN) == SOCKET_ERROR)
378         {
379                 WinPrint("WINS_Listen: %s\n", WINS_ErrorMessage(WSAGetLastError()));
380                 return -1;
381         } //end if
382         return 0;
383 } //end of the function WINS_Listen
384 //===========================================================================
385 //
386 // Parameter:                           -
387 // Returns:                                     -
388 // Changes Globals:             -
389 //===========================================================================
390 int WINS_Accept(int socket, struct sockaddr_s *addr)
391 {
392         int addrlen = sizeof (struct sockaddr_s);
393         int newsocket;
394         BOOL _true = 1;
395
396         newsocket = accept(socket, (struct sockaddr *)addr, &addrlen);
397         if (newsocket == INVALID_SOCKET)
398         {
399                 if (WSAGetLastError() == WSAEWOULDBLOCK) return -1;
400                 WinPrint("WINS_Accept: %s\n", WINS_ErrorMessage(WSAGetLastError()));
401                 return -1;
402         } //end if
403         //
404         if (setsockopt(newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof(int)) == SOCKET_ERROR)
405         {
406                 WinPrint("WINS_Accept: %s\n", WINS_ErrorMessage(WSAGetLastError()));
407                 WinPrint("setsockopt error\n");
408         } //end if
409         return newsocket;
410 } //end of the function WINS_Accept
411 //===========================================================================
412 //
413 // Parameter:                           -
414 // Returns:                                     -
415 // Changes Globals:             -
416 //===========================================================================
417 int WINS_CloseSocket(int socket)
418 {
419         /*
420         if (socket == net_broadcastsocket)
421                 net_broadcastsocket = 0;
422         */
423 //      shutdown(socket, SD_SEND);
424
425         if (closesocket(socket) == SOCKET_ERROR)
426         {
427                 WinPrint("WINS_CloseSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
428                 return SOCKET_ERROR;
429         } //end if
430         return 0;
431 } //end of the function WINS_CloseSocket
432 //===========================================================================
433 // this lets you type only as much of the net address as required, using
434 // the local network components to fill in the rest
435 //
436 // Parameter:                           -
437 // Returns:                                     -
438 // Changes Globals:             -
439 //===========================================================================
440 static int PartialIPAddress (char *in, struct sockaddr_s *hostaddr)
441 {
442         char buff[256];
443         char *b;
444         int addr;
445         int num;
446         int mask;
447         
448         buff[0] = '.';
449         b = buff;
450         strcpy(buff+1, in);
451         if (buff[1] == '.') b++;
452
453         addr = 0;
454         mask=-1;
455         while (*b == '.')
456         {
457                 num = 0;
458                 if (*++b < '0' || *b > '9') return -1;
459                 while (!( *b < '0' || *b > '9'))
460                   num = num*10 + *(b++) - '0';
461                 mask<<=8;
462                 addr = (addr<<8) + num;
463         }
464         
465         hostaddr->sa_family = AF_INET;
466         ((struct sockaddr_in *)hostaddr)->sin_port = htons((u_short)net_hostport);
467         ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
468         
469         return 0;
470 } //end of the function PartialIPAddress
471 //===========================================================================
472 //
473 // Parameter:                           -
474 // Returns:                                     -
475 // Changes Globals:             -
476 //===========================================================================
477 int WINS_Connect(int socket, struct sockaddr_s *addr)
478 {
479         int ret;
480         u_long _true2 = 0xFFFFFFFF;
481
482         ret = connect(socket, (struct sockaddr *)addr, sizeof(struct sockaddr_s));
483         if (ret == SOCKET_ERROR)
484         {
485                 WinPrint("WINS_Connect: %s\n", WINS_ErrorMessage(WSAGetLastError()));
486                 return -1;
487         } //end if
488         if (ioctlsocket(socket, FIONBIO, &_true2) == -1)
489         {
490                 WinPrint("WINS_Connect: %s\n", WINS_ErrorMessage(WSAGetLastError()));
491                 return -1;
492         } //end if
493         return 0;
494 } //end of the function WINS_Connect
495 //===========================================================================
496 //
497 // Parameter:                           -
498 // Returns:                                     -
499 // Changes Globals:             -
500 //===========================================================================
501 int WINS_CheckNewConnections(void)
502 {
503         char buf[4];
504
505         if (net_acceptsocket == -1)
506                 return -1;
507
508         if (recvfrom(net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0)
509                 return net_acceptsocket;
510         return -1;
511 } //end of the function WINS_CheckNewConnections
512 //===========================================================================
513 // returns the number of bytes read
514 // 0 if no bytes available
515 // -1 on failure
516 //
517 // Parameter:                           -
518 // Returns:                                     -
519 // Changes Globals:             -
520 //===========================================================================
521 int WINS_Read(int socket, byte *buf, int len, struct sockaddr_s *addr)
522 {
523         int addrlen = sizeof (struct sockaddr_s);
524         int ret, errno;
525
526         if (addr)
527         {
528                 ret = recvfrom(socket, buf, len, 0, (struct sockaddr *)addr, &addrlen);
529                 if (ret == -1)
530                 {
531                         errno = WSAGetLastError();
532
533                         if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
534                                 return 0;
535                 } //end if
536         } //end if
537         else
538         {
539                 ret = recv(socket, buf, len, 0);
540                 if (ret == SOCKET_ERROR)
541                 {
542                         errno = WSAGetLastError();
543
544                         if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED)
545                                 return 0;
546                 } //end if
547         } //end else
548         if (ret == SOCKET_ERROR)
549         {
550                 WinPrint("WINS_Read: %s\n", WINS_ErrorMessage(WSAGetLastError()));
551         } //end if
552         return ret;
553 } //end of the function WINS_Read
554 //===========================================================================
555 //
556 // Parameter:                           -
557 // Returns:                                     -
558 // Changes Globals:             -
559 //===========================================================================
560 int WINS_MakeSocketBroadcastCapable (int socket)
561 {
562         int     i = 1;
563
564         // make this socket broadcast capable
565         if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
566                 return -1;
567         net_broadcastsocket = socket;
568
569         return 0;
570 } //end of the function WINS_MakeSocketBroadcastCapable
571 //===========================================================================
572 //
573 // Parameter:                           -
574 // Returns:                                     -
575 // Changes Globals:             -
576 //===========================================================================
577 int WINS_Broadcast (int socket, byte *buf, int len)
578 {
579         int ret;
580
581         if (socket != net_broadcastsocket)
582         {
583                 if (net_broadcastsocket != 0)
584                         WinError("Attempted to use multiple broadcasts sockets\n");
585                 ret = WINS_MakeSocketBroadcastCapable (socket);
586                 if (ret == -1)
587                 {
588                         WinPrint("Unable to make socket broadcast capable\n");
589                         return ret;
590                 }
591         }
592
593         return WINS_Write (socket, buf, len, &broadcastaddr);
594 } //end of the function WINS_Broadcast
595 //===========================================================================
596 // returns qtrue on success or qfalse on failure
597 //
598 // Parameter:                           -
599 // Returns:                                     -
600 // Changes Globals:             -
601 //===========================================================================
602 int WINS_Write(int socket, byte *buf, int len, struct sockaddr_s *addr)
603 {
604         int ret, written;
605
606         if (addr)
607         {
608                 written = 0;
609                 while(written < len)
610                 {
611                         ret = sendto (socket, &buf[written], len-written, 0, (struct sockaddr *)addr, sizeof(struct sockaddr_s));
612                         if (ret == SOCKET_ERROR)
613                         {
614                                 if (WSAGetLastError() != WSAEWOULDBLOCK)
615                                         return qfalse;
616                                 Sleep(1000);
617                         } //end if
618                         else
619                         {
620                                 written += ret;
621                         }
622                 }
623         } //end if
624         else
625         {
626                 written = 0;
627                 while(written < len)
628                 {
629                         ret = send(socket, buf, len, 0);
630                         if (ret == SOCKET_ERROR)
631                         {
632                                 if (WSAGetLastError() != WSAEWOULDBLOCK)
633                                         return qfalse;
634                                 Sleep(1000);
635                         } //end if
636                         else
637                         {
638                                 written += ret;
639                         }
640                 }
641         } //end else
642         if (ret == SOCKET_ERROR)
643         {
644                 WinPrint("WINS_Write: %s\n", WINS_ErrorMessage(WSAGetLastError()));
645         } //end if
646         return (ret == len);
647 } //end of the function WINS_Write
648 //===========================================================================
649 //
650 // Parameter:                           -
651 // Returns:                                     -
652 // Changes Globals:             -
653 //===========================================================================
654 char *WINS_AddrToString (struct sockaddr_s *addr)
655 {
656         static char buffer[22];
657         int haddr;
658
659         haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
660         sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port));
661         return buffer;
662 } //end of the function WINS_AddrToString
663 //===========================================================================
664 //
665 // Parameter:                           -
666 // Returns:                                     -
667 // Changes Globals:             -
668 //===========================================================================
669 int WINS_StringToAddr(char *string, struct sockaddr_s *addr)
670 {
671         int ha1, ha2, ha3, ha4, hp;
672         int ipaddr;
673
674         sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
675         ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
676
677         addr->sa_family = AF_INET;
678         ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
679         ((struct sockaddr_in *)addr)->sin_port = htons((u_short)hp);
680         return 0;
681 } //end of the function WINS_StringToAddr
682 //===========================================================================
683 //
684 // Parameter:                           -
685 // Returns:                                     -
686 // Changes Globals:             -
687 //===========================================================================
688 int WINS_GetSocketAddr(int socket, struct sockaddr_s *addr)
689 {
690         int addrlen = sizeof(struct sockaddr_s);
691         unsigned int a;
692
693         memset(addr, 0, sizeof(struct sockaddr_s));
694         getsockname(socket, (struct sockaddr *)addr, &addrlen);
695         a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
696         if (a == 0 || a == inet_addr("127.0.0.1"))
697                 ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
698
699         return 0;
700 } //end of the function WINS_GetSocketAddr
701 //===========================================================================
702 //
703 // Parameter:                           -
704 // Returns:                                     -
705 // Changes Globals:             -
706 //===========================================================================
707 int WINS_GetNameFromAddr (struct sockaddr_s *addr, char *name)
708 {
709         struct hostent *hostentry;
710
711         hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
712         if (hostentry)
713         {
714                 strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
715                 return 0;
716         }
717
718         strcpy (name, WINS_AddrToString (addr));
719         return 0;
720 } //end of the function WINS_GetNameFromAddr
721 //===========================================================================
722 //
723 // Parameter:                           -
724 // Returns:                                     -
725 // Changes Globals:             -
726 //===========================================================================
727 int WINS_GetAddrFromName(char *name, struct sockaddr_s *addr)
728 {
729         struct hostent *hostentry;
730
731         if (name[0] >= '0' && name[0] <= '9')
732                 return PartialIPAddress (name, addr);
733         
734         hostentry = gethostbyname (name);
735         if (!hostentry)
736                 return -1;
737
738         addr->sa_family = AF_INET;
739         ((struct sockaddr_in *)addr)->sin_port = htons((u_short)net_hostport);
740         ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
741
742         return 0;
743 } //end of the function WINS_GetAddrFromName
744 //===========================================================================
745 //
746 // Parameter:                           -
747 // Returns:                                     -
748 // Changes Globals:             -
749 //===========================================================================
750 int WINS_AddrCompare (struct sockaddr_s *addr1, struct sockaddr_s *addr2)
751 {
752         if (addr1->sa_family != addr2->sa_family)
753                 return -1;
754
755         if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
756                 return -1;
757
758         if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
759                 return 1;
760
761         return 0;
762 } //end of the function WINS_AddrCompare
763 //===========================================================================
764 //
765 // Parameter:                           -
766 // Returns:                                     -
767 // Changes Globals:             -
768 //===========================================================================
769 int WINS_GetSocketPort (struct sockaddr_s *addr)
770 {
771         return ntohs(((struct sockaddr_in *)addr)->sin_port);
772 } //end of the function WINS_GetSocketPort
773 //===========================================================================
774 //
775 // Parameter:                           -
776 // Returns:                                     -
777 // Changes Globals:             -
778 //===========================================================================
779 int WINS_SetSocketPort (struct sockaddr_s *addr, int port)
780 {
781         ((struct sockaddr_in *)addr)->sin_port = htons((u_short)port);
782         return 0;
783 } //end of the function WINS_SetSocketPort