]> git.saurik.com Git - wxWidgets.git/blob - src/unix/gsocket.c
wxSocket 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
570 SOCKLEN_T fromlen;
571 int ret;
572
573 fromlen = sizeof(from);
574
575 MASK_SIGNAL();
576 ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
577 UNMASK_SIGNAL();
578 if (ret == -1) {
579 socket->m_error = GSOCK_IOERR;
580 return -1;
581 }
582
583 if (!socket->m_peer)
584 socket->m_peer = GAddress_new();
585 _GAddress_translate_from(socket->m_peer, &from, fromlen);
586
587 return ret;
588 }
589
590 int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
591 {
592 int ret;
593
594 MASK_SIGNAL();
595 ret = send(socket->m_fd, buffer, size, 0);
596 UNMASK_SIGNAL();
597 if (ret == -1) {
598 socket->m_error = GSOCK_IOERR;
599 return -1;
600 }
601 return ret;
602 }
603
604 int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
605 {
606 struct sockaddr *addr;
607 int len, ret;
608
609 if (!socket->m_peer) {
610 socket->m_error = GSOCK_INVADDR;
611 return -1;
612 }
613
614 _GAddress_translate_to(socket->m_peer, &addr, &len);
615
616 MASK_SIGNAL();
617 ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
618 UNMASK_SIGNAL();
619 if (ret == -1) {
620 socket->m_error = GSOCK_IOERR;
621 return -1;
622 }
623
624 free(addr);
625
626 return ret;
627 }
628
629 void _GSocket_Detected_Read(GSocket *socket)
630 {
631 char c;
632 int ret;
633
634 if (socket->m_stream) {
635 ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
636
637 if (ret < 0 && socket->m_server) {
638 CALL_FALLBACK(socket, GSOCK_CONNECTION);
639 return;
640 }
641
642 if (ret > 0) {
643 CALL_FALLBACK(socket, GSOCK_INPUT);
644 } else {
645 CALL_FALLBACK(socket, GSOCK_LOST);
646 }
647 }
648 }
649
650 void _GSocket_Detected_Write(GSocket *socket)
651 {
652 CALL_FALLBACK(socket, GSOCK_OUTPUT);
653 }
654
655 #undef CALL_FALLBACK
656 #undef MASK_SIGNAL
657 #undef UNMASK_SIGNAL
658
659 /*
660 * -------------------------------------------------------------------------
661 * GAddress
662 * -------------------------------------------------------------------------
663 */
664
665 #define CHECK_ADDRESS(address, family, retval) \
666 { \
667 if (address->m_family == GSOCK_NOFAMILY) \
668 _GAddress_Init_##family(address); \
669 if (address->m_family != GSOCK_##family) {\
670 address->m_error = GSOCK_INVADDR; \
671 return retval; \
672 } \
673 }
674
675 GAddress *GAddress_new()
676 {
677 GAddress *address;
678
679 address = (GAddress *)malloc(sizeof(GAddress));
680
681 address->m_family = GSOCK_NOFAMILY;
682 address->m_addr = NULL;
683 address->m_len = 0;
684
685 return address;
686 }
687
688 GAddress *GAddress_copy(GAddress *address)
689 {
690 GAddress *addr2;
691
692 assert(address != NULL);
693
694 addr2 = (GAddress *)malloc(sizeof(GAddress));
695 memcpy(addr2, address, sizeof(GAddress));
696
697 if (address->m_addr) {
698 addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
699 memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
700 }
701
702 return addr2;
703 }
704
705 void GAddress_destroy(GAddress *address)
706 {
707 assert(address != NULL);
708
709 free(address);
710 }
711
712 void GAddress_SetFamily(GAddress *address, GAddressType type)
713 {
714 assert(address != NULL);
715
716 address->m_family = type;
717 }
718
719 GAddressType GAddress_GetFamily(GAddress *address)
720 {
721 assert(address != NULL);
722
723 return address->m_family;
724 }
725
726 void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
727 address->m_realfamily = addr->sa_family;
728 switch (addr->sa_family) {
729 case AF_INET:
730 address->m_family = GSOCK_INET;
731 break;
732 case AF_UNIX:
733 address->m_family = GSOCK_UNIX;
734 break;
735 #ifdef AF_INET6
736 case AF_INET6:
737 address->m_family = GSOCK_INET6;
738 break;
739 #endif
740 default:
741 {
742 /* TODO error */
743 }
744 }
745
746 if (address->m_addr)
747 free(address->m_addr);
748
749 address->m_len = len;
750 address->m_addr = (struct sockaddr *)malloc(len);
751 memcpy(address->m_addr, addr, len);
752 }
753
754 void _GAddress_translate_to(GAddress *address,
755 struct sockaddr **addr, int *len)
756 {
757 if (!address->m_addr) {
758 /* TODO error */
759 return;
760 }
761
762 *len = address->m_len;
763 *addr = (struct sockaddr *)malloc(address->m_len);
764 memcpy(*addr, address->m_addr, address->m_len);
765 }
766
767 /*
768 * -------------------------------------------------------------------------
769 * Internet address family
770 * -------------------------------------------------------------------------
771 */
772
773 void _GAddress_Init_INET(GAddress *address)
774 {
775 address->m_len = sizeof(struct sockaddr_in);
776 address->m_addr = (struct sockaddr *)malloc(address->m_len);
777 address->m_family = GSOCK_INET;
778 address->m_realfamily = PF_INET;
779 ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
780 ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr = INADDR_ANY;
781 }
782
783 GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
784 {
785 struct hostent *he;
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
794 /* only name for the moment */
795 if (inet_aton(hostname, addr) == 0) {
796 struct in_addr *array_addr;
797
798 if ((he = gethostbyname(hostname)) == NULL) {
799 address->m_error = GSOCK_NOHOST;
800 return GSOCK_NOHOST;
801 }
802 array_addr = (struct in_addr *) *(he->h_addr_list);
803 addr->s_addr = array_addr[0].s_addr;
804 }
805 return GSOCK_NOERROR;
806 }
807
808 GSocketError GAddress_INET_SetHostAddress(GAddress *address,
809 unsigned long hostaddr)
810 {
811 struct in_addr *addr;
812
813 assert(address != NULL);
814
815 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
816
817 addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
818 addr->s_addr = hostaddr;
819
820 return GSOCK_NOERROR;
821 }
822
823 GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port,
824 const char *protocol)
825 {
826 struct servent *se;
827 struct sockaddr_in *addr;
828
829 assert(address != NULL);
830 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
831
832 if (!port) {
833 address->m_error = GSOCK_INVPORT;
834 return GSOCK_INVOP;
835 }
836
837 /* TODO: TCP or UDP */
838 se = getservbyname(port, protocol);
839 if (!se) {
840 if (isdigit(port[0])) {
841 int port_int;
842
843 port_int = atoi(port);
844 addr = (struct sockaddr_in *)address->m_addr;
845 addr->sin_port = htons(port_int);
846 return GSOCK_NOERROR;
847 }
848
849 address->m_error = GSOCK_INVPORT;
850 return GSOCK_INVPORT;
851 }
852
853 addr = (struct sockaddr_in *)address->m_addr;
854 addr->sin_port = se->s_port;
855
856 return GSOCK_NOERROR;
857 }
858
859 GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
860 {
861 struct sockaddr_in *addr;
862
863 assert(address != NULL);
864 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
865
866 addr = (struct sockaddr_in *)address->m_addr;
867 addr->sin_port = htons(port);
868
869 return GSOCK_NOERROR;
870 }
871
872 GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
873 {
874 struct hostent *he;
875 char *addr_buf;
876 struct sockaddr_in *addr;
877
878 assert(address != NULL);
879 CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
880
881 addr = (struct sockaddr_in *)address->m_addr;
882 addr_buf = (char *)&(addr->sin_addr);
883
884 he = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
885 if (he == NULL) {
886 address->m_error = GSOCK_NOHOST;
887 return GSOCK_NOHOST;
888 }
889
890 strncpy(hostname, he->h_name, sbuf);
891
892 return GSOCK_NOERROR;
893 }
894
895 unsigned long GAddress_INET_GetHostAddress(GAddress *address)
896 {
897 struct sockaddr_in *addr;
898
899 assert(address != NULL);
900 CHECK_ADDRESS(address, INET, 0);
901
902 addr = (struct sockaddr_in *)address->m_addr;
903
904 return addr->sin_addr.s_addr;
905 }
906
907 unsigned short GAddress_INET_GetPort(GAddress *address)
908 {
909 struct sockaddr_in *addr;
910
911 assert(address != NULL);
912 CHECK_ADDRESS(address, INET, 0);
913
914 addr = (struct sockaddr_in *)address->m_addr;
915 return ntohs(addr->sin_port);
916 }
917
918 /*
919 * -------------------------------------------------------------------------
920 * Unix address family
921 * -------------------------------------------------------------------------
922 */
923
924 void _GAddress_Init_UNIX(GAddress *address)
925 {
926 address->m_len = sizeof(struct sockaddr_un);
927 address->m_addr = (struct sockaddr *)malloc(address->m_len);
928 address->m_family = GSOCK_UNIX;
929 address->m_realfamily = PF_UNIX;
930 ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
931 ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
932 }
933
934 GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
935 {
936 struct sockaddr_un *addr;
937
938 assert(address != NULL);
939
940 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
941
942 addr = ((struct sockaddr_un *)address->m_addr);
943 memcpy(addr->sun_path, path, strlen(path));
944
945 return GSOCK_NOERROR;
946 }
947
948 GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
949 {
950 struct sockaddr_un *addr;
951
952 assert(address != NULL);
953 CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
954
955 addr = (struct sockaddr_un *)address->m_addr;
956
957 strncpy(path, addr->sun_path, sbuf);
958
959 return GSOCK_NOERROR;
960 }