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