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