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