]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
ab328de2e79076ea2911caa36cbd41f56d8c36a3
[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 if (sck->m_stream)
242 type = SOCK_STREAM;
243 else
244 type = SOCK_DGRAM;
245
246 sck->m_fd = socket(sck->m_local->m_realfamily, type, 0);
247
248 if (sck->m_fd == -1) {
249 sck->m_error = GSOCK_IOERR;
250 return GSOCK_IOERR;
251 }
252
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 if (listen(sck->m_fd, 5) < 0) {
261 close(sck->m_fd);
262 sck->m_fd = -1;
263 sck->m_error = GSOCK_IOERR;
264 return GSOCK_IOERR;
265 }
266
267 sck->m_server = TRUE;
268
269 return GSOCK_NOERROR;
270
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 (socket->m_fd == -1 || !socket->m_server) {
283 socket->m_error = GSOCK_INVSOCK;
284 return NULL;
285 }
286
287 _GSocket_Enable(socket, GSOCK_CONNECTION);
288
289 connection = GSocket_new();
290
291 connection->m_fd = accept(socket->m_fd, NULL, NULL);
292 if (connection->m_fd == -1) {
293 GSocket_destroy(connection);
294 socket->m_error = GSOCK_IOERR;
295 return NULL;
296 }
297
298 connection->m_stream = TRUE;
299 connection->m_server = FALSE;
300 connection->m_oriented = TRUE;
301
302 return connection;
303 }
304
305 /* Non oriented connections */
306
307 GSocketError GSocket_SetNonOriented(GSocket *sck)
308 {
309 assert(sck != NULL);
310
311 if (sck->m_fd != -1) {
312 sck->m_error = GSOCK_INVSOCK;
313 return GSOCK_INVSOCK;
314 }
315
316 if (!sck->m_local) {
317 sck->m_error = GSOCK_INVADDR;
318 return GSOCK_INVADDR;
319 }
320
321 sck->m_stream = FALSE;
322 sck->m_server = FALSE;
323 sck->m_oriented = FALSE;
324
325 sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
326
327 if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
328 close(sck->m_fd);
329 sck->m_fd = -1;
330 sck->m_error = GSOCK_IOERR;
331 return GSOCK_IOERR;
332 }
333
334 return GSOCK_NOERROR;
335 }
336
337 /* Client specific parts */
338
339 /*
340 GSocket_Connect() establishes a client connection to a server using the "Peer"
341 field of GSocket. "Peer" must be set by GSocket_SetPeer() before
342 GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
343 */
344 GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
345 {
346 int type;
347
348 assert(sck != NULL);
349
350 if (sck->m_fd != -1) {
351 sck->m_error = GSOCK_INVSOCK;
352 return GSOCK_INVSOCK;
353 }
354
355 if (!sck->m_peer) {
356 sck->m_error = GSOCK_INVADDR;
357 return GSOCK_INVADDR;
358 }
359
360 sck->m_stream = (stream == GSOCK_STREAMED);
361 sck->m_oriented = TRUE;
362
363 if (sck->m_stream)
364 type = SOCK_STREAM;
365 else
366 type = SOCK_DGRAM;
367
368 sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
369
370 if (sck->m_fd == -1) {
371 sck->m_error = GSOCK_IOERR;
372 return GSOCK_IOERR;
373 }
374
375 if (connect(sck->m_fd, sck->m_peer->m_addr,
376 sck->m_peer->m_len) != 0) {
377 close(sck->m_fd);
378 sck->m_fd = -1;
379 sck->m_error = GSOCK_IOERR;
380 return GSOCK_IOERR;
381 }
382
383 sck->m_server = FALSE;
384
385 return GSOCK_NOERROR;
386 }
387
388 /* Generic IO */
389
390 /* Like recv(), send(), ... */
391 int GSocket_Read(GSocket *socket, char *buffer, int size)
392 {
393 assert(socket != NULL);
394
395 if (socket->m_fd == -1 || socket->m_server) {
396 socket->m_error = GSOCK_INVSOCK;
397 return -1;
398 }
399
400 _GSocket_Enable(socket, GSOCK_INPUT);
401
402 if (socket->m_oriented)
403 return _GSocket_Recv_Stream(socket, buffer, size);
404 else
405 return _GSocket_Recv_Dgram(socket, buffer, size);
406 }
407
408 int GSocket_Write(GSocket *socket, const char *buffer,
409 int size)
410 {
411 assert(socket != NULL);
412
413 if (socket->m_fd == -1 || socket->m_server) {
414 socket->m_error = GSOCK_INVSOCK;
415 return -1;
416 }
417
418 _GSocket_Enable(socket, GSOCK_OUTPUT);
419
420 if (socket->m_oriented)
421 return _GSocket_Send_Stream(socket, buffer, size);
422 else
423 return _GSocket_Send_Dgram(socket, buffer, size);
424 }
425
426 bool GSocket_DataAvailable(GSocket *socket)
427 {
428 fd_set read_set;
429 struct timeval tv;
430
431 assert(socket != NULL);
432
433 if (socket->m_fd == -1 || socket->m_server) {
434 socket->m_error = GSOCK_INVSOCK;
435 return FALSE;
436 }
437
438 FD_ZERO(&read_set);
439 FD_SET(socket->m_fd, &read_set);
440
441 tv.tv_sec = 0;
442 tv.tv_usec = 0;
443
444 select(socket->m_fd+1, &read_set, NULL, NULL, &tv);
445
446 return FD_ISSET(socket->m_fd, &read_set);
447 }
448
449 /* Flags */
450
451 /*
452 GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
453 if we don't want to wait.
454 */
455 void GSocket_SetBlocking(GSocket *socket, bool block)
456 {
457 assert(socket != NULL);
458
459 socket->m_blocking = block;
460
461 if (socket->m_fd != -1)
462 ioctl(socket->m_fd, FIONBIO, &block);
463 }
464
465 /*
466 GSocket_GetError() returns the last error occured on the socket stream.
467 */
468
469 GSocketError GSocket_GetError(GSocket *socket)
470 {
471 assert(socket != NULL);
472
473 return socket->m_error;
474 }
475
476 /* Callbacks */
477
478 /*
479 Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
480 INPUT: The function is called when there is at least a byte in the
481 input buffer
482 OUTPUT: The function is called when the system is sure the next write call
483 will not block
484 CONNECTION: Two cases is possible:
485 Client socket -> the connection is established
486 Server socket -> a client request a connection
487 LOST: the connection is lost
488
489 SetFallback accepts a combination of these flags so a same callback can
490 receive different events.
491
492 An event is generated only once and its state is reseted when the relative
493 IO call is requested.
494 For example: INPUT -> GSocket_Read()
495 CONNECTION -> GSocket_Accept()
496 */
497 void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
498 GSocketFallback fallback, char *cdata)
499 {
500 int count;
501
502 assert (socket != NULL);
503
504 for (count=0;count<GSOCK_MAX_EVENT;count++) {
505 if ((event & (1 << count)) != 0) {
506 socket->m_fbacks[count] = fallback;
507 socket->m_data[count] = cdata;
508
509 _GSocket_Install_Fallback(socket, count);
510 _GSocket_Enable(socket, count);
511 }
512 }
513 }
514
515 /*
516 UnsetFallback will disables all fallbacks specified by "event".
517 NOTE: event may be a combination of flags
518 */
519 void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
520 {
521 int count = 0;
522
523 assert(socket != NULL);
524
525 for (count=0;count<GSOCK_MAX_EVENT;count++) {
526 if ((event & (1 << count)) != 0) {
527 _GSocket_Disable(socket, count);
528 socket->m_fbacks[count] = NULL;
529 _GSocket_Uninstall_Fallback(socket, count);
530 }
531 }
532 }
533
534 #define CALL_FALLBACK(socket, event) \
535 if (socket->m_iocalls[event] && \
536 socket->m_fbacks[event]) {\
537 _GSocket_Disable(socket, event); \
538 socket->m_fbacks[event](socket, event, \
539 socket->m_data[event]); \
540 }
541
542 #define MASK_SIGNAL() \
543 { \
544 void (*old_handler)(int); \
545 \
546 old_handler = signal(SIGPIPE, SIG_IGN);
547
548 #define UNMASK_SIGNAL() \
549 signal(SIGPIPE, old_handler); \
550 }
551
552 void _GSocket_Enable(GSocket *socket, GSocketEvent event)
553 {
554 socket->m_iocalls[event] = TRUE;
555 if (socket->m_fbacks[event])
556 _GSocket_Install_Fallback(socket, event);
557 }
558
559 void _GSocket_Disable(GSocket *socket, GSocketEvent event)
560 {
561 socket->m_iocalls[event] = FALSE;
562 if (socket->m_fbacks[event])
563 _GSocket_Uninstall_Fallback(socket, event);
564 }
565
566 int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
567 {
568 int ret;
569
570 MASK_SIGNAL();
571 ret = recv(socket->m_fd, buffer, size, 0);
572 UNMASK_SIGNAL();
573 if (ret == -1) {
574 socket->m_error = GSOCK_IOERR;
575 return -1;
576 }
577 return ret;
578 }
579
580 int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
581 {
582 struct sockaddr from;
583 SOCKLEN_T fromlen;
584 int ret;
585
586 fromlen = sizeof(from);
587
588 MASK_SIGNAL();
589 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
590 UNMASK_SIGNAL();
591 if (ret == -1) {
592 socket->m_error = GSOCK_IOERR;
593 return -1;
594 }
595
596 if (!socket->m_peer)
597 socket->m_peer = GAddress_new();
598 _GAddress_translate_from(socket->m_peer, &from, fromlen);
599
600 return ret;
601 }
602
603 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
604 {
605 int ret;
606
607 MASK_SIGNAL();
608 ret = send(socket->m_fd, buffer, size, 0);
609 UNMASK_SIGNAL();
610 if (ret == -1) {
611 socket->m_error = GSOCK_IOERR;
612 return -1;
613 }
614 return ret;
615 }
616
617 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
618 {
619 struct sockaddr *addr;
620 int len, ret;
621
622 if (!socket->m_peer) {
623 socket->m_error = GSOCK_INVADDR;
624 return -1;
625 }
626
627 _GAddress_translate_to(socket->m_peer, &addr, &len);
628
629 MASK_SIGNAL();
630 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
631 UNMASK_SIGNAL();
632 if (ret == -1) {
633 socket->m_error = GSOCK_IOERR;
634 return -1;
635 }
636
637 free(addr);
638
639 return ret;
640 }
641
642 void _GSocket_Detected_Read(GSocket *socket)
643 {
644 char c;
645 int ret;
646
647 if (socket->m_stream) {
648 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
649
650 if (ret < 0 && socket->m_server) {
651 CALL_FALLBACK(socket, GSOCK_CONNECTION);
652 return;
653 }
654
655 if (ret > 0) {
656 CALL_FALLBACK(socket, GSOCK_INPUT);
657 } else {
658 CALL_FALLBACK(socket, GSOCK_LOST);
659 }
660 }
661 }
662
663 void _GSocket_Detected_Write(GSocket *socket)
664 {
665 CALL_FALLBACK(socket, GSOCK_OUTPUT);
666 }
667
668 #undef CALL_FALLBACK
669 #undef MASK_SIGNAL
670 #undef UNMASK_SIGNAL
671
672 /*
673 * -------------------------------------------------------------------------
674 * GAddress
675 * -------------------------------------------------------------------------
676 */
677
678 #define CHECK_ADDRESS(address, family, retval) \
679 { \
680 if (address->m_family == GSOCK_NOFAMILY) \
681 _GAddress_Init_##family(address); \
682 if (address->m_family != GSOCK_##family) {\
683 address->m_error = GSOCK_INVADDR; \
684 return retval; \
685 } \
686 }
687
688 GAddress *GAddress_new()
689 {
690 GAddress *address;
691
692 address = (GAddress *)malloc(sizeof(GAddress));
693
694 address->m_family = GSOCK_NOFAMILY;
695 address->m_addr = NULL;
696 address->m_len = 0;
697
698 return address;
699 }
700
701 GAddress *GAddress_copy(GAddress *address)
702 {
703 GAddress *addr2;
704
705 assert(address != NULL);
706
707 addr2 = (GAddress *)malloc(sizeof(GAddress));
708 memcpy(addr2, address, sizeof(GAddress));
709
710 if (address->m_addr) {
711 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
712 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
713 }
714
715 return addr2;
716 }
717
718 void GAddress_destroy(GAddress *address)
719 {
720 assert(address != NULL);
721
722 free(address);
723 }
724
725 void GAddress_SetFamily(GAddress *address, GAddressType type)
726 {
727 assert(address != NULL);
728
729 address->m_family = type;
730 }
731
732 GAddressType GAddress_GetFamily(GAddress *address)
733 {
734 assert(address != NULL);
735
736 return address->m_family;
737 }
738
739 void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
740 address->m_realfamily = addr->sa_family;
741 switch (addr->sa_family) {
742 case AF_INET:
743 address->m_family = GSOCK_INET;
744 break;
745 case AF_UNIX:
746 address->m_family = GSOCK_UNIX;
747 break;
748 #ifdef AF_INET6
749 case AF_INET6:
750 address->m_family = GSOCK_INET6;
751 break;
752 #endif
753 default:
754 {
755 /* TODO error */
756 }
757 }
758
759 if (address->m_addr)
760 free(address->m_addr);
761
762 address->m_len = len;
763 address->m_addr = (struct sockaddr *)malloc(len);
764 memcpy(address->m_addr, addr, len);
765 }
766
767 void _GAddress_translate_to(GAddress *address,
768 struct sockaddr **addr, int *len)
769 {
770 if (!address->m_addr) {
771 /* TODO error */
772 return;
773 }
774
775 *len = address->m_len;
776 *addr = (struct sockaddr *)malloc(address->m_len);
777 memcpy(*addr, address->m_addr, address->m_len);
778 }
779
780 /*
781 * -------------------------------------------------------------------------
782 * Internet address family
783 * -------------------------------------------------------------------------
784 */
785
786 void _GAddress_Init_INET(GAddress *address)
787 {
788 address->m_len = sizeof(struct sockaddr_in);
789 address->m_addr = (struct sockaddr *)malloc(address->m_len);
790 address->m_family = GSOCK_INET;
791 address->m_realfamily = PF_INET;
792 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
793 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
794 }
795
796 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
797 {
798 struct hostent *he;
799 struct in_addr *addr;
800
801 assert(address != NULL);
802
803 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
804
805 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
806
807 /* only name for the moment */
808 if (inet_aton(hostname, addr) == 0) {
809 struct in_addr *array_addr;
810
811 if ((he = gethostbyname(hostname)) == NULL) {
812 address->m_error = GSOCK_NOHOST;
813 return GSOCK_NOHOST;
814 }
815 array_addr = (struct in_addr *) *(he->h_addr_list);
816 addr->s_addr = array_addr[0].s_addr;
817 }
818 return GSOCK_NOERROR;
819 }
820
821 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
822 unsigned long hostaddr)
823 {
824 struct in_addr *addr;
825
826 assert(address != NULL);
827
828 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
829
830 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
831 addr->s_addr = hostaddr;
832
833 return GSOCK_NOERROR;
834 }
835
836 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
837 const char *protocol)
838 {
839 struct servent *se;
840 struct sockaddr_in *addr;
841
842 assert(address != NULL);
843 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
844
845 if (!port) {
846 address->m_error = GSOCK_INVPORT;
847 return GSOCK_INVOP;
848 }
849
850 /* TODO: TCP or UDP */
851 se = getservbyname(port, protocol);
852 if (!se) {
853 if (isdigit(port[0])) {
854 int port_int;
855
856 port_int = atoi(port);
857 addr = (struct sockaddr_in *)address->m_addr;
858 addr->sin_port = htons(port_int);
859 return GSOCK_NOERROR;
860 }
861
862 address->m_error = GSOCK_INVPORT;
863 return GSOCK_INVPORT;
864 }
865
866 addr = (struct sockaddr_in *)address->m_addr;
867 addr->sin_port = se->s_port;
868
869 return GSOCK_NOERROR;
870 }
871
872 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
873 {
874 struct sockaddr_in *addr;
875
876 assert(address != NULL);
877 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
878
879 addr = (struct sockaddr_in *)address->m_addr;
880 addr->sin_port = htons(port);
881
882 return GSOCK_NOERROR;
883 }
884
885 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
886 {
887 struct hostent *he;
888 char *addr_buf;
889 struct sockaddr_in *addr;
890
891 assert(address != NULL);
892 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
893
894 addr = (struct sockaddr_in *)address->m_addr;
895 addr_buf = (char *)&(addr->sin_addr);
896
897 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
898 if (he == NULL) {
899 address->m_error = GSOCK_NOHOST;
900 return GSOCK_NOHOST;
901 }
902
903 strncpy(hostname, he->h_name, sbuf);
904
905 return GSOCK_NOERROR;
906 }
907
908 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
909 {
910 struct sockaddr_in *addr;
911
912 assert(address != NULL);
913 CHECK_ADDRESS(address, INET, 0);
914
915 addr = (struct sockaddr_in *)address->m_addr;
916
917 return addr->sin_addr.s_addr;
918 }
919
920 unsigned short GAddress_INET_GetPort(GAddress *address)
921 {
922 struct sockaddr_in *addr;
923
924 assert(address != NULL);
925 CHECK_ADDRESS(address, INET, 0);
926
927 addr = (struct sockaddr_in *)address->m_addr;
928 return ntohs(addr->sin_port);
929 }
930
931 /*
932 * -------------------------------------------------------------------------
933 * Unix address family
934 * -------------------------------------------------------------------------
935 */
936
937 void _GAddress_Init_UNIX(GAddress *address)
938 {
939 address->m_len = sizeof(struct sockaddr_un);
940 address->m_addr = (struct sockaddr *)malloc(address->m_len);
941 address->m_family = GSOCK_UNIX;
942 address->m_realfamily = PF_UNIX;
943 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
944 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
945 }
946
947 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
948 {
949 struct sockaddr_un *addr;
950
951 assert(address != NULL);
952
953 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
954
955 addr = ((struct sockaddr_un *)address->m_addr);
956 memcpy(addr->sun_path, path, strlen(path));
957
958 return GSOCK_NOERROR;
959 }
960
961 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
962 {
963 struct sockaddr_un *addr;
964
965 assert(address != NULL);
966 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
967
968 addr = (struct sockaddr_un *)address->m_addr;
969
970 strncpy(path, addr->sun_path, sbuf);
971
972 return GSOCK_NOERROR;
973 }
974
975 #endif // wxUSE_SOCKETS