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