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