-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
-*/\r
-\r
-//===========================================================================\r
-//\r
-// Name: l_net_wins.c\r
-// Function: WinSock\r
-// Programmer: MrElusive\r
-// Last update: TTimo: cross-platform version, l_net library\r
-// Tab Size: 2\r
-// Notes:\r
-//===========================================================================\r
-\r
-//#include <windows.h>\r
-#include <unistd.h>\r
-#include <stdio.h>\r
-#include <stdlib.h>\r
-#include <string.h>\r
-#include "l_net.h"\r
-#include "l_net_wins.h"\r
-\r
-#include <arpa/inet.h>\r
-#include <sys/types.h>\r
-#include <sys/socket.h>\r
-#include <sys/ioctl.h>\r
-#include <netinet/in.h>\r
-#include <netinet/tcp.h>\r
-#include <errno.h>\r
-#include <netdb.h>\r
-#define SOCKET_ERROR -1\r
-#define INVALID_SOCKET -1\r
-\r
-extern void WinPrint(char *str, ...);\r
-\r
-#define WinError WinPrint\r
-\r
-#define qtrue 1\r
-#define qfalse 0\r
-\r
-#define ioctlsocket ioctl\r
-#define closesocket close\r
-\r
-int WSAGetLastError()\r
-{\r
- return errno;\r
-}\r
-\r
-/*\r
-typedef struct tag_error_struct\r
-{\r
- int errnum;\r
- LPSTR errstr;\r
-} ERROR_STRUCT;\r
-*/\r
-\r
-typedef struct tag_error_struct\r
-{\r
- int errnum;\r
- const char *errstr;\r
-} ERROR_STRUCT;\r
-\r
-#define NET_NAMELEN 64\r
-\r
-static char my_tcpip_address[NET_NAMELEN];\r
-\r
-#define DEFAULTnet_hostport 26000\r
-\r
-#define MAXHOSTNAMELEN 256\r
-\r
-static int net_acceptsocket = -1; // socket for fielding new connections\r
-static int net_controlsocket;\r
-static int net_hostport; // udp port number for acceptsocket\r
-static int net_broadcastsocket = 0;\r
-//static qboolean ifbcastinit = qfalse;\r
-//static struct sockaddr_s broadcastaddr;\r
-static struct sockaddr_s broadcastaddr;\r
-\r
-static unsigned long myAddr;\r
-\r
-ERROR_STRUCT errlist[] = {\r
- {EACCES,"EACCES - The address is protected, user is not root"},\r
- {EAGAIN,"EAGAIN - Operation on non-blocking socket that cannot return immediatly"},\r
- {EBADF, "EBADF - sockfd is not a valid descriptor"},\r
- {EFAULT, "EFAULT - The parameter is not in a writable part of the user address space"},\r
- {EINVAL,"EINVAL - The socket is already bound to an address"},\r
- {ENOBUFS,"ENOBUFS - not enough memory"},\r
- {ENOMEM, "ENOMEM - not enough memory"},\r
- {ENOTCONN, "ENOTCONN - not connected"},\r
- {ENOTSOCK,"ENOTSOCK - Argument is file descriptor not a socket"},\r
- {EOPNOTSUPP,"ENOTSUPP - The referenced socket is not of type SOCK_STREAM"},\r
- {EPERM, "EPERM - Firewall rules forbid connection"},\r
- {-1, NULL}\r
-};\r
-\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-char *WINS_ErrorMessage(int error)\r
-{\r
- int search = 0;\r
-\r
- if (!error) return "No error occurred";\r
-\r
- for (search = 0; errlist[search].errstr; search++)\r
- {\r
- if (error == errlist[search].errnum)\r
- return (char *)errlist[search].errstr;\r
- } //end for\r
-\r
- return "Unknown error";\r
-} //end of the function WINS_ErrorMessage\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Init(void)\r
-{\r
- int i;\r
- struct hostent *local;\r
- char buff[MAXHOSTNAMELEN];\r
- struct sockaddr_s addr;\r
- char *p;\r
- int r;\r
-/* \r
- linux doesn't have anything to initialize for the net\r
- "Windows .. built for the internet .. the internet .. built with unix" \r
- */\r
-#if 0\r
- WORD wVersionRequested; \r
-\r
- wVersionRequested = MAKEWORD(2, 2);\r
-\r
- r = WSAStartup (wVersionRequested, &winsockdata);\r
-\r
- if (r)\r
- {\r
- WinPrint("Winsock initialization failed.\n");\r
- return -1;\r
- }\r
-#endif\r
- /*\r
- i = COM_CheckParm ("-udpport");\r
- if (i == 0)*/\r
- net_hostport = DEFAULTnet_hostport;\r
- /*\r
- else if (i < com_argc-1)\r
- net_hostport = Q_atoi (com_argv[i+1]);\r
- else\r
- Sys_Error ("WINS_Init: you must specify a number after -udpport");\r
- */\r
-\r
- // determine my name & address\r
- gethostname(buff, MAXHOSTNAMELEN);\r
- local = gethostbyname(buff);\r
- myAddr = *(int *)local->h_addr_list[0];\r
-\r
- // if the quake hostname isn't set, set it to the machine name\r
-// if (Q_strcmp(hostname.string, "UNNAMED") == 0)\r
- {\r
- // see if it's a text IP address (well, close enough)\r
- for (p = buff; *p; p++)\r
- if ((*p < '0' || *p > '9') && *p != '.')\r
- break;\r
-\r
- // if it is a real name, strip off the domain; we only want the host\r
- if (*p)\r
- {\r
- for (i = 0; i < 15; i++)\r
- if (buff[i] == '.')\r
- break;\r
- buff[i] = 0;\r
- }\r
-// Cvar_Set ("hostname", buff);\r
- }\r
-\r
- //++timo WTF is that net_controlsocket? it's sole purpose is to retrieve the local IP?\r
- if ((net_controlsocket = WINS_OpenSocket (0)) == SOCKET_ERROR)\r
- WinError("WINS_Init: Unable to open control socket\n");\r
-\r
- ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;\r
- ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;\r
- ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((u_short)net_hostport);\r
-\r
- WINS_GetSocketAddr (net_controlsocket, &addr);\r
- strcpy(my_tcpip_address, WINS_AddrToString (&addr));\r
- p = strrchr (my_tcpip_address, ':');\r
- if (p) *p = 0;\r
- WinPrint("Winsock Initialized\n");\r
-\r
- return net_controlsocket;\r
-} //end of the function WINS_Init\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-char *WINS_MyAddress(void)\r
-{\r
- return my_tcpip_address;\r
-} //end of the function WINS_MyAddress\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-void WINS_Shutdown(void)\r
-{\r
- //WINS_Listen(0);\r
- WINS_CloseSocket(net_controlsocket);\r
-// WSACleanup();\r
- //\r
- WinPrint("Winsock Shutdown\n");\r
-} //end of the function WINS_Shutdown\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-/*\r
-void WINS_Listen(int state)\r
-{\r
- // enable listening\r
- if (state)\r
- {\r
- if (net_acceptsocket != -1)\r
- return;\r
- if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1)\r
- WinError ("WINS_Listen: Unable to open accept socket\n");\r
- return;\r
- }\r
-\r
- // disable listening\r
- if (net_acceptsocket == -1)\r
- return;\r
- WINS_CloseSocket (net_acceptsocket);\r
- net_acceptsocket = -1;\r
-} //end of the function WINS_Listen*/\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_OpenSocket(int port)\r
-{\r
- int newsocket;\r
- struct sockaddr_in address;\r
- u_long _true = 1;\r
-\r
- if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
-\r
- if (ioctlsocket (newsocket, FIONBIO, &_true) == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- closesocket(newsocket);\r
- return -1;\r
- } //end if\r
-\r
- memset((char *) &address, 0, sizeof(address));\r
- address.sin_family = AF_INET;\r
- address.sin_addr.s_addr = INADDR_ANY;\r
- address.sin_port = htons((u_short)port);\r
- if( bind (newsocket, (void *)&address, sizeof(address)) == -1)\r
- {\r
- WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- closesocket(newsocket);\r
- return -1;\r
- } //end if\r
-\r
- return newsocket;\r
-} //end of the function WINS_OpenSocket\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_OpenReliableSocket(int port)\r
-{\r
- int newsocket;\r
- struct sockaddr_in address;\r
- qboolean _true = 0xFFFFFFFF;\r
-\r
- //IPPROTO_TCP\r
- //\r
- if ((newsocket = socket(AF_INET, SOCK_STREAM, 0)) == -1)\r
- {\r
- WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
-\r
- memset((char *) &address, 0, sizeof(address));\r
- address.sin_family = AF_INET;\r
- address.sin_addr.s_addr = htonl(INADDR_ANY);\r
- address.sin_port = htons((u_short)port);\r
- if (bind(newsocket, (void *)&address, sizeof(address)) == -1)\r
- {\r
- WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- closesocket(newsocket);\r
- return -1;\r
- } //end if\r
-\r
- //\r
- if (setsockopt(newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof(int)) == -1)\r
- {\r
- WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- WinPrint("setsockopt error\n");\r
- } //end if\r
-\r
- return newsocket;\r
-} //end of the function WINS_OpenReliableSocket\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Listen(int socket)\r
-{\r
- u_long _true = 1;\r
-\r
- if (ioctlsocket(socket, FIONBIO, &_true) == -1)\r
- {\r
- WinPrint("WINS_Listen: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
- if (listen(socket, SOMAXCONN) == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_Listen: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
- return 0;\r
-} //end of the function WINS_Listen\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Accept(int socket, struct sockaddr_s *addr)\r
-{\r
- int addrlen = sizeof (struct sockaddr_s);\r
- int newsocket;\r
- qboolean _true = 1;\r
-\r
- newsocket = accept(socket, (struct sockaddr *)addr, &addrlen);\r
- if (newsocket == INVALID_SOCKET)\r
- {\r
- if (errno == EAGAIN) return -1;\r
- WinPrint("WINS_Accept: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
- //\r
- if (setsockopt(newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof(int)) == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_Accept: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- WinPrint("setsockopt error\n");\r
- } //end if\r
- return newsocket;\r
-} //end of the function WINS_Accept\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_CloseSocket(int socket)\r
-{\r
- /*\r
- if (socket == net_broadcastsocket)\r
- net_broadcastsocket = 0;\r
- */\r
-// shutdown(socket, SD_SEND);\r
-\r
- if (closesocket(socket) == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_CloseSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return SOCKET_ERROR;\r
- } //end if\r
- return 0;\r
-} //end of the function WINS_CloseSocket\r
-//===========================================================================\r
-// this lets you type only as much of the net address as required, using\r
-// the local network components to fill in the rest\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-static int PartialIPAddress (char *in, struct sockaddr_s *hostaddr)\r
-{\r
- char buff[256];\r
- char *b;\r
- int addr;\r
- int num;\r
- int mask;\r
- \r
- buff[0] = '.';\r
- b = buff;\r
- strcpy(buff+1, in);\r
- if (buff[1] == '.') b++;\r
-\r
- addr = 0;\r
- mask=-1;\r
- while (*b == '.')\r
- {\r
- num = 0;\r
- if (*++b < '0' || *b > '9') return -1;\r
- while (!( *b < '0' || *b > '9'))\r
- num = num*10 + *(b++) - '0';\r
- mask<<=8;\r
- addr = (addr<<8) + num;\r
- }\r
- \r
- hostaddr->sa_family = AF_INET;\r
- ((struct sockaddr_in *)hostaddr)->sin_port = htons((u_short)net_hostport);\r
- ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);\r
- \r
- return 0;\r
-} //end of the function PartialIPAddress\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Connect(int socket, struct sockaddr_s *addr)\r
-{\r
- int ret;\r
- u_long _true2 = 0xFFFFFFFF;\r
-\r
- ret = connect(socket, (struct sockaddr *)addr, sizeof(struct sockaddr_s));\r
- if (ret == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_Connect: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
- if (ioctlsocket(socket, FIONBIO, &_true2) == -1)\r
- {\r
- WinPrint("WINS_Connect: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- return -1;\r
- } //end if\r
- return 0;\r
-} //end of the function WINS_Connect\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_CheckNewConnections(void)\r
-{\r
- char buf[4];\r
-\r
- if (net_acceptsocket == -1)\r
- return -1;\r
-\r
- if (recvfrom(net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0)\r
- return net_acceptsocket;\r
- return -1;\r
-} //end of the function WINS_CheckNewConnections\r
-//===========================================================================\r
-// returns the number of bytes read\r
-// 0 if no bytes available\r
-// -1 on failure\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Read(int socket, byte *buf, int len, struct sockaddr_s *addr)\r
-{\r
- int addrlen = sizeof (struct sockaddr_s);\r
- int ret;\r
-\r
- if (addr)\r
- {\r
- ret = recvfrom(socket, buf, len, 0, (struct sockaddr *)addr, &addrlen);\r
- if (ret == -1)\r
- {\r
-// errno = WSAGetLastError();\r
-\r
- if (errno == EAGAIN || errno == ENOTCONN)\r
- return 0;\r
- } //end if\r
- } //end if\r
- else\r
- {\r
- ret = recv(socket, buf, len, 0);\r
- // if there's no data on the socket ret == -1 and errno == EAGAIN\r
- // MSDN states that if ret == 0 the socket has been closed\r
- // man recv doesn't say anything\r
- if (ret == 0)\r
- return -1;\r
- if (ret == SOCKET_ERROR)\r
- {\r
-// errno = WSAGetLastError();\r
-\r
- if (errno == EAGAIN || errno == ENOTCONN)\r
- return 0;\r
- } //end if\r
- } //end else\r
- if (ret == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_Read: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- } //end if\r
- return ret;\r
-} //end of the function WINS_Read\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_MakeSocketBroadcastCapable (int socket)\r
-{\r
- int i = 1;\r
-\r
- // make this socket broadcast capable\r
- if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)\r
- return -1;\r
- net_broadcastsocket = socket;\r
-\r
- return 0;\r
-} //end of the function WINS_MakeSocketBroadcastCapable\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Broadcast (int socket, byte *buf, int len)\r
-{\r
- int ret;\r
-\r
- if (socket != net_broadcastsocket)\r
- {\r
- if (net_broadcastsocket != 0)\r
- WinError("Attempted to use multiple broadcasts sockets\n");\r
- ret = WINS_MakeSocketBroadcastCapable (socket);\r
- if (ret == -1)\r
- {\r
- WinPrint("Unable to make socket broadcast capable\n");\r
- return ret;\r
- }\r
- }\r
-\r
- return WINS_Write (socket, buf, len, &broadcastaddr);\r
-} //end of the function WINS_Broadcast\r
-//===========================================================================\r
-// returns qtrue on success or qfalse on failure\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_Write(int socket, byte *buf, int len, struct sockaddr_s *addr)\r
-{\r
- int ret, written;\r
-\r
- if (addr)\r
- {\r
- written = 0;\r
- while(written < len)\r
- {\r
- ret = sendto (socket, &buf[written], len-written, 0, (struct sockaddr *)addr, sizeof(struct sockaddr_s));\r
- if (ret == SOCKET_ERROR)\r
- {\r
- if (WSAGetLastError() != EAGAIN)\r
- return qfalse;\r
- //++timo FIXME: what is this used for?\r
-// Sleep(1000);\r
- } //end if\r
- else\r
- {\r
- written += ret;\r
- }\r
- }\r
- } //end if\r
- else\r
- {\r
- written = 0;\r
- while(written < len)\r
- {\r
- ret = send(socket, buf, len, 0);\r
- if (ret == SOCKET_ERROR)\r
- {\r
- if (WSAGetLastError() != EAGAIN)\r
- return qfalse;\r
- //++timo FIXME: what is this used for?\r
-// Sleep(1000);\r
- } //end if\r
- else\r
- {\r
- written += ret;\r
- }\r
- }\r
- } //end else\r
- if (ret == SOCKET_ERROR)\r
- {\r
- WinPrint("WINS_Write: %s\n", WINS_ErrorMessage(WSAGetLastError()));\r
- } //end if\r
- return (ret == len);\r
-} //end of the function WINS_Write\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-char *WINS_AddrToString (struct sockaddr_s *addr)\r
-{\r
- static char buffer[22];\r
- int haddr;\r
-\r
- haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);\r
- 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
- return buffer;\r
-} //end of the function WINS_AddrToString\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_StringToAddr(char *string, struct sockaddr_s *addr)\r
-{\r
- int ha1, ha2, ha3, ha4, hp;\r
- int ipaddr;\r
-\r
- sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);\r
- ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;\r
-\r
- addr->sa_family = AF_INET;\r
- ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);\r
- ((struct sockaddr_in *)addr)->sin_port = htons((u_short)hp);\r
- return 0;\r
-} //end of the function WINS_StringToAddr\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_GetSocketAddr(int socket, struct sockaddr_s *addr)\r
-{\r
- int addrlen = sizeof(struct sockaddr_s);\r
- unsigned int a;\r
-\r
- memset(addr, 0, sizeof(struct sockaddr_s));\r
- getsockname(socket, (struct sockaddr *)addr, &addrlen);\r
- a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;\r
- if (a == 0 || a == inet_addr("127.0.0.1"))\r
- ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;\r
-\r
- return 0;\r
-} //end of the function WINS_GetSocketAddr\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_GetNameFromAddr (struct sockaddr_s *addr, char *name)\r
-{\r
- struct hostent *hostentry;\r
-\r
- hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);\r
- if (hostentry)\r
- {\r
- strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);\r
- return 0;\r
- }\r
-\r
- strcpy (name, WINS_AddrToString (addr));\r
- return 0;\r
-} //end of the function WINS_GetNameFromAddr\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_GetAddrFromName(char *name, struct sockaddr_s *addr)\r
-{\r
- struct hostent *hostentry;\r
-\r
- if (name[0] >= '0' && name[0] <= '9')\r
- return PartialIPAddress (name, addr);\r
- \r
- hostentry = gethostbyname (name);\r
- if (!hostentry)\r
- return -1;\r
-\r
- addr->sa_family = AF_INET;\r
- ((struct sockaddr_in *)addr)->sin_port = htons((u_short)net_hostport);\r
- ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];\r
-\r
- return 0;\r
-} //end of the function WINS_GetAddrFromName\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_AddrCompare (struct sockaddr_s *addr1, struct sockaddr_s *addr2)\r
-{\r
- if (addr1->sa_family != addr2->sa_family)\r
- return -1;\r
-\r
- if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)\r
- return -1;\r
-\r
- if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)\r
- return 1;\r
-\r
- return 0;\r
-} //end of the function WINS_AddrCompare\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_GetSocketPort (struct sockaddr_s *addr)\r
-{\r
- return ntohs(((struct sockaddr_in *)addr)->sin_port);\r
-} //end of the function WINS_GetSocketPort\r
-//===========================================================================\r
-//\r
-// Parameter: -\r
-// Returns: -\r
-// Changes Globals: -\r
-//===========================================================================\r
-int WINS_SetSocketPort (struct sockaddr_s *addr, int port)\r
-{\r
- ((struct sockaddr_in *)addr)->sin_port = htons((u_short)port);\r
- return 0;\r
-} //end of the function WINS_SetSocketPort\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+//===========================================================================
+//
+// Name: l_net_wins.c
+// Function: WinSock
+// Programmer: MrElusive
+// Last update: TTimo: cross-platform version, l_net library
+// Tab Size: 2
+// Notes:
+//===========================================================================
+
+//#include <windows.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "l_net.h"
+#include "l_net_wins.h"
+
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <errno.h>
+#include <netdb.h>
+#define SOCKET_ERROR -1
+#define INVALID_SOCKET -1
+
+extern void WinPrint(char *str, ...);
+
+#define WinError WinPrint
+
+#define qtrue 1
+#define qfalse 0
+
+#define ioctlsocket ioctl
+#define closesocket close
+
+int WSAGetLastError()
+{
+ return errno;
+}
+
+/*
+typedef struct tag_error_struct
+{
+ int errnum;
+ LPSTR errstr;
+} ERROR_STRUCT;
+*/
+
+typedef struct tag_error_struct
+{
+ int errnum;
+ const char *errstr;
+} ERROR_STRUCT;
+
+#define NET_NAMELEN 64
+
+static char my_tcpip_address[NET_NAMELEN];
+
+#define DEFAULTnet_hostport 26000
+
+#define MAXHOSTNAMELEN 256
+
+static int net_acceptsocket = -1; // socket for fielding new connections
+static int net_controlsocket;
+static int net_hostport; // udp port number for acceptsocket
+static int net_broadcastsocket = 0;
+//static qboolean ifbcastinit = qfalse;
+//static struct sockaddr_s broadcastaddr;
+static struct sockaddr_s broadcastaddr;
+
+static unsigned long myAddr;
+
+ERROR_STRUCT errlist[] = {
+ {EACCES,"EACCES - The address is protected, user is not root"},
+ {EAGAIN,"EAGAIN - Operation on non-blocking socket that cannot return immediatly"},
+ {EBADF, "EBADF - sockfd is not a valid descriptor"},
+ {EFAULT, "EFAULT - The parameter is not in a writable part of the user address space"},
+ {EINVAL,"EINVAL - The socket is already bound to an address"},
+ {ENOBUFS,"ENOBUFS - not enough memory"},
+ {ENOMEM, "ENOMEM - not enough memory"},
+ {ENOTCONN, "ENOTCONN - not connected"},
+ {ENOTSOCK,"ENOTSOCK - Argument is file descriptor not a socket"},
+ {EOPNOTSUPP,"ENOTSUPP - The referenced socket is not of type SOCK_STREAM"},
+ {EPERM, "EPERM - Firewall rules forbid connection"},
+ {-1, NULL}
+};
+
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+char *WINS_ErrorMessage(int error)
+{
+ int search = 0;
+
+ if (!error) return "No error occurred";
+
+ for (search = 0; errlist[search].errstr; search++)
+ {
+ if (error == errlist[search].errnum)
+ return (char *)errlist[search].errstr;
+ } //end for
+
+ return "Unknown error";
+} //end of the function WINS_ErrorMessage
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Init(void)
+{
+ int i;
+ struct hostent *local;
+ char buff[MAXHOSTNAMELEN];
+ struct sockaddr_s addr;
+ char *p;
+ int r;
+/*
+ linux doesn't have anything to initialize for the net
+ "Windows .. built for the internet .. the internet .. built with unix"
+ */
+#if 0
+ WORD wVersionRequested;
+
+ wVersionRequested = MAKEWORD(2, 2);
+
+ r = WSAStartup (wVersionRequested, &winsockdata);
+
+ if (r)
+ {
+ WinPrint("Winsock initialization failed.\n");
+ return -1;
+ }
+#endif
+ /*
+ i = COM_CheckParm ("-udpport");
+ if (i == 0)*/
+ net_hostport = DEFAULTnet_hostport;
+ /*
+ else if (i < com_argc-1)
+ net_hostport = Q_atoi (com_argv[i+1]);
+ else
+ Sys_Error ("WINS_Init: you must specify a number after -udpport");
+ */
+
+ // determine my name & address
+ gethostname(buff, MAXHOSTNAMELEN);
+ local = gethostbyname(buff);
+ myAddr = *(int *)local->h_addr_list[0];
+
+ // if the quake hostname isn't set, set it to the machine name
+// if (Q_strcmp(hostname.string, "UNNAMED") == 0)
+ {
+ // see if it's a text IP address (well, close enough)
+ for (p = buff; *p; p++)
+ if ((*p < '0' || *p > '9') && *p != '.')
+ break;
+
+ // if it is a real name, strip off the domain; we only want the host
+ if (*p)
+ {
+ for (i = 0; i < 15; i++)
+ if (buff[i] == '.')
+ break;
+ buff[i] = 0;
+ }
+// Cvar_Set ("hostname", buff);
+ }
+
+ //++timo WTF is that net_controlsocket? it's sole purpose is to retrieve the local IP?
+ if ((net_controlsocket = WINS_OpenSocket (0)) == SOCKET_ERROR)
+ WinError("WINS_Init: Unable to open control socket\n");
+
+ ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
+ ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
+ ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((u_short)net_hostport);
+
+ WINS_GetSocketAddr (net_controlsocket, &addr);
+ strcpy(my_tcpip_address, WINS_AddrToString (&addr));
+ p = strrchr (my_tcpip_address, ':');
+ if (p) *p = 0;
+ WinPrint("Winsock Initialized\n");
+
+ return net_controlsocket;
+} //end of the function WINS_Init
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+char *WINS_MyAddress(void)
+{
+ return my_tcpip_address;
+} //end of the function WINS_MyAddress
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+void WINS_Shutdown(void)
+{
+ //WINS_Listen(0);
+ WINS_CloseSocket(net_controlsocket);
+// WSACleanup();
+ //
+ WinPrint("Winsock Shutdown\n");
+} //end of the function WINS_Shutdown
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+/*
+void WINS_Listen(int state)
+{
+ // enable listening
+ if (state)
+ {
+ if (net_acceptsocket != -1)
+ return;
+ if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1)
+ WinError ("WINS_Listen: Unable to open accept socket\n");
+ return;
+ }
+
+ // disable listening
+ if (net_acceptsocket == -1)
+ return;
+ WINS_CloseSocket (net_acceptsocket);
+ net_acceptsocket = -1;
+} //end of the function WINS_Listen*/
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_OpenSocket(int port)
+{
+ int newsocket;
+ struct sockaddr_in address;
+ u_long _true = 1;
+
+ if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == SOCKET_ERROR)
+ {
+ WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+
+ if (ioctlsocket (newsocket, FIONBIO, &_true) == SOCKET_ERROR)
+ {
+ WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ closesocket(newsocket);
+ return -1;
+ } //end if
+
+ memset((char *) &address, 0, sizeof(address));
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_port = htons((u_short)port);
+ if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
+ {
+ WinPrint("WINS_OpenSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ closesocket(newsocket);
+ return -1;
+ } //end if
+
+ return newsocket;
+} //end of the function WINS_OpenSocket
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_OpenReliableSocket(int port)
+{
+ int newsocket;
+ struct sockaddr_in address;
+ qboolean _true = 0xFFFFFFFF;
+
+ //IPPROTO_TCP
+ //
+ if ((newsocket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ {
+ WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+
+ memset((char *) &address, 0, sizeof(address));
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = htonl(INADDR_ANY);
+ address.sin_port = htons((u_short)port);
+ if (bind(newsocket, (void *)&address, sizeof(address)) == -1)
+ {
+ WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ closesocket(newsocket);
+ return -1;
+ } //end if
+
+ //
+ if (setsockopt(newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof(int)) == -1)
+ {
+ WinPrint("WINS_OpenReliableSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ WinPrint("setsockopt error\n");
+ } //end if
+
+ return newsocket;
+} //end of the function WINS_OpenReliableSocket
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Listen(int socket)
+{
+ u_long _true = 1;
+
+ if (ioctlsocket(socket, FIONBIO, &_true) == -1)
+ {
+ WinPrint("WINS_Listen: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+ if (listen(socket, SOMAXCONN) == SOCKET_ERROR)
+ {
+ WinPrint("WINS_Listen: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+ return 0;
+} //end of the function WINS_Listen
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Accept(int socket, struct sockaddr_s *addr)
+{
+ int addrlen = sizeof (struct sockaddr_s);
+ int newsocket;
+ qboolean _true = 1;
+
+ newsocket = accept(socket, (struct sockaddr *)addr, &addrlen);
+ if (newsocket == INVALID_SOCKET)
+ {
+ if (errno == EAGAIN) return -1;
+ WinPrint("WINS_Accept: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+ //
+ if (setsockopt(newsocket, IPPROTO_TCP, TCP_NODELAY, (void *) &_true, sizeof(int)) == SOCKET_ERROR)
+ {
+ WinPrint("WINS_Accept: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ WinPrint("setsockopt error\n");
+ } //end if
+ return newsocket;
+} //end of the function WINS_Accept
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_CloseSocket(int socket)
+{
+ /*
+ if (socket == net_broadcastsocket)
+ net_broadcastsocket = 0;
+ */
+// shutdown(socket, SD_SEND);
+
+ if (closesocket(socket) == SOCKET_ERROR)
+ {
+ WinPrint("WINS_CloseSocket: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return SOCKET_ERROR;
+ } //end if
+ return 0;
+} //end of the function WINS_CloseSocket
+//===========================================================================
+// this lets you type only as much of the net address as required, using
+// the local network components to fill in the rest
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+static int PartialIPAddress (char *in, struct sockaddr_s *hostaddr)
+{
+ char buff[256];
+ char *b;
+ int addr;
+ int num;
+ int mask;
+
+ buff[0] = '.';
+ b = buff;
+ strcpy(buff+1, in);
+ if (buff[1] == '.') b++;
+
+ addr = 0;
+ mask=-1;
+ while (*b == '.')
+ {
+ num = 0;
+ if (*++b < '0' || *b > '9') return -1;
+ while (!( *b < '0' || *b > '9'))
+ num = num*10 + *(b++) - '0';
+ mask<<=8;
+ addr = (addr<<8) + num;
+ }
+
+ hostaddr->sa_family = AF_INET;
+ ((struct sockaddr_in *)hostaddr)->sin_port = htons((u_short)net_hostport);
+ ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
+
+ return 0;
+} //end of the function PartialIPAddress
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Connect(int socket, struct sockaddr_s *addr)
+{
+ int ret;
+ u_long _true2 = 0xFFFFFFFF;
+
+ ret = connect(socket, (struct sockaddr *)addr, sizeof(struct sockaddr_s));
+ if (ret == SOCKET_ERROR)
+ {
+ WinPrint("WINS_Connect: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+ if (ioctlsocket(socket, FIONBIO, &_true2) == -1)
+ {
+ WinPrint("WINS_Connect: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ return -1;
+ } //end if
+ return 0;
+} //end of the function WINS_Connect
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_CheckNewConnections(void)
+{
+ char buf[4];
+
+ if (net_acceptsocket == -1)
+ return -1;
+
+ if (recvfrom(net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0)
+ return net_acceptsocket;
+ return -1;
+} //end of the function WINS_CheckNewConnections
+//===========================================================================
+// returns the number of bytes read
+// 0 if no bytes available
+// -1 on failure
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Read(int socket, byte *buf, int len, struct sockaddr_s *addr)
+{
+ int addrlen = sizeof (struct sockaddr_s);
+ int ret;
+
+ if (addr)
+ {
+ ret = recvfrom(socket, buf, len, 0, (struct sockaddr *)addr, &addrlen);
+ if (ret == -1)
+ {
+// errno = WSAGetLastError();
+
+ if (errno == EAGAIN || errno == ENOTCONN)
+ return 0;
+ } //end if
+ } //end if
+ else
+ {
+ ret = recv(socket, buf, len, 0);
+ // if there's no data on the socket ret == -1 and errno == EAGAIN
+ // MSDN states that if ret == 0 the socket has been closed
+ // man recv doesn't say anything
+ if (ret == 0)
+ return -1;
+ if (ret == SOCKET_ERROR)
+ {
+// errno = WSAGetLastError();
+
+ if (errno == EAGAIN || errno == ENOTCONN)
+ return 0;
+ } //end if
+ } //end else
+ if (ret == SOCKET_ERROR)
+ {
+ WinPrint("WINS_Read: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ } //end if
+ return ret;
+} //end of the function WINS_Read
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_MakeSocketBroadcastCapable (int socket)
+{
+ int i = 1;
+
+ // make this socket broadcast capable
+ if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
+ return -1;
+ net_broadcastsocket = socket;
+
+ return 0;
+} //end of the function WINS_MakeSocketBroadcastCapable
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Broadcast (int socket, byte *buf, int len)
+{
+ int ret;
+
+ if (socket != net_broadcastsocket)
+ {
+ if (net_broadcastsocket != 0)
+ WinError("Attempted to use multiple broadcasts sockets\n");
+ ret = WINS_MakeSocketBroadcastCapable (socket);
+ if (ret == -1)
+ {
+ WinPrint("Unable to make socket broadcast capable\n");
+ return ret;
+ }
+ }
+
+ return WINS_Write (socket, buf, len, &broadcastaddr);
+} //end of the function WINS_Broadcast
+//===========================================================================
+// returns qtrue on success or qfalse on failure
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_Write(int socket, byte *buf, int len, struct sockaddr_s *addr)
+{
+ int ret, written;
+
+ if (addr)
+ {
+ written = 0;
+ while(written < len)
+ {
+ ret = sendto (socket, &buf[written], len-written, 0, (struct sockaddr *)addr, sizeof(struct sockaddr_s));
+ if (ret == SOCKET_ERROR)
+ {
+ if (WSAGetLastError() != EAGAIN)
+ return qfalse;
+ //++timo FIXME: what is this used for?
+// Sleep(1000);
+ } //end if
+ else
+ {
+ written += ret;
+ }
+ }
+ } //end if
+ else
+ {
+ written = 0;
+ while(written < len)
+ {
+ ret = send(socket, buf, len, 0);
+ if (ret == SOCKET_ERROR)
+ {
+ if (WSAGetLastError() != EAGAIN)
+ return qfalse;
+ //++timo FIXME: what is this used for?
+// Sleep(1000);
+ } //end if
+ else
+ {
+ written += ret;
+ }
+ }
+ } //end else
+ if (ret == SOCKET_ERROR)
+ {
+ WinPrint("WINS_Write: %s\n", WINS_ErrorMessage(WSAGetLastError()));
+ } //end if
+ return (ret == len);
+} //end of the function WINS_Write
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+char *WINS_AddrToString (struct sockaddr_s *addr)
+{
+ static char buffer[22];
+ int haddr;
+
+ haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
+ 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));
+ return buffer;
+} //end of the function WINS_AddrToString
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_StringToAddr(char *string, struct sockaddr_s *addr)
+{
+ int ha1, ha2, ha3, ha4, hp;
+ int ipaddr;
+
+ sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
+ ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
+
+ addr->sa_family = AF_INET;
+ ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
+ ((struct sockaddr_in *)addr)->sin_port = htons((u_short)hp);
+ return 0;
+} //end of the function WINS_StringToAddr
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_GetSocketAddr(int socket, struct sockaddr_s *addr)
+{
+ int addrlen = sizeof(struct sockaddr_s);
+ unsigned int a;
+
+ memset(addr, 0, sizeof(struct sockaddr_s));
+ getsockname(socket, (struct sockaddr *)addr, &addrlen);
+ a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
+ if (a == 0 || a == inet_addr("127.0.0.1"))
+ ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
+
+ return 0;
+} //end of the function WINS_GetSocketAddr
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_GetNameFromAddr (struct sockaddr_s *addr, char *name)
+{
+ struct hostent *hostentry;
+
+ hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
+ if (hostentry)
+ {
+ strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
+ return 0;
+ }
+
+ strcpy (name, WINS_AddrToString (addr));
+ return 0;
+} //end of the function WINS_GetNameFromAddr
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_GetAddrFromName(char *name, struct sockaddr_s *addr)
+{
+ struct hostent *hostentry;
+
+ if (name[0] >= '0' && name[0] <= '9')
+ return PartialIPAddress (name, addr);
+
+ hostentry = gethostbyname (name);
+ if (!hostentry)
+ return -1;
+
+ addr->sa_family = AF_INET;
+ ((struct sockaddr_in *)addr)->sin_port = htons((u_short)net_hostport);
+ ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
+
+ return 0;
+} //end of the function WINS_GetAddrFromName
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_AddrCompare (struct sockaddr_s *addr1, struct sockaddr_s *addr2)
+{
+ if (addr1->sa_family != addr2->sa_family)
+ return -1;
+
+ if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
+ return -1;
+
+ if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
+ return 1;
+
+ return 0;
+} //end of the function WINS_AddrCompare
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_GetSocketPort (struct sockaddr_s *addr)
+{
+ return ntohs(((struct sockaddr_in *)addr)->sin_port);
+} //end of the function WINS_GetSocketPort
+//===========================================================================
+//
+// Parameter: -
+// Returns: -
+// Changes Globals: -
+//===========================================================================
+int WINS_SetSocketPort (struct sockaddr_s *addr, int port)
+{
+ ((struct sockaddr_in *)addr)->sin_port = htons((u_short)port);
+ return 0;
+} //end of the function WINS_SetSocketPort