]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
Compile fixes for samples and dialoged,
[wxWidgets.git] / src / unix / gsocket.c
1 /* -------------------------------------------------------------------------
2 * Project: GSocket (Generic Socket) for WX
3 * Name: gsocket.c
4 * Purpose: GSocket main Unix file
5 * CVSID: $Id$
6 * -------------------------------------------------------------------------
7 */
8
9 #include "wx/setup.h"
10
11 #if wxUSE_SOCKETS
12
13 #include <assert.h>
14 #include <sys/ioctl.h>
15 #include <sys/types.h>
16 #ifdef vms
17 #include <socket.h>
18 #else
19 #include <sys/socket.h>
20 #endif
21 #include <sys/un.h>
22 #include <sys/time.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <netdb.h>
26 #include <errno.h>
27
28 #include <string.h>
29 #include <unistd.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stddef.h>
33 #include <ctype.h>
34
35 #ifdef sun
36 # include <sys/filio.h>
37 #endif
38
39 #ifdef sgi
40 # include <bstring.h>
41 #endif
42
43 #include <signal.h>
44
45 #include "wx/gsocket.h"
46 #include "gsockunx.h"
47
48 #ifndef SOCKLEN_T
49
50 #ifdef __GLIBC__
51 # if __GLIBC__ == 2
52 # define SOCKLEN_T socklen_t
53 # endif
54 #else
55 # define SOCKLEN_T int
56 #endif
57
58 #endif
59
60 /* Global initialisers */
61
62 bool GSocket_Init()
63 {
64 return TRUE;
65 }
66
67 void GSocket_Cleanup()
68 {
69 }
70
71 /* Constructors / Destructors */
72
73 GSocket *GSocket_new()
74 {
75 int i;
76 GSocket *socket;
77
78 socket = (GSocket *)malloc(sizeof(GSocket));
79
80 if (socket == NULL)
81 return NULL;
82
83 socket->m_fd = -1;
84 for (i=0;i<GSOCK_MAX_EVENT;i++) {
85 socket->m_fbacks[i] = NULL;
86 socket->m_iocalls[i] = FALSE;
87 }
88 socket->m_local = NULL;
89 socket->m_peer = NULL;
90 socket->m_error = GSOCK_NOERROR;
91 socket->m_server = FALSE;
92 socket->m_stream = TRUE;
93 socket->m_gui_dependent = NULL;
94 socket->m_blocking = FALSE;
95 socket->m_timeout = 10*60*1000;
96 // 10 minutes * 60 sec * 1000 millisec
97
98 /* We initialize the GUI specific entries here */
99 _GSocket_GUI_Init(socket);
100
101 return socket;
102 }
103
104 void GSocket_destroy(GSocket *socket)
105 {
106 assert(socket != NULL);
107
108 /* First, we check that the socket is really shutdowned */
109 if (socket->m_fd != -1)
110 GSocket_Shutdown(socket);
111
112 /* We destroy GUI specific variables */
113 _GSocket_GUI_Destroy(socket);
114
115 /* We destroy private addresses */
116 if (socket->m_local)
117 GAddress_destroy(socket->m_local);
118
119 if (socket->m_peer)
120 GAddress_destroy(socket->m_peer);
121
122 /* We destroy socket itself */
123 free(socket);
124 }
125
126 void GSocket_Shutdown(GSocket *socket)
127 {
128 int evt;
129
130 assert(socket != NULL);
131
132 /* If socket has been created, we shutdown it */
133 if (socket->m_fd != -1) {
134 shutdown(socket->m_fd, 2);
135 close(socket->m_fd);
136 socket->m_fd = -1;
137 }
138
139 /* We also disable GUI callbacks */
140 for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
141 _GSocket_Uninstall_Callback(socket, evt);
142 }
143
144 /* Address handling */
145
146 GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
147 {
148 assert(socket != NULL);
149
150 if ((socket->m_fd != -1 && !socket->m_server)) {
151 socket->m_error = GSOCK_INVSOCK;
152 return GSOCK_INVSOCK;
153 }
154
155 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
156 socket->m_error = GSOCK_INVADDR;
157 return GSOCK_INVADDR;
158 }
159
160 if (socket->m_local)
161 GAddress_destroy(socket->m_local);
162
163 socket->m_local = GAddress_copy(address);
164
165 return GSOCK_NOERROR;
166 }
167
168 GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
169 {
170 assert(socket != NULL);
171
172 if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
173 socket->m_error = GSOCK_INVADDR;
174 return GSOCK_INVADDR;
175 }
176
177 if (socket->m_peer)
178 GAddress_destroy(socket->m_peer);
179
180 socket->m_peer = GAddress_copy(address);
181
182 return GSOCK_NOERROR;
183 }
184
185 GAddress *GSocket_GetLocal(GSocket *socket)
186 {
187 GAddress *address;
188 struct sockaddr addr;
189 SOCKLEN_T size;
190
191 assert(socket != NULL);
192
193 if (socket->m_local)
194 return GAddress_copy(socket->m_local);
195
196 if (socket->m_fd == -1) {
197 socket->m_error = GSOCK_INVSOCK;
198 return NULL;
199 }
200
201 size = sizeof(addr);
202
203 if (getsockname(socket->m_fd, &addr, &size) < 0) {
204 socket->m_error = GSOCK_IOERR;
205 return NULL;
206 }
207
208 address = GAddress_new();
209 if (address == NULL) {
210 socket->m_error = GSOCK_MEMERR;
211 return NULL;
212 }
213 if (!_GAddress_translate_from(address, &addr, size)) {
214 socket->m_error = GSOCK_MEMERR;
215 GAddress_destroy(address);
216 return NULL;
217 }
218
219 return address;
220 }
221
222 GAddress *GSocket_GetPeer(GSocket *socket)
223 {
224 assert(socket != NULL);
225
226 if (socket->m_peer)
227 return GAddress_copy(socket->m_peer);
228
229 return NULL;
230 }
231
232 /* Server specific parts */
233
234 /*
235 GSocket_SetServer() setup the socket as a server. It uses the "Local" field
236 of GSocket. "Local" must be set by GSocket_SetLocal() before
237 GSocket_SetServer() is called. GSOCK_INVSOCK if socket has been initialized.
238 In case, you haven't yet defined the local address, it returns GSOCK_INVADDR.
239 In the other cases it returns GSOCK_IOERR.
240 */
241 GSocketError GSocket_SetServer(GSocket *sck)
242 {
243 int type;
244
245 assert(sck != NULL);
246
247 if (sck->m_fd != -1) {
248 sck->m_error = GSOCK_INVSOCK;
249 return GSOCK_INVSOCK;
250 }
251
252 if (!sck->m_local) {
253 sck->m_error = GSOCK_INVADDR;
254 return GSOCK_INVADDR;
255 }
256
257 /* We always have a stream here */
258 sck->m_stream = TRUE;
259
260 /* Create the socket */
261 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_STREAM, 0);
262
263 if (sck->m_fd == -1) {
264 sck->m_error = GSOCK_IOERR;
265 return GSOCK_IOERR;
266 }
267
268 /* Bind the socket to the LOCAL address */
269 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
270 close(sck->m_fd);
271 sck->m_fd = -1;
272 sck->m_error = GSOCK_IOERR;
273 return GSOCK_IOERR;
274 }
275
276 /* Enable listening up to 5 connections */
277 if (listen(sck->m_fd, 5) < 0) {
278 close(sck->m_fd);
279 sck->m_fd = -1;
280 sck->m_error = GSOCK_IOERR;
281 return GSOCK_IOERR;
282 }
283
284 GSocket_SetNonBlocking(sck, sck->m_blocking);
285 GSocket_SetTimeout(sck, sck->m_timeout);
286
287 return GSOCK_NOERROR;
288 }
289
290 /*
291 GSocket_WaitConnection() waits for an incoming client connection.
292 */
293 GSocket *GSocket_WaitConnection(GSocket *socket)
294 {
295 GSocket *connection;
296
297 assert(socket != NULL);
298
299 /* If the socket has already been created, we exit immediately */
300 if (socket->m_fd == -1 || !socket->m_server) {
301 socket->m_error = GSOCK_INVSOCK;
302 return NULL;
303 }
304
305 /* Reenable GSOCK_CONNECTION event */
306 _GSocket_Enable(socket, GSOCK_CONNECTION);
307
308 /* Create a GSocket object for the new connection */
309 connection = GSocket_new();
310
311 /* Accept the incoming connection */
312 connection->m_fd = accept(socket->m_fd, NULL, NULL);
313 if (connection->m_fd == -1) {
314 GSocket_destroy(connection);
315 socket->m_error = GSOCK_IOERR;
316 return NULL;
317 }
318
319 /* Initialize all fields */
320 connection->m_stream = TRUE;
321 connection->m_server = FALSE;
322 connection->m_oriented = TRUE;
323
324 return connection;
325 }
326
327 /* Non oriented connections */
328
329 GSocketError GSocket_SetNonOriented(GSocket *sck)
330 {
331 assert(sck != NULL);
332
333 if (sck->m_fd != -1) {
334 sck->m_error = GSOCK_INVSOCK;
335 return GSOCK_INVSOCK;
336 }
337
338 if (!sck->m_local) {
339 sck->m_error = GSOCK_INVADDR;
340 return GSOCK_INVADDR;
341 }
342
343 sck->m_stream = FALSE;
344 sck->m_server = FALSE;
345 sck->m_oriented = FALSE;
346
347 /* Create the socket */
348 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
349
350 /* Bind it to the LOCAL address */
351 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
352 close(sck->m_fd);
353 sck->m_fd = -1;
354 sck->m_error = GSOCK_IOERR;
355 return GSOCK_IOERR;
356 }
357
358 GSocket_SetNonBlocking(sck, sck->m_blocking);
359 GSocket_SetTimeout(sck, sck->m_timeout);
360
361 return GSOCK_NOERROR;
362 }
363
364 /* Client specific parts */
365
366 /*
367 GSocket_Connect() establishes a client connection to a server using the "Peer"
368 field of GSocket. "Peer" must be set by GSocket_SetPeer() before
369 GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
370 */
371 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
372 {
373 int type;
374
375 assert(sck != NULL);
376
377 if (sck->m_fd != -1) {
378 sck->m_error = GSOCK_INVSOCK;
379 return GSOCK_INVSOCK;
380 }
381
382 if (!sck->m_peer) {
383 sck->m_error = GSOCK_INVADDR;
384 return GSOCK_INVADDR;
385 }
386
387 /* Test whether we want the socket to be a stream (e.g. TCP) */
388 sck->m_stream = (stream == GSOCK_STREAMED);
389 sck->m_oriented = TRUE;
390
391 if (sck->m_stream)
392 type = SOCK_STREAM;
393 else
394 type = SOCK_DGRAM;
395
396 /* Create the socket */
397 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
398
399 if (sck->m_fd == -1) {
400 sck->m_error = GSOCK_IOERR;
401 return GSOCK_IOERR;
402 }
403
404 /* Connect it to the PEER address */
405 if (connect(sck->m_fd, sck->m_peer->m_addr,
406 sck->m_peer->m_len) != 0) {
407 close(sck->m_fd);
408 sck->m_fd = -1;
409 sck->m_error = GSOCK_IOERR;
410 return GSOCK_IOERR;
411 }
412
413 /* It is not a server */
414 sck->m_server = FALSE;
415
416 GSocket_SetNonBlocking(sck, sck->m_blocking);
417 GSocket_SetTimeout(sck, sck->m_timeout);
418
419 return GSOCK_NOERROR;
420 }
421
422 /* Generic IO */
423
424 /* Like recv(), send(), ... */
425 int GSocket_Read(GSocket *socket, char *buffer, int size)
426 {
427 assert(socket != NULL);
428
429 if (socket->m_fd == -1 || socket->m_server) {
430 socket->m_error = GSOCK_INVSOCK;
431 return -1;
432 }
433
434 /* Reenable GSOCK_INPUT event */
435 _GSocket_Enable(socket, GSOCK_INPUT);
436
437 if (socket->m_stream)
438 return _GSocket_Recv_Stream(socket, buffer, size);
439 else
440 return _GSocket_Recv_Dgram(socket, buffer, size);
441 }
442
443 int GSocket_Write(GSocket *socket, const char *buffer,
444 int size)
445 {
446 assert(socket != NULL);
447
448 if (socket->m_fd == -1 || socket->m_server) {
449 socket->m_error = GSOCK_INVSOCK;
450 return -1;
451 }
452
453 _GSocket_Enable(socket, GSOCK_OUTPUT);
454
455 if (socket->m_stream)
456 return _GSocket_Send_Stream(socket, buffer, size);
457 else
458 return _GSocket_Send_Dgram(socket, buffer, size);
459 }
460
461 bool GSocket_DataAvailable(GSocket *socket)
462 {
463 fd_set read_set;
464 struct timeval tv;
465
466 assert(socket != NULL);
467
468 if (socket->m_fd == -1 || socket->m_server) {
469 socket->m_error = GSOCK_INVSOCK;
470 return FALSE;
471 }
472
473 FD_ZERO(&read_set);
474 FD_SET(socket->m_fd, &read_set);
475
476 tv.tv_sec = 0;
477 tv.tv_usec = 0;
478
479 select(socket->m_fd+1, &read_set, NULL, NULL, &tv);
480
481 return FD_ISSET(socket->m_fd, &read_set);
482 }
483
484 /* Flags */
485
486 /*
487 GSocket_SetNonBlocking() puts the socket in non-blocking mode. This is useful
488 if we don't want to wait.
489 */
490 void GSocket_SetNonBlocking(GSocket *socket, bool non_block)
491 {
492 assert(socket != NULL);
493
494 socket->m_blocking = block;
495
496 if (socket->m_fd != -1)
497 ioctl(socket->m_fd, FIONBIO, &block);
498 }
499
500 /*
501 * GSocket_SetTimeout()
502 */
503
504 #ifndef LINUX
505 # define CAN_USE_TIMEOUT
506 #elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
507 # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1)
508 # define CAN_USE_TIMEOUT
509 # endif
510 #endif
511
512 void GSocket_SetTimeout(GSocket *socket, unsigned long millisec)
513 {
514 assert(socket != NULL);
515
516 /* Neither GLIBC 2.0 nor the kernel 2.0.36 define SO_SNDTIMEO or
517 SO_RCVTIMEO. The man pages, that these flags should exist but
518 are read only. RR. */
519 /* OK, restrict this to GLIBC 2.1. GL. */
520 #ifdef CAN_USE_TIMEOUT
521 socket->m_timeout = millisec;
522 if (socket->m_fd != -1) {
523 struct timeval tval;
524
525 tval.tv_sec = millisec / 1000;
526 tval.tv_usec = (millisec % 1000) * 1000;
527 setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
528 setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
529 }
530 #endif
531 }
532
533 /*
534 GSocket_GetError() returns the last error occured on the socket stream.
535 */
536
537 GSocketError GSocket_GetError(GSocket *socket)
538 {
539 assert(socket != NULL);
540
541 return socket->m_error;
542 }
543
544 /* Callbacks */
545
546 /*
547 Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
548 INPUT: The function is called when there is at least a byte in the
549 input buffer
550 OUTPUT: The function is called when the system is sure the next write call
551 will not block
552 CONNECTION: Two cases is possible:
553 Client socket -> the connection is established
554 Server socket -> a client request a connection
555 LOST: the connection is lost
556
557 SetCallback accepts a combination of these flags so a same callback can
558 receive different events.
559
560 An event is generated only once and its state is reseted when the relative
561 IO call is requested.
562 For example: INPUT -> GSocket_Read()
563 CONNECTION -> GSocket_Accept()
564 */
565 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
566 GSocketCallback fallback, char *cdata)
567 {
568 int count;
569
570 assert (socket != NULL);
571
572 for (count=0;count<GSOCK_MAX_EVENT;count++) {
573 /* We test each flag and, if it is enabled, we enable the corresponding
574 event */
575 if ((event & (1 << count)) != 0) {
576 socket->m_fbacks[count] = fallback;
577 socket->m_data[count] = cdata;
578 _GSocket_Enable(socket, count);
579 }
580 }
581 }
582
583 /*
584 UnsetCallback will disables all fallbacks specified by "event".
585 NOTE: event may be a combination of flags
586 */
587 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
588 {
589 int count = 0;
590
591 assert(socket != NULL);
592
593 for (count=0;count<GSOCK_MAX_EVENT;count++) {
594 if ((event & (1 << count)) != 0) {
595 _GSocket_Disable(socket, count);
596 socket->m_fbacks[count] = NULL;
597 }
598 }
599 }
600
601 #define CALL_FALLBACK(socket, event) \
602 if (socket->m_iocalls[event] && \
603 socket->m_fbacks[event]) {\
604 _GSocket_Disable(socket, event); \
605 socket->m_fbacks[event](socket, event, \
606 socket->m_data[event]); \
607 }
608
609 #define MASK_SIGNAL() \
610 { \
611 void (*old_handler)(int); \
612 \
613 old_handler = signal(SIGPIPE, SIG_IGN);
614
615 #define UNMASK_SIGNAL() \
616 signal(SIGPIPE, old_handler); \
617 }
618
619 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
620 {
621 socket->m_iocalls[event] = TRUE;
622 if (socket->m_fbacks[event])
623 _GSocket_Install_Callback(socket, event);
624 }
625
626 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
627 {
628 socket->m_iocalls[event] = FALSE;
629 if (socket->m_fbacks[event])
630 _GSocket_Uninstall_Callback(socket, event);
631 }
632
633 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
634 {
635 int ret;
636
637 MASK_SIGNAL();
638 ret = recv(socket->m_fd, buffer, size, 0);
639 UNMASK_SIGNAL();
640 if (ret == -1 && errno != EAGAIN) {
641 socket->m_error = GSOCK_IOERR;
642 return -1;
643 }
644 if (errno == EAGAIN) {
645 socket->m_error = GSOCK_TRYAGAIN;
646 return -1;
647 }
648 return ret;
649 }
650
651 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
652 {
653 struct sockaddr from;
654 SOCKLEN_T fromlen;
655 int ret;
656
657 fromlen = sizeof(from);
658
659 MASK_SIGNAL();
660 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
661 UNMASK_SIGNAL();
662 if (ret == -1 && errno != EAGAIN) {
663 socket->m_error = GSOCK_IOERR;
664 return -1;
665 }
666 if (errno == EAGAIN) {
667 socket->m_error = GSOCK_TRYAGAIN;
668 return -1;
669 }
670
671 /* Translate a system address into a GSocket address */
672 if (!socket->m_peer) {
673 socket->m_peer = GAddress_new();
674 if (!socket->m_peer) {
675 socket->m_error = GSOCK_MEMERR;
676 return -1;
677 }
678 }
679 if (!_GAddress_translate_from(socket->m_peer, &from, fromlen)) {
680 socket->m_error = GSOCK_MEMERR;
681 return -1;
682 }
683
684 return ret;
685 }
686
687 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
688 {
689 int ret;
690
691 MASK_SIGNAL();
692 ret = send(socket->m_fd, buffer, size, 0);
693 UNMASK_SIGNAL();
694 if (ret == -1 && errno != EAGAIN) {
695 socket->m_error = GSOCK_IOERR;
696 return -1;
697 }
698 if (errno == EAGAIN) {
699 socket->m_error = GSOCK_TRYAGAIN;
700 return -1;
701 }
702 return ret;
703 }
704
705 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
706 {
707 struct sockaddr *addr;
708 int len, ret;
709
710 if (!socket->m_peer) {
711 socket->m_error = GSOCK_INVADDR;
712 return -1;
713 }
714
715 if (!_GAddress_translate_to(socket->m_peer, &addr, &len)) {
716 socket->m_error = GSOCK_MEMERR;
717 return -1;
718 }
719
720 MASK_SIGNAL();
721 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
722 UNMASK_SIGNAL();
723
724 /* Frees memory allocated from _GAddress_translate_to */
725 free(addr);
726
727 if (ret == -1 && errno != EAGAIN) {
728 socket->m_error = GSOCK_IOERR;
729 return -1;
730 }
731 if (errno == EAGAIN) {
732 socket->m_error = GSOCK_TRYAGAIN;
733 return -1;
734 }
735
736 return ret;
737 }
738
739 void _GSocket_Detected_Read(GSocket *socket)
740 {
741 char c;
742 int ret;
743
744 if (socket->m_stream) {
745 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
746
747 if (ret < 0 && socket->m_server) {
748 CALL_FALLBACK(socket, GSOCK_CONNECTION);
749 return;
750 }
751
752 if (ret > 0) {
753 CALL_FALLBACK(socket, GSOCK_INPUT);
754 } else {
755 CALL_FALLBACK(socket, GSOCK_LOST);
756 }
757 }
758 }
759
760 void _GSocket_Detected_Write(GSocket *socket)
761 {
762 CALL_FALLBACK(socket, GSOCK_OUTPUT);
763 }
764
765 #undef CALL_FALLBACK
766 #undef MASK_SIGNAL
767 #undef UNMASK_SIGNAL
768
769 /*
770 * -------------------------------------------------------------------------
771 * GAddress
772 * -------------------------------------------------------------------------
773 */
774
775 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
776 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
777 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
778 */
779 #define CHECK_ADDRESS(address, family, retval) \
780 { \
781 if (address->m_family == GSOCK_NOFAMILY) \
782 if (!_GAddress_Init_##family(address)) {\
783 address->m_error = GSOCK_MEMERR; \
784 return retval; \
785 }\
786 if (address->m_family != GSOCK_##family) {\
787 address->m_error = GSOCK_INVADDR; \
788 return retval; \
789 } \
790 }
791
792 GAddress *GAddress_new()
793 {
794 GAddress *address;
795
796 address = (GAddress *)malloc(sizeof(GAddress));
797
798 if (address == NULL)
799 return NULL;
800
801 address->m_family = GSOCK_NOFAMILY;
802 address->m_addr = NULL;
803 address->m_len = 0;
804
805 return address;
806 }
807
808 GAddress *GAddress_copy(GAddress *address)
809 {
810 GAddress *addr2;
811
812 assert(address != NULL);
813
814 addr2 = (GAddress *)malloc(sizeof(GAddress));
815
816 if (addr2 == NULL)
817 return NULL;
818
819 memcpy(addr2, address, sizeof(GAddress));
820
821 if (address->m_addr) {
822 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
823 if (addr2->m_addr == NULL) {
824 free(addr2);
825 return NULL;
826 }
827 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
828 }
829
830 return addr2;
831 }
832
833 void GAddress_destroy(GAddress *address)
834 {
835 assert(address != NULL);
836
837 free(address);
838 }
839
840 void GAddress_SetFamily(GAddress *address, GAddressType type)
841 {
842 assert(address != NULL);
843
844 address->m_family = type;
845 }
846
847 GAddressType GAddress_GetFamily(GAddress *address)
848 {
849 assert(address != NULL);
850
851 return address->m_family;
852 }
853
854 bool _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
855 address->m_realfamily = addr->sa_family;
856 switch (addr->sa_family) {
857 case AF_INET:
858 address->m_family = GSOCK_INET;
859 break;
860 case AF_UNIX:
861 address->m_family = GSOCK_UNIX;
862 break;
863 #ifdef AF_INET6
864 case AF_INET6:
865 address->m_family = GSOCK_INET6;
866 break;
867 #endif
868 default:
869 {
870 /* TODO error */
871 }
872 }
873
874 if (address->m_addr)
875 free(address->m_addr);
876
877 address->m_len = len;
878 address->m_addr = (struct sockaddr *)malloc(len);
879 if (address->m_addr == NULL)
880 return FALSE;
881 memcpy(address->m_addr, addr, len);
882
883 return TRUE;
884 }
885
886 bool _GAddress_translate_to(GAddress *address,
887 struct sockaddr **addr, int *len)
888 {
889 if (!address->m_addr) {
890 /* TODO error */
891 return;
892 }
893
894 *len = address->m_len;
895 *addr = (struct sockaddr *)malloc(address->m_len);
896 if (*addr == NULL)
897 return FALSE;
898
899 memcpy(*addr, address->m_addr, address->m_len);
900 return TRUE;
901 }
902
903 /*
904 * -------------------------------------------------------------------------
905 * Internet address family
906 * -------------------------------------------------------------------------
907 */
908
909 bool _GAddress_Init_INET(GAddress *address)
910 {
911 address->m_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_in));
912 if (address->m_addr == NULL)
913 return FALSE;
914
915 address->m_len = sizeof(struct sockaddr_in);
916
917 address->m_family = GSOCK_INET;
918 address->m_realfamily = PF_INET;
919 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
920 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
921
922 return TRUE;
923 }
924
925 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
926 {
927 struct hostent *he;
928 struct in_addr *addr;
929
930 assert(address != NULL);
931
932 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
933
934 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
935
936 /* If it is a numeric host name, convert it now */
937 if (inet_aton(hostname, addr) == 0) {
938 struct in_addr *array_addr;
939
940 /* It is a real name, we solve it */
941 if ((he = gethostbyname(hostname)) == NULL) {
942 address->m_error = GSOCK_NOHOST;
943 return GSOCK_NOHOST;
944 }
945 array_addr = (struct in_addr *) *(he->h_addr_list);
946 addr->s_addr = array_addr[0].s_addr;
947 }
948 return GSOCK_NOERROR;
949 }
950
951 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
952 unsigned long hostaddr)
953 {
954 struct in_addr *addr;
955
956 assert(address != NULL);
957
958 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
959
960 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
961 addr->s_addr = hostaddr;
962
963 return GSOCK_NOERROR;
964 }
965
966 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
967 const char *protocol)
968 {
969 struct servent *se;
970 struct sockaddr_in *addr;
971
972 assert(address != NULL);
973 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
974
975 if (!port) {
976 address->m_error = GSOCK_INVPORT;
977 return GSOCK_INVOP;
978 }
979
980 se = getservbyname(port, protocol);
981 if (!se) {
982 if (isdigit(port[0])) {
983 int port_int;
984
985 port_int = atoi(port);
986 addr = (struct sockaddr_in *)address->m_addr;
987 addr->sin_port = htons(port_int);
988 return GSOCK_NOERROR;
989 }
990
991 address->m_error = GSOCK_INVPORT;
992 return GSOCK_INVPORT;
993 }
994
995 addr = (struct sockaddr_in *)address->m_addr;
996 addr->sin_port = se->s_port;
997
998 return GSOCK_NOERROR;
999 }
1000
1001 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
1002 {
1003 struct sockaddr_in *addr;
1004
1005 assert(address != NULL);
1006 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1007
1008 addr = (struct sockaddr_in *)address->m_addr;
1009 addr->sin_port = htons(port);
1010
1011 return GSOCK_NOERROR;
1012 }
1013
1014 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
1015 {
1016 struct hostent *he;
1017 char *addr_buf;
1018 struct sockaddr_in *addr;
1019
1020 assert(address != NULL);
1021 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
1022
1023 addr = (struct sockaddr_in *)address->m_addr;
1024 addr_buf = (char *)&(addr->sin_addr);
1025
1026 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
1027 if (he == NULL) {
1028 address->m_error = GSOCK_NOHOST;
1029 return GSOCK_NOHOST;
1030 }
1031
1032 strncpy(hostname, he->h_name, sbuf);
1033
1034 return GSOCK_NOERROR;
1035 }
1036
1037 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
1038 {
1039 struct sockaddr_in *addr;
1040
1041 assert(address != NULL);
1042 CHECK_ADDRESS(address, INET, 0);
1043
1044 addr = (struct sockaddr_in *)address->m_addr;
1045
1046 return addr->sin_addr.s_addr;
1047 }
1048
1049 unsigned short GAddress_INET_GetPort(GAddress *address)
1050 {
1051 struct sockaddr_in *addr;
1052
1053 assert(address != NULL);
1054 CHECK_ADDRESS(address, INET, 0);
1055
1056 addr = (struct sockaddr_in *)address->m_addr;
1057 return ntohs(addr->sin_port);
1058 }
1059
1060 /*
1061 * -------------------------------------------------------------------------
1062 * Unix address family
1063 * -------------------------------------------------------------------------
1064 */
1065
1066 bool _GAddress_Init_UNIX(GAddress *address)
1067 {
1068 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1069 if (address->m_addr == NULL)
1070 return FALSE;
1071
1072 address->m_len = sizeof(struct sockaddr_un);
1073 address->m_family = GSOCK_UNIX;
1074 address->m_realfamily = PF_UNIX;
1075 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1076 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1077
1078 return TRUE;
1079 }
1080
1081 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1082 {
1083 struct sockaddr_un *addr;
1084
1085 assert(address != NULL);
1086
1087 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1088
1089 addr = ((struct sockaddr_un *)address->m_addr);
1090 memcpy(addr->sun_path, path, strlen(path));
1091
1092 return GSOCK_NOERROR;
1093 }
1094
1095 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1096 {
1097 struct sockaddr_un *addr;
1098
1099 assert(address != NULL);
1100 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1101
1102 addr = (struct sockaddr_un *)address->m_addr;
1103
1104 strncpy(path, addr->sun_path, sbuf);
1105
1106 return GSOCK_NOERROR;
1107 }
1108
1109 #endif // wxUSE_SOCKETS