zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDLnet.c
Go to the documentation of this file.
1 /*
2  SDL_net: An example cross-platform network library for use with SDL
3  Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4  Copyright (C) 2012 Simeon Maxein <smaxein@googlemail.com>
5 
6  This software is provided 'as-is', without any express or implied
7  warranty. In no event will the authors be held liable for any damages
8  arising from the use of this software.
9 
10  Permission is granted to anyone to use this software for any purpose,
11  including commercial applications, and to alter it and redistribute it
12  freely, subject to the following restrictions:
13 
14  1. The origin of this software must not be misrepresented; you must not
15  claim that you wrote the original software. If you use this software
16  in a product, an acknowledgment in the product documentation would be
17  appreciated but is not required.
18  2. Altered source versions must be plainly marked as such, and must not be
19  misrepresented as being the original software.
20  3. This notice may not be removed or altered from any source distribution.
21 */
22 
23 /* $Id$ */
24 
25 #include "SDLnetsys.h"
26 #include "SDL_net.h"
27 
28 #ifdef WITHOUT_SDL
29 #include <string.h>
30 #include <stdarg.h>
31 #endif
32 
34 {
35  static SDLNet_version linked_version;
36  SDL_NET_VERSION(&linked_version);
37  return(&linked_version);
38 }
39 
40 /* Since the UNIX/Win32/BeOS code is so different from MacOS,
41  we'll just have two completely different sections here.
42 */
43 static int SDLNet_started = 0;
44 
45 #ifndef __USE_W32_SOCKETS
46 #include <signal.h>
47 #endif
48 
49 #ifndef __USE_W32_SOCKETS
50 
52 {
53  return errno;
54 }
55 
56 void SDLNet_SetLastError(int err)
57 {
58  errno = err;
59 }
60 
61 #endif
62 
63 static char errorbuf[1024];
64 
65 void SDLCALL SDLNet_SetError(const char *fmt, ...)
66 {
67  va_list argp;
68  va_start(argp, fmt);
69  SDL_vsnprintf(errorbuf, sizeof(errorbuf), fmt, argp);
70  va_end(argp);
71 #ifndef WITHOUT_SDL
72  SDL_SetError("%s", errorbuf);
73 #endif
74 }
75 
76 const char * SDLCALL SDLNet_GetError(void)
77 {
78 #ifdef WITHOUT_SDL
79  return errorbuf;
80 #else
81  return SDL_GetError();
82 #endif
83 }
84 
85 /* Initialize/Cleanup the network API */
86 int SDLNet_Init(void)
87 {
88  if ( !SDLNet_started ) {
89 #ifdef __USE_W32_SOCKETS
90  /* Start up the windows networking */
91  WORD version_wanted = MAKEWORD(1,1);
92  WSADATA wsaData;
93 
94  if ( WSAStartup(version_wanted, &wsaData) != 0 ) {
95  SDLNet_SetError("Couldn't initialize Winsock 1.1\n");
96  return(-1);
97  }
98 #else
99  /* SIGPIPE is generated when a remote socket is closed */
100  void (*handler)(int);
101  handler = signal(SIGPIPE, SIG_IGN);
102  if ( handler != SIG_DFL ) {
103  signal(SIGPIPE, handler);
104  }
105 #endif
106  }
107  ++SDLNet_started;
108  return(0);
109 }
110 void SDLNet_Quit(void)
111 {
112  if ( SDLNet_started == 0 ) {
113  return;
114  }
115  if ( --SDLNet_started == 0 ) {
116 #ifdef __USE_W32_SOCKETS
117  /* Clean up windows networking */
118  if ( WSACleanup() == SOCKET_ERROR ) {
119  if ( WSAGetLastError() == WSAEINPROGRESS ) {
120 #ifndef _WIN32_WCE
121  WSACancelBlockingCall();
122 #endif
123  WSACleanup();
124  }
125  }
126 #else
127  /* Restore the SIGPIPE handler */
128  void (*handler)(int);
129  handler = signal(SIGPIPE, SIG_DFL);
130  if ( handler != SIG_IGN ) {
131  signal(SIGPIPE, handler);
132  }
133 #endif
134  }
135 }
136 
137 /* Resolve a host name and port to an IP address in network form */
138 int SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port)
139 {
140  int retval = 0;
141 
142  /* Perform the actual host resolution */
143  if ( host == NULL ) {
144  address->host = INADDR_ANY;
145  } else {
146  address->host = inet_addr(host);
147  if ( address->host == INADDR_NONE ) {
148  struct hostent *hp;
149 
150  hp = gethostbyname(host);
151  if ( hp ) {
152  memcpy(&address->host,hp->h_addr,hp->h_length);
153  } else {
154  retval = -1;
155  }
156  }
157  }
158  address->port = SDLNet_Read16(&port);
159 
160  /* Return the status */
161  return(retval);
162 }
163 
164 /* Resolve an ip address to a host name in canonical form.
165  If the ip couldn't be resolved, this function returns NULL,
166  otherwise a pointer to a static buffer containing the hostname
167  is returned. Note that this function is not thread-safe.
168 */
169 /* Written by Miguel Angel Blanch.
170  * Main Programmer of Arianne RPG.
171  * http://come.to/arianne_rpg
172  */
173 const char *SDLNet_ResolveIP(const IPaddress *ip)
174 {
175  struct hostent *hp;
176  struct in_addr in;
177 
178  hp = gethostbyaddr((const char *)&ip->host, sizeof(ip->host), AF_INET);
179  if ( hp != NULL ) {
180  return hp->h_name;
181  }
182 
183  in.s_addr = ip->host;
184  return inet_ntoa(in);
185 }
186 
187 int SDLNet_GetLocalAddresses(IPaddress *addresses, int maxcount)
188 {
189  int count = 0;
190 #ifdef SIOCGIFCONF
191 /* Defined on Mac OS X */
192 #ifndef _SIZEOF_ADDR_IFREQ
193 #define _SIZEOF_ADDR_IFREQ sizeof
194 #endif
195  SOCKET sock;
196  struct ifconf conf;
197  char data[4096];
198  struct ifreq *ifr;
199  struct sockaddr_in *sock_addr;
200 
201  sock = socket(AF_INET, SOCK_DGRAM, 0);
202  if ( sock == INVALID_SOCKET ) {
203  return 0;
204  }
205 
206  conf.ifc_len = sizeof(data);
207  conf.ifc_buf = (caddr_t) data;
208  if ( ioctl(sock, SIOCGIFCONF, &conf) < 0 ) {
209  closesocket(sock);
210  return 0;
211  }
212 
213  ifr = (struct ifreq*)data;
214  while ((char*)ifr < data+conf.ifc_len) {
215  if (ifr->ifr_addr.sa_family == AF_INET) {
216  if (count < maxcount) {
217  sock_addr = (struct sockaddr_in*)&ifr->ifr_addr;
218  addresses[count].host = sock_addr->sin_addr.s_addr;
219  addresses[count].port = sock_addr->sin_port;
220  }
221  ++count;
222  }
223  ifr = (struct ifreq*)((char*)ifr + _SIZEOF_ADDR_IFREQ(*ifr));
224  }
225  closesocket(sock);
226 #elif defined(__WIN32__)
227  PIP_ADAPTER_INFO pAdapterInfo;
228  PIP_ADAPTER_INFO pAdapter;
229  PIP_ADDR_STRING pAddress;
230  DWORD dwRetVal = 0;
231  ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
232 
233  pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof (IP_ADAPTER_INFO));
234  if (pAdapterInfo == NULL) {
235  return 0;
236  }
237 
238  if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == ERROR_BUFFER_OVERFLOW) {
239  pAdapterInfo = (IP_ADAPTER_INFO *) realloc(pAdapterInfo, ulOutBufLen);
240  if (pAdapterInfo == NULL) {
241  return 0;
242  }
243  dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
244  }
245 
246  if (dwRetVal == NO_ERROR) {
247  for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
248  for (pAddress = &pAdapterInfo->IpAddressList; pAddress; pAddress = pAddress->Next) {
249  if (count < maxcount) {
250  addresses[count].host = inet_addr(pAddress->IpAddress.String);
251  addresses[count].port = 0;
252  }
253  ++count;
254  }
255  }
256  }
257  free(pAdapterInfo);
258 #endif
259  return count;
260 }
261 
262 #if !defined(WITHOUT_SDL) && !SDL_DATA_ALIGNED /* function versions for binary compatibility */
263 
264 #undef SDLNet_Write16
265 #undef SDLNet_Write32
266 #undef SDLNet_Read16
267 #undef SDLNet_Read32
268 
269 /* Write a 16/32 bit value to network packet buffer */
270 extern DECLSPEC void SDLCALL SDLNet_Write16(Uint16 value, void *area);
271 extern DECLSPEC void SDLCALL SDLNet_Write32(Uint32 value, void *area);
272 
273 /* Read a 16/32 bit value from network packet buffer */
274 extern DECLSPEC Uint16 SDLCALL SDLNet_Read16(void *area);
275 extern DECLSPEC Uint32 SDLCALL SDLNet_Read32(const void *area);
276 
277 void SDLNet_Write16(Uint16 value, void *areap)
278 {
279  (*(Uint16 *)(areap) = SDL_SwapBE16(value));
280 }
281 
282 void SDLNet_Write32(Uint32 value, void *areap)
283 {
284  *(Uint32 *)(areap) = SDL_SwapBE32(value);
285 }
286 
287 Uint16 SDLNet_Read16(void *areap)
288 {
289  return (SDL_SwapBE16(*(Uint16 *)(areap)));
290 }
291 
292 Uint32 SDLNet_Read32(const void *areap)
293 {
294  return (SDL_SwapBE32(*(Uint32 *)(areap)));
295 }
296 
297 #endif /* !defined(WITHOUT_SDL) && !SDL_DATA_ALIGNED */
static int SDLNet_started
Definition: SDLnet.c:43
DECLSPEC void SDLCALL SDLNet_SetError(const char *fmt,...)
Definition: SDLnet.c:65
#define SOCKET
Definition: SDLnetsys.h:78
#define SDLNet_Write16(value, areap)
Definition: SDL_net.h:376
Uint32 host
Definition: SDL_net.h:91
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
Definition: glew.h:1824
#define closesocket
Definition: SDLnetsys.h:76
#define NULL
Definition: ftobjs.h:61
DECLSPEC int SDLCALL SDLNet_Init(void)
Definition: SDLnet.c:86
SDL_EventEntry * free
Definition: SDL_events.c:80
#define DECLSPEC
Definition: begin_code.h:62
int SDLNet_GetLastError(void)
Definition: SDLnet.c:51
#define SDLNet_Write32(value, areap)
Definition: SDL_net.h:377
#define SDLCALL
Definition: begin_code.h:72
#define SDL_NET_VERSION(X)
Definition: SDL_net.h:66
DECLSPEC const char *SDLCALL SDL_GetError(void)
Definition: SDL_error.c:204
#define INADDR_NONE
Definition: SDL_net.h:105
HANDLE LPVOID * pAddress
Definition: wglew.h:826
static char errorbuf[1024]
Definition: SDLnet.c:63
#define SDL_SwapBE32(X)
Definition: SDL_endian.h:216
#define SDL_SwapBE16(X)
Definition: SDL_endian.h:215
DECLSPEC const SDLNet_version *SDLCALL SDLNet_Linked_Version(void)
Definition: SDLnet.c:33
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
#define INVALID_SOCKET
Definition: SDLnetsys.h:79
Information the version of SDL in use.
Definition: SDL_version.h:51
int
Definition: SDL_systhread.c:37
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
GLint GLsizei count
Definition: gl2ext.h:1011
GLuint GLuint64EXT address
Definition: glew.h:13266
#define realloc
Definition: SDL_malloc.c:637
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
#define SDLNet_Read32(areap)
Definition: SDL_net.h:381
Uint16 port
Definition: SDL_net.h:92
DECLSPEC const char *SDLCALL SDLNet_ResolveIP(const IPaddress *ip)
Definition: SDLnet.c:173
DECLSPEC void SDLCALL SDLNet_Quit(void)
Definition: SDLnet.c:110
DECLSPEC int SDLCALL SDLNet_GetLocalAddresses(IPaddress *addresses, int maxcount)
Definition: SDLnet.c:187
DECLSPEC int SDLCALL SDLNet_ResolveHost(IPaddress *address, const char *host, Uint16 port)
Definition: SDLnet.c:138
#define malloc
Definition: SDL_malloc.c:635
EGLSurface EGLint void ** value
Definition: eglext.h:301
#define memcpy
Definition: SDL_malloc.c:634
TCPsocket sock
Definition: chatd.c:41
#define INADDR_ANY
Definition: SDL_net.h:102
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
#define SOCKET_ERROR
Definition: SDLnetsys.h:80
uint16_t Uint16
An unsigned 16-bit integer type.
Definition: SDL_stdinc.h:137
void SDLNet_SetLastError(int err)
Definition: SDLnet.c:56
#define SDLNet_Read16(areap)
Definition: SDL_net.h:380
DECLSPEC int SDLCALL SDL_vsnprintf(char *text, size_t maxlen, const char *fmt, va_list ap)
Definition: SDL_string.c:1479
DECLSPEC const char *SDLCALL SDLNet_GetError(void)
Definition: SDLnet.c:76