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