merge the formfield patch from ooo-build
[ooovba.git] / sal / osl / unx / socket.c
blob44f065191a24a16f3afd74ebb1390ccc10c200ce
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: socket.c,v $
10 * $Revision: 1.29.60.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "system.h"
33 #include <osl/socket.h>
34 #include <osl/diagnose.h>
35 #include <osl/mutex.h>
36 #include <osl/signal.h>
38 #include <rtl/alloc.h>
40 #include <ctype.h>
41 #include <sal/types.h>
43 #include "sockimpl.h"
46 /* defines for poll */
47 #ifdef HAVE_POLL_H
48 #undef HAVE_POLL_H
49 #endif
51 #if defined(LINUX) || defined (IRIX) || defined(NETBSD) || defined ( FREEBSD ) || defined (MACOSX)
52 #include <sys/poll.h>
53 #define HAVE_POLL_H
54 #endif /* HAVE_POLL_H */
56 #if defined(SOLARIS)
57 #include <poll.h>
58 #define HAVE_POLL_H
59 #endif /* SOLARIS */
61 #ifndef HAVE_POLL_H
62 #define POLLIN 0x0001
63 #define POLLOUT 0x0002
64 #define POLLPRI 0x0004
65 #endif /* HAVE_POLL_H */
68 /* defines for shutdown */
69 #define SD_RECEIVE 0
70 #define SD_SEND 1
71 #define SD_BOTH 2
75 oslSocketAddr is a pointer to a Berkeley struct sockaddr.
76 I refrained from using sockaddr_in because of possible further
77 extensions of this socket-interface (IP-NG?).
78 The intention was to hide all Berkeley data-structures from
79 direct access past the osl-interface.
81 The current implementation is internet (IP) centered. All
82 the constructor-functions (osl_create...) take parameters
83 that will probably make sense only in the IP-environment
84 (e.g. because of using the dotted-address-format).
86 If the interface will be extended to host other protocol-
87 families, I expect no externally visible changes in the
88 existing functions. You'll probably need only new
89 constructor-functions who take the different address
90 formats into consideration (maybe a long dotted address
91 or whatever).
94 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
95 /* are the same! I don't like it very much but see no other easy way to */
96 /* conceal the struct sockaddr from the eyes of the user. */
99 #define OSL_INVALID_SOCKET -1
100 #define OSL_SOCKET_ERROR -1
103 /* Buffer size for gethostbyname */
104 #define MAX_HOSTBUFFER_SIZE 2048
106 /*****************************************************************************/
107 /* enum oslAddrFamily */
108 /*****************************************************************************/
110 /* map */
111 static unsigned long FamilyMap[]= {
112 AF_INET, /* osl_Socket_FamilyInet */
113 AF_IPX, /* osl_Socket_FamilyIpx */
114 0 /* osl_Socket_FamilyInvalid */
117 /* reverse map */
118 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
120 oslAddrFamily i= (oslAddrFamily)0;
122 while(i != osl_Socket_FamilyInvalid)
124 if(FamilyMap[i] == nativeType)
125 return i;
126 i = (oslAddrFamily) ( i + 1 );
129 return i;
132 /* macros */
133 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
134 #define FAMILY_TO_NATIVE(x) (short)FamilyMap[x]
136 /*****************************************************************************/
137 /* enum oslProtocol */
138 /*****************************************************************************/
140 /* map */
141 static sal_uInt32 ProtocolMap[]= {
142 0, /* osl_Socket_ProtocolIp */
143 NSPROTO_IPX, /* osl_Socket_ProtocolIpx */
144 NSPROTO_SPX, /* osl_Socket_ProtocolSpx */
145 NSPROTO_SPXII, /* osl_Socket_ProtocolSpxII */
146 0 /* osl_Socket_ProtocolInvalid */
149 /* reverse map */
150 /* mfe: NOT USED
151 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
153 oslProtocol i= (oslProtocol)0;
155 while(i != osl_Socket_ProtocolInvalid)
157 if(ProtocolMap[i] == nativeType)
158 return i;
159 i = (oslProtocol) ( i + 1);
162 return i;
166 /* macros */
167 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
168 #define PROTOCOL_TO_NATIVE(x) ProtocolMap[x]
171 /*****************************************************************************/
172 /* enum oslSocketType */
173 /*****************************************************************************/
175 /* map */
176 static sal_uInt32 TypeMap[]= {
177 SOCK_STREAM, /* osl_Socket_TypeStream */
178 SOCK_DGRAM, /* osl_Socket_TypeDgram */
179 SOCK_RAW, /* osl_Socket_TypeRaw */
180 SOCK_RDM, /* osl_Socket_TypeRdm */
181 SOCK_SEQPACKET, /* osl_Socket_TypeSeqPacket */
182 0 /* osl_Socket_TypeInvalid */
185 /* reverse map */
186 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
188 oslSocketType i= (oslSocketType)0;
190 while(i != osl_Socket_TypeInvalid)
192 if(TypeMap[i] == nativeType)
193 return i;
194 i = (oslSocketType)(i + 1);
197 return i;
200 /* macros */
201 #define TYPE_TO_NATIVE(x) TypeMap[x]
202 #define TYPE_FROM_NATIVE(y) osl_SocketTypeFromNative(y)
205 /*****************************************************************************/
206 /* enum oslSocketOption */
207 /*****************************************************************************/
209 /* map */
210 static sal_uInt32 OptionMap[]= {
211 SO_DEBUG, /* osl_Socket_OptionDebug */
212 SO_ACCEPTCONN, /* osl_Socket_OptionAcceptConn */
213 SO_REUSEADDR, /* osl_Socket_OptionReuseAddr */
214 SO_KEEPALIVE, /* osl_Socket_OptionKeepAlive */
215 SO_DONTROUTE, /* osl_Socket_OptionDontRoute */
216 SO_BROADCAST, /* osl_Socket_OptionBroadcast */
217 SO_USELOOPBACK, /* osl_Socket_OptionUseLoopback */
218 SO_LINGER, /* osl_Socket_OptionLinger */
219 SO_OOBINLINE, /* osl_Socket_OptionOOBinLine */
220 SO_SNDBUF, /* osl_Socket_OptionSndBuf */
221 SO_RCVBUF, /* osl_Socket_OptionRcvBuf */
222 SO_SNDLOWAT, /* osl_Socket_OptionSndLowat */
223 SO_RCVLOWAT, /* osl_Socket_OptionRcvLowat */
224 SO_SNDTIMEO, /* osl_Socket_OptionSndTimeo */
225 SO_RCVTIMEO, /* osl_Socket_OptionRcvTimeo */
226 SO_ERROR, /* osl_Socket_OptionError */
227 SO_TYPE, /* osl_Socket_OptionType */
228 TCP_NODELAY, /* osl_Socket_OptionTcpNoDelay */
229 0 /* osl_Socket_OptionInvalid */
232 /* reverse map */
233 /* mfe: NOT USED
234 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
236 oslSocketOption i= (oslSocketOption)0;
238 while(i != osl_Socket_OptionInvalid)
240 if(OptionMap[i] == nativeType)
241 return i;
242 i = (oslSocketOption) ( i + 1 );
245 return i;
248 /* macros */
249 #define OPTION_TO_NATIVE(x) OptionMap[x]
250 #define OPTION_FROM_NATIVE(y) osl_SocketOptionFromNative(y)
253 /*****************************************************************************/
254 /* enum oslSocketOptionLevel */
255 /*****************************************************************************/
257 static sal_uInt32 OptionLevelMap[]= {
258 SOL_SOCKET, /* osl_Socket_LevelSocket */
259 IPPROTO_TCP, /* osl_Socket_LevelTcp */
260 0 /* osl_Socket_LevelInvalid */
263 /* reverse map */
264 /* mfe: NOT USED
265 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
267 oslSocketOptionLevel i= (oslSocketOptionLevel)0;
269 while(i != osl_Socket_LevelInvalid)
271 if(OptionLevelMap[i] == nativeType)
272 return i;
273 i = (oslSocketOptionLevel) ( i + 1 );
276 return i;
279 /* macros */
280 #define OPTION_LEVEL_TO_NATIVE(x) OptionLevelMap[x]
281 #define OPTION_LEVEL_FROM_NATIVE(y) osl_SocketOptionLevelFromNative(y)
283 /*****************************************************************************/
284 /* enum oslSocketMsgFlag */
285 /*****************************************************************************/
287 static sal_uInt32 SocketMsgFlagMap[]= {
288 0, /* osl_Socket_MsgNormal */
289 MSG_OOB, /* osl_Socket_MsgOOB */
290 MSG_PEEK, /* osl_Socket_MsgPeek */
291 MSG_DONTROUTE, /* osl_Socket_MsgDontRoute */
292 MSG_MAXIOVLEN, /* osl_Socket_MsgMaxIOVLen */
293 0 /* osl_Socket_MsgInvalid */
296 /* reverse map */
297 /* mfe: NOT USED
298 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
300 oslSocketMsgFlag i= (oslSocketMsgFlag)0;
302 while(i != osl_Socket_MsgInvalid)
304 if(SocketMsgFlagMap[i] == nativeType)
305 return i;
306 i = (oslSocketMsgFlag) ( i + 1 );
309 return i;
313 /* macros */
314 #define MSG_FLAG_TO_NATIVE(x) SocketMsgFlagMap[x]
315 #define MSG_FLAG_FROM_NATIVE(y) osl_SocketMsgFlagFromNative(y)
318 /*****************************************************************************/
319 /* enum oslSocketDirection */
320 /*****************************************************************************/
322 static sal_uInt32 SocketDirection[]= {
323 SD_RECEIVE, /* osl_Socket_DirRead */
324 SD_SEND, /* osl_Socket_DirWrite */
325 SD_BOTH, /* osl_Socket_DirReadWrite */
326 0 /* osl_Socket_DirInvalid */
329 /* reverse map */
330 /* mfe: NOT USED
331 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
333 oslSocketDirection i= (oslSocketDirection)0;
335 while(i != osl_Socket_DirInvalid)
337 if(SocketDirection[i] == nativeType)
338 return i;
339 i = (oslSocketDirection) ( i + 1 );
342 return i;
346 /* macros */
347 #define DIRECTION_TO_NATIVE(x) SocketDirection[x]
348 #define DIRECTION_FROM_NATIVE(y) osl_SocketDirectionFromNative(y)
350 /*****************************************************************************/
351 /* enum oslSocketError */
352 /*****************************************************************************/
354 static struct
356 int errcode;
357 oslSocketError error;
358 } SocketError[]= {
359 { 0, osl_Socket_E_None }, /* no error */
360 { ENOTSOCK, osl_Socket_E_NotSocket }, /* Socket operation on non-socket */
361 { EDESTADDRREQ, osl_Socket_E_DestAddrReq }, /* Destination address required */
362 { EMSGSIZE, osl_Socket_E_MsgSize }, /* Message too long */
363 { EPROTOTYPE, osl_Socket_E_Prototype }, /* Protocol wrong type for socket */
364 { ENOPROTOOPT, osl_Socket_E_NoProtocol }, /* Protocol not available */
365 { EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
366 { ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport }, /* Socket type not supported */
367 { EOPNOTSUPP, osl_Socket_E_OpNotSupport }, /* Operation not supported on socket */
368 { EPFNOSUPPORT, osl_Socket_E_PfNoSupport }, /* Protocol family not supported */
369 { EAFNOSUPPORT, osl_Socket_E_AfNoSupport }, /* Address family not supported by */
370 /* protocol family */
371 { EADDRINUSE, osl_Socket_E_AddrInUse }, /* Address already in use */
372 { EADDRNOTAVAIL, osl_Socket_E_AddrNotAvail }, /* Can't assign requested address */
373 { ENETDOWN, osl_Socket_E_NetDown }, /* Network is down */
374 { ENETUNREACH, osl_Socket_E_NetUnreachable }, /* Network is unreachable */
375 { ENETRESET, osl_Socket_E_NetReset }, /* Network dropped connection because */
376 /* of reset */
377 { ECONNABORTED, osl_Socket_E_ConnAborted }, /* Software caused connection abort */
378 { ECONNRESET, osl_Socket_E_ConnReset }, /* Connection reset by peer */
379 { ENOBUFS, osl_Socket_E_NoBufferSpace }, /* No buffer space available */
380 { EISCONN, osl_Socket_E_IsConnected }, /* Socket is already connected */
381 { ENOTCONN, osl_Socket_E_NotConnected }, /* Socket is not connected */
382 { ESHUTDOWN, osl_Socket_E_Shutdown }, /* Can't send after socket shutdown */
383 { ETOOMANYREFS, osl_Socket_E_TooManyRefs }, /* Too many references: can't splice */
384 { ETIMEDOUT, osl_Socket_E_TimedOut }, /* Connection timed out */
385 { ECONNREFUSED, osl_Socket_E_ConnRefused }, /* Connection refused */
386 { EHOSTDOWN, osl_Socket_E_HostDown }, /* Host is down */
387 { EHOSTUNREACH, osl_Socket_E_HostUnreachable }, /* No route to host */
388 { EWOULDBLOCK, osl_Socket_E_WouldBlock }, /* call would block on non-blocking socket */
389 { EALREADY, osl_Socket_E_Already }, /* operation already in progress */
390 { EINPROGRESS, osl_Socket_E_InProgress }, /* operation now in progress */
391 { EAGAIN, osl_Socket_E_WouldBlock }, /* same as EWOULDBLOCK */
392 { -1, osl_Socket_E_InvalidError }
395 /* map */
396 /* mfe: NOT USED
397 static int osl_NativeFromSocketError(oslSocketError errorCode)
399 int i = 0;
401 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
402 (SocketError[i].error != errorCode)) i++;
404 return SocketError[i].errcode;
408 /* reverse map */
409 static oslSocketError osl_SocketErrorFromNative(int nativeType)
411 int i = 0;
413 while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
414 (SocketError[i].errcode != nativeType)) i++;
416 return SocketError[i].error;
419 /* macros */
420 #define ERROR_TO_NATIVE(x) osl_NativeFromSocketError(x)
421 #define ERROR_FROM_NATIVE(y) osl_SocketErrorFromNative(y)
423 /*****************************************************************************/
424 /* local function prototypes */
425 /*****************************************************************************/
427 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
428 const sal_Char* pszDottedAddr, sal_Int32 Port);
430 oslSocketAddr SAL_CALL osl_psz_createIpxSocketAddr (
431 const sal_Char NetNumber[4],
432 const sal_Char NodeNumber[6],
433 sal_uInt32 SocketNumber);
435 oslHostAddr SAL_CALL osl_psz_createHostAddr (
436 const sal_Char *pszHostname, const oslSocketAddr Addr);
438 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (
439 const sal_Char *pszHostname);
441 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (
442 const oslHostAddr Addr);
444 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
445 sal_Char *pBuffer, sal_uInt32 nBufLen);
447 oslSocketAddr SAL_CALL osl_psz_resolveHostname (
448 const sal_Char* pszHostname);
450 sal_Int32 SAL_CALL osl_psz_getServicePort (
451 const sal_Char* pszServicename, const sal_Char* pszProtocol);
453 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr (
454 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
456 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr (
457 oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
459 void SAL_CALL osl_psz_getLastSocketErrorDescription (
460 oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
462 /*****************************************************************************/
463 /* osl_create/destroy-SocketImpl */
464 /*****************************************************************************/
466 #if OSL_DEBUG_LEVEL > 1
467 static sal_uInt32 g_nSocketImpl = 0;
468 static sal_uInt32 g_nSocketAddr = 0;
470 /* sorry, must be implemented otherwise */
471 #if 0
472 struct LeakWarning
474 ~LeakWarning()
476 if( g_nSocketImpl )
477 OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
478 if( g_nSocketAddr )
479 OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
482 LeakWarning socketWarning;
483 #endif
485 #endif /* OSL_DEBUG_LEVEL */
488 oslSocket __osl_createSocketImpl(int Socket)
490 oslSocket pSocket;
492 pSocket = (oslSocket)calloc(1, sizeof(struct oslSocketImpl));
494 pSocket->m_Socket = Socket;
495 pSocket->m_nLastError = 0;
496 pSocket->m_CloseCallback = 0;
497 pSocket->m_CallbackArg = 0;
498 pSocket->m_nRefCount = 1;
500 #if defined(LINUX)
501 pSocket->m_bIsAccepting = sal_False;
502 #endif
504 #if OSL_DEBUG_LEVEL > 1
505 g_nSocketImpl ++;
506 #endif
507 return pSocket;
510 void __osl_destroySocketImpl(oslSocket Socket)
512 if ( Socket != NULL)
513 free((struct oslSocketImpl *) Socket);
514 #if OSL_DEBUG_LEVEL > 1
515 g_nSocketImpl --;
516 #endif
519 static oslSocketAddr __osl_createSocketAddr( )
521 oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
522 #if OSL_DEBUG_LEVEL > 1
523 g_nSocketAddr ++;
524 #endif
525 return pAddr;
528 static oslSocketAddr __osl_createSocketAddrWithFamily(
529 oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
531 oslSocketAddr pAddr;
533 OSL_ASSERT( family == osl_Socket_FamilyInet );
535 pAddr = __osl_createSocketAddr();
536 switch( family )
538 case osl_Socket_FamilyInet:
540 struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
542 pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
543 pInetAddr->sin_addr.s_addr = nAddr;
544 pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
545 break;
547 default:
548 pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
550 return pAddr;
553 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
555 oslSocketAddr pAddr = __osl_createSocketAddr();
556 memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
557 return pAddr;
560 static void __osl_destroySocketAddr( oslSocketAddr addr )
562 #if OSL_DEBUG_LEVEL > 1
563 g_nSocketAddr --;
564 #endif
565 rtl_freeMemory( addr );
568 /*****************************************************************************/
569 /* osl_createEmptySocketAddr */
570 /*****************************************************************************/
571 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
573 oslSocketAddr pAddr = 0;
575 /* is it an internet-Addr? */
576 if (Family == osl_Socket_FamilyInet)
578 pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
580 else
582 pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
585 return pAddr;
588 /*****************************************************************************/
589 /* osl_copySocketAddr */
590 /*****************************************************************************/
591 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
593 oslSocketAddr pCopy = 0;
594 if (Addr)
596 pCopy = __osl_createSocketAddr();
598 if (pCopy)
599 memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
601 return pCopy;
604 /*****************************************************************************/
605 /* osl_isEqualSocketAddr */
606 /*****************************************************************************/
607 sal_Bool SAL_CALL osl_isEqualSocketAddr (
608 oslSocketAddr Addr1,
609 oslSocketAddr Addr2)
611 struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
612 struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
614 OSL_ASSERT(pAddr1);
615 OSL_ASSERT(pAddr2);
617 if (pAddr1->sa_family == pAddr2->sa_family)
619 switch (pAddr1->sa_family)
621 case AF_INET:
623 struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
624 struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
626 if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
627 (pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
628 (pInetAddr1->sin_port == pInetAddr2->sin_port))
629 return (sal_True);
632 default:
634 return (memcmp(pAddr1, Addr2, sizeof(struct sockaddr)) == 0);
639 return (sal_False);
642 /*****************************************************************************/
643 /* osl_createInetBroadcastAddr */
644 /*****************************************************************************/
645 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
646 rtl_uString *strDottedAddr,
647 sal_Int32 Port)
649 sal_uInt32 nAddr = OSL_INADDR_NONE;
650 oslSocketAddr pAddr;
652 if (strDottedAddr && strDottedAddr->length)
654 /* Dotted host address for limited broadcast */
655 rtl_String *pDottedAddr = NULL;
657 rtl_uString2String (
658 &pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
659 RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
661 nAddr = inet_addr (pDottedAddr->buffer);
662 rtl_string_release (pDottedAddr);
665 if (nAddr != OSL_INADDR_NONE)
667 /* Limited broadcast */
668 nAddr = ntohl(nAddr);
669 if (IN_CLASSA(nAddr))
671 nAddr &= IN_CLASSA_NET;
672 nAddr |= IN_CLASSA_HOST;
674 else if (IN_CLASSB(nAddr))
676 nAddr &= IN_CLASSB_NET;
677 nAddr |= IN_CLASSB_HOST;
679 else if (IN_CLASSC(nAddr))
681 nAddr &= IN_CLASSC_NET;
682 nAddr |= IN_CLASSC_HOST;
684 else
686 /* No broadcast in class D */
687 return ((oslSocketAddr)NULL);
689 nAddr = htonl(nAddr);
692 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
693 return pAddr;
696 /*****************************************************************************/
697 /* osl_createInetSocketAddr */
698 /*****************************************************************************/
699 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
700 rtl_uString *ustrDottedAddr,
701 sal_Int32 Port)
703 rtl_String* strDottedAddr=0;
704 oslSocketAddr Addr;
705 sal_Char* pszDottedAddr=0;
707 if ( ustrDottedAddr != 0 )
709 rtl_uString2String( &strDottedAddr,
710 rtl_uString_getStr(ustrDottedAddr),
711 rtl_uString_getLength(ustrDottedAddr),
712 RTL_TEXTENCODING_UTF8,
713 OUSTRING_TO_OSTRING_CVTFLAGS);
714 pszDottedAddr = rtl_string_getStr(strDottedAddr);
718 Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
720 if ( strDottedAddr != 0 )
722 rtl_string_release(strDottedAddr);
725 return Addr;
728 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
729 const sal_Char* pszDottedAddr,
730 sal_Int32 Port)
732 oslSocketAddr pAddr = 0;
733 sal_Int32 Addr = inet_addr(pszDottedAddr);
734 if(Addr != -1)
736 /* valid dotted addr */
737 pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
739 return pAddr;
742 /*****************************************************************************/
743 /* osl_setAddrOfSocketAddr */
744 /*****************************************************************************/
745 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
747 oslSocketResult res = osl_Socket_Error;
749 OSL_ASSERT( pAddr );
750 OSL_ASSERT( pByteSeq );
752 if( pAddr && pByteSeq )
754 struct sockaddr_in * pSystemInetAddr;
756 OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
757 OSL_ASSERT( pByteSeq->nElements == 4 );
759 pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
760 memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
761 res = osl_Socket_Ok;
763 return res;
766 /*****************************************************************************/
767 /* osl_getAddrOfSocketAddr */
768 /*****************************************************************************/
769 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
771 oslSocketResult res = osl_Socket_Error;
773 OSL_ASSERT( pAddr );
774 OSL_ASSERT( ppByteSeq );
776 if( pAddr && ppByteSeq )
778 struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
779 rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
780 res = osl_Socket_Ok;
782 return res;
786 /*****************************************************************************/
787 /* _osl_getFullQualifiedDomainName */
788 /*****************************************************************************/
790 /** try to figure out a full-qualified hostname, by adding the current domain
791 as given by the domainname program to the given hostname.
792 This function MUST NOT call gethostbyname since pHostName allready points
793 to data returned by gethostname and would be garbled: use gethostname_r
794 instead!
797 /* wrap around different interfaces to reentrant gethostbyname */
798 static struct hostent* _osl_gethostbyname_r (
799 const char *name, struct hostent *result,
800 char *buffer, int buflen, int *h_errnop)
802 #if defined(LINUX) || (defined(FREEBSD) && (__FreeBSD_version >= 601103))
803 struct hostent *__result; /* will be the same as result */
804 int __error;
805 __error = gethostbyname_r (name, result, buffer, buflen,
806 &__result, h_errnop);
807 return __error ? NULL : __result ;
808 #else
809 return gethostbyname_r( name, result, buffer, buflen, h_errnop);
810 #endif
813 static sal_Bool _osl_getDomainName (sal_Char *buffer, sal_Int32 bufsiz)
815 sal_Bool result;
816 int p[2];
818 result = sal_False;
819 if (pipe (p) == 0)
821 pid_t pid;
822 int nStatus;
824 pid = fork();
825 if (pid == 0)
827 char *argv[] =
829 "/bin/domainname",
830 NULL
833 close (p[0]);
834 dup2 (p[1], 1);
835 close (p[1]);
837 execv ("/bin/domainname", argv);
838 // arriving here means exec failed
839 _exit(-1);
841 else if (pid > 0)
843 sal_Int32 k = 0, n = bufsiz;
845 close (p[1]);
846 if ((k = read (p[0], buffer, n - 1)) > 0)
848 buffer[k] = 0;
849 if (buffer[k - 1] == '\n')
850 buffer[k - 1] = 0;
851 result = sal_True;
853 close (p[0]);
854 waitpid (pid, &nStatus, 0);
856 else
858 close (p[0]);
859 close (p[1]);
862 return (result);
865 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
867 # define DOMAINNAME_LENGTH 512
868 sal_uInt32 nLengthOfHostName;
869 static sal_uInt32 nLengthOfDomainName = 0;
870 static sal_Char *pDomainName = NULL;
872 sal_Char *pFullQualifiedName;
873 #if 0 /* OBSOLETE */
874 FILE *pPipeToDomainnameExe;
875 #endif /* OBSOLETE */
877 /* get a '\0' terminated domainname */
879 /* read default domainname default from environment */
880 if (nLengthOfDomainName == 0)
882 sal_Char *pEnvDomain;
884 pEnvDomain = getenv ("STAR_OVERRIDE_DOMAINNAME");
885 if (pEnvDomain)
887 pDomainName = strdup (pEnvDomain);
888 nLengthOfDomainName = strlen (pDomainName);
892 #if 1 /* NEW */
893 if (nLengthOfDomainName == 0)
895 sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
897 pDomainNameBuffer[0] = '\0';
899 if (_osl_getDomainName (pDomainNameBuffer, DOMAINNAME_LENGTH))
901 pDomainName = strdup (pDomainNameBuffer);
902 nLengthOfDomainName = strlen (pDomainName);
906 #endif /* NEW */
907 #if 0 /* OBSOLETE */
908 #ifdef SCO
910 /* call 'domainname > /usr/tmp/some-tmp-file', since
911 popen read pclose do block or core-dump,
912 (even the pipe-stuff that comes with pthreads) */
913 if (nLengthOfDomainName == 0)
915 sal_Char tmp_name[ L_tmpnam ];
916 FILE *tmp_file;
917 sal_Char domain_call [ L_tmpnam + 16 ] = "domainname > ";
919 tmp_name[0] = '\0';
921 tmpnam ( tmp_name );
922 strcat ( domain_call, tmp_name );
923 if ( (system ( domain_call ) == 0)
924 && ((tmp_file = fopen( tmp_name, "r" )) != NULL ) )
926 sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
928 pDomainNameBuffer[0] = '\0';
930 if ( fgets ( pDomainNameBuffer, DOMAINNAME_LENGTH, tmp_file ) )
932 pDomainName = strdup( pDomainNameBuffer );
933 nLengthOfDomainName = strlen( pDomainName );
934 if ( ( nLengthOfDomainName > 0 )
935 && ( pDomainName[ nLengthOfDomainName - 1] == '\n' ) )
936 pDomainName[ --nLengthOfDomainName ] = '\0';
938 fclose ( tmp_file );
940 unlink( tmp_name );
943 #else /* !SCO */
945 /* read the domainname from pipe to the program domainname */
946 if ( (nLengthOfDomainName == 0)
947 && (pPipeToDomainnameExe = popen( "domainname", "r")) )
949 sal_Char c;
950 sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
951 sal_Char *pDomainNamePointer;
953 pDomainNameBuffer[0] = '\0';
955 pDomainNamePointer = pDomainNameBuffer;
956 while ( ((c = getc( pPipeToDomainnameExe )) != EOF)
957 && (nLengthOfDomainName < (DOMAINNAME_LENGTH - 1)) )
959 if (! isspace(c))
961 nLengthOfDomainName++ ;
962 *pDomainNamePointer++ = (sal_Char)c;
965 *pDomainNamePointer = '\0';
966 pDomainName = strdup( pDomainNameBuffer );
968 pclose( pPipeToDomainnameExe );
971 #endif /* !SCO */
972 #endif /* OBSOLETE */
974 /* compose hostname and domainname */
975 nLengthOfHostName = strlen( pHostName );
976 pFullQualifiedName = (sal_Char*) malloc( (nLengthOfHostName + 1
977 + nLengthOfDomainName + 1) * sizeof(sal_Char) );
978 memcpy( pFullQualifiedName, pHostName,
979 (nLengthOfHostName + 1) * sizeof(sal_Char) );
981 if ( nLengthOfDomainName > 0 )
983 /* fqdn = hostname + '.' + domainname + '\0' */
984 pFullQualifiedName[ nLengthOfHostName ] = '.';
985 memcpy( pFullQualifiedName + nLengthOfHostName + 1, pDomainName,
986 nLengthOfDomainName + 1 );
989 /* check whether full-qualified name and hostname point to the same host
990 * should almost always be true */
991 if ( nLengthOfDomainName > 0 )
993 struct hostent *pQualifiedHostByName;
994 struct hostent *pHostByName;
995 sal_Bool bHostsAreEqual;
997 /* buffer for calls to reentrant version of gethostbyname */
998 struct hostent aHostByName, aQualifiedHostByName;
999 sal_Char pHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1000 sal_Char pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1001 int nErrorNo;
1003 pHostBuffer[0] = '\0';
1004 pQualifiedHostBuffer[0] = '\0';
1006 /* get list of addresses */
1007 pQualifiedHostByName = _osl_gethostbyname_r (
1008 pFullQualifiedName,
1009 &aQualifiedHostByName, pQualifiedHostBuffer,
1010 sizeof(pQualifiedHostBuffer), &nErrorNo );
1011 pHostByName = _osl_gethostbyname_r (
1012 pHostName,
1013 &aHostByName, pHostBuffer,
1014 sizeof(pHostBuffer), &nErrorNo );
1016 /* compare addresses */
1017 bHostsAreEqual = sal_False;
1018 if ( pQualifiedHostByName && pHostByName )
1020 sal_Char **p, **q;
1021 struct in_addr in;
1023 /* lists are expected to be (very) short */
1024 for ( p = pQualifiedHostByName->h_addr_list; *p != NULL; p++ )
1026 for ( q = pHostByName->h_addr_list; *q != NULL; q++ )
1028 /* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1029 if ( memcmp( *p, *q, sizeof(in.s_addr) ) == 0 )
1031 bHostsAreEqual = sal_True;
1032 break;
1035 if ( bHostsAreEqual )
1036 break;
1040 /* very strange case, but have to believe it: reduce the
1041 * full qualified name to the unqualified host name */
1042 if ( !bHostsAreEqual )
1044 OSL_TRACE("_osl_getFullQualifiedDomainName: "
1045 "suspect FQDN: %s\n", pFullQualifiedName);
1047 pFullQualifiedName[ nLengthOfHostName ] = '\0';
1048 pFullQualifiedName = (sal_Char*)realloc ( pFullQualifiedName,
1049 (nLengthOfHostName + 1) * sizeof( sal_Char ));
1053 /* always return a hostname looked up as carefully as possible
1054 * this string must be freed by the caller */
1055 return pFullQualifiedName;
1058 /*****************************************************************************/
1059 /* _osl_isFullQualifiedDomainName */
1060 /*****************************************************************************/
1061 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
1063 /* a FQDN (aka 'hostname.domain.top_level_domain' )
1064 * is a name which contains a dot '.' in it ( would
1065 * match as well for 'hostname.' but is good enough
1066 * for now )*/
1067 return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
1070 /*****************************************************************************/
1071 /* oslHostAddr */
1072 /*****************************************************************************/
1073 struct oslHostAddrImpl
1075 sal_Char *pHostName;
1076 oslSocketAddr pSockAddr;
1079 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
1081 oslHostAddr pAddr= NULL;
1082 oslSocketAddr pSockAddr = 0;
1084 sal_Char *cn;
1086 if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
1087 return ((oslHostAddr)NULL);
1089 if (_osl_isFullQualifiedDomainName(he->h_name))
1091 cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1092 OSL_ASSERT(cn);
1093 if (cn == NULL)
1094 return ((oslHostAddr)NULL);
1096 strcpy(cn, he->h_name);
1098 else
1100 cn =_osl_getFullQualifiedDomainName (he->h_name);
1101 OSL_ASSERT(cn);
1102 if (cn == NULL)
1103 return ((oslHostAddr)NULL);
1106 pSockAddr = __osl_createSocketAddr();
1107 OSL_ASSERT(pSockAddr);
1108 if (pSockAddr == NULL)
1110 free(cn);
1111 return ((oslHostAddr)NULL);
1114 pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
1115 if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1117 struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
1118 memcpy (
1119 &(sin->sin_addr.s_addr),
1120 he->h_addr_list[0],
1121 he->h_length);
1123 else
1125 /* unknown address family */
1126 /* future extensions for new families might be implemented here */
1128 OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1129 OSL_ASSERT(sal_False);
1131 __osl_destroySocketAddr( pSockAddr );
1132 free (cn);
1133 return ((oslHostAddr)NULL);
1136 pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1137 OSL_ASSERT(pAddr);
1138 if (pAddr == NULL)
1140 __osl_destroySocketAddr( pSockAddr );
1141 free (cn);
1142 return ((oslHostAddr)NULL);
1145 pAddr->pHostName= cn;
1146 pAddr->pSockAddr= pSockAddr;
1148 return pAddr;
1151 /*****************************************************************************/
1152 /* osl_createHostAddr */
1153 /*****************************************************************************/
1154 oslHostAddr SAL_CALL osl_createHostAddr (
1155 rtl_uString *ustrHostname,
1156 const oslSocketAddr Addr)
1158 oslHostAddr HostAddr;
1159 rtl_String* strHostname=0;
1160 sal_Char* pszHostName=0;
1162 if ( ustrHostname != 0 )
1164 rtl_uString2String( &strHostname,
1165 rtl_uString_getStr(ustrHostname),
1166 rtl_uString_getLength(ustrHostname),
1167 RTL_TEXTENCODING_UTF8,
1168 OUSTRING_TO_OSTRING_CVTFLAGS );
1169 pszHostName = rtl_string_getStr(strHostname);
1172 HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
1174 if ( strHostname != 0 )
1176 rtl_string_release(strHostname);
1180 return HostAddr;
1183 oslHostAddr SAL_CALL osl_psz_createHostAddr (
1184 const sal_Char *pszHostname,
1185 const oslSocketAddr pAddr)
1187 oslHostAddr pHostAddr;
1188 sal_Char *cn;
1190 OSL_ASSERT(pszHostname && pAddr);
1191 if ((pszHostname == NULL) || (pAddr == NULL))
1192 return ((oslHostAddr)NULL);
1194 cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
1195 OSL_ASSERT(cn);
1196 if (cn == NULL)
1197 return ((oslHostAddr)NULL);
1199 strcpy (cn, pszHostname);
1201 pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1202 OSL_ASSERT(pHostAddr);
1203 if (pAddr == NULL)
1205 free (cn);
1206 return ((oslHostAddr)NULL);
1209 pHostAddr->pHostName= cn;
1210 pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
1212 return pHostAddr;
1215 /*****************************************************************************/
1216 /* osl_createHostAddrByName */
1217 /*****************************************************************************/
1218 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
1220 oslHostAddr HostAddr;
1221 rtl_String* strHostname=0;
1222 sal_Char* pszHostName=0;
1224 if ( ustrHostname != 0 )
1226 rtl_uString2String( &strHostname,
1227 rtl_uString_getStr(ustrHostname),
1228 rtl_uString_getLength(ustrHostname),
1229 RTL_TEXTENCODING_UTF8,
1230 OUSTRING_TO_OSTRING_CVTFLAGS );
1231 pszHostName=rtl_string_getStr(strHostname);
1234 HostAddr = osl_psz_createHostAddrByName(pszHostName);
1236 if ( strHostname != 0 )
1238 rtl_string_release(strHostname);
1241 return HostAddr;
1244 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
1246 struct hostent *he;
1247 oslHostAddr addr;
1249 static oslMutex mutex = NULL;
1251 if (mutex == NULL)
1252 mutex = osl_createMutex();
1254 osl_acquireMutex(mutex);
1256 he = gethostbyname((sal_Char *)pszHostname);
1257 addr = _osl_hostentToHostAddr (he);
1259 osl_releaseMutex(mutex);
1261 return addr;
1264 /*****************************************************************************/
1265 /* osl_createHostAddrByAddr */
1266 /*****************************************************************************/
1267 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
1269 OSL_ASSERT(pAddr);
1271 if (pAddr == NULL)
1272 return ((oslHostAddr)NULL);
1274 if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1276 const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
1277 struct hostent *he;
1279 if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
1280 return ((oslHostAddr)NULL);
1282 he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
1283 sizeof (sin->sin_addr),
1284 sin->sin_family);
1285 return _osl_hostentToHostAddr (he);
1288 return ((oslHostAddr)NULL);
1291 /*****************************************************************************/
1292 /* osl_copyHostAddr */
1293 /*****************************************************************************/
1294 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
1296 OSL_ASSERT(pAddr);
1298 if (pAddr)
1299 return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
1300 else
1301 return ((oslHostAddr)NULL);
1304 /*****************************************************************************/
1305 /* osl_getHostnameOfHostAddr */
1306 /*****************************************************************************/
1307 void SAL_CALL osl_getHostnameOfHostAddr (
1308 const oslHostAddr Addr,
1309 rtl_uString **ustrHostname)
1311 const sal_Char* pHostname=0;
1313 pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1315 rtl_uString_newFromAscii (ustrHostname, pHostname);
1317 return;
1320 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1322 OSL_ASSERT(pAddr);
1324 if (pAddr)
1325 return pAddr->pHostName;
1326 else
1327 return NULL;
1330 /*****************************************************************************/
1331 /* osl_getSocketAddrOfHostAddr */
1332 /*****************************************************************************/
1333 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1335 OSL_ASSERT(pAddr);
1337 if (pAddr)
1338 return ((oslSocketAddr)(pAddr->pSockAddr));
1339 else
1340 return NULL;
1343 /*****************************************************************************/
1344 /* osl_destroyHostAddr */
1345 /*****************************************************************************/
1346 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1348 if (pAddr)
1350 if (pAddr->pHostName)
1351 free (pAddr->pHostName);
1352 if (pAddr->pSockAddr)
1353 osl_destroySocketAddr (pAddr->pSockAddr);
1354 free (pAddr);
1358 /*****************************************************************************/
1359 /* osl_getLocalHostname */
1360 /*****************************************************************************/
1361 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1363 oslSocketResult Result;
1364 sal_Char pszHostname[1024];
1366 pszHostname[0] = '\0';
1368 Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1370 rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1372 return Result;
1375 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1376 sal_Char *pBuffer, sal_uInt32 nBufLen)
1378 static sal_Char LocalHostname[256] = "";
1380 if (strlen(LocalHostname) == 0)
1382 const sal_Char *pStr;
1384 #ifdef SYSV
1385 struct utsname uts;
1387 if (uname(&uts) < 0)
1388 return osl_Socket_Error;
1390 if ((strlen(uts.nodename) + 1) > nBufLen)
1391 return osl_Socket_Error;
1393 strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1394 #else /* BSD compatible */
1396 if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1397 return osl_Socket_Error;
1398 LocalHostname[sizeof(LocalHostname)-1] = 0;
1399 #endif /* SYSV */
1401 /* check if we have an FQDN */
1402 if (strchr(LocalHostname, '.') == NULL)
1404 oslHostAddr Addr;
1406 /* no, determine it via dns */
1407 Addr = osl_psz_createHostAddrByName(LocalHostname);
1409 if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1411 #if 0 /* OBSOLETE */
1412 sal_Char* pChr;
1413 #endif /* OBSOLETE */
1414 strcpy(LocalHostname, pStr);
1416 #if 0 /* OBSOLETE */
1417 /* already done by _osl_getFullQualifiedDomainName() with
1418 much better heuristics, so this may be contraproductive */
1420 /* no FQDN, last try append domain name */
1421 if ((pChr = strchr(LocalHostname, '.')) == NULL)
1423 FILE *fp;
1425 pChr = &LocalHostname[strlen(LocalHostname)];
1427 if ( (fp = popen("domainname", "r")) != 0 )
1429 int c;
1431 *pChr++ = '.';
1433 while ((c = getc(fp)) != EOF)
1435 if (! isspace(c))
1436 *pChr++ = (sal_Char)c;
1439 *pChr = '\0';
1441 fclose(fp);
1443 else
1444 LocalHostname[0] = '\0';
1446 #endif /* OBSOLETE */
1449 osl_destroyHostAddr(Addr);
1453 if (strlen(LocalHostname) > 0)
1455 strncpy(pBuffer, LocalHostname, nBufLen);
1456 pBuffer[nBufLen - 1] = '\0';
1458 return osl_Socket_Ok;
1461 return osl_Socket_Error;
1464 /*****************************************************************************/
1465 /* osl_resolveHostname */
1466 /*****************************************************************************/
1467 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1469 oslSocketAddr Addr;
1470 rtl_String* strHostname=0;
1471 sal_Char* pszHostName=0;
1473 if ( ustrHostname != 0 )
1475 rtl_uString2String( &strHostname,
1476 rtl_uString_getStr(ustrHostname),
1477 rtl_uString_getLength(ustrHostname),
1478 RTL_TEXTENCODING_UTF8,
1479 OUSTRING_TO_OSTRING_CVTFLAGS );
1480 pszHostName = rtl_string_getStr(strHostname);
1484 Addr = osl_psz_resolveHostname(pszHostName);
1486 if ( strHostname != 0 )
1488 rtl_string_release(strHostname);
1492 return Addr;
1496 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1498 struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1500 if (pAddr)
1502 oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1504 osl_destroyHostAddr(pAddr);
1506 return (SockAddr);
1509 return ((oslSocketAddr)NULL);
1512 /*****************************************************************************/
1513 /* osl_getServicePort */
1514 /*****************************************************************************/
1515 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1517 sal_Int32 nPort;
1518 rtl_String* strServicename=0;
1519 rtl_String* strProtocol=0;
1520 sal_Char* pszServiceName=0;
1521 sal_Char* pszProtocol=0;
1523 if ( ustrServicename != 0 )
1525 rtl_uString2String( &strServicename,
1526 rtl_uString_getStr(ustrServicename),
1527 rtl_uString_getLength(ustrServicename),
1528 RTL_TEXTENCODING_UTF8,
1529 OUSTRING_TO_OSTRING_CVTFLAGS );
1530 pszServiceName = rtl_string_getStr(strServicename);
1533 if ( ustrProtocol != 0 )
1535 rtl_uString2String( &strProtocol,
1536 rtl_uString_getStr(ustrProtocol),
1537 rtl_uString_getLength(ustrProtocol),
1538 RTL_TEXTENCODING_UTF8,
1539 OUSTRING_TO_OSTRING_CVTFLAGS );
1540 pszProtocol = rtl_string_getStr(strProtocol);
1543 nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1545 if ( strServicename != 0 )
1547 rtl_string_release(strServicename);
1550 if ( strProtocol != 0 )
1552 rtl_string_release(strProtocol);
1556 return nPort;
1560 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1561 const sal_Char* pszProtocol)
1563 struct servent* ps;
1565 ps= getservbyname(pszServicename, pszProtocol);
1567 if (ps != 0)
1568 return ntohs(ps->s_port);
1570 return OSL_INVALID_PORT;
1573 /*****************************************************************************/
1574 /* osl_destroySocketAddr */
1575 /*****************************************************************************/
1576 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1578 __osl_destroySocketAddr( pAddr );
1581 /*****************************************************************************/
1582 /* osl_getFamilyOfSocketAddr */
1583 /*****************************************************************************/
1584 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1586 OSL_ASSERT(pAddr);
1588 if (pAddr)
1589 return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1590 else
1591 return osl_Socket_FamilyInvalid;
1594 /*****************************************************************************/
1595 /* osl_getInetPortOfSocketAddr */
1596 /*****************************************************************************/
1597 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1599 OSL_ASSERT(pAddr);
1600 if( pAddr )
1602 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1604 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1605 return ntohs(pSystemInetAddr->sin_port);
1607 return OSL_INVALID_PORT;
1610 /*****************************************************************************/
1611 /* osl_setInetPortOfSocketAddr */
1612 /*****************************************************************************/
1613 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1615 OSL_ASSERT(pAddr);
1616 if( pAddr )
1618 struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1619 if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1621 pSystemInetAddr->sin_port= htons((short)Port);
1622 return sal_True;
1626 /* this is not a inet-addr => can't set port */
1627 return sal_False;
1630 /*****************************************************************************/
1631 /* osl_getHostnameOfSocketAddr */
1632 /*****************************************************************************/
1633 oslSocketResult SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1635 oslSocketResult Result;
1636 sal_Char pszHostname[1024];
1638 pszHostname[0] = '\0';
1640 Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1642 rtl_uString_newFromAscii(ustrHostname,pszHostname);
1644 return Result;
1648 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1649 sal_Char *pBuffer, sal_uInt32 BufferSize)
1651 oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1653 if (pHostAddr)
1655 strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1657 pBuffer[BufferSize - 1] = '\0';
1659 osl_destroyHostAddr(pHostAddr);
1661 return osl_Socket_Ok;
1664 return osl_Socket_Error;
1667 /*****************************************************************************/
1668 /* osl_getDottedInetAddrOfSocketAddr */
1669 /*****************************************************************************/
1670 oslSocketResult SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1672 oslSocketResult Result;
1673 sal_Char pszDottedInetAddr[1024];
1675 pszDottedInetAddr[0] = '\0';
1677 Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1679 rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1681 return Result;
1685 oslSocketResult SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1686 sal_Char *pBuffer, sal_uInt32 BufferSize)
1688 OSL_ASSERT(pAddr);
1690 if( pAddr )
1692 struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1694 if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1696 strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1697 pBuffer[BufferSize - 1] = '\0';
1699 return osl_Socket_Ok;
1703 return osl_Socket_Error;
1706 #if 0 /* OBSOLETE */
1707 /*****************************************************************************/
1708 /* osl_getIpxNetNumber */
1709 /*****************************************************************************/
1710 oslSocketResult SAL_CALL osl_getIpxNetNumber(oslSocketAddr Addr,
1711 oslSocketIpxNetNumber NetNumber)
1714 struct sockaddr_ipx* pAddr;
1716 pAddr= (struct sockaddr_ipx*)Addr;
1718 OSL_ASSERT(pAddr);
1720 if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1722 memcpy(NetNumber, pAddr->sa_netnum, sizeof(NetNumber));
1724 return osl_Socket_Ok;
1726 else
1727 return osl_Socket_Error;
1731 /*****************************************************************************/
1732 /* osl_getIpxNodeNumber */
1733 /*****************************************************************************/
1734 oslSocketResult SAL_CALL osl_getIpxNodeNumber(oslSocketAddr Addr,
1735 oslSocketIpxNodeNumber NodeNumber)
1738 struct sockaddr_ipx* pAddr;
1740 pAddr= (struct sockaddr_ipx*)Addr;
1742 OSL_ASSERT(pAddr);
1744 if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1746 memcpy(NodeNumber, pAddr->sa_nodenum, sizeof(NodeNumber));
1748 return osl_Socket_Ok;
1750 else
1751 return osl_Socket_Error;
1755 /*****************************************************************************/
1756 /* osl_getIpxSocketNumber */
1757 /*****************************************************************************/
1758 sal_Int32 SAL_CALL osl_getIpxSocketNumber(oslSocketAddr Addr)
1760 struct sockaddr_ipx* pAddr= (struct sockaddr_ipx*)Addr;
1761 OSL_ASSERT(pAddr);
1763 if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1764 return pAddr->sa_socket;
1765 else
1766 return OSL_INVALID_IPX_SOCKET_NO;
1769 #endif /* OBSOLETE */
1771 /*****************************************************************************/
1772 /* osl_createSocket */
1773 /*****************************************************************************/
1774 oslSocket SAL_CALL osl_createSocket(oslAddrFamily Family,
1775 oslSocketType Type,
1776 oslProtocol Protocol)
1778 int Flags;
1779 oslSocket pSocket;
1781 /* alloc memory */
1782 pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1784 /* create socket */
1785 pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1786 TYPE_TO_NATIVE(Type),
1787 PROTOCOL_TO_NATIVE(Protocol));
1789 /* creation failed => free memory */
1790 if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1792 OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1793 errno,
1794 strerror(errno));
1796 __osl_destroySocketImpl((pSocket));
1797 pSocket= 0;
1799 else
1801 /* set close-on-exec flag */
1802 if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1804 Flags |= FD_CLOEXEC;
1805 if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1807 pSocket->m_nLastError=errno;
1808 OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1809 errno,
1810 strerror(errno));
1813 else
1815 pSocket->m_nLastError=errno;
1819 pSocket->m_CloseCallback = NULL;
1820 pSocket->m_CallbackArg = NULL;
1823 return pSocket;
1826 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1828 osl_incrementInterlockedCount( &(pSocket->m_nRefCount ) );
1831 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1833 if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
1835 #if defined(LINUX)
1836 if ( pSocket->m_bIsAccepting == sal_True )
1838 OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1839 return;
1841 #endif /* LINUX */
1842 osl_closeSocket( pSocket );
1843 __osl_destroySocketImpl( pSocket );
1849 /*****************************************************************************/
1850 /* osl_closeSocket */
1851 /*****************************************************************************/
1852 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1854 int nRet;
1855 int nFD;
1857 /* socket already invalid */
1858 if(pSocket==0)
1859 return;
1861 pSocket->m_nLastError=0;
1862 nFD = pSocket->m_Socket;
1864 pSocket->m_Socket = OSL_INVALID_SOCKET;
1866 #if defined(LINUX)
1867 pSocket->m_bIsInShutdown = sal_True;
1869 if ( pSocket->m_bIsAccepting == sal_True )
1871 int nConnFD;
1872 struct sockaddr aSockAddr;
1873 socklen_t nSockLen = sizeof(aSockAddr);
1875 nRet = getsockname(nFD, &aSockAddr, &nSockLen);
1876 #if OSL_DEBUG_LEVEL > 1
1877 if ( nRet < 0 )
1879 perror("getsockname");
1881 #endif /* OSL_DEBUG_LEVEL */
1883 if ( aSockAddr.sa_family == AF_INET )
1885 struct sockaddr_in* pSockAddrIn = (struct sockaddr_in*) &aSockAddr;
1887 if ( pSockAddrIn->sin_addr.s_addr == htonl(INADDR_ANY) )
1889 pSockAddrIn->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1892 nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1893 #if OSL_DEBUG_LEVEL > 1
1894 if ( nConnFD < 0 )
1896 perror("socket");
1898 #endif /* OSL_DEBUG_LEVEL */
1900 nRet = connect(nConnFD, &aSockAddr, sizeof(aSockAddr));
1901 #if OSL_DEBUG_LEVEL > 1
1902 if ( nRet < 0 )
1904 perror("connect");
1906 #endif /* OSL_DEBUG_LEVEL */
1907 close(nConnFD);
1910 #endif /* LINUX */
1912 /* registrierten Callback ausfuehren */
1913 if (pSocket->m_CloseCallback != NULL)
1915 pSocket->m_CloseCallback(pSocket->m_CallbackArg);
1918 nRet=close(nFD);
1919 if ( nRet != 0 )
1921 pSocket->m_nLastError=errno;
1922 OSL_TRACE("closeSocket close error '%s'\n",strerror(errno));
1925 pSocket->m_Socket = OSL_INVALID_SOCKET;
1928 /*****************************************************************************/
1929 /* osl_getLocalAddrOfSocket */
1930 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1931 /* are the same! I don't like it very much but see no other easy way to conceal */
1932 /* the struct sockaddr from the eyes of the user. */
1933 /*****************************************************************************/
1934 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1936 socklen_t AddrLen;
1937 struct sockaddr Addr;
1938 oslSocketAddr pAddr;
1940 if (pSocket == NULL) /* ENOTSOCK */
1941 return ((oslSocketAddr)NULL);
1943 AddrLen= sizeof(struct sockaddr);
1945 if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1946 return ((oslSocketAddr)NULL);
1948 pAddr = __osl_createSocketAddrFromSystem( &Addr );
1949 return pAddr;
1952 /*****************************************************************************/
1953 /* osl_getPeerAddrOfSocket */
1954 /*****************************************************************************/
1955 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1957 socklen_t AddrLen;
1958 struct sockaddr Addr;
1960 OSL_ASSERT(pSocket);
1961 if ( pSocket == 0 )
1963 return 0;
1966 pSocket->m_nLastError=0;
1967 AddrLen= sizeof(struct sockaddr);
1969 if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1971 pSocket->m_nLastError=errno;
1972 return 0;
1974 return __osl_createSocketAddrFromSystem( &Addr );
1977 /*****************************************************************************/
1978 /* osl_bindAddrToSocket */
1979 /*****************************************************************************/
1980 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1981 oslSocketAddr pAddr)
1983 int nRet;
1985 OSL_ASSERT(pSocket && pAddr );
1986 if ( pSocket == 0 || pAddr == 0 )
1988 return sal_False;
1991 pSocket->m_nLastError=0;
1993 nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1995 if ( nRet == OSL_SOCKET_ERROR)
1997 pSocket->m_nLastError=errno;
1998 return sal_False;
2001 return sal_True;
2005 /*****************************************************************************/
2006 /* osl_listenOnSocket */
2007 /*****************************************************************************/
2008 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
2009 sal_Int32 MaxPendingConnections)
2011 int nRet;
2013 OSL_ASSERT(pSocket);
2014 if ( pSocket == 0 )
2016 return sal_False;
2019 pSocket->m_nLastError=0;
2021 nRet = listen(pSocket->m_Socket,
2022 MaxPendingConnections == -1 ?
2023 SOMAXCONN :
2024 MaxPendingConnections);
2025 if ( nRet == OSL_SOCKET_ERROR)
2027 pSocket->m_nLastError=errno;
2028 return sal_False;
2031 return sal_True;
2035 /*****************************************************************************/
2036 /* osl_connectSocketTo */
2037 /*****************************************************************************/
2038 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
2039 oslSocketAddr pAddr,
2040 const TimeValue* pTimeout)
2042 fd_set WriteSet;
2043 fd_set ExcptSet;
2044 int ReadyHandles;
2045 struct timeval tv;
2046 oslSocketResult Result= osl_Socket_Ok;
2048 OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
2050 if ( pSocket == 0 )
2052 return osl_Socket_Error;
2055 pSocket->m_nLastError=0;
2057 if (osl_isNonBlockingMode(pSocket))
2059 if (connect(pSocket->m_Socket,
2060 &(pAddr->m_sockaddr),
2061 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2062 return osl_Socket_Ok;
2063 else
2064 if (errno == EWOULDBLOCK || errno == EINPROGRESS)
2066 pSocket->m_nLastError=EINPROGRESS;
2067 return osl_Socket_InProgress;
2071 pSocket->m_nLastError=errno;
2072 OSL_TRACE("can't connect : '%s'",strerror(errno));
2073 return osl_Socket_Error;
2076 /* set socket temporarily to non-blocking */
2077 OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
2079 /* initiate connect */
2080 if(connect(pSocket->m_Socket,
2081 &(pAddr->m_sockaddr),
2082 sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2084 /* immediate connection */
2085 osl_enableNonBlockingMode(pSocket, sal_False);
2087 return osl_Socket_Ok;
2089 else
2091 /* really an error or just delayed? */
2092 if (errno != EINPROGRESS)
2094 pSocket->m_nLastError=errno;
2095 OSL_TRACE(
2096 "osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2097 errno, strerror(errno));
2099 osl_enableNonBlockingMode(pSocket, sal_False);
2100 return osl_Socket_Error;
2105 /* prepare select set for socket */
2106 FD_ZERO(&WriteSet);
2107 FD_ZERO(&ExcptSet);
2108 FD_SET(pSocket->m_Socket, &WriteSet);
2109 FD_SET(pSocket->m_Socket, &ExcptSet);
2111 /* prepare timeout */
2112 if (pTimeout)
2114 /* divide milliseconds into seconds and microseconds */
2115 tv.tv_sec= pTimeout->Seconds;
2116 tv.tv_usec= pTimeout->Nanosec / 1000L;
2119 /* select */
2120 ReadyHandles= select(pSocket->m_Socket+1,
2122 PTR_FD_SET(WriteSet),
2123 PTR_FD_SET(ExcptSet),
2124 (pTimeout) ? &tv : 0);
2126 if (ReadyHandles > 0) /* connected */
2128 if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
2130 int nErrorCode = 0;
2131 socklen_t nErrorSize = sizeof( nErrorCode );
2133 int nSockOpt;
2135 nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
2136 &nErrorCode, &nErrorSize );
2137 if ( (nSockOpt == 0) && (nErrorCode == 0))
2138 Result = osl_Socket_Ok;
2139 else
2140 Result = osl_Socket_Error;
2142 else
2144 Result= osl_Socket_Error;
2147 else if (ReadyHandles < 0) /* error */
2149 if (errno == EBADF) /* most probably interrupted by close() */
2151 /* do not access pSockImpl because it is about to be or */
2152 /* already destroyed */
2153 return osl_Socket_Interrupted;
2155 else
2157 pSocket->m_nLastError=errno;
2158 Result= osl_Socket_Error;
2161 else /* timeout */
2163 pSocket->m_nLastError=errno;
2164 Result= osl_Socket_TimedOut;
2167 osl_enableNonBlockingMode(pSocket, sal_False);
2169 return Result;
2173 /*****************************************************************************/
2174 /* osl_acceptConnectionOnSocket */
2175 /*****************************************************************************/
2176 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
2177 oslSocketAddr* ppAddr)
2179 struct sockaddr Addr;
2180 int Connection, Flags;
2181 oslSocket pConnectionSockImpl;
2183 socklen_t AddrLen = sizeof(struct sockaddr);
2184 OSL_ASSERT(pSocket);
2185 if ( pSocket == 0 )
2187 return 0;
2190 pSocket->m_nLastError=0;
2191 #if defined(LINUX)
2192 pSocket->m_bIsAccepting = sal_True;
2193 #endif /* LINUX */
2195 if( ppAddr && *ppAddr )
2197 osl_destroySocketAddr( *ppAddr );
2198 *ppAddr = 0;
2201 /* prevent Linux EINTR behaviour */
2204 Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
2205 } while (Connection == -1 && errno == EINTR);
2208 /* accept failed? */
2209 if( Connection == OSL_SOCKET_ERROR )
2211 pSocket->m_nLastError=errno;
2212 OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno));
2214 #if defined(LINUX)
2215 pSocket->m_bIsAccepting = sal_False;
2216 #endif /* LINUX */
2217 return 0;
2220 OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
2223 #if defined(LINUX)
2224 if ( pSocket->m_bIsInShutdown == sal_True )
2226 close(Connection);
2227 OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2228 return 0;
2230 #endif /* LINUX */
2233 if(ppAddr)
2235 *ppAddr= __osl_createSocketAddrFromSystem(&Addr);
2238 /* alloc memory */
2239 pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
2241 /* set close-on-exec flag */
2242 if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
2244 Flags |= FD_CLOEXEC;
2245 if (fcntl(Connection, F_SETFD, Flags) == -1)
2247 pSocket->m_nLastError=errno;
2248 OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2249 errno,
2250 strerror(errno));
2255 pConnectionSockImpl->m_Socket = Connection;
2256 pConnectionSockImpl->m_nLastError = 0;
2257 pConnectionSockImpl->m_CloseCallback = NULL;
2258 pConnectionSockImpl->m_CallbackArg = NULL;
2259 #if defined(LINUX)
2260 pConnectionSockImpl->m_bIsAccepting = sal_False;
2262 pSocket->m_bIsAccepting = sal_False;
2263 #endif /* LINUX */
2264 return pConnectionSockImpl;
2267 /*****************************************************************************/
2268 /* osl_receiveSocket */
2269 /*****************************************************************************/
2270 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
2271 void* pBuffer,
2272 sal_uInt32 BytesToRead,
2273 oslSocketMsgFlag Flag)
2275 int nRead;
2277 OSL_ASSERT(pSocket);
2278 if ( pSocket == 0 )
2280 OSL_TRACE("osl_receiveSocket : Invalid socket");
2281 return -1;
2284 pSocket->m_nLastError=0;
2288 nRead = recv(pSocket->m_Socket,
2289 (sal_Char*)pBuffer,
2290 BytesToRead,
2291 MSG_FLAG_TO_NATIVE(Flag));
2292 } while ( nRead < 0 && errno == EINTR );
2294 if ( nRead < 0 )
2296 pSocket->m_nLastError=errno;
2297 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
2299 else if ( nRead == 0 )
2301 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2304 return nRead;
2308 /*****************************************************************************/
2309 /* osl_receiveFromSocket */
2310 /*****************************************************************************/
2311 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
2312 oslSocketAddr pSenderAddr,
2313 void* pBuffer,
2314 sal_uInt32 BufferSize,
2315 oslSocketMsgFlag Flag)
2317 int nRead;
2318 struct sockaddr *pSystemSockAddr = 0;
2319 socklen_t AddrLen = 0;
2320 if( pSenderAddr )
2322 AddrLen = sizeof( struct sockaddr );
2323 pSystemSockAddr = &(pSenderAddr->m_sockaddr);
2326 OSL_ASSERT(pSocket);
2327 if ( pSocket == 0 )
2329 OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2330 return -1;
2333 pSocket->m_nLastError=0;
2335 nRead = recvfrom(pSocket->m_Socket,
2336 (sal_Char*)pBuffer,
2337 BufferSize,
2338 MSG_FLAG_TO_NATIVE(Flag),
2339 pSystemSockAddr,
2340 &AddrLen);
2342 if ( nRead < 0 )
2344 pSocket->m_nLastError=errno;
2345 OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
2347 else if ( nRead == 0 )
2349 OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2352 return nRead;
2356 /*****************************************************************************/
2357 /* osl_sendSocket */
2358 /*****************************************************************************/
2359 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
2360 const void* pBuffer,
2361 sal_uInt32 BytesToSend,
2362 oslSocketMsgFlag Flag)
2364 int nWritten;
2366 OSL_ASSERT(pSocket);
2367 if ( pSocket == 0 )
2369 OSL_TRACE("osl_sendSocket : Invalid socket");
2370 return -1;
2373 pSocket->m_nLastError=0;
2377 nWritten = send(pSocket->m_Socket,
2378 (sal_Char*)pBuffer,
2379 BytesToSend,
2380 MSG_FLAG_TO_NATIVE(Flag));
2381 } while ( nWritten < 0 && errno == EINTR );
2384 if ( nWritten < 0 )
2386 pSocket->m_nLastError=errno;
2387 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
2389 else if ( nWritten == 0 )
2391 OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
2394 return nWritten;
2397 /*****************************************************************************/
2398 /* osl_sendToSocket */
2399 /*****************************************************************************/
2400 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
2401 oslSocketAddr ReceiverAddr,
2402 const void* pBuffer,
2403 sal_uInt32 BytesToSend,
2404 oslSocketMsgFlag Flag)
2406 int nWritten;
2408 struct sockaddr *pSystemSockAddr = 0;
2409 int AddrLen = 0;
2410 if( ReceiverAddr )
2412 pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
2413 AddrLen = sizeof( struct sockaddr );
2416 OSL_ASSERT(pSocket);
2417 if ( pSocket == 0 )
2419 OSL_TRACE("osl_sendToSocket : Invalid socket");
2420 return -1;
2423 pSocket->m_nLastError=0;
2425 /* ReceiverAddr might be 0 when used on a connected socket. */
2426 /* Then sendto should behave like send. */
2428 nWritten = sendto(pSocket->m_Socket,
2429 (sal_Char*)pBuffer,
2430 BytesToSend,
2431 MSG_FLAG_TO_NATIVE(Flag),
2432 pSystemSockAddr,
2433 AddrLen);
2435 if ( nWritten < 0 )
2437 pSocket->m_nLastError=errno;
2438 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
2440 else if ( nWritten == 0 )
2442 OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
2445 return nWritten;
2448 /*****************************************************************************/
2449 /* osl_readSocket */
2450 /*****************************************************************************/
2451 sal_Int32 SAL_CALL osl_readSocket (
2452 oslSocket pSocket, void *pBuffer, sal_Int32 n )
2454 sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
2455 sal_uInt32 BytesRead= 0;
2456 sal_uInt32 BytesToRead= n;
2458 OSL_ASSERT( pSocket);
2460 /* loop until all desired bytes were read or an error occured */
2461 while (BytesToRead > 0)
2463 sal_Int32 RetVal;
2464 RetVal= osl_receiveSocket(pSocket,
2465 Ptr,
2466 BytesToRead,
2467 osl_Socket_MsgNormal);
2469 /* error occured? */
2470 if(RetVal <= 0)
2472 break;
2475 BytesToRead -= RetVal;
2476 BytesRead += RetVal;
2477 Ptr += RetVal;
2480 return BytesRead;
2483 /*****************************************************************************/
2484 /* osl_writeSocket */
2485 /*****************************************************************************/
2486 sal_Int32 SAL_CALL osl_writeSocket(
2487 oslSocket pSocket, const void *pBuffer, sal_Int32 n )
2489 /* loop until all desired bytes were send or an error occured */
2490 sal_uInt32 BytesSend= 0;
2491 sal_uInt32 BytesToSend= n;
2492 sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
2494 OSL_ASSERT( pSocket );
2496 while (BytesToSend > 0)
2498 sal_Int32 RetVal;
2500 RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2502 /* error occured? */
2503 if(RetVal <= 0)
2505 break;
2508 BytesToSend -= RetVal;
2509 BytesSend += RetVal;
2510 Ptr += RetVal;
2513 return BytesSend;
2516 /*****************************************************************************/
2517 /* __osl_socket_poll */
2518 /*****************************************************************************/
2520 #ifdef HAVE_POLL_H /* poll() */
2522 sal_Bool __osl_socket_poll (
2523 oslSocket pSocket,
2524 const TimeValue* pTimeout,
2525 short nEvent)
2527 struct pollfd fds;
2528 int timeout;
2529 int result;
2531 OSL_ASSERT(pSocket);
2532 pSocket->m_nLastError = 0;
2534 fds.fd = pSocket->m_Socket;
2535 fds.events = nEvent;
2536 fds.revents = 0;
2538 timeout = -1;
2539 if (pTimeout)
2541 /* Convert to [ms] */
2542 timeout = pTimeout->Seconds * 1000;
2543 timeout += pTimeout->Nanosec / (1000 * 1000);
2546 result = poll (&fds, 1, timeout);
2547 if (result < 0)
2549 pSocket->m_nLastError = errno;
2550 OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2551 errno, strerror(errno));
2552 return sal_False;
2554 if (result == 0)
2556 /* Timeout */
2557 return sal_False;
2560 return ((fds.revents & nEvent) == nEvent);
2563 #else /* select() */
2565 sal_Bool __osl_socket_poll (
2566 oslSocket pSocket,
2567 const TimeValue* pTimeout,
2568 short nEvent)
2570 fd_set fds;
2571 struct timeval tv;
2572 int result;
2574 OSL_ASSERT(pSocket);
2575 pSocket->m_nLastError = 0;
2577 FD_ZERO(&fds);
2578 FD_SET(pSocket->m_Socket, &fds);
2580 if (pTimeout)
2582 /* Convert to 'timeval' */
2583 tv.tv_sec = pTimeout->Seconds;
2584 tv.tv_usec = pTimeout->Nanosec / 1000;
2587 result = select (
2588 pSocket->m_Socket + 1,
2589 (nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2590 (nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2591 (nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2592 (pTimeout) ? &tv : NULL);
2594 if (result < 0)
2596 pSocket->m_nLastError = errno;
2597 OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2598 errno, strerror(errno));
2599 return sal_False;
2601 if (result == 0)
2603 /* Timeout */
2604 return sal_False;
2607 return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2610 #endif /* HAVE_POLL_H */
2612 /*****************************************************************************/
2613 /* osl_isReceiveReady */
2614 /*****************************************************************************/
2615 sal_Bool SAL_CALL osl_isReceiveReady (
2616 oslSocket pSocket, const TimeValue* pTimeout)
2618 OSL_ASSERT(pSocket);
2619 if (pSocket == NULL)
2621 /* ENOTSOCK */
2622 return sal_False;
2625 return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2628 /*****************************************************************************/
2629 /* osl_isSendReady */
2630 /*****************************************************************************/
2631 sal_Bool SAL_CALL osl_isSendReady (
2632 oslSocket pSocket, const TimeValue* pTimeout)
2634 OSL_ASSERT(pSocket);
2635 if (pSocket == NULL)
2637 /* ENOTSOCK */
2638 return sal_False;
2641 return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2644 /*****************************************************************************/
2645 /* osl_isExceptionPending */
2646 /*****************************************************************************/
2647 sal_Bool SAL_CALL osl_isExceptionPending (
2648 oslSocket pSocket, const TimeValue* pTimeout)
2650 OSL_ASSERT(pSocket);
2651 if (pSocket == NULL)
2653 /* ENOTSOCK */
2654 return sal_False;
2657 return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2660 /*****************************************************************************/
2661 /* osl_shutdownSocket */
2662 /*****************************************************************************/
2663 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2664 oslSocketDirection Direction)
2666 int nRet;
2668 OSL_ASSERT(pSocket);
2669 if ( pSocket == 0 )
2671 return sal_False;
2674 pSocket->m_nLastError=0;
2676 nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2677 if (nRet != 0 )
2679 pSocket->m_nLastError=errno;
2680 OSL_TRACE("shutdown error '%s'\n",strerror(errno));
2682 return (nRet==0);
2686 /*****************************************************************************/
2687 /* osl_getSocketOption */
2688 /*****************************************************************************/
2689 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2690 oslSocketOptionLevel Level,
2691 oslSocketOption Option,
2692 void* pBuffer,
2693 sal_uInt32 BufferLen)
2695 socklen_t nOptLen = (socklen_t) BufferLen;
2697 OSL_ASSERT(pSocket);
2698 if ( pSocket == 0 )
2700 return -1;
2703 pSocket->m_nLastError=0;
2705 if(getsockopt(pSocket->m_Socket,
2706 OPTION_LEVEL_TO_NATIVE(Level),
2707 OPTION_TO_NATIVE(Option),
2708 (sal_Char*)pBuffer,
2709 &nOptLen) == -1)
2711 pSocket->m_nLastError=errno;
2712 return -1;
2715 return BufferLen;
2718 /*****************************************************************************/
2719 /* osl_setSocketOption */
2720 /*****************************************************************************/
2721 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2722 oslSocketOptionLevel Level,
2723 oslSocketOption Option,
2724 void* pBuffer,
2725 sal_uInt32 BufferLen)
2727 int nRet;
2729 OSL_ASSERT(pSocket);
2730 if ( pSocket == 0 )
2732 return sal_False;
2735 pSocket->m_nLastError=0;
2737 nRet = setsockopt(pSocket->m_Socket,
2738 OPTION_LEVEL_TO_NATIVE(Level),
2739 OPTION_TO_NATIVE(Option),
2740 (sal_Char*)pBuffer,
2741 BufferLen);
2743 if ( nRet < 0 )
2745 pSocket->m_nLastError=errno;
2746 return sal_False;
2749 return sal_True;
2752 /*****************************************************************************/
2753 /* osl_enableNonBlockingMode */
2754 /*****************************************************************************/
2755 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2756 sal_Bool On)
2758 int flags;
2759 int nRet;
2761 OSL_ASSERT(pSocket);
2762 if ( pSocket == 0 )
2764 return sal_False;
2767 pSocket->m_nLastError=0;
2769 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2771 if (On)
2772 flags |= O_NONBLOCK;
2773 else
2774 flags &= ~(O_NONBLOCK);
2776 nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2778 if ( nRet < 0 )
2780 pSocket->m_nLastError=errno;
2781 return sal_False;
2784 return sal_True;
2787 /*****************************************************************************/
2788 /* osl_isNonBlockingMode */
2789 /*****************************************************************************/
2790 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2792 int flags;
2794 OSL_ASSERT(pSocket);
2795 if ( pSocket == 0 )
2797 return sal_False;
2800 pSocket->m_nLastError=0;
2802 flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2804 if (flags == -1 || !(flags & O_NONBLOCK))
2805 return sal_False;
2806 else
2807 return sal_True;
2810 /*****************************************************************************/
2811 /* osl_getSocketType */
2812 /*****************************************************************************/
2813 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2815 int Type=0;
2816 socklen_t TypeSize= sizeof(Type);
2818 OSL_ASSERT(pSocket);
2819 if ( pSocket == 0 )
2821 return osl_Socket_TypeInvalid;
2824 pSocket->m_nLastError=0;
2826 if(getsockopt(pSocket->m_Socket,
2827 OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2828 OPTION_TO_NATIVE(osl_Socket_OptionType),
2829 (sal_Char*)&Type,
2830 &TypeSize) == -1)
2832 /* error */
2833 pSocket->m_nLastError=errno;
2834 return osl_Socket_TypeInvalid;
2837 return TYPE_FROM_NATIVE(Type);
2841 /*****************************************************************************/
2842 /* osl_getLastSocketErrorDescription */
2843 /*****************************************************************************/
2844 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2846 sal_Char pszError[1024];
2848 pszError[0] = '\0';
2850 osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2852 rtl_uString_newFromAscii(ustrError,pszError);
2854 return;
2858 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2860 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2861 pBuffer[BufferSize-1]= '\0';
2863 if ( pSocket == 0 )
2865 strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2866 return;
2869 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2870 return;
2873 /*****************************************************************************/
2874 /* osl_getLastSocketError */
2875 /*****************************************************************************/
2876 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2878 if ( pSocket == 0 )
2880 return ERROR_FROM_NATIVE(EINVAL);
2883 return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2886 /*****************************************************************************/
2887 /* SocketSet */
2888 /*****************************************************************************/
2889 typedef struct _TSocketSetImpl
2891 int m_MaxHandle; /* for select(), the largest descriptor in the set */
2892 fd_set m_Set; /* the set of descriptors */
2894 } TSocketSetImpl;
2896 /*****************************************************************************/
2897 /* osl_createSocketSet */
2898 /*****************************************************************************/
2899 oslSocketSet SAL_CALL osl_createSocketSet()
2901 TSocketSetImpl* pSet;
2903 pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2905 OSL_ASSERT(pSet);
2907 if(pSet)
2909 pSet->m_MaxHandle= 0;
2910 FD_ZERO(&pSet->m_Set);
2913 return (oslSocketSet)pSet;
2916 /*****************************************************************************/
2917 /* osl_destroySocketSet */
2918 /*****************************************************************************/
2919 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2921 if(Set)
2922 free(Set);
2925 /*****************************************************************************/
2926 /* osl_clearSocketSet */
2927 /*****************************************************************************/
2928 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2930 TSocketSetImpl* pSet;
2931 OSL_ASSERT(Set);
2932 if ( Set == 0 )
2934 return;
2937 pSet= (TSocketSetImpl*)Set;
2938 pSet->m_MaxHandle= 0;
2940 FD_ZERO(&pSet->m_Set);
2943 /*****************************************************************************/
2944 /* osl_addToSocketSet */
2945 /*****************************************************************************/
2946 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2948 TSocketSetImpl* pSet;
2950 OSL_ASSERT(Set);
2951 OSL_ASSERT(pSocket);
2953 if ( Set == 0 || pSocket == 0)
2955 return;
2958 pSet= (TSocketSetImpl*)Set;
2960 /* correct max handle */
2961 if(pSocket->m_Socket > pSet->m_MaxHandle)
2962 pSet->m_MaxHandle= pSocket->m_Socket;
2963 FD_SET(pSocket->m_Socket, &pSet->m_Set);
2967 /*****************************************************************************/
2968 /* osl_removeFromSocketSet */
2969 /*****************************************************************************/
2970 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2972 TSocketSetImpl* pSet;
2974 OSL_ASSERT(Set);
2975 OSL_ASSERT(pSocket);
2977 if ( Set == 0 || pSocket == 0)
2979 return;
2982 pSet= (TSocketSetImpl*)Set;
2984 /* correct max handle */
2985 if(pSocket->m_Socket == pSet->m_MaxHandle)
2987 /* not optimal, since the next used descriptor might be */
2988 /* much smaller than m_Socket-1, but it will do */
2989 pSet->m_MaxHandle--;
2990 if(pSet->m_MaxHandle < 0)
2992 pSet->m_MaxHandle= 0; /* avoid underflow */
2996 FD_CLR(pSocket->m_Socket, &pSet->m_Set);
2999 /*****************************************************************************/
3000 /* osl_isInSocketSet */
3001 /*****************************************************************************/
3002 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
3004 TSocketSetImpl* pSet;
3006 OSL_ASSERT(Set);
3007 OSL_ASSERT(pSocket);
3008 if ( Set == 0 || pSocket == 0 )
3010 return sal_False;
3013 pSet= (TSocketSetImpl*)Set;
3015 return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
3018 /*****************************************************************************/
3019 /* osl_demultiplexSocketEvents */
3020 /*****************************************************************************/
3021 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
3022 oslSocketSet OutgoingSet,
3023 oslSocketSet OutOfBandSet,
3024 const TimeValue* pTimeout)
3026 int MaxHandle= 0;
3027 struct timeval tv;
3028 TSocketSetImpl* pInSet;
3029 TSocketSetImpl* pOutSet;
3030 TSocketSetImpl* pOOBSet;
3032 if (pTimeout)
3034 /* non-blocking call */
3035 tv.tv_sec = pTimeout->Seconds;
3036 tv.tv_usec = pTimeout->Nanosec / 1000L;
3039 /* map opaque data to impl-types */
3040 pInSet= (TSocketSetImpl*)IncomingSet;
3041 pOutSet= (TSocketSetImpl*)OutgoingSet;
3042 pOOBSet= (TSocketSetImpl*)OutOfBandSet;
3044 /* get max handle from all sets */
3045 if (pInSet)
3046 MaxHandle= pInSet->m_MaxHandle;
3048 if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
3049 MaxHandle= pOutSet->m_MaxHandle;
3051 if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
3052 MaxHandle= pOOBSet->m_MaxHandle;
3054 return select(MaxHandle+1,
3055 pInSet ? PTR_FD_SET(pInSet->m_Set) : 0,
3056 pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
3057 pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
3058 pTimeout ? &tv : 0);