]> git.xonotic.org Git - xonotic/netradiant.git/blob - libs/l_net/l_net_berkley.c
crn_rgba: use “algorithm” header to avoid std::min/max being unknown
[xonotic/netradiant.git] / libs / l_net / l_net_berkley.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:  TTimo: cross-platform version, l_net library
28 // Tab Size:     2
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
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <sys/ioctl.h>
42 #include <netinet/in.h>
43 #include <netinet/tcp.h>
44 #include <arpa/inet.h>
45 #include <errno.h>
46 #include <netdb.h>
47 #include <unistd.h>
48 #include <stdarg.h>
49 #include <stdio.h>
50 const int SOCKET_ERROR = -1;
51 const int INVALID_SOCKET = -1;
52
53 #define WinError WinPrint
54
55 #define ioctlsocket ioctl
56 #define closesocket close
57
58 int WSAGetLastError(){
59         return errno;
60 }
61
62 /*
63    typedef struct tag_error_struct
64    {
65     int     errnum;
66     LPSTR   errstr;
67    } ERROR_STRUCT;
68  */
69
70 typedef struct tag_error_struct
71 {
72         int errnum;
73         const char *errstr;
74 } ERROR_STRUCT;
75
76 #define NET_NAMELEN         64
77
78 static char my_tcpip_address[NET_NAMELEN];
79
80 const int DEFAULTnet_hostport = 26000;
81
82 const int MAXHOSTNAMELEN = 256;
83
84 static int net_acceptsocket = -1;       // socket for fielding new connections
85 static int net_controlsocket;
86 static int net_hostport;                // udp port number for acceptsocket
87 static int net_broadcastsocket = 0;
88 //static qboolean ifbcastinit = qfalse;
89 //static struct sockaddr_s broadcastaddr;
90 static struct sockaddr_s broadcastaddr;
91
92 static unsigned long myAddr;
93
94 ERROR_STRUCT errlist[] = {
95         {EACCES,"EACCES - The address is protected, user is not root"},
96         {EAGAIN,"EAGAIN - Operation on non-blocking socket that cannot return immediatly"},
97         {EBADF, "EBADF - sockfd is not a valid descriptor"},
98         {EFAULT, "EFAULT - The parameter is not in a writable part of the user address space"},
99         {EINVAL,"EINVAL - The socket is already bound to an address"},
100         {ENOBUFS,"ENOBUFS - not enough memory"},
101         {ENOMEM, "ENOMEM - not enough memory"},
102         {ENOTCONN, "ENOTCONN - not connected"},
103         {ENOTSOCK,"ENOTSOCK - Argument is file descriptor not a socket"},
104         {EOPNOTSUPP,"ENOTSUPP - The referenced socket is not of type SOCK_STREAM"},
105         {EPERM, "EPERM - Firewall rules forbid connection"},
106         {-1, NULL}
107 };
108
109 //===========================================================================
110 //
111 // Parameter:                           -
112 // Returns:                                     -
113 // Changes Globals:             -
114 //===========================================================================
115 const char *WINS_ErrorMessage( int error ){
116         int search = 0;
117
118         if ( !error ) {
119                 return "No error occurred";
120         }
121
122         for ( search = 0; errlist[search].errstr; search++ )
123         {
124                 if ( error == errlist[search].errnum ) {
125                         return errlist[search].errstr;
126                 }
127         }  //end for
128
129         return "Unknown error";
130 } //end of the function WINS_ErrorMessage
131 //===========================================================================
132 //
133 // Parameter:                           -
134 // Returns:                                     -
135 // Changes Globals:             -
136 //===========================================================================
137 int WINS_Init( void ){
138         int i;
139         struct hostent *local;
140         char buff[MAXHOSTNAMELEN];
141         struct sockaddr_s addr;
142         char    *p;
143 /*
144    linux doesn't have anything to initialize for the net
145    "Windows .. built for the internet .. the internet .. built with unix"
146  */
147 #if 0
148         WORD wVersionRequested;
149
150         wVersionRequested = MAKEWORD( 2, 2 );
151
152         r = WSAStartup( wVersionRequested, &winsockdata );
153
154         if ( r ) {
155                 WinPrint( "Winsock initialization failed.\n" );
156                 return -1;
157         }
158 #endif
159         /*
160            i = COM_CheckParm ("-udpport");
161            if (i == 0)*/
162         net_hostport = DEFAULTnet_hostport;
163         /*
164            else if (i < com_argc-1)
165             net_hostport = Q_atoi (com_argv[i+1]);
166            else
167             Sys_Error ("WINS_Init: you must specify a number after -udpport");
168          */
169
170         // determine my name & address
171         gethostname( buff, MAXHOSTNAMELEN );
172         local = gethostbyname( buff );
173         if(local && local->h_addr_list && local->h_addr_list[0])
174                 myAddr = *(int *)local->h_addr_list[0];
175         else
176                 myAddr = inet_addr("127.0.0.1");
177
178         // if the quake hostname isn't set, set it to the machine name
179 //      if (Q_strcmp(hostname.string, "UNNAMED") == 0)
180         {
181                 // see if it's a text IP address (well, close enough)
182                 for ( p = buff; *p; p++ )
183                         if ( ( *p < '0' || *p > '9' ) && *p != '.' ) {
184                                 break;
185                         }
186
187                 // if it is a real name, strip off the domain; we only want the host
188                 if ( *p ) {
189                         for ( i = 0; i < 15; i++ )
190                                 if ( buff[i] == '.' ) {
191                                         break;
192                                 }
193                         buff[i] = 0;
194                 }
195 //              Cvar_Set ("hostname", buff);
196         }
197
198         //++timo WTF is that net_controlsocket? it's sole purpose is to retrieve the local IP?
199         if ( ( net_controlsocket = WINS_OpenSocket( 0 ) ) == SOCKET_ERROR ) {
200                 WinError( "WINS_Init: Unable to open control socket\n" );
201         }
202
203         ( (struct sockaddr_in *)&broadcastaddr )->sin_family = AF_INET;
204         ( (struct sockaddr_in *)&broadcastaddr )->sin_addr.s_addr = INADDR_BROADCAST;
205         ( (struct sockaddr_in *)&broadcastaddr )->sin_port = htons( (u_short)net_hostport );
206
207         WINS_GetSocketAddr( net_controlsocket, &addr );
208         strcpy( my_tcpip_address,  WINS_AddrToString( &addr ) );
209         p = strrchr( my_tcpip_address, ':' );
210         if ( p ) {
211                 *p = 0;
212         }
213         WinPrint( "Winsock Initialized\n" );
214
215         return net_controlsocket;
216 } //end of the function WINS_Init
217 //===========================================================================
218 //
219 // Parameter:                           -
220 // Returns:                                     -
221 // Changes Globals:             -
222 //===========================================================================
223 char *WINS_MyAddress( void ){
224         return my_tcpip_address;
225 } //end of the function WINS_MyAddress
226 //===========================================================================
227 //
228 // Parameter:                           -
229 // Returns:                                     -
230 // Changes Globals:             -
231 //===========================================================================
232 void WINS_Shutdown( void ){
233         //WINS_Listen(0);
234         WINS_CloseSocket( net_controlsocket );
235 //      WSACleanup();
236         //
237         //WinPrint("Winsock Shutdown\n");
238 } //end of the function WINS_Shutdown
239 //===========================================================================
240 //
241 // Parameter:                           -
242 // Returns:                                     -
243 // Changes Globals:             -
244 //===========================================================================
245 /*
246    void WINS_Listen(int state)
247    {
248     // enable listening
249     if (state)
250     {
251         if (net_acceptsocket != -1)
252             return;
253         if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1)
254             WinError ("WINS_Listen: Unable to open accept socket\n");
255         return;
256     }
257
258     // disable listening
259     if (net_acceptsocket == -1)
260         return;
261     WINS_CloseSocket (net_acceptsocket);
262     net_acceptsocket = -1;
263    } //end of the function WINS_Listen*/
264 //===========================================================================
265 //
266 // Parameter:                           -
267 // Returns:                                     -
268 // Changes Globals:             -
269 //===========================================================================
270 int WINS_OpenSocket( int port ){
271         int newsocket;
272         struct sockaddr_in address;
273         u_long _true = 1;
274
275         if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == SOCKET_ERROR ) {
276                 WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
277                 return -1;
278         } //end if
279
280         if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) {
281                 WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
282                 closesocket( newsocket );
283                 return -1;
284         } //end if
285
286         memset( (char *) &address, 0, sizeof( address ) );
287         address.sin_family = AF_INET;
288         address.sin_addr.s_addr = INADDR_ANY;
289         address.sin_port = htons( (u_short)port );
290         if ( bind( newsocket, (void *)&address, sizeof( address ) ) == -1 ) {
291                 WinPrint( "WINS_OpenSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
292                 closesocket( newsocket );
293                 return -1;
294         } //end if
295
296         return newsocket;
297 } //end of the function WINS_OpenSocket
298 //===========================================================================
299 //
300 // Parameter:                           -
301 // Returns:                                     -
302 // Changes Globals:             -
303 //===========================================================================
304 int WINS_OpenReliableSocket( int port ){
305         int newsocket;
306         struct sockaddr_in address;
307         qboolean _true = 0xFFFFFFFF;
308
309         //IPPROTO_TCP
310         //
311         if ( ( newsocket = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) {
312                 WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
313                 return -1;
314         } //end if
315
316         memset( (char *) &address, 0, sizeof( address ) );
317         address.sin_family = AF_INET;
318         address.sin_addr.s_addr = htonl( INADDR_ANY );
319         address.sin_port = htons( (u_short)port );
320         if ( bind( newsocket, (void *)&address, sizeof( address ) ) == -1 ) {
321                 WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
322                 closesocket( newsocket );
323                 return -1;
324         } //end if
325
326         //
327         if ( setsockopt( newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof( int ) ) == -1 ) {
328                 WinPrint( "WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
329                 WinPrint( "setsockopt error\n" );
330         } //end if
331
332         return newsocket;
333 } //end of the function WINS_OpenReliableSocket
334 //===========================================================================
335 //
336 // Parameter:                           -
337 // Returns:                                     -
338 // Changes Globals:             -
339 //===========================================================================
340 int WINS_Listen( int socket ){
341         u_long _true = 1;
342
343         if ( ioctlsocket( socket, FIONBIO, &_true ) == -1 ) {
344                 WinPrint( "WINS_Listen: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
345                 return -1;
346         } //end if
347         if ( listen( socket, SOMAXCONN ) == SOCKET_ERROR ) {
348                 WinPrint( "WINS_Listen: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
349                 return -1;
350         } //end if
351         return 0;
352 } //end of the function WINS_Listen
353 //===========================================================================
354 //
355 // Parameter:                           -
356 // Returns:                                     -
357 // Changes Globals:             -
358 //===========================================================================
359 int WINS_Accept( int socket, struct sockaddr_s *addr ){
360         socklen_t addrlen = sizeof( struct sockaddr_s );
361         int newsocket;
362         qboolean _true = 1;
363
364         newsocket = accept( socket, (struct sockaddr *)addr, &addrlen );
365         if ( newsocket == INVALID_SOCKET ) {
366                 if ( errno == EAGAIN ) {
367                         return -1;
368                 }
369                 WinPrint( "WINS_Accept: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
370                 return -1;
371         } //end if
372           //
373         if ( setsockopt( newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof( int ) ) == SOCKET_ERROR ) {
374                 WinPrint( "WINS_Accept: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
375                 WinPrint( "setsockopt error\n" );
376         } //end if
377         return newsocket;
378 } //end of the function WINS_Accept
379 //===========================================================================
380 //
381 // Parameter:                           -
382 // Returns:                                     -
383 // Changes Globals:             -
384 //===========================================================================
385 int WINS_CloseSocket( int socket ){
386         /*
387            if (socket == net_broadcastsocket)
388             net_broadcastsocket = 0;
389          */
390 //      shutdown(socket, SD_SEND);
391
392         if ( closesocket( socket ) == SOCKET_ERROR ) {
393                 WinPrint( "WINS_CloseSocket: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
394                 return SOCKET_ERROR;
395         } //end if
396         return 0;
397 } //end of the function WINS_CloseSocket
398 //===========================================================================
399 // this lets you type only as much of the net address as required, using
400 // the local network components to fill in the rest
401 //
402 // Parameter:                           -
403 // Returns:                                     -
404 // Changes Globals:             -
405 //===========================================================================
406 static int PartialIPAddress( char *in, struct sockaddr_s *hostaddr ){
407         char buff[256];
408         char *b;
409         int addr;
410         int num;
411         int mask;
412
413         buff[0] = '.';
414         b = buff;
415         strcpy( buff + 1, in );
416         if ( buff[1] == '.' ) {
417                 b++;
418         }
419
420         addr = 0;
421         mask = -1;
422         while ( *b == '.' )
423         {
424                 num = 0;
425                 if ( *++b < '0' || *b > '9' ) {
426                         return -1;
427                 }
428                 while ( !( *b < '0' || *b > '9' ) )
429                         num = num * 10 + *( b++ ) - '0';
430                 mask <<= 8;
431                 addr = ( addr << 8 ) + num;
432         }
433
434         hostaddr->sa_family = AF_INET;
435         ( (struct sockaddr_in *)hostaddr )->sin_port = htons( (u_short)net_hostport );
436         ( (struct sockaddr_in *)hostaddr )->sin_addr.s_addr = ( myAddr & htonl( mask ) ) | htonl( addr );
437
438         return 0;
439 } //end of the function PartialIPAddress
440 //===========================================================================
441 //
442 // Parameter:                           -
443 // Returns:                                     -
444 // Changes Globals:             -
445 //===========================================================================
446 int WINS_Connect( int socket, struct sockaddr_s *addr ){
447         int ret;
448         u_long _true2 = 0xFFFFFFFF;
449
450         ret = connect( socket, (struct sockaddr *)addr, sizeof( struct sockaddr_s ) );
451         if ( ret == SOCKET_ERROR ) {
452                 WinPrint( "WINS_Connect: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
453                 return -1;
454         } //end if
455         if ( ioctlsocket( socket, FIONBIO, &_true2 ) == -1 ) {
456                 WinPrint( "WINS_Connect: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
457                 return -1;
458         } //end if
459         return 0;
460 } //end of the function WINS_Connect
461 //===========================================================================
462 //
463 // Parameter:                           -
464 // Returns:                                     -
465 // Changes Globals:             -
466 //===========================================================================
467 int WINS_CheckNewConnections( void ){
468         char buf[4];
469
470         if ( net_acceptsocket == -1 ) {
471                 return -1;
472         }
473
474         if ( recvfrom( net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL ) > 0 ) {
475                 return net_acceptsocket;
476         }
477         return -1;
478 } //end of the function WINS_CheckNewConnections
479 //===========================================================================
480 // returns the number of bytes read
481 // 0 if no bytes available
482 // -1 on failure
483 //
484 // Parameter:                           -
485 // Returns:                                     -
486 // Changes Globals:             -
487 //===========================================================================
488 int WINS_Read( int socket, byte *buf, int len, struct sockaddr_s *addr ){
489         socklen_t addrlen = sizeof( struct sockaddr_s );
490         int ret;
491
492         if ( addr ) {
493                 ret = recvfrom( socket, buf, len, 0, (struct sockaddr *)addr, &addrlen );
494                 if ( ret == -1 ) {
495 //                      errno = WSAGetLastError();
496
497                         if ( errno == EAGAIN || errno == ENOTCONN ) {
498                                 return 0;
499                         }
500                 } //end if
501         } //end if
502         else
503         {
504                 ret = recv( socket, buf, len, 0 );
505                 // if there's no data on the socket ret == -1 and errno == EAGAIN
506                 // MSDN states that if ret == 0 the socket has been closed
507                 // man recv doesn't say anything
508                 if ( ret == 0 ) {
509                         return -1;
510                 }
511                 if ( ret == SOCKET_ERROR ) {
512 //                      errno = WSAGetLastError();
513
514                         if ( errno == EAGAIN || errno == ENOTCONN ) {
515                                 return 0;
516                         }
517                 } //end if
518         } //end else
519         if ( ret == SOCKET_ERROR ) {
520                 WinPrint( "WINS_Read: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
521         } //end if
522         return ret;
523 } //end of the function WINS_Read
524 //===========================================================================
525 //
526 // Parameter:                           -
527 // Returns:                                     -
528 // Changes Globals:             -
529 //===========================================================================
530 int WINS_MakeSocketBroadcastCapable( int socket ){
531         int i = 1;
532
533         // make this socket broadcast capable
534         if ( setsockopt( socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof( i ) ) < 0 ) {
535                 return -1;
536         }
537         net_broadcastsocket = socket;
538
539         return 0;
540 } //end of the function WINS_MakeSocketBroadcastCapable
541 //===========================================================================
542 //
543 // Parameter:                           -
544 // Returns:                                     -
545 // Changes Globals:             -
546 //===========================================================================
547 int WINS_Broadcast( int socket, byte *buf, int len ){
548         int ret;
549
550         if ( socket != net_broadcastsocket ) {
551                 if ( net_broadcastsocket != 0 ) {
552                         WinError( "Attempted to use multiple broadcasts sockets\n" );
553                 }
554                 ret = WINS_MakeSocketBroadcastCapable( socket );
555                 if ( ret == -1 ) {
556                         WinPrint( "Unable to make socket broadcast capable\n" );
557                         return ret;
558                 }
559         }
560
561         return WINS_Write( socket, buf, len, &broadcastaddr );
562 } //end of the function WINS_Broadcast
563 //===========================================================================
564 // returns qtrue on success or qfalse on failure
565 //
566 // Parameter:                           -
567 // Returns:                                     -
568 // Changes Globals:             -
569 //===========================================================================
570 int WINS_Write( int socket, byte *buf, int len, struct sockaddr_s *addr ){
571         int ret, written;
572         ret = 0;
573
574         if ( addr ) {
575                 written = 0;
576                 while ( written < len )
577                 {
578                         ret = sendto( socket, &buf[written], len - written, 0, (struct sockaddr *)addr, sizeof( struct sockaddr_s ) );
579                         if ( ret == SOCKET_ERROR ) {
580                                 if ( WSAGetLastError() != EAGAIN ) {
581                                         return qfalse;
582                                 }
583                                 //++timo FIXME: what is this used for?
584 //                              Sleep(1000);
585                         } //end if
586                         else
587                         {
588                                 written += ret;
589                         }
590                 }
591         } //end if
592         else
593         {
594                 written = 0;
595                 while ( written < len )
596                 {
597                         ret = send( socket, buf, len, 0 );
598                         if ( ret == SOCKET_ERROR ) {
599                                 if ( WSAGetLastError() != EAGAIN ) {
600                                         return qfalse;
601                                 }
602                                 //++timo FIXME: what is this used for?
603 //                              Sleep(1000);
604                         } //end if
605                         else
606                         {
607                                 written += ret;
608                         }
609                 }
610         } //end else
611         if ( ret == SOCKET_ERROR ) {
612                 WinPrint( "WINS_Write: %s\n", WINS_ErrorMessage( WSAGetLastError() ) );
613         } //end if
614         return ( ret == len );
615 } //end of the function WINS_Write
616 //===========================================================================
617 //
618 // Parameter:                           -
619 // Returns:                                     -
620 // Changes Globals:             -
621 //===========================================================================
622 char *WINS_AddrToString( struct sockaddr_s *addr ){
623         static char buffer[22];
624         int haddr;
625
626         haddr = ntohl( ( (struct sockaddr_in *)addr )->sin_addr.s_addr );
627         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 ) );
628         return buffer;
629 } //end of the function WINS_AddrToString
630 //===========================================================================
631 //
632 // Parameter:                           -
633 // Returns:                                     -
634 // Changes Globals:             -
635 //===========================================================================
636 int WINS_StringToAddr( char *string, struct sockaddr_s *addr ){
637         int ha1, ha2, ha3, ha4, hp;
638         int ipaddr;
639
640         sscanf( string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp );
641         ipaddr = ( ha1 << 24 ) | ( ha2 << 16 ) | ( ha3 << 8 ) | ha4;
642
643         addr->sa_family = AF_INET;
644         ( (struct sockaddr_in *)addr )->sin_addr.s_addr = htonl( ipaddr );
645         ( (struct sockaddr_in *)addr )->sin_port = htons( (u_short)hp );
646         return 0;
647 } //end of the function WINS_StringToAddr
648 //===========================================================================
649 //
650 // Parameter:                           -
651 // Returns:                                     -
652 // Changes Globals:             -
653 //===========================================================================
654 int WINS_GetSocketAddr( int socket, struct sockaddr_s *addr ){
655         socklen_t addrlen = sizeof( struct sockaddr_s );
656         unsigned int a;
657
658         memset( addr, 0, sizeof( struct sockaddr_s ) );
659         getsockname( socket, (struct sockaddr *)addr, &addrlen );
660         a = ( (struct sockaddr_in *)addr )->sin_addr.s_addr;
661         if ( a == 0 || a == inet_addr( "127.0.0.1" ) ) {
662                 ( (struct sockaddr_in *)addr )->sin_addr.s_addr = myAddr;
663         }
664
665         return 0;
666 } //end of the function WINS_GetSocketAddr
667 //===========================================================================
668 //
669 // Parameter:                           -
670 // Returns:                                     -
671 // Changes Globals:             -
672 //===========================================================================
673 int WINS_GetNameFromAddr( struct sockaddr_s *addr, char *name ){
674         struct hostent *hostentry;
675
676         hostentry = gethostbyaddr( (char *)&( (struct sockaddr_in *)addr )->sin_addr, sizeof( struct in_addr ), AF_INET );
677         if ( hostentry ) {
678                 strncpy( name, (char *)hostentry->h_name, NET_NAMELEN - 1 );
679                 return 0;
680         }
681
682         strcpy( name, WINS_AddrToString( addr ) );
683         return 0;
684 } //end of the function WINS_GetNameFromAddr
685 //===========================================================================
686 //
687 // Parameter:                           -
688 // Returns:                                     -
689 // Changes Globals:             -
690 //===========================================================================
691 int WINS_GetAddrFromName( char *name, struct sockaddr_s *addr ){
692         struct hostent *hostentry;
693
694         if ( name[0] >= '0' && name[0] <= '9' ) {
695                 return PartialIPAddress( name, addr );
696         }
697
698         hostentry = gethostbyname( name );
699         if ( !hostentry ) {
700                 return -1;
701         }
702
703         addr->sa_family = AF_INET;
704         ( (struct sockaddr_in *)addr )->sin_port = htons( (u_short)net_hostport );
705         ( (struct sockaddr_in *)addr )->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
706
707         return 0;
708 } //end of the function WINS_GetAddrFromName
709 //===========================================================================
710 //
711 // Parameter:                           -
712 // Returns:                                     -
713 // Changes Globals:             -
714 //===========================================================================
715 int WINS_AddrCompare( struct sockaddr_s *addr1, struct sockaddr_s *addr2 ){
716         if ( addr1->sa_family != addr2->sa_family ) {
717                 return -1;
718         }
719
720         if ( ( (struct sockaddr_in *)addr1 )->sin_addr.s_addr != ( (struct sockaddr_in *)addr2 )->sin_addr.s_addr ) {
721                 return -1;
722         }
723
724         if ( ( (struct sockaddr_in *)addr1 )->sin_port != ( (struct sockaddr_in *)addr2 )->sin_port ) {
725                 return 1;
726         }
727
728         return 0;
729 } //end of the function WINS_AddrCompare
730 //===========================================================================
731 //
732 // Parameter:                           -
733 // Returns:                                     -
734 // Changes Globals:             -
735 //===========================================================================
736 int WINS_GetSocketPort( struct sockaddr_s *addr ){
737         return ntohs( ( (struct sockaddr_in *)addr )->sin_port );
738 } //end of the function WINS_GetSocketPort
739 //===========================================================================
740 //
741 // Parameter:                           -
742 // Returns:                                     -
743 // Changes Globals:             -
744 //===========================================================================
745 int WINS_SetSocketPort( struct sockaddr_s *addr, int port ){
746         ( (struct sockaddr_in *)addr )->sin_port = htons( (u_short)port );
747         return 0;
748 } //end of the function WINS_SetSocketPort