]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
9ab270d19b57970427888ff77bdf3d84953e2f8c
[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 if (socket->m_fd != -1) {
498 struct timeval tval;
499
500 tval.tv_sec = millisec / 1000;
501 tval.tv_usec = (millisec % 1000) * 1000;
502 setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval));
503 setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval));
504 }
505 }
506
507 /*
508 GSocket_GetError() returns the last error occured on the socket stream.
509 */
510
511 GSocketError GSocket_GetError(GSocket *socket)
512 {
513 assert(socket != NULL);
514
515 return socket->m_error;
516 }
517
518 /* Callbacks */
519
520 /*
521 Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
522 INPUT: The function is called when there is at least a byte in the
523 input buffer
524 OUTPUT: The function is called when the system is sure the next write call
525 will not block
526 CONNECTION: Two cases is possible:
527 Client socket -> the connection is established
528 Server socket -> a client request a connection
529 LOST: the connection is lost
530
531 SetCallback accepts a combination of these flags so a same callback can
532 receive different events.
533
534 An event is generated only once and its state is reseted when the relative
535 IO call is requested.
536 For example: INPUT -> GSocket_Read()
537 CONNECTION -> GSocket_Accept()
538 */
539 void GSocket_SetCallback(GSocket *socket, GSocketEventFlags event,
540 GSocketCallback fallback, char *cdata)
541 {
542 int count;
543
544 assert (socket != NULL);
545
546 for (count=0;count<GSOCK_MAX_EVENT;count++) {
547 /* We test each flag and, if it is enabled, we enable the corresponding
548 event */
549 if ((event & (1 << count)) != 0) {
550 socket->m_fbacks[count] = fallback;
551 socket->m_data[count] = cdata;
552
553 _GSocket_Install_Callback(socket, count);
554 _GSocket_Enable(socket, count);
555 }
556 }
557 }
558
559 /*
560 UnsetCallback will disables all fallbacks specified by "event".
561 NOTE: event may be a combination of flags
562 */
563 void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event)
564 {
565 int count = 0;
566
567 assert(socket != NULL);
568
569 for (count=0;count<GSOCK_MAX_EVENT;count++) {
570 if ((event & (1 << count)) != 0) {
571 _GSocket_Disable(socket, count);
572 socket->m_fbacks[count] = NULL;
573 _GSocket_Uninstall_Callback(socket, count);
574 }
575 }
576 }
577
578 #define CALL_FALLBACK(socket, event) \
579 if (socket->m_iocalls[event] && \
580 socket->m_fbacks[event]) {\
581 _GSocket_Disable(socket, event); \
582 socket->m_fbacks[event](socket, event, \
583 socket->m_data[event]); \
584 }
585
586 #define MASK_SIGNAL() \
587 { \
588 void (*old_handler)(int); \
589 \
590 old_handler = signal(SIGPIPE, SIG_IGN);
591
592 #define UNMASK_SIGNAL() \
593 signal(SIGPIPE, old_handler); \
594 }
595
596 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
597 {
598 socket->m_iocalls[event] = TRUE;
599 if (socket->m_fbacks[event])
600 _GSocket_Install_Callback(socket, event);
601 }
602
603 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
604 {
605 socket->m_iocalls[event] = FALSE;
606 if (socket->m_fbacks[event])
607 _GSocket_Uninstall_Callback(socket, event);
608 }
609
610 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
611 {
612 int ret;
613
614 MASK_SIGNAL();
615 ret = recv(socket->m_fd, buffer, size, 0);
616 UNMASK_SIGNAL();
617 if (ret == -1 && errno != EAGAIN) {
618 socket->m_error = GSOCK_IOERR;
619 return -1;
620 }
621 if (errno == EAGAIN) {
622 socket->m_error = GSOCK_TRYAGAIN;
623 return -1;
624 }
625 return ret;
626 }
627
628 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
629 {
630 struct sockaddr from;
631 SOCKLEN_T fromlen;
632 int ret;
633
634 fromlen = sizeof(from);
635
636 MASK_SIGNAL();
637 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
638 UNMASK_SIGNAL();
639 if (ret == -1 && errno != EAGAIN) {
640 socket->m_error = GSOCK_IOERR;
641 return -1;
642 }
643 if (errno == EAGAIN) {
644 socket->m_error = GSOCK_TRYAGAIN;
645 return -1;
646 }
647
648 /* Translate a system address into a GSocket address */
649 if (!socket->m_peer)
650 socket->m_peer = GAddress_new();
651 _GAddress_translate_from(socket->m_peer, &from, fromlen);
652
653 return ret;
654 }
655
656 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
657 {
658 int ret;
659
660 MASK_SIGNAL();
661 ret = send(socket->m_fd, buffer, size, 0);
662 UNMASK_SIGNAL();
663 if (ret == -1 && errno != EAGAIN) {
664 socket->m_error = GSOCK_IOERR;
665 return -1;
666 }
667 if (errno == EAGAIN) {
668 socket->m_error = GSOCK_TRYAGAIN;
669 return -1;
670 }
671 return ret;
672 }
673
674 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
675 {
676 struct sockaddr *addr;
677 int len, ret;
678
679 if (!socket->m_peer) {
680 socket->m_error = GSOCK_INVADDR;
681 return -1;
682 }
683
684 _GAddress_translate_to(socket->m_peer, &addr, &len);
685
686 MASK_SIGNAL();
687 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
688 UNMASK_SIGNAL();
689
690 /* Frees memory allocated from _GAddress_translate_to */
691 free(addr);
692
693 if (ret == -1 && errno != EAGAIN) {
694 socket->m_error = GSOCK_IOERR;
695 return -1;
696 }
697 if (errno == EAGAIN) {
698 socket->m_error = GSOCK_TRYAGAIN;
699 return -1;
700 }
701
702 return ret;
703 }
704
705 void _GSocket_Detected_Read(GSocket *socket)
706 {
707 char c;
708 int ret;
709
710 if (socket->m_stream) {
711 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
712
713 if (ret < 0 && socket->m_server) {
714 CALL_FALLBACK(socket, GSOCK_CONNECTION);
715 return;
716 }
717
718 if (ret > 0) {
719 CALL_FALLBACK(socket, GSOCK_INPUT);
720 } else {
721 CALL_FALLBACK(socket, GSOCK_LOST);
722 }
723 }
724 }
725
726 void _GSocket_Detected_Write(GSocket *socket)
727 {
728 CALL_FALLBACK(socket, GSOCK_OUTPUT);
729 }
730
731 #undef CALL_FALLBACK
732 #undef MASK_SIGNAL
733 #undef UNMASK_SIGNAL
734
735 /*
736 * -------------------------------------------------------------------------
737 * GAddress
738 * -------------------------------------------------------------------------
739 */
740
741 /* CHECK_ADDRESS verifies that the current family is either GSOCK_NOFAMILY or
742 * GSOCK_*family*. In case it is GSOCK_NOFAMILY, it initializes address to be
743 * a GSOCK_*family*. In other cases, it returns GSOCK_INVADDR.
744 */
745 #define CHECK_ADDRESS(address, family, retval) \
746 { \
747 if (address->m_family == GSOCK_NOFAMILY) \
748 _GAddress_Init_##family(address); \
749 if (address->m_family != GSOCK_##family) {\
750 address->m_error = GSOCK_INVADDR; \
751 return retval; \
752 } \
753 }
754
755 GAddress *GAddress_new()
756 {
757 GAddress *address;
758
759 address = (GAddress *)malloc(sizeof(GAddress));
760
761 address->m_family = GSOCK_NOFAMILY;
762 address->m_addr = NULL;
763 address->m_len = 0;
764
765 return address;
766 }
767
768 GAddress *GAddress_copy(GAddress *address)
769 {
770 GAddress *addr2;
771
772 assert(address != NULL);
773
774 addr2 = (GAddress *)malloc(sizeof(GAddress));
775 memcpy(addr2, address, sizeof(GAddress));
776
777 if (address->m_addr) {
778 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
779 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
780 }
781
782 return addr2;
783 }
784
785 void GAddress_destroy(GAddress *address)
786 {
787 assert(address != NULL);
788
789 free(address);
790 }
791
792 void GAddress_SetFamily(GAddress *address, GAddressType type)
793 {
794 assert(address != NULL);
795
796 address->m_family = type;
797 }
798
799 GAddressType GAddress_GetFamily(GAddress *address)
800 {
801 assert(address != NULL);
802
803 return address->m_family;
804 }
805
806 void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
807 address->m_realfamily = addr->sa_family;
808 switch (addr->sa_family) {
809 case AF_INET:
810 address->m_family = GSOCK_INET;
811 break;
812 case AF_UNIX:
813 address->m_family = GSOCK_UNIX;
814 break;
815 #ifdef AF_INET6
816 case AF_INET6:
817 address->m_family = GSOCK_INET6;
818 break;
819 #endif
820 default:
821 {
822 /* TODO error */
823 }
824 }
825
826 if (address->m_addr)
827 free(address->m_addr);
828
829 address->m_len = len;
830 address->m_addr = (struct sockaddr *)malloc(len);
831 memcpy(address->m_addr, addr, len);
832 }
833
834 void _GAddress_translate_to(GAddress *address,
835 struct sockaddr **addr, int *len)
836 {
837 if (!address->m_addr) {
838 /* TODO error */
839 return;
840 }
841
842 *len = address->m_len;
843 *addr = (struct sockaddr *)malloc(address->m_len);
844 memcpy(*addr, address->m_addr, address->m_len);
845 }
846
847 /*
848 * -------------------------------------------------------------------------
849 * Internet address family
850 * -------------------------------------------------------------------------
851 */
852
853 void _GAddress_Init_INET(GAddress *address)
854 {
855 address->m_len = sizeof(struct sockaddr_in);
856 address->m_addr = (struct sockaddr *)malloc(address->m_len);
857 address->m_family = GSOCK_INET;
858 address->m_realfamily = PF_INET;
859 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
860 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
861 }
862
863 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
864 {
865 struct hostent *he;
866 struct in_addr *addr;
867
868 assert(address != NULL);
869
870 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
871
872 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
873
874 /* If it is a numeric host name, convert it now */
875 if (inet_aton(hostname, addr) == 0) {
876 struct in_addr *array_addr;
877
878 /* It is a real name, we solve it */
879 if ((he = gethostbyname(hostname)) == NULL) {
880 address->m_error = GSOCK_NOHOST;
881 return GSOCK_NOHOST;
882 }
883 array_addr = (struct in_addr *) *(he->h_addr_list);
884 addr->s_addr = array_addr[0].s_addr;
885 }
886 return GSOCK_NOERROR;
887 }
888
889 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
890 unsigned long hostaddr)
891 {
892 struct in_addr *addr;
893
894 assert(address != NULL);
895
896 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
897
898 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
899 addr->s_addr = hostaddr;
900
901 return GSOCK_NOERROR;
902 }
903
904 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
905 const char *protocol)
906 {
907 struct servent *se;
908 struct sockaddr_in *addr;
909
910 assert(address != NULL);
911 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
912
913 if (!port) {
914 address->m_error = GSOCK_INVPORT;
915 return GSOCK_INVOP;
916 }
917
918 se = getservbyname(port, protocol);
919 if (!se) {
920 if (isdigit(port[0])) {
921 int port_int;
922
923 port_int = atoi(port);
924 addr = (struct sockaddr_in *)address->m_addr;
925 addr->sin_port = htons(port_int);
926 return GSOCK_NOERROR;
927 }
928
929 address->m_error = GSOCK_INVPORT;
930 return GSOCK_INVPORT;
931 }
932
933 addr = (struct sockaddr_in *)address->m_addr;
934 addr->sin_port = se->s_port;
935
936 return GSOCK_NOERROR;
937 }
938
939 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
940 {
941 struct sockaddr_in *addr;
942
943 assert(address != NULL);
944 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
945
946 addr = (struct sockaddr_in *)address->m_addr;
947 addr->sin_port = htons(port);
948
949 return GSOCK_NOERROR;
950 }
951
952 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
953 {
954 struct hostent *he;
955 char *addr_buf;
956 struct sockaddr_in *addr;
957
958 assert(address != NULL);
959 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
960
961 addr = (struct sockaddr_in *)address->m_addr;
962 addr_buf = (char *)&(addr->sin_addr);
963
964 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
965 if (he == NULL) {
966 address->m_error = GSOCK_NOHOST;
967 return GSOCK_NOHOST;
968 }
969
970 strncpy(hostname, he->h_name, sbuf);
971
972 return GSOCK_NOERROR;
973 }
974
975 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
976 {
977 struct sockaddr_in *addr;
978
979 assert(address != NULL);
980 CHECK_ADDRESS(address, INET, 0);
981
982 addr = (struct sockaddr_in *)address->m_addr;
983
984 return addr->sin_addr.s_addr;
985 }
986
987 unsigned short GAddress_INET_GetPort(GAddress *address)
988 {
989 struct sockaddr_in *addr;
990
991 assert(address != NULL);
992 CHECK_ADDRESS(address, INET, 0);
993
994 addr = (struct sockaddr_in *)address->m_addr;
995 return ntohs(addr->sin_port);
996 }
997
998 /*
999 * -------------------------------------------------------------------------
1000 * Unix address family
1001 * -------------------------------------------------------------------------
1002 */
1003
1004 void _GAddress_Init_UNIX(GAddress *address)
1005 {
1006 address->m_len = sizeof(struct sockaddr_un);
1007 address->m_addr = (struct sockaddr *)malloc(address->m_len);
1008 address->m_family = GSOCK_UNIX;
1009 address->m_realfamily = PF_UNIX;
1010 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
1011 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
1012 }
1013
1014 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
1015 {
1016 struct sockaddr_un *addr;
1017
1018 assert(address != NULL);
1019
1020 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1021
1022 addr = ((struct sockaddr_un *)address->m_addr);
1023 memcpy(addr->sun_path, path, strlen(path));
1024
1025 return GSOCK_NOERROR;
1026 }
1027
1028 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
1029 {
1030 struct sockaddr_un *addr;
1031
1032 assert(address != NULL);
1033 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
1034
1035 addr = (struct sockaddr_un *)address->m_addr;
1036
1037 strncpy(path, addr->sun_path, sbuf);
1038
1039 return GSOCK_NOERROR;
1040 }
1041
1042 #endif // wxUSE_SOCKETS