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