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