Capture the Flag, 2008 Jun 17
[SauerbratenRemote.git] / src / enet / win32.c
blob1bfe0d637b4ceeecdd5fecaf0895ad0ce9c61440
1 /**
2 @file win32.c
3 @brief ENet Win32 system specific functions
4 */
5 #ifdef WIN32
7 #include <time.h>
8 #define ENET_BUILDING_LIB 1
9 #include "enet/enet.h"
11 static enet_uint32 timeBase = 0;
13 int
14 enet_initialize (void)
16 WORD versionRequested = MAKEWORD (1, 1);
17 WSADATA wsaData;
19 if (WSAStartup (versionRequested, & wsaData))
20 return -1;
22 if (LOBYTE (wsaData.wVersion) != 1||
23 HIBYTE (wsaData.wVersion) != 1)
25 WSACleanup ();
27 return -1;
30 timeBeginPeriod (1);
32 return 0;
35 void
36 enet_deinitialize (void)
38 timeEndPeriod (1);
40 WSACleanup ();
43 enet_uint32
44 enet_time_get (void)
46 return (enet_uint32) timeGetTime () - timeBase;
49 void
50 enet_time_set (enet_uint32 newTimeBase)
52 timeBase = (enet_uint32) timeGetTime () - newTimeBase;
55 int
56 enet_address_set_host (ENetAddress * address, const char * name)
58 struct hostent * hostEntry;
60 hostEntry = gethostbyname (name);
61 if (hostEntry == NULL ||
62 hostEntry -> h_addrtype != AF_INET)
64 unsigned long host = inet_addr (name);
65 if (host == INADDR_NONE)
66 return -1;
67 address -> host = host;
68 return 0;
71 address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
73 return 0;
76 int
77 enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
79 char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
80 if (addr == NULL)
81 return -1;
82 strncpy (name, addr, nameLength);
83 return 0;
86 int
87 enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
89 struct in_addr in;
90 struct hostent * hostEntry;
92 in.s_addr = address -> host;
94 hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
95 if (hostEntry == NULL)
96 return enet_address_get_host_ip (address, name, nameLength);
98 strncpy (name, hostEntry -> h_name, nameLength);
100 return 0;
103 ENetSocket
104 enet_socket_create (ENetSocketType type, const ENetAddress * address)
106 ENetSocket newSocket = socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
107 struct sockaddr_in sin;
109 if (newSocket == ENET_SOCKET_NULL)
110 return ENET_SOCKET_NULL;
112 memset (& sin, 0, sizeof (struct sockaddr_in));
114 sin.sin_family = AF_INET;
116 if (address != NULL)
118 sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
119 sin.sin_addr.s_addr = address -> host;
121 else
123 sin.sin_port = 0;
124 sin.sin_addr.s_addr = INADDR_ANY;
127 if (bind (newSocket,
128 (struct sockaddr *) & sin,
129 sizeof (struct sockaddr_in)) == SOCKET_ERROR ||
130 (type == ENET_SOCKET_TYPE_STREAM &&
131 address != NULL &&
132 address -> port != ENET_PORT_ANY &&
133 listen (newSocket, SOMAXCONN) == SOCKET_ERROR))
135 closesocket (newSocket);
137 return ENET_SOCKET_NULL;
140 return newSocket;
144 enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
146 int result = SOCKET_ERROR;
147 switch (option)
149 case ENET_SOCKOPT_NONBLOCK:
151 u_long nonBlocking = (u_long) value;
152 result = ioctlsocket (socket, FIONBIO, & nonBlocking);
153 break;
156 case ENET_SOCKOPT_BROADCAST:
157 result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
158 break;
160 case ENET_SOCKOPT_RCVBUF:
161 result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
162 break;
164 case ENET_SOCKOPT_SNDBUF:
165 result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
166 break;
168 default:
169 break;
171 return result == SOCKET_ERROR ? -1 : 0;
175 enet_socket_connect (ENetSocket socket, const ENetAddress * address)
177 struct sockaddr_in sin;
179 memset (& sin, 0, sizeof (struct sockaddr_in));
181 sin.sin_family = AF_INET;
182 sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
183 sin.sin_addr.s_addr = address -> host;
185 return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
188 ENetSocket
189 enet_socket_accept (ENetSocket socket, ENetAddress * address)
191 SOCKET result;
192 struct sockaddr_in sin;
193 int sinLength = sizeof (struct sockaddr_in);
195 result = accept (socket,
196 address != NULL ? (struct sockaddr *) & sin : NULL,
197 address != NULL ? & sinLength : NULL);
199 if (result == INVALID_SOCKET)
200 return ENET_SOCKET_NULL;
202 if (address != NULL)
204 address -> host = (enet_uint32) sin.sin_addr.s_addr;
205 address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
208 return result;
211 void
212 enet_socket_destroy (ENetSocket socket)
214 closesocket (socket);
218 enet_socket_send (ENetSocket socket,
219 const ENetAddress * address,
220 const ENetBuffer * buffers,
221 size_t bufferCount)
223 struct sockaddr_in sin;
224 DWORD sentLength;
226 if (address != NULL)
228 memset (& sin, 0, sizeof (struct sockaddr_in));
230 sin.sin_family = AF_INET;
231 sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
232 sin.sin_addr.s_addr = address -> host;
235 if (WSASendTo (socket,
236 (LPWSABUF) buffers,
237 (DWORD) bufferCount,
238 & sentLength,
240 address != NULL ? (struct sockaddr *) & sin : 0,
241 address != NULL ? sizeof (struct sockaddr_in) : 0,
242 NULL,
243 NULL) == SOCKET_ERROR)
245 if (WSAGetLastError () == WSAEWOULDBLOCK)
246 return 0;
248 return -1;
251 return (int) sentLength;
255 enet_socket_receive (ENetSocket socket,
256 ENetAddress * address,
257 ENetBuffer * buffers,
258 size_t bufferCount)
260 INT sinLength = sizeof (struct sockaddr_in);
261 DWORD flags = 0,
262 recvLength;
263 struct sockaddr_in sin;
265 if (WSARecvFrom (socket,
266 (LPWSABUF) buffers,
267 (DWORD) bufferCount,
268 & recvLength,
269 & flags,
270 address != NULL ? (struct sockaddr *) & sin : NULL,
271 address != NULL ? & sinLength : NULL,
272 NULL,
273 NULL) == SOCKET_ERROR)
275 switch (WSAGetLastError ())
277 case WSAEWOULDBLOCK:
278 case WSAECONNRESET:
279 return 0;
282 return -1;
285 if (flags & MSG_PARTIAL)
286 return -1;
288 if (address != NULL)
290 address -> host = (enet_uint32) sin.sin_addr.s_addr;
291 address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
294 return (int) recvLength;
298 enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
300 fd_set readSet, writeSet;
301 struct timeval timeVal;
302 int selectCount;
304 timeVal.tv_sec = timeout / 1000;
305 timeVal.tv_usec = (timeout % 1000) * 1000;
307 FD_ZERO (& readSet);
308 FD_ZERO (& writeSet);
310 if (* condition & ENET_SOCKET_WAIT_SEND)
311 FD_SET (socket, & writeSet);
313 if (* condition & ENET_SOCKET_WAIT_RECEIVE)
314 FD_SET (socket, & readSet);
316 selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
318 if (selectCount < 0)
319 return -1;
321 * condition = ENET_SOCKET_WAIT_NONE;
323 if (selectCount == 0)
324 return 0;
326 if (FD_ISSET (socket, & writeSet))
327 * condition |= ENET_SOCKET_WAIT_SEND;
329 if (FD_ISSET (socket, & readSet))
330 * condition |= ENET_SOCKET_WAIT_RECEIVE;
332 return 0;
335 #endif