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