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