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