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