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