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