]> git.saurik.com Git - wxWidgets.git/blame - src/msw/gsocket.cpp
Add wxDataViewCtrl::ExpandAncestors() and call it from both EnsureVisible() and Select()
[wxWidgets.git] / src / msw / gsocket.cpp
CommitLineData
f7ff39c6 1/* -------------------------------------------------------------------------
51fe4b60 2 * Project: wxSocketImpl (Generic Socket)
521bf4ff 3 * Name: src/msw/gsocket.cpp
99d80019
JS
4 * Copyright: (c) Guilhem Lavaux
5 * Licence: wxWindows Licence
6 * Author: Guillermo Rodriguez Garcia <guille@iies.es>
51fe4b60 7 * Purpose: wxSocketImpl main MSW file
99d80019
JS
8 * Licence: The wxWindows licence
9 * CVSID: $Id$
f7ff39c6
DE
10 * -------------------------------------------------------------------------
11 */
12
86afa786
VS
13// For compilers that support precompilation, includes "wx.h".
14#include "wx/wxprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
f7ff39c6
DE
20#ifdef _MSC_VER
21 /* RPCNOTIFICATION_ROUTINE in rasasync.h (included from winsock.h),
22 * warning: conditional expression is constant.
23 */
24# pragma warning(disable:4115)
25 /* FD_SET,
26 * warning: named type definition in parentheses.
27 */
28# pragma warning(disable:4127)
29 /* GAddress_UNIX_GetPath,
30 * warning: unreferenced formal parameter.
31 */
32# pragma warning(disable:4100)
33
34#ifdef __WXWINCE__
35 /* windows.h results in tons of warnings at max warning level */
36# ifdef _MSC_VER
37# pragma warning(push, 1)
38# endif
39# include <windows.h>
40# ifdef _MSC_VER
41# pragma warning(pop)
42# pragma warning(disable:4514)
43# endif
44#endif
45
46#endif /* _MSC_VER */
47
f6afe7fd
RN
48#if defined(__CYGWIN__)
49 //CYGWIN gives annoying warning about runtime stuff if we don't do this
50# define USE_SYS_TYPES_FD_SET
51# include <sys/types.h>
52#endif
53
f7ff39c6
DE
54#include <winsock.h>
55
2804f77d 56#include "wx/platform.h"
f7ff39c6 57
2804f77d 58#if wxUSE_SOCKETS
f7ff39c6 59
60913641 60#include "wx/private/socket.h"
a3cf8dca
VZ
61#include "wx/link.h"
62
63wxFORCE_LINK_MODULE(gsockmsw)
f7ff39c6 64
2804f77d 65#ifdef __WXWINCE__
f7ff39c6
DE
66#ifndef isdigit
67#define isdigit(x) (x > 47 && x < 58)
68#endif
69#include "wx/msw/wince/net.h"
70#endif
71
72#include <string.h>
73#include <stdio.h>
74#include <stdlib.h>
75#include <stddef.h>
76#include <ctype.h>
77
02564412 78#include "wx/private/socket.h"
8575ff50 79
54cb21d6
VZ
80/* static */
81wxSocketImpl *wxSocketImpl::Create(wxSocketBase& wxsocket)
82{
83 return new wxSocketImplMSW(wxsocket);
84}
85
51fe4b60 86void wxSocketImplMSW::DoClose()
f7ff39c6 87{
51fe4b60
VZ
88 wxSocketManager::Get()->
89 Uninstall_Callback(this, wxSOCKET_MAX_EVENT /* unused anyhow */);
f7ff39c6 90
51fe4b60 91 closesocket(m_fd);
f7ff39c6
DE
92}
93
51fe4b60 94/*
f7ff39c6 95 * Waits for an incoming client connection. Returns a pointer to
51fe4b60
VZ
96 * a wxSocketImpl object, or NULL if there was an error, in which case
97 * the last error field will be updated for the calling wxSocketImpl.
f7ff39c6 98 *
51fe4b60
VZ
99 * Error codes (set in the calling wxSocketImpl)
100 * wxSOCKET_INVSOCK - the socket is not valid or not a server.
101 * wxSOCKET_TIMEDOUT - timeout, no incoming connections.
102 * wxSOCKET_WOULDBLOCK - the call would block and the socket is nonblocking.
103 * wxSOCKET_MEMERR - couldn't allocate memory.
104 * wxSOCKET_IOERR - low-level error.
f7ff39c6 105 */
51fe4b60 106wxSocketImpl *wxSocketImplMSW::WaitConnection(wxSocketBase& wxsocket)
f7ff39c6 107{
51fe4b60 108 wxSocketImpl *connection;
8575ff50 109 wxSockAddr from;
9e03e02d 110 WX_SOCKLEN_T fromlen = sizeof(from);
51fe4b60 111 wxSocketError err;
f7ff39c6
DE
112 u_long arg = 1;
113
f7ff39c6 114 /* Reenable CONNECTION events */
51fe4b60 115 m_detected &= ~wxSOCKET_CONNECTION_FLAG;
f7ff39c6
DE
116
117 /* If the socket has already been created, we exit immediately */
c90cc42e 118 if (m_fd == INVALID_SOCKET || !m_server)
f7ff39c6 119 {
51fe4b60 120 m_error = wxSOCKET_INVSOCK;
f7ff39c6
DE
121 return NULL;
122 }
123
51fe4b60
VZ
124 /* Create a wxSocketImpl object for the new connection */
125 connection = wxSocketImplMSW::Create(wxsocket);
f7ff39c6
DE
126
127 if (!connection)
128 {
51fe4b60 129 m_error = wxSOCKET_MEMERR;
f7ff39c6
DE
130 return NULL;
131 }
132
133 /* Wait for a connection (with timeout) */
51fe4b60 134 if (Input_Timeout() == wxSOCKET_TIMEDOUT)
f7ff39c6 135 {
85431efa 136 delete connection;
51fe4b60 137 /* m_error set by Input_Timeout */
f7ff39c6
DE
138 return NULL;
139 }
140
8575ff50 141 connection->m_fd = accept(m_fd, (sockaddr*)&from, &fromlen);
f7ff39c6
DE
142
143 if (connection->m_fd == INVALID_SOCKET)
144 {
145 if (WSAGetLastError() == WSAEWOULDBLOCK)
51fe4b60 146 m_error = wxSOCKET_WOULDBLOCK;
f7ff39c6 147 else
51fe4b60 148 m_error = wxSOCKET_IOERR;
f7ff39c6 149
85431efa 150 delete connection;
f7ff39c6
DE
151 return NULL;
152 }
153
154 /* Initialize all fields */
948c96ef
DE
155 connection->m_server = false;
156 connection->m_stream = true;
f7ff39c6
DE
157
158 /* Setup the peer address field */
159 connection->m_peer = GAddress_new();
160 if (!connection->m_peer)
161 {
85431efa 162 delete connection;
51fe4b60 163 m_error = wxSOCKET_MEMERR;
f7ff39c6
DE
164 return NULL;
165 }
8575ff50 166 err = _GAddress_translate_from(connection->m_peer, (sockaddr*)&from, fromlen);
51fe4b60 167 if (err != wxSOCKET_NOERROR)
f7ff39c6
DE
168 {
169 GAddress_destroy(connection->m_peer);
85431efa 170 delete connection;
c90cc42e 171 m_error = err;
f7ff39c6
DE
172 return NULL;
173 }
174
175 ioctlsocket(connection->m_fd, FIONBIO, (u_long FAR *) &arg);
51fe4b60 176 wxSocketManager::Get()->Install_Callback(connection);
f7ff39c6
DE
177
178 return connection;
179}
180
51fe4b60 181wxSocketError wxSocketImplMSW::DoHandleConnect(int ret)
f7ff39c6 182{
51fe4b60
VZ
183 // TODO: review this
184 if (ret == SOCKET_ERROR)
f7ff39c6 185 {
51fe4b60
VZ
186 int err = WSAGetLastError();
187
188 /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
189 * is in blocking mode, we select() for the specified timeout
190 * checking for writability to see if the connection request
191 * completes.
192 */
193 if ((err == WSAEWOULDBLOCK) && (!m_non_blocking))
194 {
195 err = Connect_Timeout();
196
197 if (err != wxSOCKET_NOERROR)
198 {
199 Close();
200 /* m_error is set in Connect_Timeout */
201 }
202
203 return (wxSocketError) err;
204 }
205
206 /* If connect failed with EWOULDBLOCK and the wxSocketImpl object
207 * is set to nonblocking, we set m_error to wxSOCKET_WOULDBLOCK
208 * (and return wxSOCKET_WOULDBLOCK) but we don't close the socket;
209 * this way if the connection completes, a wxSOCKET_CONNECTION
210 * event will be generated, if enabled.
211 */
212 if ((err == WSAEWOULDBLOCK) && (m_non_blocking))
213 {
214 m_establishing = true;
215 m_error = wxSOCKET_WOULDBLOCK;
216 return wxSOCKET_WOULDBLOCK;
217 }
218
219 /* If connect failed with an error other than EWOULDBLOCK,
220 * then the call to Connect() has failed.
221 */
c90cc42e 222 Close();
51fe4b60
VZ
223 m_error = wxSOCKET_IOERR;
224 return wxSOCKET_IOERR;
f7ff39c6
DE
225 }
226
51fe4b60 227 return wxSOCKET_NOERROR;
f7ff39c6
DE
228}
229
230/* Generic IO */
231
232/* Like recv(), send(), ... */
51fe4b60 233int wxSocketImplMSW::Read(char *buffer, int size)
f7ff39c6
DE
234{
235 int ret;
236
f7ff39c6 237 /* Reenable INPUT events */
51fe4b60 238 m_detected &= ~wxSOCKET_INPUT_FLAG;
f7ff39c6 239
c90cc42e 240 if (m_fd == INVALID_SOCKET || m_server)
f7ff39c6 241 {
51fe4b60 242 m_error = wxSOCKET_INVSOCK;
f7ff39c6
DE
243 return -1;
244 }
245
246 /* If the socket is blocking, wait for data (with a timeout) */
51fe4b60 247 if (Input_Timeout() == wxSOCKET_TIMEDOUT)
976abb72 248 {
51fe4b60 249 m_error = wxSOCKET_TIMEDOUT;
f7ff39c6 250 return -1;
976abb72 251 }
f7ff39c6
DE
252
253 /* Read the data */
c90cc42e
DE
254 if (m_stream)
255 ret = Recv_Stream(buffer, size);
f7ff39c6 256 else
c90cc42e 257 ret = Recv_Dgram(buffer, size);
f7ff39c6
DE
258
259 if (ret == SOCKET_ERROR)
260 {
261 if (WSAGetLastError() != WSAEWOULDBLOCK)
51fe4b60 262 m_error = wxSOCKET_IOERR;
f7ff39c6 263 else
51fe4b60 264 m_error = wxSOCKET_WOULDBLOCK;
f7ff39c6
DE
265 return -1;
266 }
267
268 return ret;
269}
270
51fe4b60 271int wxSocketImplMSW::Write(const char *buffer, int size)
f7ff39c6
DE
272{
273 int ret;
274
c90cc42e 275 if (m_fd == INVALID_SOCKET || m_server)
f7ff39c6 276 {
51fe4b60 277 m_error = wxSOCKET_INVSOCK;
f7ff39c6
DE
278 return -1;
279 }
280
281 /* If the socket is blocking, wait for writability (with a timeout) */
51fe4b60 282 if (Output_Timeout() == wxSOCKET_TIMEDOUT)
f7ff39c6
DE
283 return -1;
284
285 /* Write the data */
c90cc42e
DE
286 if (m_stream)
287 ret = Send_Stream(buffer, size);
f7ff39c6 288 else
c90cc42e 289 ret = Send_Dgram(buffer, size);
f7ff39c6
DE
290
291 if (ret == SOCKET_ERROR)
292 {
293 if (WSAGetLastError() != WSAEWOULDBLOCK)
51fe4b60 294 m_error = wxSOCKET_IOERR;
f7ff39c6 295 else
51fe4b60 296 m_error = wxSOCKET_WOULDBLOCK;
f7ff39c6
DE
297
298 /* Only reenable OUTPUT events after an error (just like WSAAsyncSelect
299 * does). Once the first OUTPUT event is received, users can assume
300 * that the socket is writable until a read operation fails. Only then
301 * will further OUTPUT events be posted.
302 */
51fe4b60 303 m_detected &= ~wxSOCKET_OUTPUT_FLAG;
f7ff39c6
DE
304 return -1;
305 }
306
307 return ret;
308}
309
f7ff39c6
DE
310/* Internals (IO) */
311
51fe4b60 312/*
f7ff39c6
DE
313 * For blocking sockets, wait until data is available or
314 * until timeout ellapses.
315 */
51fe4b60 316wxSocketError wxSocketImplMSW::Input_Timeout()
f7ff39c6
DE
317{
318 fd_set readfds;
319
c90cc42e 320 if (!m_non_blocking)
f7ff39c6
DE
321 {
322 FD_ZERO(&readfds);
c90cc42e
DE
323 FD_SET(m_fd, &readfds);
324 if (select(0, &readfds, NULL, NULL, &m_timeout) == 0)
f7ff39c6 325 {
51fe4b60
VZ
326 m_error = wxSOCKET_TIMEDOUT;
327 return wxSOCKET_TIMEDOUT;
f7ff39c6
DE
328 }
329 }
51fe4b60 330 return wxSOCKET_NOERROR;
f7ff39c6
DE
331}
332
51fe4b60 333/*
f7ff39c6
DE
334 * For blocking sockets, wait until data can be sent without
335 * blocking or until timeout ellapses.
336 */
51fe4b60 337wxSocketError wxSocketImplMSW::Output_Timeout()
f7ff39c6
DE
338{
339 fd_set writefds;
340
c90cc42e 341 if (!m_non_blocking)
f7ff39c6
DE
342 {
343 FD_ZERO(&writefds);
c90cc42e
DE
344 FD_SET(m_fd, &writefds);
345 if (select(0, NULL, &writefds, NULL, &m_timeout) == 0)
f7ff39c6 346 {
51fe4b60
VZ
347 m_error = wxSOCKET_TIMEDOUT;
348 return wxSOCKET_TIMEDOUT;
f7ff39c6
DE
349 }
350 }
51fe4b60 351 return wxSOCKET_NOERROR;
f7ff39c6
DE
352}
353
51fe4b60 354/*
f7ff39c6
DE
355 * For blocking sockets, wait until the connection is
356 * established or fails, or until timeout ellapses.
357 */
51fe4b60 358wxSocketError wxSocketImplMSW::Connect_Timeout()
f7ff39c6
DE
359{
360 fd_set writefds;
361 fd_set exceptfds;
362
363 FD_ZERO(&writefds);
364 FD_ZERO(&exceptfds);
c90cc42e
DE
365 FD_SET(m_fd, &writefds);
366 FD_SET(m_fd, &exceptfds);
367 if (select(0, NULL, &writefds, &exceptfds, &m_timeout) == 0)
f7ff39c6 368 {
51fe4b60
VZ
369 m_error = wxSOCKET_TIMEDOUT;
370 return wxSOCKET_TIMEDOUT;
f7ff39c6 371 }
c90cc42e 372 if (!FD_ISSET(m_fd, &writefds))
f7ff39c6 373 {
51fe4b60
VZ
374 m_error = wxSOCKET_IOERR;
375 return wxSOCKET_IOERR;
f7ff39c6
DE
376 }
377
51fe4b60 378 return wxSOCKET_NOERROR;
f7ff39c6
DE
379}
380
51fe4b60 381int wxSocketImplMSW::Recv_Stream(char *buffer, int size)
f7ff39c6 382{
c90cc42e 383 return recv(m_fd, buffer, size, 0);
f7ff39c6
DE
384}
385
51fe4b60 386int wxSocketImplMSW::Recv_Dgram(char *buffer, int size)
f7ff39c6 387{
8575ff50 388 wxSockAddr from;
9e03e02d 389 WX_SOCKLEN_T fromlen = sizeof(from);
f7ff39c6 390 int ret;
51fe4b60 391 wxSocketError err;
f7ff39c6 392
8575ff50 393 ret = recvfrom(m_fd, buffer, size, 0, (sockaddr*)&from, &fromlen);
f7ff39c6
DE
394
395 if (ret == SOCKET_ERROR)
396 return SOCKET_ERROR;
397
51fe4b60 398 /* Translate a system address into a wxSocketImpl address */
c90cc42e 399 if (!m_peer)
f7ff39c6 400 {
c90cc42e
DE
401 m_peer = GAddress_new();
402 if (!m_peer)
f7ff39c6 403 {
51fe4b60 404 m_error = wxSOCKET_MEMERR;
f7ff39c6
DE
405 return -1;
406 }
407 }
8575ff50 408 err = _GAddress_translate_from(m_peer, (sockaddr*)&from, fromlen);
51fe4b60 409 if (err != wxSOCKET_NOERROR)
f7ff39c6 410 {
c90cc42e
DE
411 GAddress_destroy(m_peer);
412 m_peer = NULL;
413 m_error = err;
f7ff39c6
DE
414 return -1;
415 }
416
417 return ret;
418}
419
51fe4b60 420int wxSocketImplMSW::Send_Stream(const char *buffer, int size)
f7ff39c6 421{
c90cc42e 422 return send(m_fd, buffer, size, 0);
f7ff39c6
DE
423}
424
51fe4b60 425int wxSocketImplMSW::Send_Dgram(const char *buffer, int size)
f7ff39c6
DE
426{
427 struct sockaddr *addr;
428 int len, ret;
51fe4b60 429 wxSocketError err;
f7ff39c6 430
c90cc42e 431 if (!m_peer)
f7ff39c6 432 {
51fe4b60 433 m_error = wxSOCKET_INVADDR;
f7ff39c6
DE
434 return -1;
435 }
436
c90cc42e 437 err = _GAddress_translate_to(m_peer, &addr, &len);
51fe4b60 438 if (err != wxSOCKET_NOERROR)
f7ff39c6 439 {
c90cc42e 440 m_error = err;
f7ff39c6
DE
441 return -1;
442 }
443
c90cc42e 444 ret = sendto(m_fd, buffer, size, 0, addr, len);
f7ff39c6
DE
445
446 /* Frees memory allocated by _GAddress_translate_to */
447 free(addr);
448
449 return ret;
450}
451
f7ff39c6
DE
452/*
453 * -------------------------------------------------------------------------
454 * GAddress
455 * -------------------------------------------------------------------------
456 */
457
458/* CHECK_ADDRESS verifies that the current address family is either
51fe4b60
VZ
459 * wxSOCKET_NOFAMILY or wxSOCKET_*family*, and if it is wxSOCKET_NOFAMILY, it
460 * initalizes it to be a wxSOCKET_*family*. In other cases, it returns
f7ff39c6
DE
461 * an appropiate error code.
462 *
463 * CHECK_ADDRESS_RETVAL does the same but returning 'retval' on error.
464 */
465#define CHECK_ADDRESS(address, family) \
466{ \
51fe4b60
VZ
467 if (address->m_family == wxSOCKET_NOFAMILY) \
468 if (_GAddress_Init_##family(address) != wxSOCKET_NOERROR) \
f7ff39c6 469 return address->m_error; \
51fe4b60 470 if (address->m_family != wxSOCKET_##family) \
f7ff39c6 471 { \
51fe4b60
VZ
472 address->m_error = wxSOCKET_INVADDR; \
473 return wxSOCKET_INVADDR; \
f7ff39c6
DE
474 } \
475}
476
477#define CHECK_ADDRESS_RETVAL(address, family, retval) \
478{ \
51fe4b60
VZ
479 if (address->m_family == wxSOCKET_NOFAMILY) \
480 if (_GAddress_Init_##family(address) != wxSOCKET_NOERROR) \
f7ff39c6 481 return retval; \
51fe4b60 482 if (address->m_family != wxSOCKET_##family) \
f7ff39c6 483 { \
51fe4b60 484 address->m_error = wxSOCKET_INVADDR; \
f7ff39c6
DE
485 return retval; \
486 } \
487}
488
489
2804f77d 490GAddress *GAddress_new()
f7ff39c6
DE
491{
492 GAddress *address;
493
494 if ((address = (GAddress *) malloc(sizeof(GAddress))) == NULL)
495 return NULL;
496
51fe4b60 497 address->m_family = wxSOCKET_NOFAMILY;
f7ff39c6
DE
498 address->m_addr = NULL;
499 address->m_len = 0;
500
501 return address;
502}
503
504GAddress *GAddress_copy(GAddress *address)
505{
506 GAddress *addr2;
507
f7ff39c6
DE
508 if ((addr2 = (GAddress *) malloc(sizeof(GAddress))) == NULL)
509 return NULL;
510
511 memcpy(addr2, address, sizeof(GAddress));
512
513 if (address->m_addr)
514 {
515 addr2->m_addr = (struct sockaddr *) malloc(addr2->m_len);
516 if (addr2->m_addr == NULL)
517 {
518 free(addr2);
519 return NULL;
520 }
521 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
522 }
523
524 return addr2;
525}
526
527void GAddress_destroy(GAddress *address)
528{
f7ff39c6
DE
529 if (address->m_addr)
530 free(address->m_addr);
531
532 free(address);
533}
534
535void GAddress_SetFamily(GAddress *address, GAddressType type)
536{
f7ff39c6
DE
537 address->m_family = type;
538}
539
540GAddressType GAddress_GetFamily(GAddress *address)
541{
f7ff39c6
DE
542 return address->m_family;
543}
544
51fe4b60 545wxSocketError _GAddress_translate_from(GAddress *address,
f7ff39c6
DE
546 struct sockaddr *addr, int len)
547{
548 address->m_realfamily = addr->sa_family;
549 switch (addr->sa_family)
550 {
551 case AF_INET:
51fe4b60 552 address->m_family = wxSOCKET_INET;
f7ff39c6
DE
553 break;
554 case AF_UNIX:
51fe4b60 555 address->m_family = wxSOCKET_UNIX;
f7ff39c6 556 break;
8575ff50 557#if wxUSE_IPV6
f7ff39c6 558 case AF_INET6:
51fe4b60 559 address->m_family = wxSOCKET_INET6;
f7ff39c6
DE
560 break;
561#endif
562 default:
563 {
51fe4b60
VZ
564 address->m_error = wxSOCKET_INVOP;
565 return wxSOCKET_INVOP;
f7ff39c6
DE
566 }
567 }
568
569 if (address->m_addr)
570 free(address->m_addr);
571
572 address->m_len = len;
573 address->m_addr = (struct sockaddr *) malloc(len);
574
575 if (address->m_addr == NULL)
576 {
51fe4b60
VZ
577 address->m_error = wxSOCKET_MEMERR;
578 return wxSOCKET_MEMERR;
f7ff39c6
DE
579 }
580 memcpy(address->m_addr, addr, len);
581
51fe4b60 582 return wxSOCKET_NOERROR;
f7ff39c6
DE
583}
584
51fe4b60 585wxSocketError _GAddress_translate_to(GAddress *address,
f7ff39c6
DE
586 struct sockaddr **addr, int *len)
587{
588 if (!address->m_addr)
589 {
51fe4b60
VZ
590 address->m_error = wxSOCKET_INVADDR;
591 return wxSOCKET_INVADDR;
f7ff39c6
DE
592 }
593
594 *len = address->m_len;
595 *addr = (struct sockaddr *) malloc(address->m_len);
596 if (*addr == NULL)
597 {
51fe4b60
VZ
598 address->m_error = wxSOCKET_MEMERR;
599 return wxSOCKET_MEMERR;
f7ff39c6
DE
600 }
601
602 memcpy(*addr, address->m_addr, address->m_len);
51fe4b60 603 return wxSOCKET_NOERROR;
f7ff39c6
DE
604}
605
606/*
607 * -------------------------------------------------------------------------
608 * Internet address family
609 * -------------------------------------------------------------------------
610 */
611
51fe4b60 612wxSocketError _GAddress_Init_INET(GAddress *address)
f7ff39c6
DE
613{
614 address->m_len = sizeof(struct sockaddr_in);
615 address->m_addr = (struct sockaddr *) malloc(address->m_len);
616 if (address->m_addr == NULL)
617 {
51fe4b60
VZ
618 address->m_error = wxSOCKET_MEMERR;
619 return wxSOCKET_MEMERR;
f7ff39c6
DE
620 }
621
51fe4b60 622 address->m_family = wxSOCKET_INET;
f7ff39c6
DE
623 address->m_realfamily = AF_INET;
624 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
625 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
626
51fe4b60 627 return wxSOCKET_NOERROR;
f7ff39c6
DE
628}
629
51fe4b60 630wxSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
f7ff39c6
DE
631{
632 struct hostent *he;
633 struct in_addr *addr;
634
f7ff39c6
DE
635 CHECK_ADDRESS(address, INET);
636
637 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
638
639 addr->s_addr = inet_addr(hostname);
640
641 /* If it is a numeric host name, convert it now */
642 if (addr->s_addr == INADDR_NONE)
643 {
644 struct in_addr *array_addr;
645
646 /* It is a real name, we solve it */
647 if ((he = gethostbyname(hostname)) == NULL)
648 {
649 /* addr->s_addr = INADDR_NONE just done by inet_addr() above */
51fe4b60
VZ
650 address->m_error = wxSOCKET_NOHOST;
651 return wxSOCKET_NOHOST;
f7ff39c6
DE
652 }
653 array_addr = (struct in_addr *) *(he->h_addr_list);
654 addr->s_addr = array_addr[0].s_addr;
655 }
51fe4b60 656 return wxSOCKET_NOERROR;
f7ff39c6
DE
657}
658
51fe4b60 659wxSocketError GAddress_INET_SetBroadcastAddress(GAddress *address)
60edcf45
VZ
660{
661 return GAddress_INET_SetHostAddress(address, INADDR_BROADCAST);
662}
663
51fe4b60 664wxSocketError GAddress_INET_SetAnyAddress(GAddress *address)
f7ff39c6
DE
665{
666 return GAddress_INET_SetHostAddress(address, INADDR_ANY);
667}
668
51fe4b60 669wxSocketError GAddress_INET_SetHostAddress(GAddress *address,
f7ff39c6
DE
670 unsigned long hostaddr)
671{
672 struct in_addr *addr;
673
f7ff39c6
DE
674 CHECK_ADDRESS(address, INET);
675
676 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
d0ee33f5 677 addr->s_addr = htonl(hostaddr);
f7ff39c6 678
51fe4b60 679 return wxSOCKET_NOERROR;
f7ff39c6
DE
680}
681
51fe4b60 682wxSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
f7ff39c6
DE
683 const char *protocol)
684{
685 struct servent *se;
686 struct sockaddr_in *addr;
687
f7ff39c6
DE
688 CHECK_ADDRESS(address, INET);
689
690 if (!port)
691 {
51fe4b60
VZ
692 address->m_error = wxSOCKET_INVPORT;
693 return wxSOCKET_INVPORT;
f7ff39c6
DE
694 }
695
696 se = getservbyname(port, protocol);
697 if (!se)
698 {
699 if (isdigit(port[0]))
700 {
701 int port_int;
702
703 port_int = atoi(port);
704 addr = (struct sockaddr_in *)address->m_addr;
705 addr->sin_port = htons((u_short) port_int);
51fe4b60 706 return wxSOCKET_NOERROR;
f7ff39c6
DE
707 }
708
51fe4b60
VZ
709 address->m_error = wxSOCKET_INVPORT;
710 return wxSOCKET_INVPORT;
f7ff39c6
DE
711 }
712
713 addr = (struct sockaddr_in *)address->m_addr;
714 addr->sin_port = se->s_port;
715
51fe4b60 716 return wxSOCKET_NOERROR;
f7ff39c6
DE
717}
718
51fe4b60 719wxSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
f7ff39c6
DE
720{
721 struct sockaddr_in *addr;
722
f7ff39c6
DE
723 CHECK_ADDRESS(address, INET);
724
725 addr = (struct sockaddr_in *)address->m_addr;
726 addr->sin_port = htons(port);
727
51fe4b60 728 return wxSOCKET_NOERROR;
f7ff39c6
DE
729}
730
51fe4b60 731wxSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
f7ff39c6
DE
732{
733 struct hostent *he;
734 char *addr_buf;
735 struct sockaddr_in *addr;
736
f7ff39c6
DE
737 CHECK_ADDRESS(address, INET);
738
739 addr = (struct sockaddr_in *)address->m_addr;
740 addr_buf = (char *)&(addr->sin_addr);
741
742 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
743 if (he == NULL)
744 {
51fe4b60
VZ
745 address->m_error = wxSOCKET_NOHOST;
746 return wxSOCKET_NOHOST;
f7ff39c6
DE
747 }
748
749 strncpy(hostname, he->h_name, sbuf);
750
51fe4b60 751 return wxSOCKET_NOERROR;
f7ff39c6
DE
752}
753
754unsigned long GAddress_INET_GetHostAddress(GAddress *address)
755{
756 struct sockaddr_in *addr;
757
f7ff39c6
DE
758 CHECK_ADDRESS_RETVAL(address, INET, 0);
759
760 addr = (struct sockaddr_in *)address->m_addr;
761
762 return ntohl(addr->sin_addr.s_addr);
763}
764
765unsigned short GAddress_INET_GetPort(GAddress *address)
766{
767 struct sockaddr_in *addr;
768
f7ff39c6
DE
769 CHECK_ADDRESS_RETVAL(address, INET, 0);
770
771 addr = (struct sockaddr_in *)address->m_addr;
772 return ntohs(addr->sin_port);
773}
774
8575ff50
VZ
775
776#if wxUSE_IPV6
777/*
778 * -------------------------------------------------------------------------
779 * Internet IPv6 address family
780 * -------------------------------------------------------------------------
781 */
782#include "ws2tcpip.h"
783
784#ifdef __VISUALC__
785 #pragma comment(lib,"ws2_32")
786#endif // __VISUALC__
787
51fe4b60 788wxSocketError _GAddress_Init_INET6(GAddress *address)
8575ff50
VZ
789{
790 struct in6_addr any_address = IN6ADDR_ANY_INIT;
791 address->m_len = sizeof(struct sockaddr_in6);
792 address->m_addr = (struct sockaddr *) malloc(address->m_len);
793 if (address->m_addr == NULL)
794 {
51fe4b60
VZ
795 address->m_error = wxSOCKET_MEMERR;
796 return wxSOCKET_MEMERR;
8575ff50
VZ
797 }
798 memset(address->m_addr,0,address->m_len);
799
51fe4b60 800 address->m_family = wxSOCKET_INET6;
8575ff50
VZ
801 address->m_realfamily = AF_INET6;
802 ((struct sockaddr_in6 *)address->m_addr)->sin6_family = AF_INET6;
803 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = any_address;
804
51fe4b60 805 return wxSOCKET_NOERROR;
8575ff50
VZ
806}
807
51fe4b60 808wxSocketError GAddress_INET6_SetHostName(GAddress *address, const char *hostname)
8575ff50 809{
8575ff50
VZ
810 CHECK_ADDRESS(address, INET6);
811
812 addrinfo hints;
813 memset( & hints, 0, sizeof( hints ) );
814 hints.ai_family = AF_INET6;
815 addrinfo * info = 0;
816 if ( getaddrinfo( hostname, "0", & hints, & info ) || ! info )
817 {
51fe4b60
VZ
818 address->m_error = wxSOCKET_NOHOST;
819 return wxSOCKET_NOHOST;
8575ff50
VZ
820 }
821
822 memcpy( address->m_addr, info->ai_addr, info->ai_addrlen );
823 freeaddrinfo( info );
51fe4b60 824 return wxSOCKET_NOERROR;
8575ff50
VZ
825}
826
51fe4b60 827wxSocketError GAddress_INET6_SetAnyAddress(GAddress *address)
8575ff50 828{
8575ff50
VZ
829 CHECK_ADDRESS(address, INET6);
830
831 struct in6_addr addr;
832 memset( & addr, 0, sizeof( addr ) );
833 return GAddress_INET6_SetHostAddress(address, addr);
834}
51fe4b60 835wxSocketError GAddress_INET6_SetHostAddress(GAddress *address,
8575ff50
VZ
836 struct in6_addr hostaddr)
837{
8575ff50
VZ
838 CHECK_ADDRESS(address, INET6);
839
840 ((struct sockaddr_in6 *)address->m_addr)->sin6_addr = hostaddr;
841
51fe4b60 842 return wxSOCKET_NOERROR;
8575ff50
VZ
843}
844
51fe4b60 845wxSocketError GAddress_INET6_SetPortName(GAddress *address, const char *port,
8575ff50
VZ
846 const char *protocol)
847{
848 struct servent *se;
849 struct sockaddr_in6 *addr;
850
8575ff50
VZ
851 CHECK_ADDRESS(address, INET6);
852
853 if (!port)
854 {
51fe4b60
VZ
855 address->m_error = wxSOCKET_INVPORT;
856 return wxSOCKET_INVPORT;
8575ff50
VZ
857 }
858
859 se = getservbyname(port, protocol);
860 if (!se)
861 {
8a5a7042 862 if (isdigit((unsigned char) port[0]))
8575ff50
VZ
863 {
864 int port_int;
865
866 port_int = atoi(port);
867 addr = (struct sockaddr_in6 *)address->m_addr;
868 addr->sin6_port = htons((u_short) port_int);
51fe4b60 869 return wxSOCKET_NOERROR;
8575ff50
VZ
870 }
871
51fe4b60
VZ
872 address->m_error = wxSOCKET_INVPORT;
873 return wxSOCKET_INVPORT;
8575ff50
VZ
874 }
875
876 addr = (struct sockaddr_in6 *)address->m_addr;
877 addr->sin6_port = se->s_port;
878
51fe4b60 879 return wxSOCKET_NOERROR;
8575ff50
VZ
880}
881
51fe4b60 882wxSocketError GAddress_INET6_SetPort(GAddress *address, unsigned short port)
8575ff50
VZ
883{
884 struct sockaddr_in6 *addr;
885
8575ff50
VZ
886 CHECK_ADDRESS(address, INET6);
887
888 addr = (struct sockaddr_in6 *)address->m_addr;
889 addr->sin6_port = htons(port);
890
51fe4b60 891 return wxSOCKET_NOERROR;
8575ff50
VZ
892}
893
51fe4b60 894wxSocketError GAddress_INET6_GetHostName(GAddress *address, char *hostname, size_t sbuf)
8575ff50
VZ
895{
896 struct hostent *he;
897 char *addr_buf;
898 struct sockaddr_in6 *addr;
899
8575ff50
VZ
900 CHECK_ADDRESS(address, INET6);
901
902 addr = (struct sockaddr_in6 *)address->m_addr;
903 addr_buf = (char *)&(addr->sin6_addr);
904
905 he = gethostbyaddr(addr_buf, sizeof(addr->sin6_addr), AF_INET6);
906 if (he == NULL)
907 {
51fe4b60
VZ
908 address->m_error = wxSOCKET_NOHOST;
909 return wxSOCKET_NOHOST;
8575ff50
VZ
910 }
911
912 strncpy(hostname, he->h_name, sbuf);
913
51fe4b60 914 return wxSOCKET_NOERROR;
8575ff50
VZ
915}
916
51fe4b60 917wxSocketError GAddress_INET6_GetHostAddress(GAddress *address,struct in6_addr *hostaddr)
8575ff50 918{
51fe4b60 919 CHECK_ADDRESS_RETVAL(address, INET6, wxSOCKET_INVADDR);
8575ff50 920 *hostaddr = ( (struct sockaddr_in6 *)address->m_addr )->sin6_addr;
51fe4b60 921 return wxSOCKET_NOERROR;
8575ff50
VZ
922}
923
924unsigned short GAddress_INET6_GetPort(GAddress *address)
925{
8575ff50
VZ
926 CHECK_ADDRESS_RETVAL(address, INET6, 0);
927
928 return ntohs( ((struct sockaddr_in6 *)address->m_addr)->sin6_port );
929}
930
931#endif // wxUSE_IPV6
932
f7ff39c6
DE
933/*
934 * -------------------------------------------------------------------------
935 * Unix address family
936 * -------------------------------------------------------------------------
937 */
938
51fe4b60 939wxSocketError _GAddress_Init_UNIX(GAddress *address)
f7ff39c6 940{
51fe4b60
VZ
941 address->m_error = wxSOCKET_INVADDR;
942 return wxSOCKET_INVADDR;
f7ff39c6
DE
943}
944
51fe4b60 945wxSocketError GAddress_UNIX_SetPath(GAddress *address, const char *WXUNUSED(path))
f7ff39c6 946{
51fe4b60
VZ
947 address->m_error = wxSOCKET_INVADDR;
948 return wxSOCKET_INVADDR;
f7ff39c6
DE
949}
950
51fe4b60 951wxSocketError GAddress_UNIX_GetPath(GAddress *address, char *WXUNUSED(path), size_t WXUNUSED(sbuf))
f7ff39c6 952{
51fe4b60
VZ
953 address->m_error = wxSOCKET_INVADDR;
954 return wxSOCKET_INVADDR;
f7ff39c6
DE
955}
956
2804f77d 957#endif // wxUSE_SOCKETS