xref: /trunk/main/sal/osl/unx/socket.c (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "system.h"
29 
30 #include <osl/socket.h>
31 #include <osl/diagnose.h>
32 #include <osl/mutex.h>
33 #include <osl/signal.h>
34 
35 #include <rtl/alloc.h>
36 
37 #include <ctype.h>
38 #include <sal/types.h>
39 
40 #include "sockimpl.h"
41 
42 
43 /* defines for poll */
44 #ifdef HAVE_POLL_H
45 #undef HAVE_POLL_H
46 #endif
47 
48 #if defined(LINUX) || defined(NETBSD) || defined ( FREEBSD ) || defined (MACOSX)
49 #include <sys/poll.h>
50 #define HAVE_POLL_H
51 #endif /* HAVE_POLL_H */
52 
53 #if defined(SOLARIS)
54 #include <poll.h>
55 #define HAVE_POLL_H
56 #endif /* SOLARIS */
57 
58 #ifndef HAVE_POLL_H
59 #define POLLIN  0x0001
60 #define POLLOUT 0x0002
61 #define POLLPRI 0x0004
62 #endif /* HAVE_POLL_H */
63 
64 
65 /* defines for shutdown */
66 #define SD_RECEIVE 0
67 #define SD_SEND 1
68 #define SD_BOTH 2
69 
70 
71 /*
72 	oslSocketAddr is a pointer to a Berkeley struct sockaddr.
73 	I refrained from using sockaddr_in because of possible further
74 	extensions of this socket-interface (IP-NG?).
75 	The intention was to hide all Berkeley data-structures from
76 	direct access past the osl-interface.
77 
78 	The current implementation is internet (IP) centered. All
79 	the constructor-functions (osl_create...) take parameters
80 	that will probably make sense only in the IP-environment
81 	(e.g. because of using the dotted-address-format).
82 
83 	If the interface will be extended to host other protocol-
84 	families, I expect no externally visible changes in the
85 	existing functions. You'll probably need only new
86 	constructor-functions who take the different address
87 	formats into consideration (maybe a long dotted address
88 	or whatever).
89 */
90 
91 /* _Note_ that I rely on the fact that oslSocketAddr and struct sockaddr */
92 /* are the same! I don't like it very much but see no other easy way to  */
93 /* conceal the struct sockaddr from the eyes of the user. */
94 
95 
96 #define OSL_INVALID_SOCKET		-1
97 #define OSL_SOCKET_ERROR		-1
98 
99 
100 /* Buffer size for gethostbyname */
101 #define MAX_HOSTBUFFER_SIZE 2048
102 
103 /*****************************************************************************/
104 /* enum oslAddrFamily */
105 /*****************************************************************************/
106 
107 /* map */
108 static unsigned long FamilyMap[]= {
109 	AF_INET,					/* osl_Socket_FamilyInet    */
110 	AF_IPX,						/* osl_Socket_FamilyIpx     */
111 	0							/* osl_Socket_FamilyInvalid */
112 };
113 
114 /* reverse map */
115 static oslAddrFamily osl_AddrFamilyFromNative(sal_uInt32 nativeType)
116 {
117 	oslAddrFamily i= (oslAddrFamily)0;
118 
119 	while(i != osl_Socket_FamilyInvalid)
120 	{
121 		if(FamilyMap[i] == nativeType)
122 			return i;
123 		i = (oslAddrFamily) ( i + 1 );
124 	}
125 
126 	return i;
127 }
128 
129 /* macros */
130 #define FAMILY_FROM_NATIVE(y) osl_AddrFamilyFromNative(y)
131 #define FAMILY_TO_NATIVE(x)	(short)FamilyMap[x]
132 
133 /*****************************************************************************/
134 /* enum oslProtocol */
135 /*****************************************************************************/
136 
137 /* map */
138 static sal_uInt32 ProtocolMap[]= {
139 	0,							/* osl_Socket_ProtocolIp	  */
140 	NSPROTO_IPX,				/* osl_Socket_ProtocolIpx	  */
141 	NSPROTO_SPX,				/* osl_Socket_ProtocolSpx	  */
142 	NSPROTO_SPXII,				/* osl_Socket_ProtocolSpxII   */
143 	0							/* osl_Socket_ProtocolInvalid */
144 };
145 
146 /* reverse map */
147 /* mfe: NOT USED
148 static oslProtocol osl_ProtocolFromNative(sal_uInt32 nativeType)
149 {
150 	oslProtocol i= (oslProtocol)0;
151 
152 	while(i != osl_Socket_ProtocolInvalid)
153 	{
154 		if(ProtocolMap[i] == nativeType)
155 			return i;
156 		i = (oslProtocol) ( i + 1);
157 	}
158 
159 	return i;
160 }
161 */
162 
163 /* macros */
164 #define PROTOCOL_FROM_NATIVE(y) osl_ProtocolFromNative(y)
165 #define PROTOCOL_TO_NATIVE(x)	ProtocolMap[x]
166 
167 
168 /*****************************************************************************/
169 /* enum oslSocketType */
170 /*****************************************************************************/
171 
172 /* map */
173 static sal_uInt32 TypeMap[]= {
174 	SOCK_STREAM,				/* osl_Socket_TypeStream    */
175 	SOCK_DGRAM,					/* osl_Socket_TypeDgram     */
176 	SOCK_RAW,					/* osl_Socket_TypeRaw       */
177 	SOCK_RDM,					/* osl_Socket_TypeRdm       */
178 	SOCK_SEQPACKET,				/* osl_Socket_TypeSeqPacket */
179 	0							/* osl_Socket_TypeInvalid   */
180 };
181 
182 /* reverse map */
183 static oslSocketType osl_SocketTypeFromNative(sal_uInt32 nativeType)
184 {
185 	oslSocketType i= (oslSocketType)0;
186 
187 	while(i != osl_Socket_TypeInvalid)
188 	{
189 		if(TypeMap[i] == nativeType)
190 			return i;
191 		i = (oslSocketType)(i + 1);
192 	}
193 
194 	return i;
195 }
196 
197 /* macros */
198 #define TYPE_TO_NATIVE(x)		TypeMap[x]
199 #define TYPE_FROM_NATIVE(y)		osl_SocketTypeFromNative(y)
200 
201 
202 /*****************************************************************************/
203 /* enum oslSocketOption */
204 /*****************************************************************************/
205 
206 /* map */
207 static sal_uInt32 OptionMap[]= {
208 	SO_DEBUG,					/* osl_Socket_OptionDebug 		*/
209 	SO_ACCEPTCONN,				/* osl_Socket_OptionAcceptConn  */
210 	SO_REUSEADDR,				/* osl_Socket_OptionReuseAddr   */
211 	SO_KEEPALIVE,				/* osl_Socket_OptionKeepAlive   */
212 	SO_DONTROUTE,				/* osl_Socket_OptionDontRoute   */
213 	SO_BROADCAST,				/* osl_Socket_OptionBroadcast   */
214 	SO_USELOOPBACK,				/* osl_Socket_OptionUseLoopback */
215 	SO_LINGER,					/* osl_Socket_OptionLinger		*/
216 	SO_OOBINLINE,				/* osl_Socket_OptionOOBinLine   */
217 	SO_SNDBUF,					/* osl_Socket_OptionSndBuf      */
218 	SO_RCVBUF,					/* osl_Socket_OptionRcvBuf      */
219 	SO_SNDLOWAT,				/* osl_Socket_OptionSndLowat    */
220 	SO_RCVLOWAT,				/* osl_Socket_OptionRcvLowat    */
221 	SO_SNDTIMEO,				/* osl_Socket_OptionSndTimeo    */
222 	SO_RCVTIMEO,				/* osl_Socket_OptionRcvTimeo    */
223 	SO_ERROR,					/* osl_Socket_OptionError       */
224 	SO_TYPE,					/* osl_Socket_OptionType        */
225 	TCP_NODELAY,				/* osl_Socket_OptionTcpNoDelay  */
226 	0							/* osl_Socket_OptionInvalid     */
227 };
228 
229 /* reverse map */
230 /* mfe: NOT USED
231 static oslSocketOption osl_SocketOptionFromNative(sal_uInt32 nativeType)
232 {
233 	oslSocketOption i= (oslSocketOption)0;
234 
235 	while(i != osl_Socket_OptionInvalid)
236 	{
237 		if(OptionMap[i] == nativeType)
238 			return i;
239 		i = (oslSocketOption) ( i + 1 );
240 	}
241 
242 	return i;
243 }
244 */
245 /* macros */
246 #define OPTION_TO_NATIVE(x)		OptionMap[x]
247 #define OPTION_FROM_NATIVE(y)		osl_SocketOptionFromNative(y)
248 
249 
250 /*****************************************************************************/
251 /* enum oslSocketOptionLevel */
252 /*****************************************************************************/
253 
254 static sal_uInt32 OptionLevelMap[]= {
255 	SOL_SOCKET,					/* osl_Socket_LevelSocket  */
256 	IPPROTO_TCP,				/* osl_Socket_LevelTcp     */
257 	0							/* osl_Socket_LevelInvalid */
258 };
259 
260 /* reverse map */
261 /* mfe: NOT USED
262 static oslSocketOptionLevel osl_SocketOptionLevelFromNative(sal_uInt32 nativeType)
263 {
264 	oslSocketOptionLevel i= (oslSocketOptionLevel)0;
265 
266 	while(i != osl_Socket_LevelInvalid)
267 	{
268 		if(OptionLevelMap[i] == nativeType)
269 			return i;
270 		i = (oslSocketOptionLevel) ( i + 1 );
271 	}
272 
273 	return i;
274 }
275 */
276 /* macros */
277 #define OPTION_LEVEL_TO_NATIVE(x)		OptionLevelMap[x]
278 #define OPTION_LEVEL_FROM_NATIVE(y)		osl_SocketOptionLevelFromNative(y)
279 
280 /*****************************************************************************/
281 /* enum oslSocketMsgFlag */
282 /*****************************************************************************/
283 
284 static sal_uInt32 SocketMsgFlagMap[]= {
285 	0,							/* osl_Socket_MsgNormal    */
286 	MSG_OOB,					/* osl_Socket_MsgOOB       */
287 	MSG_PEEK,					/* osl_Socket_MsgPeek      */
288 	MSG_DONTROUTE,				/* osl_Socket_MsgDontRoute */
289 	MSG_MAXIOVLEN,				/* osl_Socket_MsgMaxIOVLen */
290 	0							/* osl_Socket_MsgInvalid   */
291 };
292 
293 /* reverse map */
294 /* mfe: NOT USED
295 static oslSocketMsgFlag osl_SocketMsgFlagFromNative(sal_uInt32 nativeType)
296 {
297 	oslSocketMsgFlag i= (oslSocketMsgFlag)0;
298 
299 	while(i != osl_Socket_MsgInvalid)
300 	{
301 		if(SocketMsgFlagMap[i] == nativeType)
302 			return i;
303 		i = (oslSocketMsgFlag) ( i + 1 );
304 	}
305 
306 	return i;
307 }
308 */
309 
310 /* macros */
311 #define MSG_FLAG_TO_NATIVE(x)		SocketMsgFlagMap[x]
312 #define MSG_FLAG_FROM_NATIVE(y)		osl_SocketMsgFlagFromNative(y)
313 
314 
315 /*****************************************************************************/
316 /* enum oslSocketDirection */
317 /*****************************************************************************/
318 
319 static sal_uInt32 SocketDirection[]= {
320 	SD_RECEIVE,					/* osl_Socket_DirRead      */
321 	SD_SEND,					/* osl_Socket_DirWrite     */
322 	SD_BOTH,					/* osl_Socket_DirReadWrite */
323 	0							/* osl_Socket_DirInvalid   */
324 };
325 
326 /* reverse map */
327 /* mfe: NOT USED
328 static oslSocketDirection osl_SocketDirectionFromNative(sal_uInt32 nativeType)
329 {
330 	oslSocketDirection i= (oslSocketDirection)0;
331 
332 	while(i != osl_Socket_DirInvalid)
333 	{
334 		if(SocketDirection[i] == nativeType)
335 			return i;
336 		i = (oslSocketDirection) ( i + 1 );
337 	}
338 
339 	return i;
340 }
341 */
342 
343 /* macros */
344 #define DIRECTION_TO_NATIVE(x)		SocketDirection[x]
345 #define DIRECTION_FROM_NATIVE(y)	osl_SocketDirectionFromNative(y)
346 
347 /*****************************************************************************/
348 /* enum oslSocketError */
349 /*****************************************************************************/
350 
351 static struct
352 {
353 	int            errcode;
354 	oslSocketError error;
355 } SocketError[]= {
356 	{ 0,			   osl_Socket_E_None 			  }, /* no error */
357 	{ ENOTSOCK,		   osl_Socket_E_NotSocket 		  }, /* Socket operation on non-socket */
358 	{ EDESTADDRREQ,	   osl_Socket_E_DestAddrReq 	  }, /* Destination address required */
359 	{ EMSGSIZE,		   osl_Socket_E_MsgSize 		  }, /* Message too long */
360 	{ EPROTOTYPE,	   osl_Socket_E_Prototype 		  }, /* Protocol wrong type for socket */
361 	{ ENOPROTOOPT,	   osl_Socket_E_NoProtocol 		  }, /* Protocol not available */
362 	{ EPROTONOSUPPORT, osl_Socket_E_ProtocolNoSupport }, /* Protocol not supported */
363 	{ ESOCKTNOSUPPORT, osl_Socket_E_TypeNoSupport 	  }, /* Socket type not supported */
364 	{ EOPNOTSUPP,	   osl_Socket_E_OpNotSupport 	  }, /* Operation not supported on socket */
365 	{ EPFNOSUPPORT,	   osl_Socket_E_PfNoSupport 	  }, /* Protocol family not supported */
366 	{ EAFNOSUPPORT,	   osl_Socket_E_AfNoSupport 	  }, /* Address family not supported by */
367 					   									 /* protocol family */
368 	{ EADDRINUSE,	   osl_Socket_E_AddrInUse 		  }, /* Address already in use */
369 	{ EADDRNOTAVAIL,   osl_Socket_E_AddrNotAvail 	  }, /* Can't assign requested address */
370 	{ ENETDOWN,		   osl_Socket_E_NetDown 		  }, /* Network is down */
371 	{ ENETUNREACH,	   osl_Socket_E_NetUnreachable    }, /* Network is unreachable */
372 	{ ENETRESET,	   osl_Socket_E_NetReset 		  }, /* Network dropped connection because */
373 					   								 	 /* of reset */
374 	{ ECONNABORTED,	   osl_Socket_E_ConnAborted 	  }, /* Software caused connection abort */
375 	{ ECONNRESET,	   osl_Socket_E_ConnReset 		  }, /* Connection reset by peer */
376 	{ ENOBUFS,		   osl_Socket_E_NoBufferSpace 	  }, /* No buffer space available */
377 	{ EISCONN,		   osl_Socket_E_IsConnected 	  }, /* Socket is already connected */
378 	{ ENOTCONN,		   osl_Socket_E_NotConnected 	  }, /* Socket is not connected */
379 	{ ESHUTDOWN,	   osl_Socket_E_Shutdown 		  }, /* Can't send after socket shutdown */
380 	{ ETOOMANYREFS,	   osl_Socket_E_TooManyRefs 	  }, /* Too many references: can't splice */
381 	{ ETIMEDOUT,	   osl_Socket_E_TimedOut 		  }, /* Connection timed out */
382 	{ ECONNREFUSED,	   osl_Socket_E_ConnRefused 	  }, /* Connection refused */
383 	{ EHOSTDOWN,	   osl_Socket_E_HostDown 		  }, /* Host is down */
384 	{ EHOSTUNREACH,	   osl_Socket_E_HostUnreachable   }, /* No route to host */
385 	{ EWOULDBLOCK,	   osl_Socket_E_WouldBlock 		  }, /* call would block on non-blocking socket */
386 	{ EALREADY,		   osl_Socket_E_Already 		  }, /* operation already in progress */
387 	{ EINPROGRESS,	   osl_Socket_E_InProgress 		  }, /* operation now in progress */
388 	{ EAGAIN,		   osl_Socket_E_WouldBlock 		  }, /* same as EWOULDBLOCK */
389 	{ -1,		   	   osl_Socket_E_InvalidError      }
390 };
391 
392 /* map */
393 /* mfe: NOT USED
394 static int osl_NativeFromSocketError(oslSocketError errorCode)
395 {
396 	int i = 0;
397 
398 	while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
399 		   (SocketError[i].error != errorCode)) i++;
400 
401 	return SocketError[i].errcode;
402 }
403 */
404 
405 /* reverse map */
406 static oslSocketError osl_SocketErrorFromNative(int nativeType)
407 {
408 	int i = 0;
409 
410 	while ((SocketError[i].error != osl_Socket_E_InvalidError) &&
411 		   (SocketError[i].errcode != nativeType)) i++;
412 
413 	return SocketError[i].error;
414 }
415 
416 /* macros */
417 #define ERROR_TO_NATIVE(x)		osl_NativeFromSocketError(x)
418 #define ERROR_FROM_NATIVE(y)	osl_SocketErrorFromNative(y)
419 
420 /*****************************************************************************/
421 /* local function prototypes */
422 /*****************************************************************************/
423 
424 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
425 	const sal_Char* pszDottedAddr, sal_Int32 Port);
426 
427 oslSocketAddr SAL_CALL osl_psz_createIpxSocketAddr (
428 	const sal_Char NetNumber[4],
429 	const sal_Char NodeNumber[6],
430 	sal_uInt32 SocketNumber);
431 
432 oslHostAddr SAL_CALL osl_psz_createHostAddr (
433 	const sal_Char *pszHostname, const oslSocketAddr Addr);
434 
435 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (
436 	const sal_Char *pszHostname);
437 
438 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (
439 	const oslHostAddr Addr);
440 
441 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
442 	sal_Char *pBuffer, sal_uInt32 nBufLen);
443 
444 oslSocketAddr SAL_CALL osl_psz_resolveHostname (
445 	const sal_Char* pszHostname);
446 
447 sal_Int32 SAL_CALL osl_psz_getServicePort (
448 	const sal_Char* pszServicename, const sal_Char* pszProtocol);
449 
450 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr (
451 	oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
452 
453 oslSocketResult	SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr (
454 	oslSocketAddr Addr, sal_Char *pBuffer, sal_uInt32 BufferSize);
455 
456 void SAL_CALL osl_psz_getLastSocketErrorDescription (
457 	oslSocket Socket, sal_Char* pBuffer, sal_uInt32 BufferSize);
458 
459 /*****************************************************************************/
460 /* osl_create/destroy-SocketImpl */
461 /*****************************************************************************/
462 
463 #if OSL_DEBUG_LEVEL > 1
464 static sal_uInt32 g_nSocketImpl = 0;
465 static sal_uInt32 g_nSocketAddr = 0;
466 
467 /* sorry, must be implemented otherwise */
468 #if 0
469 struct LeakWarning
470 {
471 	~LeakWarning()
472 	{
473 		if( g_nSocketImpl )
474 			OSL_TRACE( "sal_socket: %d socket instances leak\n" , g_nSocketImpl );
475 		if( g_nSocketAddr )
476 			OSL_TRACE( "sal_socket: %d socket address instances leak\n" , g_nSocketAddr );
477 	}
478 };
479 LeakWarning socketWarning;
480 #endif
481 
482 #endif /* OSL_DEBUG_LEVEL */
483 
484 
485 oslSocket __osl_createSocketImpl(int Socket)
486 {
487 	oslSocket pSocket;
488 
489 	pSocket = (oslSocket)calloc(1, sizeof(struct oslSocketImpl));
490 
491 	pSocket->m_Socket = Socket;
492     pSocket->m_nLastError = 0;
493     pSocket->m_CloseCallback = 0;
494     pSocket->m_CallbackArg = 0;
495 	pSocket->m_nRefCount = 1;
496 
497 #if defined(LINUX)
498     pSocket->m_bIsAccepting = sal_False;
499 #endif
500 
501 #if OSL_DEBUG_LEVEL > 1
502 	g_nSocketImpl ++;
503 #endif
504 	return pSocket;
505 }
506 
507 void __osl_destroySocketImpl(oslSocket Socket)
508 {
509 	if ( Socket != NULL)
510 		free((struct oslSocketImpl *) Socket);
511 #if OSL_DEBUG_LEVEL > 1
512 	g_nSocketImpl --;
513 #endif
514 }
515 
516 static oslSocketAddr __osl_createSocketAddr(  )
517 {
518 	oslSocketAddr pAddr = (oslSocketAddr) rtl_allocateZeroMemory( sizeof( struct oslSocketAddrImpl ));
519 #if OSL_DEBUG_LEVEL > 1
520 	g_nSocketAddr ++;
521 #endif
522 	return pAddr;
523 }
524 
525 static oslSocketAddr __osl_createSocketAddrWithFamily(
526 	oslAddrFamily family, sal_Int32 port, sal_uInt32 nAddr )
527 {
528 	oslSocketAddr pAddr;
529 
530 	OSL_ASSERT( family == osl_Socket_FamilyInet );
531 
532 	pAddr = __osl_createSocketAddr();
533 	switch( family )
534 	{
535 	case osl_Socket_FamilyInet:
536 	{
537 		struct sockaddr_in* pInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
538 
539 		pInetAddr->sin_family = FAMILY_TO_NATIVE(osl_Socket_FamilyInet);
540 		pInetAddr->sin_addr.s_addr = nAddr;
541 		pInetAddr->sin_port = (sal_uInt16)(port&0xffff);
542 		break;
543    	}
544 	default:
545 		pAddr->m_sockaddr.sa_family = FAMILY_TO_NATIVE(family);
546 	}
547 	return pAddr;
548 }
549 
550 static oslSocketAddr __osl_createSocketAddrFromSystem( struct sockaddr *pSystemSockAddr )
551 {
552 	oslSocketAddr pAddr = __osl_createSocketAddr();
553 	memcpy( &(pAddr->m_sockaddr), pSystemSockAddr, sizeof( struct sockaddr ) );
554 	return pAddr;
555 }
556 
557 static void __osl_destroySocketAddr( oslSocketAddr addr )
558 {
559 #if OSL_DEBUG_LEVEL > 1
560 	g_nSocketAddr --;
561 #endif
562 	rtl_freeMemory( addr );
563 }
564 
565 /*****************************************************************************/
566 /* osl_createEmptySocketAddr */
567 /*****************************************************************************/
568 oslSocketAddr SAL_CALL osl_createEmptySocketAddr(oslAddrFamily Family)
569 {
570 	oslSocketAddr pAddr = 0;
571 
572 	/* is it an internet-Addr? */
573 	if (Family == osl_Socket_FamilyInet)
574 	{
575 		pAddr = __osl_createSocketAddrWithFamily(Family, 0 , htonl(INADDR_ANY) );
576 	}
577 	else
578 	{
579 		pAddr = __osl_createSocketAddrWithFamily( Family , 0 , 0 );
580 	}
581 
582 	return pAddr;
583 }
584 
585 /*****************************************************************************/
586 /* osl_copySocketAddr */
587 /*****************************************************************************/
588 oslSocketAddr SAL_CALL osl_copySocketAddr(oslSocketAddr Addr)
589 {
590 	oslSocketAddr pCopy = 0;
591 	if (Addr)
592 	{
593 		pCopy = __osl_createSocketAddr();
594 
595 		if (pCopy)
596 			memcpy(&(pCopy->m_sockaddr),&(Addr->m_sockaddr), sizeof(struct sockaddr));
597 	}
598 	return pCopy;
599 }
600 
601 /*****************************************************************************/
602 /* osl_isEqualSocketAddr */
603 /*****************************************************************************/
604 sal_Bool SAL_CALL osl_isEqualSocketAddr (
605 	oslSocketAddr Addr1,
606 	oslSocketAddr Addr2)
607 {
608     OSL_ASSERT((0 != Addr1) && (0 != Addr2));
609     if ((0 != Addr1) || (0 != Addr2))
610     {
611       struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
612       struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
613 
614       if (pAddr1->sa_family == pAddr2->sa_family)
615       {
616           switch (pAddr1->sa_family)
617           {
618 			case AF_INET:
619             {
620 				struct sockaddr_in* pInetAddr1= (struct sockaddr_in*)pAddr1;
621 				struct sockaddr_in* pInetAddr2= (struct sockaddr_in*)pAddr2;
622 
623 				if ((pInetAddr1->sin_family == pInetAddr2->sin_family) &&
624 					(pInetAddr1->sin_addr.s_addr == pInetAddr2->sin_addr.s_addr) &&
625 					(pInetAddr1->sin_port == pInetAddr2->sin_port))
626                   return (sal_True);
627             }
628 
629 			default:
630             {
631 				return (memcmp(pAddr1, pAddr2, sizeof(struct sockaddr)) == 0);
632             }
633           }
634       }
635     }
636 	return (sal_False);
637 }
638 
639 /*****************************************************************************/
640 /* osl_createInetBroadcastAddr */
641 /*****************************************************************************/
642 oslSocketAddr SAL_CALL osl_createInetBroadcastAddr (
643 	rtl_uString *strDottedAddr,
644 	sal_Int32    Port)
645 {
646 	sal_uInt32    nAddr = OSL_INADDR_NONE;
647 	oslSocketAddr pAddr;
648 
649 	if (strDottedAddr && strDottedAddr->length)
650 	{
651 		/* Dotted host address for limited broadcast */
652 		rtl_String *pDottedAddr = NULL;
653 
654 		rtl_uString2String (
655 			&pDottedAddr, strDottedAddr->buffer, strDottedAddr->length,
656 			RTL_TEXTENCODING_UTF8, OUSTRING_TO_OSTRING_CVTFLAGS);
657 
658 		nAddr = inet_addr (pDottedAddr->buffer);
659 		rtl_string_release (pDottedAddr);
660 	}
661 
662 	if (nAddr != OSL_INADDR_NONE)
663 	{
664 		/* Limited broadcast */
665 		nAddr = ntohl(nAddr);
666 		if (IN_CLASSA(nAddr))
667 		{
668 			nAddr &= IN_CLASSA_NET;
669 			nAddr |= IN_CLASSA_HOST;
670 		}
671 		else if (IN_CLASSB(nAddr))
672 		{
673 			nAddr &= IN_CLASSB_NET;
674 			nAddr |= IN_CLASSB_HOST;
675 		}
676 		else if (IN_CLASSC(nAddr))
677 		{
678 			nAddr &= IN_CLASSC_NET;
679 			nAddr |= IN_CLASSC_HOST;
680 		}
681 		else
682 		{
683 			/* No broadcast in class D */
684 			return ((oslSocketAddr)NULL);
685 		}
686 		nAddr = htonl(nAddr);
687 	}
688 
689 	pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port), nAddr );
690 	return pAddr;
691 }
692 
693 /*****************************************************************************/
694 /* osl_createInetSocketAddr */
695 /*****************************************************************************/
696 oslSocketAddr SAL_CALL osl_createInetSocketAddr (
697 	rtl_uString *ustrDottedAddr,
698 	sal_Int32    Port)
699 {
700     rtl_String* strDottedAddr=0;
701     oslSocketAddr Addr;
702     sal_Char* pszDottedAddr=0;
703 
704     if ( ustrDottedAddr != 0 )
705     {
706         rtl_uString2String( &strDottedAddr,
707                             rtl_uString_getStr(ustrDottedAddr),
708                             rtl_uString_getLength(ustrDottedAddr),
709                             RTL_TEXTENCODING_UTF8,
710                             OUSTRING_TO_OSTRING_CVTFLAGS);
711         pszDottedAddr = rtl_string_getStr(strDottedAddr);
712     }
713 
714 
715     Addr = osl_psz_createInetSocketAddr(pszDottedAddr, Port);
716 
717     if ( strDottedAddr != 0 )
718     {
719         rtl_string_release(strDottedAddr);
720     }
721 
722     return Addr;
723 }
724 
725 oslSocketAddr SAL_CALL osl_psz_createInetSocketAddr (
726 	const sal_Char* pszDottedAddr,
727 	sal_Int32       Port)
728 {
729 	oslSocketAddr pAddr = 0;
730 	sal_Int32 Addr = inet_addr(pszDottedAddr);
731 	if(Addr != -1)
732 	{
733 		/* valid dotted addr */
734 		pAddr = __osl_createSocketAddrWithFamily( osl_Socket_FamilyInet, htons(Port) , Addr );
735 	}
736 	return pAddr;
737 }
738 
739 /*****************************************************************************/
740 /* osl_setAddrOfSocketAddr */
741 /*****************************************************************************/
742 oslSocketResult SAL_CALL osl_setAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence *pByteSeq )
743 {
744 	oslSocketResult res = osl_Socket_Error;
745 
746 	OSL_ASSERT( pAddr );
747 	OSL_ASSERT( pByteSeq );
748 
749 	if( pAddr && pByteSeq )
750 	{
751 		struct sockaddr_in * pSystemInetAddr;
752 
753 		OSL_ASSERT( pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE( osl_Socket_FamilyInet ) );
754 		OSL_ASSERT( pByteSeq->nElements == 4 );
755 
756 		pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
757 		memcpy( &(pSystemInetAddr->sin_addr) , pByteSeq->elements , 4 );
758 		res = osl_Socket_Ok;
759 	}
760 	return res;
761 }
762 
763 /*****************************************************************************/
764 /* osl_getAddrOfSocketAddr */
765 /*****************************************************************************/
766 oslSocketResult SAL_CALL osl_getAddrOfSocketAddr( oslSocketAddr pAddr, sal_Sequence **ppByteSeq )
767 {
768 	oslSocketResult res = osl_Socket_Error;
769 
770 	OSL_ASSERT( pAddr );
771 	OSL_ASSERT( ppByteSeq );
772 
773 	if( pAddr && ppByteSeq )
774 	{
775 		struct sockaddr_in * pSystemInetAddr = (struct sockaddr_in * ) &(pAddr->m_sockaddr);
776 		rtl_byte_sequence_constructFromArray( ppByteSeq , (sal_Int8 *) &(pSystemInetAddr->sin_addr),4);
777 		res = osl_Socket_Ok;
778 	}
779 	return res;
780 }
781 
782 
783 /*****************************************************************************/
784 /* _osl_getFullQualifiedDomainName */
785 /*****************************************************************************/
786 
787 /** try to figure out a full-qualified hostname, by adding the current domain
788     as given by the domainname program to the given hostname.
789 	This function MUST NOT call gethostbyname since pHostName allready points
790 	to data returned by gethostname and would be garbled: use gethostname_r
791 	instead!
792  */
793 
794 /* wrap around different interfaces to reentrant gethostbyname */
795 static struct hostent* _osl_gethostbyname_r (
796 	const char *name, struct hostent *result,
797 	char *buffer, int buflen, int *h_errnop)
798 {
799 #if defined(LINUX) || (defined(FREEBSD) && (__FreeBSD_version >= 601103))
800 	struct hostent *__result; /* will be the same as result */
801 	int __error;
802 	__error = gethostbyname_r (name, result, buffer, buflen,
803 				 &__result, h_errnop);
804 	return __error ? NULL : __result ;
805 #else
806 	return gethostbyname_r( name, result, buffer, buflen, h_errnop);
807 #endif
808 }
809 
810 static sal_Bool  _osl_getDomainName (sal_Char *buffer, sal_Int32 bufsiz)
811 {
812 	sal_Bool result;
813 	int      p[2];
814 
815     result = sal_False;
816 	if (pipe (p) == 0)
817 	{
818 		pid_t pid;
819         int nStatus;
820 
821 		pid = fork();
822 		if (pid == 0)
823 		{
824 			char *argv[] =
825 			{
826 				"/bin/domainname",
827 				NULL
828 			};
829 
830 			close (p[0]);
831 			dup2  (p[1], 1);
832 			close (p[1]);
833 
834 			execv ("/bin/domainname", argv);
835             // arriving here means exec failed
836             _exit(-1);
837 		}
838 		else if (pid > 0)
839 		{
840 			sal_Int32 k = 0, n = bufsiz;
841 
842 			close (p[1]);
843 			if ((k = read (p[0], buffer, n - 1)) > 0)
844 			{
845 				buffer[k] = 0;
846 				if (buffer[k - 1] == '\n')
847 					buffer[k - 1] = 0;
848 				result = sal_True;
849 			}
850 			close (p[0]);
851             waitpid (pid, &nStatus, 0);
852 		}
853 		else
854 		{
855 			close (p[0]);
856 			close (p[1]);
857 		}
858 	}
859 	return (result);
860 }
861 
862 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
863 {
864 #	define DOMAINNAME_LENGTH 512
865 	sal_uInt32 			nLengthOfHostName;
866 	static sal_uInt32 	nLengthOfDomainName = 0;
867 	static sal_Char    *pDomainName = NULL;
868 
869 	sal_Char  *pFullQualifiedName;
870 #if 0  /* OBSOLETE */
871 	FILE      *pPipeToDomainnameExe;
872 #endif /* OBSOLETE */
873 
874 	/* get a '\0' terminated domainname */
875 
876 	/* read default domainname default from environment */
877 	if (nLengthOfDomainName == 0)
878 	{
879 	    sal_Char *pEnvDomain;
880 
881 	    pEnvDomain = getenv ("STAR_OVERRIDE_DOMAINNAME");
882 		if (pEnvDomain)
883 		{
884 		    pDomainName = strdup (pEnvDomain);
885 		    nLengthOfDomainName = strlen (pDomainName);
886 		}
887 	}
888 
889 #if 1  /* NEW */
890 	if (nLengthOfDomainName == 0)
891 	{
892 		sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
893 
894         pDomainNameBuffer[0] = '\0';
895 
896 		if (_osl_getDomainName (pDomainNameBuffer, DOMAINNAME_LENGTH))
897 		{
898 			pDomainName = strdup (pDomainNameBuffer);
899 			nLengthOfDomainName = strlen (pDomainName);
900 		}
901 	}
902 
903 #endif /* NEW */
904 #if 0  /* OBSOLETE */
905 #ifdef SCO
906 
907 	/* call 'domainname > /usr/tmp/some-tmp-file', since
908 	   popen read pclose do block or core-dump,
909 	   (even the pipe-stuff that comes with pthreads) */
910 	if (nLengthOfDomainName == 0)
911 	{
912 		sal_Char  tmp_name[ L_tmpnam ];
913         FILE 	 *tmp_file;
914 		sal_Char  domain_call [ L_tmpnam + 16 ] = "domainname > ";
915 
916         tmp_name[0] = '\0';
917 
918 		tmpnam ( tmp_name );
919 		strcat ( domain_call, tmp_name );
920 		if (   (system ( domain_call ) == 0)
921 			&& ((tmp_file = fopen( tmp_name, "r" )) != NULL ) )
922 		{
923 			sal_Char  pDomainNameBuffer[ DOMAINNAME_LENGTH ];
924 
925             pDomainNameBuffer[0] = '\0';
926 
927 			if ( fgets ( pDomainNameBuffer, DOMAINNAME_LENGTH, tmp_file ) )
928 			{
929 				pDomainName = strdup( pDomainNameBuffer );
930 				nLengthOfDomainName = strlen( pDomainName );
931 				if (   ( nLengthOfDomainName > 0 )
932 					&& ( pDomainName[ nLengthOfDomainName - 1] == '\n' ) )
933 					pDomainName[ --nLengthOfDomainName ] = '\0';
934 			}
935 			fclose ( tmp_file );
936 		}
937 		unlink( tmp_name );
938 	}
939 
940 #else /* !SCO */
941 
942 	/* read the domainname from pipe to the program domainname */
943 	if (   (nLengthOfDomainName == 0)
944 		&& (pPipeToDomainnameExe = popen( "domainname", "r")) )
945 	{
946 		sal_Char  c;
947 		sal_Char  pDomainNameBuffer[ DOMAINNAME_LENGTH ];
948 		sal_Char *pDomainNamePointer;
949 
950         pDomainNameBuffer[0] = '\0';
951 
952 		pDomainNamePointer = pDomainNameBuffer;
953     	while (    ((c = getc( pPipeToDomainnameExe )) != EOF)
954 				&& (nLengthOfDomainName < (DOMAINNAME_LENGTH - 1)) )
955         {
956         	if (! isspace(c))
957 			{
958 				 nLengthOfDomainName++ ;
959            		*pDomainNamePointer++ = (sal_Char)c;
960 			}
961 		}
962         *pDomainNamePointer = '\0';
963 		pDomainName = strdup( pDomainNameBuffer );
964 
965 		pclose( pPipeToDomainnameExe );
966 	}
967 
968 #endif /* !SCO */
969 #endif /* OBSOLETE */
970 
971 	/* compose hostname and domainname */
972 	nLengthOfHostName = strlen( pHostName );
973 	pFullQualifiedName = (sal_Char*) malloc( (nLengthOfHostName + 1
974 							+ nLengthOfDomainName + 1) * sizeof(sal_Char) );
975 	memcpy( pFullQualifiedName, pHostName,
976 		(nLengthOfHostName + 1) * sizeof(sal_Char) );
977 
978 	if ( nLengthOfDomainName > 0 )
979 	{
980 		/* fqdn = hostname + '.' + domainname + '\0' */
981 		pFullQualifiedName[ nLengthOfHostName ] = '.';
982 		memcpy( pFullQualifiedName + nLengthOfHostName + 1, pDomainName,
983 			nLengthOfDomainName + 1 );
984 	}
985 
986 	/* check whether full-qualified name and hostname point to the same host
987 	 * should almost always be true */
988 	if ( nLengthOfDomainName > 0 )
989 	{
990 		struct hostent *pQualifiedHostByName;
991 		struct hostent *pHostByName;
992 		sal_Bool        bHostsAreEqual;
993 
994 		/* buffer for calls to reentrant version of gethostbyname */
995 		struct hostent 	aHostByName, aQualifiedHostByName;
996 		sal_Char		pHostBuffer[ MAX_HOSTBUFFER_SIZE ];
997         sal_Char        pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
998 		int		nErrorNo;
999 
1000         pHostBuffer[0] = '\0';
1001         pQualifiedHostBuffer[0] = '\0';
1002 
1003         /* get list of addresses */
1004 		pQualifiedHostByName = _osl_gethostbyname_r (
1005 			pFullQualifiedName,
1006 			&aQualifiedHostByName, pQualifiedHostBuffer,
1007 			sizeof(pQualifiedHostBuffer), &nErrorNo );
1008 		pHostByName = _osl_gethostbyname_r (
1009 			pHostName,
1010 			&aHostByName, pHostBuffer,
1011 			sizeof(pHostBuffer), &nErrorNo );
1012 
1013 		/* compare addresses */
1014 		bHostsAreEqual = sal_False;
1015 		if ( pQualifiedHostByName && pHostByName )
1016 		{
1017 			sal_Char **p, **q;
1018 			struct in_addr in;
1019 
1020 			/* lists are expected to be (very) short */
1021 			for ( p = pQualifiedHostByName->h_addr_list; *p != NULL; p++ )
1022 			{
1023 				for ( q = pHostByName->h_addr_list; *q != NULL; q++ )
1024 				{
1025 					/* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1026 					if ( memcmp( *p, *q, sizeof(in.s_addr) ) == 0 )
1027 					{
1028 						bHostsAreEqual = sal_True;
1029 						break;
1030 					}
1031 				}
1032 				if ( bHostsAreEqual )
1033 					break;
1034 			}
1035 		}
1036 
1037 		/* very strange case, but have to believe it: reduce the
1038 		 * full qualified name to the unqualified host name */
1039 		if ( !bHostsAreEqual )
1040 		{
1041 			OSL_TRACE("_osl_getFullQualifiedDomainName: "
1042 					  "suspect FQDN: %s\n", pFullQualifiedName);
1043 
1044 			pFullQualifiedName[ nLengthOfHostName ] = '\0';
1045 			pFullQualifiedName = (sal_Char*)realloc ( pFullQualifiedName,
1046 								(nLengthOfHostName + 1) * sizeof( sal_Char ));
1047 		}
1048 	}
1049 
1050 	/* always return a hostname looked up as carefully as possible
1051 	 * this string must be freed by the caller */
1052 	return pFullQualifiedName;
1053 }
1054 
1055 /*****************************************************************************/
1056 /* _osl_isFullQualifiedDomainName */
1057 /*****************************************************************************/
1058 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
1059 {
1060 	/* a FQDN (aka 'hostname.domain.top_level_domain' )
1061 	 * is a name which contains a dot '.' in it ( would
1062 	 * match as well for 'hostname.' but is good enough
1063 	 * for now )*/
1064 	return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
1065 }
1066 
1067 /*****************************************************************************/
1068 /* oslHostAddr */
1069 /*****************************************************************************/
1070 struct oslHostAddrImpl
1071 {
1072 	sal_Char        *pHostName;
1073 	oslSocketAddr   pSockAddr;
1074 };
1075 
1076 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
1077 {
1078 	oslHostAddr pAddr= NULL;
1079 	oslSocketAddr pSockAddr = 0;
1080 
1081 	sal_Char        *cn;
1082 
1083 	if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
1084 		return ((oslHostAddr)NULL);
1085 
1086 	if (_osl_isFullQualifiedDomainName(he->h_name))
1087 	{
1088 		cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1089 		OSL_ASSERT(cn);
1090 		if (cn == NULL)
1091 			return ((oslHostAddr)NULL);
1092 
1093 		strcpy(cn, he->h_name);
1094 	}
1095 	else
1096 	{
1097 		cn =_osl_getFullQualifiedDomainName (he->h_name);
1098 		OSL_ASSERT(cn);
1099 		if (cn == NULL)
1100 			return ((oslHostAddr)NULL);
1101 	}
1102 
1103 	pSockAddr = __osl_createSocketAddr();
1104 	OSL_ASSERT(pSockAddr);
1105 	if (pSockAddr == NULL)
1106 	{
1107 		free(cn);
1108 		return ((oslHostAddr)NULL);
1109 	}
1110 
1111 	pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
1112 	if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1113 	{
1114 		struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
1115 		memcpy (
1116 			&(sin->sin_addr.s_addr),
1117 			he->h_addr_list[0],
1118 			he->h_length);
1119 	}
1120 	else
1121 	{
1122 		/* unknown address family */
1123 		/* future extensions for new families might be implemented here */
1124 
1125 		OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1126 		OSL_ASSERT(sal_False);
1127 
1128 		__osl_destroySocketAddr( pSockAddr );
1129 		free (cn);
1130 		return ((oslHostAddr)NULL);
1131 	}
1132 
1133 	pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1134 	OSL_ASSERT(pAddr);
1135 	if (pAddr == NULL)
1136 	{
1137 		__osl_destroySocketAddr( pSockAddr );
1138 		free (cn);
1139 		return ((oslHostAddr)NULL);
1140 	}
1141 
1142 	pAddr->pHostName= cn;
1143 	pAddr->pSockAddr= pSockAddr;
1144 
1145 	return pAddr;
1146 }
1147 
1148 /*****************************************************************************/
1149 /* osl_createHostAddr */
1150 /*****************************************************************************/
1151 oslHostAddr SAL_CALL osl_createHostAddr (
1152 	rtl_uString        *ustrHostname,
1153 	const oslSocketAddr Addr)
1154 {
1155     oslHostAddr HostAddr;
1156     rtl_String* strHostname=0;
1157     sal_Char* pszHostName=0;
1158 
1159     if ( ustrHostname != 0 )
1160     {
1161         rtl_uString2String( &strHostname,
1162                             rtl_uString_getStr(ustrHostname),
1163                             rtl_uString_getLength(ustrHostname),
1164                             RTL_TEXTENCODING_UTF8,
1165                             OUSTRING_TO_OSTRING_CVTFLAGS );
1166         pszHostName = rtl_string_getStr(strHostname);
1167     }
1168 
1169     HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
1170 
1171     if ( strHostname != 0 )
1172     {
1173         rtl_string_release(strHostname);
1174     }
1175 
1176     return HostAddr;
1177 }
1178 
1179 oslHostAddr SAL_CALL osl_psz_createHostAddr (
1180 	const sal_Char     *pszHostname,
1181 	const oslSocketAddr pAddr)
1182 {
1183 	oslHostAddr pHostAddr;
1184 	sal_Char            *cn;
1185 
1186 	OSL_ASSERT(pszHostname && pAddr);
1187 	if ((pszHostname == NULL) || (pAddr == NULL))
1188 		return ((oslHostAddr)NULL);
1189 
1190 	cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
1191 	OSL_ASSERT(cn);
1192 	if (cn == NULL)
1193 		return ((oslHostAddr)NULL);
1194 
1195 	strcpy (cn, pszHostname);
1196 
1197 	pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1198 	OSL_ASSERT(pHostAddr);
1199 	if (pHostAddr == NULL)
1200 	{
1201 		free (cn);
1202 		return ((oslHostAddr)NULL);
1203 	}
1204 
1205 	pHostAddr->pHostName= cn;
1206 	pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
1207 
1208 	return pHostAddr;
1209 }
1210 
1211 /*****************************************************************************/
1212 /* osl_createHostAddrByName */
1213 /*****************************************************************************/
1214 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
1215 {
1216     oslHostAddr HostAddr;
1217     rtl_String* strHostname=0;
1218     sal_Char* pszHostName=0;
1219 
1220     if ( ustrHostname != 0 )
1221     {
1222         rtl_uString2String( &strHostname,
1223                             rtl_uString_getStr(ustrHostname),
1224                             rtl_uString_getLength(ustrHostname),
1225                             RTL_TEXTENCODING_UTF8,
1226                             OUSTRING_TO_OSTRING_CVTFLAGS );
1227         pszHostName=rtl_string_getStr(strHostname);
1228     }
1229 
1230     HostAddr = osl_psz_createHostAddrByName(pszHostName);
1231 
1232     if ( strHostname != 0 )
1233     {
1234         rtl_string_release(strHostname);
1235     }
1236 
1237     return HostAddr;
1238 }
1239 
1240 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
1241 {
1242 	struct hostent *he;
1243         oslHostAddr	addr;
1244 
1245 	static oslMutex mutex = NULL;
1246 
1247 	if (mutex == NULL)
1248 		mutex = osl_createMutex();
1249 
1250 	osl_acquireMutex(mutex);
1251 
1252 	he = gethostbyname((sal_Char *)pszHostname);
1253 	addr = _osl_hostentToHostAddr (he);
1254 
1255 	osl_releaseMutex(mutex);
1256 
1257 	return addr;
1258 }
1259 
1260 /*****************************************************************************/
1261 /* osl_createHostAddrByAddr */
1262 /*****************************************************************************/
1263 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
1264 {
1265 	OSL_ASSERT(pAddr);
1266 
1267 	if (pAddr == NULL)
1268 		return ((oslHostAddr)NULL);
1269 
1270 	if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1271 	{
1272 		const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
1273 		struct hostent *he;
1274 
1275 		if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
1276 			return ((oslHostAddr)NULL);
1277 
1278 		he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
1279 						  sizeof (sin->sin_addr),
1280 						  sin->sin_family);
1281 		return _osl_hostentToHostAddr (he);
1282 	}
1283 
1284 	return ((oslHostAddr)NULL);
1285 }
1286 
1287 /*****************************************************************************/
1288 /* osl_copyHostAddr */
1289 /*****************************************************************************/
1290 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
1291 {
1292 	OSL_ASSERT(pAddr);
1293 
1294 	if (pAddr)
1295 		return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
1296 	else
1297 		return ((oslHostAddr)NULL);
1298 }
1299 
1300 /*****************************************************************************/
1301 /* osl_getHostnameOfHostAddr */
1302 /*****************************************************************************/
1303 void SAL_CALL osl_getHostnameOfHostAddr (
1304 	const oslHostAddr   Addr,
1305 	rtl_uString       **ustrHostname)
1306 {
1307     const sal_Char* pHostname=0;
1308 
1309     pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1310 
1311     rtl_uString_newFromAscii (ustrHostname, pHostname);
1312 
1313     return;
1314 }
1315 
1316 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1317 {
1318 	OSL_ASSERT(pAddr);
1319 
1320 	if (pAddr)
1321 		return pAddr->pHostName;
1322 	else
1323 		return NULL;
1324 }
1325 
1326 /*****************************************************************************/
1327 /* osl_getSocketAddrOfHostAddr */
1328 /*****************************************************************************/
1329 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1330 {
1331 	OSL_ASSERT(pAddr);
1332 
1333 	if (pAddr)
1334 		return ((oslSocketAddr)(pAddr->pSockAddr));
1335 	else
1336 		return NULL;
1337 }
1338 
1339 /*****************************************************************************/
1340 /* osl_destroyHostAddr */
1341 /*****************************************************************************/
1342 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1343 {
1344 	if (pAddr)
1345 	{
1346 		if (pAddr->pHostName)
1347 			free (pAddr->pHostName);
1348 		if (pAddr->pSockAddr)
1349 			osl_destroySocketAddr (pAddr->pSockAddr);
1350 		free (pAddr);
1351 	}
1352 }
1353 
1354 /*****************************************************************************/
1355 /* osl_getLocalHostname */
1356 /*****************************************************************************/
1357 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1358 {
1359     oslSocketResult Result;
1360     sal_Char pszHostname[1024];
1361 
1362     pszHostname[0] = '\0';
1363 
1364     Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1365 
1366     rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1367 
1368     return Result;
1369 }
1370 
1371 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1372 	sal_Char *pBuffer, sal_uInt32 nBufLen)
1373 {
1374 	static sal_Char LocalHostname[256] = "";
1375 
1376 	if (strlen(LocalHostname) == 0)
1377 	{
1378 		const sal_Char *pStr;
1379 
1380 #ifdef SYSV
1381 		struct utsname uts;
1382 
1383 		if (uname(&uts) < 0)
1384 			return osl_Socket_Error;
1385 
1386 		if ((strlen(uts.nodename) + 1) > nBufLen)
1387 			return osl_Socket_Error;
1388 
1389 		strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1390 #else  /* BSD compatible */
1391 
1392 		if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1393 			return osl_Socket_Error;
1394         LocalHostname[sizeof(LocalHostname)-1] = 0;
1395 #endif /* SYSV */
1396 
1397 		/* check if we have an FQDN */
1398     	if (strchr(LocalHostname, '.') == NULL)
1399         {
1400 			oslHostAddr Addr;
1401 
1402 			/* no, determine it via dns */
1403 			Addr = osl_psz_createHostAddrByName(LocalHostname);
1404 
1405 			if ((pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1406 			{
1407 #if 0  /* OBSOLETE */
1408 				sal_Char* pChr;
1409 #endif /* OBSOLETE */
1410 				strcpy(LocalHostname, pStr);
1411 
1412 #if 0  /* OBSOLETE */
1413 				/* already done by _osl_getFullQualifiedDomainName() with
1414 				   much better heuristics, so this may be contraproductive */
1415 
1416 				/* no FQDN, last try append domain name */
1417 		    	if ((pChr = strchr(LocalHostname, '.')) == NULL)
1418 		        {
1419                     FILE *fp;
1420 
1421 					pChr = &LocalHostname[strlen(LocalHostname)];
1422 
1423                     if ( (fp = popen("domainname", "r")) != 0 )
1424                     {
1425                         int c;
1426 
1427 						*pChr++ = '.';
1428 
1429                         while ((c = getc(fp)) != EOF)
1430                         {
1431                             if (! isspace(c))
1432                             	*pChr++ = (sal_Char)c;
1433                         }
1434 
1435                         *pChr = '\0';
1436 
1437                         fclose(fp);
1438                     }
1439                     else
1440 						LocalHostname[0] = '\0';
1441 				}
1442 #endif /* OBSOLETE */
1443 
1444 			}
1445 			osl_destroyHostAddr(Addr);
1446 		}
1447 	}
1448 
1449 	if (strlen(LocalHostname) > 0)
1450 	{
1451 		strncpy(pBuffer, LocalHostname, nBufLen);
1452 		pBuffer[nBufLen - 1] = '\0';
1453 
1454 		return osl_Socket_Ok;
1455 	}
1456 
1457 	return osl_Socket_Error;
1458 }
1459 
1460 /*****************************************************************************/
1461 /* osl_resolveHostname */
1462 /*****************************************************************************/
1463 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1464 {
1465     oslSocketAddr Addr;
1466     rtl_String* strHostname=0;
1467     sal_Char* pszHostName=0;
1468 
1469     if ( ustrHostname != 0 )
1470     {
1471         rtl_uString2String( &strHostname,
1472                             rtl_uString_getStr(ustrHostname),
1473                             rtl_uString_getLength(ustrHostname),
1474                             RTL_TEXTENCODING_UTF8,
1475                             OUSTRING_TO_OSTRING_CVTFLAGS );
1476         pszHostName = rtl_string_getStr(strHostname);
1477     }
1478 
1479 
1480     Addr = osl_psz_resolveHostname(pszHostName);
1481 
1482     if ( strHostname != 0 )
1483     {
1484         rtl_string_release(strHostname);
1485     }
1486 
1487 
1488     return Addr;
1489 }
1490 
1491 
1492 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1493 {
1494 	struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1495 
1496 	if (pAddr)
1497 	{
1498 		oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1499 
1500 		osl_destroyHostAddr(pAddr);
1501 
1502 		return (SockAddr);
1503 	}
1504 
1505 	return ((oslSocketAddr)NULL);
1506 }
1507 
1508 /*****************************************************************************/
1509 /* osl_getServicePort */
1510 /*****************************************************************************/
1511 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1512 {
1513     sal_Int32 nPort;
1514     rtl_String* strServicename=0;
1515     rtl_String* strProtocol=0;
1516     sal_Char* pszServiceName=0;
1517     sal_Char* pszProtocol=0;
1518 
1519     if ( ustrServicename != 0 )
1520     {
1521         rtl_uString2String( &strServicename,
1522                             rtl_uString_getStr(ustrServicename),
1523                             rtl_uString_getLength(ustrServicename),
1524                             RTL_TEXTENCODING_UTF8,
1525                             OUSTRING_TO_OSTRING_CVTFLAGS );
1526         pszServiceName = rtl_string_getStr(strServicename);
1527     }
1528 
1529     if ( ustrProtocol != 0 )
1530     {
1531         rtl_uString2String( &strProtocol,
1532                             rtl_uString_getStr(ustrProtocol),
1533                             rtl_uString_getLength(ustrProtocol),
1534                             RTL_TEXTENCODING_UTF8,
1535                             OUSTRING_TO_OSTRING_CVTFLAGS );
1536         pszProtocol = rtl_string_getStr(strProtocol);
1537     }
1538 
1539     nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1540 
1541     if ( strServicename != 0 )
1542     {
1543         rtl_string_release(strServicename);
1544     }
1545 
1546     if ( strProtocol != 0 )
1547     {
1548         rtl_string_release(strProtocol);
1549     }
1550 
1551 
1552     return nPort;
1553 }
1554 
1555 
1556 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1557 						const sal_Char* pszProtocol)
1558 {
1559 	struct servent* ps;
1560 
1561 	ps= getservbyname(pszServicename, pszProtocol);
1562 
1563 	if (ps != 0)
1564 		return ntohs(ps->s_port);
1565 
1566 	return OSL_INVALID_PORT;
1567 }
1568 
1569 /*****************************************************************************/
1570 /* osl_destroySocketAddr */
1571 /*****************************************************************************/
1572 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1573 {
1574 	__osl_destroySocketAddr( pAddr );
1575 }
1576 
1577 /*****************************************************************************/
1578 /* osl_getFamilyOfSocketAddr */
1579 /*****************************************************************************/
1580 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1581 {
1582 	OSL_ASSERT(pAddr);
1583 
1584 	if (pAddr)
1585 		return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1586 	else
1587 		return osl_Socket_FamilyInvalid;
1588 }
1589 
1590 /*****************************************************************************/
1591 /* osl_getInetPortOfSocketAddr */
1592 /*****************************************************************************/
1593 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1594 {
1595 	OSL_ASSERT(pAddr);
1596 	if( pAddr )
1597 	{
1598 		struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1599 
1600 		if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1601 			return ntohs(pSystemInetAddr->sin_port);
1602 	}
1603 	return OSL_INVALID_PORT;
1604 }
1605 
1606 /*****************************************************************************/
1607 /* osl_setInetPortOfSocketAddr */
1608 /*****************************************************************************/
1609 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1610 {
1611 	OSL_ASSERT(pAddr);
1612 	if( pAddr )
1613 	{
1614 		struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1615 		if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1616 		{
1617 			pSystemInetAddr->sin_port= htons((short)Port);
1618 			return sal_True;
1619 		}
1620 	}
1621 
1622 	/* this is not a inet-addr => can't set port */
1623 	return sal_False;
1624 }
1625 
1626 /*****************************************************************************/
1627 /* osl_getHostnameOfSocketAddr */
1628 /*****************************************************************************/
1629 oslSocketResult	SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1630 {
1631     oslSocketResult Result;
1632     sal_Char pszHostname[1024];
1633 
1634     pszHostname[0] = '\0';
1635 
1636     Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1637 
1638     rtl_uString_newFromAscii(ustrHostname,pszHostname);
1639 
1640     return Result;
1641 }
1642 
1643 
1644 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1645                                             sal_Char *pBuffer, sal_uInt32 BufferSize)
1646 {
1647 	oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1648 
1649 	if (pHostAddr)
1650 	{
1651 		strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1652 
1653 		pBuffer[BufferSize - 1] = '\0';
1654 
1655 		osl_destroyHostAddr(pHostAddr);
1656 
1657 		return osl_Socket_Ok;
1658 	}
1659 
1660 	return osl_Socket_Error;
1661 }
1662 
1663 /*****************************************************************************/
1664 /* osl_getDottedInetAddrOfSocketAddr */
1665 /*****************************************************************************/
1666 oslSocketResult	SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1667 {
1668     oslSocketResult Result;
1669     sal_Char pszDottedInetAddr[1024];
1670 
1671     pszDottedInetAddr[0] = '\0';
1672 
1673     Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1674 
1675     rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1676 
1677     return Result;
1678 
1679 }
1680 
1681 oslSocketResult	SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1682 												  sal_Char *pBuffer, sal_uInt32 BufferSize)
1683 {
1684 	OSL_ASSERT(pAddr);
1685 
1686 	if( pAddr )
1687 	{
1688 		struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1689 
1690 		if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1691 		{
1692 			strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1693 			pBuffer[BufferSize - 1] = '\0';
1694 
1695 			return osl_Socket_Ok;
1696 		}
1697 	}
1698 
1699 	return osl_Socket_Error;
1700 }
1701 
1702 #if 0  /* OBSOLETE */
1703 /*****************************************************************************/
1704 /* osl_getIpxNetNumber  */
1705 /*****************************************************************************/
1706 oslSocketResult SAL_CALL osl_getIpxNetNumber(oslSocketAddr Addr,
1707                                     oslSocketIpxNetNumber NetNumber)
1708 
1709 {
1710 	struct sockaddr_ipx* pAddr;
1711 
1712 	pAddr= (struct sockaddr_ipx*)Addr;
1713 
1714 	OSL_ASSERT(pAddr);
1715 
1716 	if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1717  	{
1718  		memcpy(NetNumber, pAddr->sa_netnum, sizeof(NetNumber));
1719 
1720   		return osl_Socket_Ok;
1721   	}
1722   	else
1723   		return osl_Socket_Error;
1724 }
1725 
1726 
1727 /*****************************************************************************/
1728 /* osl_getIpxNodeNumber  */
1729 /*****************************************************************************/
1730 oslSocketResult SAL_CALL osl_getIpxNodeNumber(oslSocketAddr Addr,
1731                                      oslSocketIpxNodeNumber NodeNumber)
1732 
1733 {
1734   	struct sockaddr_ipx* pAddr;
1735 
1736   	pAddr= (struct sockaddr_ipx*)Addr;
1737 
1738   	OSL_ASSERT(pAddr);
1739 
1740   	if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1741   	{
1742   		memcpy(NodeNumber, pAddr->sa_nodenum, sizeof(NodeNumber));
1743 
1744   		return osl_Socket_Ok;
1745   	}
1746   	else
1747   		return osl_Socket_Error;
1748 }
1749 
1750 
1751 /*****************************************************************************/
1752 /* osl_getIpxSocketNumber  */
1753 /*****************************************************************************/
1754 sal_Int32 SAL_CALL osl_getIpxSocketNumber(oslSocketAddr Addr)
1755 {
1756 	struct sockaddr_ipx* pAddr= (struct sockaddr_ipx*)Addr;
1757 	OSL_ASSERT(pAddr);
1758 
1759  	if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1760   		return pAddr->sa_socket;
1761   	else
1762   		return OSL_INVALID_IPX_SOCKET_NO;
1763 }
1764 
1765 #endif /* OBSOLETE */
1766 
1767 /*****************************************************************************/
1768 /* osl_createSocket  */
1769 /*****************************************************************************/
1770 oslSocket SAL_CALL osl_createSocket(oslAddrFamily	Family,
1771 						   oslSocketType	Type,
1772 						   oslProtocol		Protocol)
1773 {
1774 	int 		   Flags;
1775 	oslSocket pSocket;
1776 
1777 	/* alloc memory */
1778 	pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1779 
1780 	/* create socket */
1781 	pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1782 								TYPE_TO_NATIVE(Type),
1783 								PROTOCOL_TO_NATIVE(Protocol));
1784 
1785 	/* creation failed => free memory */
1786 	if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1787 	{
1788 	    OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1789 			      errno,
1790 			      strerror(errno));
1791 
1792 		__osl_destroySocketImpl((pSocket));
1793 		pSocket= 0;
1794 	}
1795 	else
1796 	{
1797 		/* set close-on-exec flag */
1798 		if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1799 		{
1800 			Flags |= FD_CLOEXEC;
1801 			if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1802             {
1803                 pSocket->m_nLastError=errno;
1804 				OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1805                           errno,
1806                           strerror(errno));
1807             }
1808 		}
1809         else
1810         {
1811             pSocket->m_nLastError=errno;
1812         }
1813 
1814 
1815 		pSocket->m_CloseCallback 	= NULL;
1816 		pSocket->m_CallbackArg	= NULL;
1817 	}
1818 
1819 	return pSocket;
1820 }
1821 
1822 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1823 {
1824 	osl_incrementInterlockedCount( &(pSocket->m_nRefCount ) );
1825 }
1826 
1827 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1828 {
1829 	if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
1830 	{
1831 #if defined(LINUX)
1832     if ( pSocket->m_bIsAccepting == sal_True )
1833     {
1834         OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1835         return;
1836     }
1837 #endif /* LINUX */
1838 		osl_closeSocket( pSocket );
1839 		__osl_destroySocketImpl( pSocket );
1840 	}
1841 }
1842 
1843 
1844 
1845 /*****************************************************************************/
1846 /* osl_closeSocket  */
1847 /*****************************************************************************/
1848 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1849 {
1850     int nRet;
1851     int nFD;
1852 
1853     /* socket already invalid */
1854 	if(pSocket==0)
1855 		return;
1856 
1857     pSocket->m_nLastError=0;
1858     nFD = pSocket->m_Socket;
1859 
1860     if (nFD == OSL_INVALID_SOCKET)
1861         return;
1862 
1863     pSocket->m_Socket = OSL_INVALID_SOCKET;
1864 
1865 #if defined(LINUX)
1866     pSocket->m_bIsInShutdown = sal_True;
1867 
1868     if ( pSocket->m_bIsAccepting == sal_True )
1869     {
1870         int nConnFD;
1871         union {
1872             struct sockaddr aSockAddr;
1873             struct sockaddr_in aSockAddrIn;
1874         } s;
1875         socklen_t nSockLen = sizeof(s.aSockAddr);
1876 
1877         nRet = getsockname(nFD, &s.aSockAddr, &nSockLen);
1878 #if OSL_DEBUG_LEVEL > 1
1879         if ( nRet < 0 )
1880         {
1881             perror("getsockname");
1882         }
1883 #endif /* OSL_DEBUG_LEVEL */
1884 
1885         if ( s.aSockAddr.sa_family == AF_INET )
1886         {
1887             if ( s.aSockAddrIn.sin_addr.s_addr == htonl(INADDR_ANY) )
1888             {
1889                 s.aSockAddrIn.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1890             }
1891 
1892             nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1893 #if OSL_DEBUG_LEVEL > 1
1894             if ( nConnFD < 0 )
1895             {
1896                 perror("socket");
1897             }
1898 #endif /* OSL_DEBUG_LEVEL */
1899 
1900             nRet = connect(nConnFD, &s.aSockAddr, sizeof(s.aSockAddr));
1901 #if OSL_DEBUG_LEVEL > 1
1902             if ( nRet < 0 )
1903             {
1904                 perror("connect");
1905             }
1906 #endif /* OSL_DEBUG_LEVEL */
1907             close(nConnFD);
1908         }
1909         pSocket->m_bIsAccepting = sal_False;
1910     }
1911 #endif /* LINUX */
1912 
1913 	/* registrierten Callback ausfuehren */
1914 	if (pSocket->m_CloseCallback != NULL)
1915 	{
1916 		pSocket->m_CloseCallback(pSocket->m_CallbackArg);
1917 	}
1918 
1919     nRet=close(nFD);
1920     if ( nRet != 0 )
1921     {
1922         pSocket->m_nLastError=errno;
1923         OSL_TRACE("closeSocket close error '%s'\n",strerror(errno));
1924     }
1925 
1926     pSocket->m_Socket = OSL_INVALID_SOCKET;
1927 }
1928 
1929 /*****************************************************************************/
1930 /* osl_getLocalAddrOfSocket  */
1931 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1932 /* are the same! I don't like it very much but see no other easy way to conceal */
1933 /* the struct sockaddr from the eyes of the user. */
1934 /*****************************************************************************/
1935 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1936 {
1937 	socklen_t AddrLen;
1938 	struct sockaddr Addr;
1939 	oslSocketAddr  pAddr;
1940 
1941 	if (pSocket == NULL) /* ENOTSOCK */
1942 		return ((oslSocketAddr)NULL);
1943 
1944 	AddrLen= sizeof(struct sockaddr);
1945 
1946 	if (getsockname(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1947 		return ((oslSocketAddr)NULL);
1948 
1949 	pAddr = __osl_createSocketAddrFromSystem( &Addr );
1950 	return pAddr;
1951 }
1952 
1953 /*****************************************************************************/
1954 /* osl_getPeerAddrOfSocket  */
1955 /*****************************************************************************/
1956 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1957 {
1958 	socklen_t AddrLen;
1959 	struct sockaddr Addr;
1960 
1961 	OSL_ASSERT(pSocket);
1962 	if ( pSocket == 0 )
1963 	{
1964 		return 0;
1965 	}
1966 
1967     pSocket->m_nLastError=0;
1968 	AddrLen= sizeof(struct sockaddr);
1969 
1970 	if(getpeername(pSocket->m_Socket, &Addr, &AddrLen) == OSL_SOCKET_ERROR)
1971     {
1972         pSocket->m_nLastError=errno;
1973 		return 0;
1974     }
1975 	return __osl_createSocketAddrFromSystem( &Addr );
1976 }
1977 
1978 /*****************************************************************************/
1979 /* osl_bindAddrToSocket  */
1980 /*****************************************************************************/
1981 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
1982 							 oslSocketAddr pAddr)
1983 {
1984     int nRet;
1985 
1986 	OSL_ASSERT(pSocket && pAddr );
1987 	if ( pSocket == 0 || pAddr == 0 )
1988 	{
1989 		return sal_False;
1990 	}
1991 
1992     pSocket->m_nLastError=0;
1993 
1994     nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
1995 
1996     if ( nRet == OSL_SOCKET_ERROR)
1997     {
1998         pSocket->m_nLastError=errno;
1999         return sal_False;
2000     }
2001 
2002 	return sal_True;
2003 }
2004 
2005 
2006 /*****************************************************************************/
2007 /* osl_listenOnSocket  */
2008 /*****************************************************************************/
2009 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
2010 						   sal_Int32 MaxPendingConnections)
2011 {
2012     int nRet;
2013 
2014 	OSL_ASSERT(pSocket);
2015 	if ( pSocket == 0 )
2016 	{
2017 		return sal_False;
2018 	}
2019 
2020     pSocket->m_nLastError=0;
2021 
2022     nRet = listen(pSocket->m_Socket,
2023                   MaxPendingConnections == -1 ?
2024                   SOMAXCONN :
2025                   MaxPendingConnections);
2026     if ( nRet == OSL_SOCKET_ERROR)
2027     {
2028         pSocket->m_nLastError=errno;
2029         return sal_False;
2030     }
2031 
2032     return sal_True;
2033 }
2034 
2035 
2036 /*****************************************************************************/
2037 /* osl_connectSocketTo  */
2038 /*****************************************************************************/
2039 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
2040 									oslSocketAddr pAddr,
2041 									const TimeValue* pTimeout)
2042 {
2043 	fd_set   WriteSet;
2044 	fd_set   ExcptSet;
2045 	int      ReadyHandles;
2046     struct timeval  tv;
2047 	oslSocketResult Result= osl_Socket_Ok;
2048 
2049 	OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
2050 
2051     if ( pSocket == 0 )
2052     {
2053         return osl_Socket_Error;
2054     }
2055 
2056     pSocket->m_nLastError=0;
2057 
2058 	if (osl_isNonBlockingMode(pSocket))
2059     {
2060 		if (connect(pSocket->m_Socket,
2061 				    &(pAddr->m_sockaddr),
2062 				    sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2063 			return osl_Socket_Ok;
2064 		else
2065 			if (errno == EWOULDBLOCK || errno == EINPROGRESS)
2066             {
2067                 pSocket->m_nLastError=EINPROGRESS;
2068 				return osl_Socket_InProgress;
2069             }
2070 
2071 
2072         pSocket->m_nLastError=errno;
2073         OSL_TRACE("can't connect : '%s'",strerror(errno));
2074 		return osl_Socket_Error;
2075 	}
2076 
2077 	/* set socket temporarily to non-blocking */
2078 	OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
2079 
2080 	/* initiate connect */
2081 	if(connect(pSocket->m_Socket,
2082 			   &(pAddr->m_sockaddr),
2083 			   sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2084 	{
2085 	   /* immediate connection */
2086 		osl_enableNonBlockingMode(pSocket, sal_False);
2087 
2088 		return osl_Socket_Ok;
2089     }
2090 	else
2091 	{
2092 	    /* really an error or just delayed? */
2093 	    if (errno != EINPROGRESS)
2094 	    {
2095             pSocket->m_nLastError=errno;
2096 			OSL_TRACE(
2097 				"osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2098 				errno, strerror(errno));
2099 
2100 			osl_enableNonBlockingMode(pSocket, sal_False);
2101 			return osl_Socket_Error;
2102 	    }
2103 	}
2104 
2105 
2106 	/* prepare select set for socket  */
2107 	FD_ZERO(&WriteSet);
2108 	FD_ZERO(&ExcptSet);
2109 	FD_SET(pSocket->m_Socket, &WriteSet);
2110 	FD_SET(pSocket->m_Socket, &ExcptSet);
2111 
2112 	/* prepare timeout */
2113 	if (pTimeout)
2114 	{
2115 		/* divide milliseconds into seconds and microseconds */
2116 		tv.tv_sec=	pTimeout->Seconds;
2117 		tv.tv_usec=	pTimeout->Nanosec / 1000L;
2118 	}
2119 
2120 	/* select */
2121     ReadyHandles= select(pSocket->m_Socket+1,
2122 						 0,
2123 						 PTR_FD_SET(WriteSet),
2124 						 PTR_FD_SET(ExcptSet),
2125 						 (pTimeout) ? &tv : 0);
2126 
2127 	if (ReadyHandles > 0)  /* connected */
2128 	{
2129 		if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
2130 		{
2131 			int nErrorCode = 0;
2132 			socklen_t nErrorSize = sizeof( nErrorCode );
2133 
2134 			int nSockOpt;
2135 
2136 			nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
2137 									&nErrorCode, &nErrorSize );
2138 			if ( (nSockOpt == 0) && (nErrorCode == 0))
2139 				Result = osl_Socket_Ok;
2140 			else
2141 				Result = osl_Socket_Error;
2142 		}
2143 		else
2144 		{
2145 			Result= osl_Socket_Error;
2146 		}
2147 	}
2148 	else if (ReadyHandles < 0)  /* error */
2149 	{
2150 	    if (errno == EBADF) /* most probably interrupted by close() */
2151 		{
2152 		    /* do not access pSockImpl because it is about to be or */
2153 		    /* already destroyed */
2154 		    return osl_Socket_Interrupted;
2155 		}
2156 		else
2157         {
2158             pSocket->m_nLastError=errno;
2159 		    Result= osl_Socket_Error;
2160         }
2161 	}
2162 	else    /* timeout */
2163 	{
2164         pSocket->m_nLastError=errno;
2165 	    Result= osl_Socket_TimedOut;
2166 	}
2167 
2168 	osl_enableNonBlockingMode(pSocket, sal_False);
2169 
2170 	return Result;
2171 }
2172 
2173 
2174 /*****************************************************************************/
2175 /* osl_acceptConnectionOnSocket  */
2176 /*****************************************************************************/
2177 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
2178 						oslSocketAddr* ppAddr)
2179 {
2180 	struct sockaddr Addr;
2181 	int Connection, Flags;
2182 	oslSocket pConnectionSockImpl;
2183 
2184 	socklen_t AddrLen = sizeof(struct sockaddr);
2185 	OSL_ASSERT(pSocket);
2186 	if ( pSocket == 0 )
2187 	{
2188 		return 0;
2189 	}
2190 
2191     pSocket->m_nLastError=0;
2192 #if defined(LINUX)
2193     pSocket->m_bIsAccepting = sal_True;
2194 #endif /* LINUX */
2195 
2196 	if( ppAddr && *ppAddr )
2197 	{
2198 		osl_destroySocketAddr( *ppAddr );
2199 		*ppAddr = 0;
2200 	}
2201 
2202     /* prevent Linux EINTR behaviour */
2203     do
2204     {
2205         Connection = accept(pSocket->m_Socket, &Addr, &AddrLen);
2206     } while (Connection == -1 && errno == EINTR);
2207 
2208 
2209     /* accept failed? */
2210     if( Connection == OSL_SOCKET_ERROR )
2211     {
2212         pSocket->m_nLastError=errno;
2213 		OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno));
2214 
2215 #if defined(LINUX)
2216         pSocket->m_bIsAccepting = sal_False;
2217 #endif /* LINUX */
2218         return 0;
2219     }
2220 
2221     OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
2222 
2223 
2224 #if defined(LINUX)
2225     if ( pSocket->m_bIsInShutdown == sal_True )
2226     {
2227         close(Connection);
2228 		OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2229         return 0;
2230     }
2231 #endif /* LINUX */
2232 
2233 
2234 	if(ppAddr)
2235 	{
2236 		*ppAddr= __osl_createSocketAddrFromSystem(&Addr);
2237     }
2238 
2239 	/* alloc memory */
2240 	pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
2241 
2242 	/* set close-on-exec flag */
2243 	if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
2244 	{
2245 		Flags |= FD_CLOEXEC;
2246 		if (fcntl(Connection, F_SETFD, Flags) == -1)
2247         {
2248             pSocket->m_nLastError=errno;
2249 			OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2250                       errno,
2251                       strerror(errno));
2252         }
2253 
2254 	}
2255 
2256 	pConnectionSockImpl->m_Socket			= Connection;
2257 	pConnectionSockImpl->m_nLastError		= 0;
2258 	pConnectionSockImpl->m_CloseCallback	= NULL;
2259 	pConnectionSockImpl->m_CallbackArg		= NULL;
2260 #if defined(LINUX)
2261 	pConnectionSockImpl->m_bIsAccepting		= sal_False;
2262 
2263     pSocket->m_bIsAccepting = sal_False;
2264 #endif /* LINUX */
2265 	return pConnectionSockImpl;
2266 }
2267 
2268 /*****************************************************************************/
2269 /* osl_receiveSocket  */
2270 /*****************************************************************************/
2271 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
2272 					      void* pBuffer,
2273 					      sal_uInt32 BytesToRead,
2274 					      oslSocketMsgFlag Flag)
2275 {
2276     int nRead;
2277 
2278 	OSL_ASSERT(pSocket);
2279 	if ( pSocket == 0 )
2280 	{
2281         OSL_TRACE("osl_receiveSocket : Invalid socket");
2282 		return -1;
2283 	}
2284 
2285     pSocket->m_nLastError=0;
2286 
2287     do
2288     {
2289         nRead =  recv(pSocket->m_Socket,
2290                       (sal_Char*)pBuffer,
2291                       BytesToRead,
2292                       MSG_FLAG_TO_NATIVE(Flag));
2293     } while ( nRead < 0 && errno == EINTR );
2294 
2295     if ( nRead < 0 )
2296     {
2297         pSocket->m_nLastError=errno;
2298         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
2299     }
2300     else if ( nRead == 0 )
2301     {
2302         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2303     }
2304 
2305     return nRead;
2306 }
2307 
2308 
2309 /*****************************************************************************/
2310 /* osl_receiveFromSocket  */
2311 /*****************************************************************************/
2312 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
2313 						      oslSocketAddr pSenderAddr,
2314 						      void* pBuffer,
2315 						      sal_uInt32 BufferSize,
2316 						      oslSocketMsgFlag Flag)
2317 {
2318     int nRead;
2319 	struct sockaddr *pSystemSockAddr = 0;
2320 	socklen_t AddrLen = 0;
2321 	if( pSenderAddr )
2322 	{
2323 		AddrLen = sizeof( struct sockaddr );
2324 		pSystemSockAddr = &(pSenderAddr->m_sockaddr);
2325 	}
2326 
2327 	OSL_ASSERT(pSocket);
2328 	if ( pSocket == 0 )
2329 	{
2330         OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2331         return -1;
2332 	}
2333 
2334     pSocket->m_nLastError=0;
2335 
2336     nRead = recvfrom(pSocket->m_Socket,
2337 					 (sal_Char*)pBuffer,
2338 					 BufferSize,
2339 					 MSG_FLAG_TO_NATIVE(Flag),
2340 					 pSystemSockAddr,
2341 					 &AddrLen);
2342 
2343     if ( nRead < 0 )
2344     {
2345         pSocket->m_nLastError=errno;
2346         OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
2347     }
2348     else if ( nRead == 0 )
2349     {
2350         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2351     }
2352 
2353 	return nRead;
2354 }
2355 
2356 
2357 /*****************************************************************************/
2358 /* osl_sendSocket  */
2359 /*****************************************************************************/
2360 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
2361 				       const void* pBuffer,
2362 				       sal_uInt32 BytesToSend,
2363 				       oslSocketMsgFlag Flag)
2364 {
2365     int nWritten;
2366 
2367 	OSL_ASSERT(pSocket);
2368 	if ( pSocket == 0 )
2369 	{
2370         OSL_TRACE("osl_sendSocket : Invalid socket");
2371 		return -1;
2372 	}
2373 
2374     pSocket->m_nLastError=0;
2375 
2376     do
2377     {
2378         nWritten = send(pSocket->m_Socket,
2379                         (sal_Char*)pBuffer,
2380                         BytesToSend,
2381                         MSG_FLAG_TO_NATIVE(Flag));
2382     } while ( nWritten < 0 && errno == EINTR );
2383 
2384 
2385     if ( nWritten < 0 )
2386     {
2387         pSocket->m_nLastError=errno;
2388         OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
2389     }
2390     else if ( nWritten == 0 )
2391     {
2392         OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
2393     }
2394 
2395 	return nWritten;
2396 }
2397 
2398 /*****************************************************************************/
2399 /* osl_sendToSocket  */
2400 /*****************************************************************************/
2401 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
2402 					     oslSocketAddr ReceiverAddr,
2403 					     const void* pBuffer,
2404 					     sal_uInt32 BytesToSend,
2405 					     oslSocketMsgFlag Flag)
2406 {
2407     int nWritten;
2408 
2409 	struct sockaddr *pSystemSockAddr = 0;
2410 	int AddrLen = 0;
2411 	if( ReceiverAddr )
2412 	{
2413 		pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
2414 		AddrLen = sizeof( struct sockaddr );
2415 	}
2416 
2417 	OSL_ASSERT(pSocket);
2418 	if ( pSocket == 0 )
2419 	{
2420         OSL_TRACE("osl_sendToSocket : Invalid socket");
2421 		return -1;
2422 	}
2423 
2424     pSocket->m_nLastError=0;
2425 
2426 	/* ReceiverAddr might be 0 when used on a connected socket. */
2427 	/* Then sendto should behave like send. */
2428 
2429     nWritten = sendto(pSocket->m_Socket,
2430                       (sal_Char*)pBuffer,
2431                       BytesToSend,
2432                       MSG_FLAG_TO_NATIVE(Flag),
2433                       pSystemSockAddr,
2434                       AddrLen);
2435 
2436     if ( nWritten < 0 )
2437     {
2438         pSocket->m_nLastError=errno;
2439         OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
2440     }
2441     else if ( nWritten == 0 )
2442     {
2443         OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
2444     }
2445 
2446 	return nWritten;
2447 }
2448 
2449 /*****************************************************************************/
2450 /* osl_readSocket  */
2451 /*****************************************************************************/
2452 sal_Int32 SAL_CALL osl_readSocket (
2453 	oslSocket pSocket, void *pBuffer, sal_Int32 n )
2454 {
2455 	sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
2456 	sal_uInt32 BytesRead= 0;
2457 	sal_uInt32 BytesToRead= n;
2458 
2459 	OSL_ASSERT( pSocket);
2460 
2461 	/* loop until all desired bytes were read or an error occured */
2462 	while (BytesToRead > 0)
2463 	{
2464 		sal_Int32 RetVal;
2465 		RetVal= osl_receiveSocket(pSocket,
2466 								   Ptr,
2467 								   BytesToRead,
2468 								   osl_Socket_MsgNormal);
2469 
2470 		/* error occured? */
2471 		if(RetVal <= 0)
2472 		{
2473 			break;
2474 		}
2475 
2476 		BytesToRead -= RetVal;
2477 		BytesRead += RetVal;
2478 		Ptr += RetVal;
2479 	}
2480 
2481 	return BytesRead;
2482 }
2483 
2484 /*****************************************************************************/
2485 /* osl_writeSocket  */
2486 /*****************************************************************************/
2487 sal_Int32 SAL_CALL osl_writeSocket(
2488 	oslSocket pSocket, const void *pBuffer, sal_Int32 n )
2489 {
2490 	/* loop until all desired bytes were send or an error occured */
2491 	sal_uInt32 BytesSend= 0;
2492 	sal_uInt32 BytesToSend= n;
2493 	sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
2494 
2495 	OSL_ASSERT( pSocket );
2496 
2497 	while (BytesToSend > 0)
2498 	{
2499 		sal_Int32 RetVal;
2500 
2501 		RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2502 
2503 		/* error occured? */
2504 		if(RetVal <= 0)
2505 		{
2506 			break;
2507 		}
2508 
2509 		BytesToSend -= RetVal;
2510 		BytesSend += RetVal;
2511 		Ptr += RetVal;
2512 
2513 	}
2514 	return BytesSend;
2515 }
2516 
2517 /*****************************************************************************/
2518 /* __osl_socket_poll */
2519 /*****************************************************************************/
2520 
2521 #ifdef HAVE_POLL_H /* poll() */
2522 
2523 sal_Bool __osl_socket_poll (
2524 	oslSocket        pSocket,
2525 	const TimeValue* pTimeout,
2526 	short            nEvent)
2527 {
2528 	struct pollfd fds;
2529 	int           timeout;
2530 	int           result;
2531 
2532 	OSL_ASSERT(0 != pSocket);
2533     if (0 == pSocket)
2534       return sal_False; /* EINVAL */
2535 
2536 	pSocket->m_nLastError = 0;
2537 
2538 	fds.fd      = pSocket->m_Socket;
2539 	fds.events  = nEvent;
2540 	fds.revents = 0;
2541 
2542 	timeout = -1;
2543 	if (pTimeout)
2544 	{
2545 		/* Convert to [ms] */
2546 		timeout  = pTimeout->Seconds * 1000;
2547 		timeout += pTimeout->Nanosec / (1000 * 1000);
2548 	}
2549 
2550 	result = poll (&fds, 1, timeout);
2551 	if (result < 0)
2552 	{
2553 		pSocket->m_nLastError = errno;
2554 		OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2555 				  errno, strerror(errno));
2556 		return sal_False;
2557 	}
2558 	if (result == 0)
2559 	{
2560 		/* Timeout */
2561 		return sal_False;
2562 	}
2563 
2564 	return ((fds.revents & nEvent) == nEvent);
2565 }
2566 
2567 #else  /* select() */
2568 
2569 sal_Bool __osl_socket_poll (
2570 	oslSocket        pSocket,
2571 	const TimeValue* pTimeout,
2572 	short            nEvent)
2573 {
2574 	fd_set         fds;
2575 	struct timeval tv;
2576 	int            result;
2577 
2578 	OSL_ASSERT(0 != pSocket);
2579     if (0 == pSocket)
2580       return sal_False; /* EINVAL */
2581 
2582 	pSocket->m_nLastError = 0;
2583 
2584 	FD_ZERO(&fds);
2585 	FD_SET(pSocket->m_Socket, &fds);
2586 
2587 	if (pTimeout)
2588 	{
2589 		/* Convert to 'timeval' */
2590 		tv.tv_sec  = pTimeout->Seconds;
2591 		tv.tv_usec = pTimeout->Nanosec / 1000;
2592 	}
2593 
2594 	result = select (
2595 		pSocket->m_Socket + 1,
2596 		(nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2597 		(nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2598 		(nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2599 		(pTimeout)          ? &tv             : NULL);
2600 
2601 	if (result < 0)
2602 	{
2603 		pSocket->m_nLastError = errno;
2604         OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2605 				  errno, strerror(errno));
2606 		return sal_False;
2607 	}
2608 	if (result == 0)
2609 	{
2610 		/* Timeout */
2611 		return sal_False;
2612 	}
2613 
2614 	return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2615 }
2616 
2617 #endif /* HAVE_POLL_H */
2618 
2619 /*****************************************************************************/
2620 /* osl_isReceiveReady  */
2621 /*****************************************************************************/
2622 sal_Bool SAL_CALL osl_isReceiveReady (
2623 	oslSocket pSocket, const TimeValue* pTimeout)
2624 {
2625 	OSL_ASSERT(pSocket);
2626 	if (pSocket == NULL)
2627 	{
2628 		/* ENOTSOCK */
2629 		return sal_False;
2630 	}
2631 
2632 	return __osl_socket_poll (pSocket, pTimeout, POLLIN);
2633 }
2634 
2635 /*****************************************************************************/
2636 /* osl_isSendReady  */
2637 /*****************************************************************************/
2638 sal_Bool SAL_CALL osl_isSendReady (
2639 	oslSocket pSocket, const TimeValue* pTimeout)
2640 {
2641 	OSL_ASSERT(pSocket);
2642 	if (pSocket == NULL)
2643 	{
2644 		/* ENOTSOCK */
2645 		return sal_False;
2646 	}
2647 
2648 	return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2649 }
2650 
2651 /*****************************************************************************/
2652 /* osl_isExceptionPending  */
2653 /*****************************************************************************/
2654 sal_Bool SAL_CALL osl_isExceptionPending (
2655 	oslSocket pSocket, const TimeValue* pTimeout)
2656 {
2657 	OSL_ASSERT(pSocket);
2658 	if (pSocket == NULL)
2659 	{
2660 		/* ENOTSOCK */
2661 		return sal_False;
2662 	}
2663 
2664 	return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2665 }
2666 
2667 /*****************************************************************************/
2668 /* osl_shutdownSocket  */
2669 /*****************************************************************************/
2670 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2671 						   oslSocketDirection Direction)
2672 {
2673     int nRet;
2674 
2675 	OSL_ASSERT(pSocket);
2676 	if ( pSocket == 0 )
2677 	{
2678 		return sal_False;
2679 	}
2680 
2681     pSocket->m_nLastError=0;
2682 
2683     nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2684     if (nRet != 0 )
2685     {
2686         pSocket->m_nLastError=errno;
2687         OSL_TRACE("shutdown error '%s'\n",strerror(errno));
2688     }
2689     return (nRet==0);
2690 }
2691 
2692 
2693 /*****************************************************************************/
2694 /* osl_getSocketOption  */
2695 /*****************************************************************************/
2696 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2697 					    	oslSocketOptionLevel	Level,
2698 							oslSocketOption			Option,
2699 							void*					pBuffer,
2700 							sal_uInt32  				BufferLen)
2701 {
2702     socklen_t nOptLen = (socklen_t) BufferLen;
2703 
2704 	OSL_ASSERT(pSocket);
2705 	if ( pSocket == 0 )
2706 	{
2707 		return -1;
2708 	}
2709 
2710     pSocket->m_nLastError=0;
2711 
2712 	if(getsockopt(pSocket->m_Socket,
2713 				  OPTION_LEVEL_TO_NATIVE(Level),
2714 				  OPTION_TO_NATIVE(Option),
2715 				  (sal_Char*)pBuffer,
2716 				  &nOptLen) == -1)
2717 	{
2718         pSocket->m_nLastError=errno;
2719 		return -1;
2720 	}
2721 
2722 	return BufferLen;
2723 }
2724 
2725 /*****************************************************************************/
2726 /* osl_setSocketOption  */
2727 /*****************************************************************************/
2728 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2729 							oslSocketOptionLevel	Level,
2730 							oslSocketOption			Option,
2731 							void*					pBuffer,
2732 							sal_uInt32					BufferLen)
2733 {
2734     int nRet;
2735 
2736 	OSL_ASSERT(pSocket);
2737 	if ( pSocket == 0 )
2738 	{
2739 		return sal_False;
2740 	}
2741 
2742     pSocket->m_nLastError=0;
2743 
2744     nRet = setsockopt(pSocket->m_Socket,
2745 					  OPTION_LEVEL_TO_NATIVE(Level),
2746 					  OPTION_TO_NATIVE(Option),
2747 					  (sal_Char*)pBuffer,
2748 					  BufferLen);
2749 
2750     if ( nRet < 0 )
2751     {
2752         pSocket->m_nLastError=errno;
2753         return sal_False;
2754     }
2755 
2756 	return sal_True;
2757 }
2758 
2759 /*****************************************************************************/
2760 /* osl_enableNonBlockingMode  */
2761 /*****************************************************************************/
2762 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2763 								  sal_Bool On)
2764 {
2765 	int flags;
2766     int nRet;
2767 
2768 	OSL_ASSERT(pSocket);
2769 	if ( pSocket == 0 )
2770 	{
2771 		return sal_False;
2772 	}
2773 
2774     pSocket->m_nLastError=0;
2775 
2776 	flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2777 
2778 	if (On)
2779 		flags |= O_NONBLOCK;
2780 	else
2781 		flags &= ~(O_NONBLOCK);
2782 
2783     nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2784 
2785     if  ( nRet < 0 )
2786     {
2787         pSocket->m_nLastError=errno;
2788         return sal_False;
2789     }
2790 
2791     return sal_True;
2792 }
2793 
2794 /*****************************************************************************/
2795 /* osl_isNonBlockingMode  */
2796 /*****************************************************************************/
2797 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2798 {
2799 	int flags;
2800 
2801 	OSL_ASSERT(pSocket);
2802 	if ( pSocket == 0 )
2803 	{
2804 		return sal_False;
2805 	}
2806 
2807     pSocket->m_nLastError=0;
2808 
2809 	flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2810 
2811 	if (flags == -1 || !(flags & O_NONBLOCK))
2812 		return sal_False;
2813 	else
2814 		return sal_True;
2815 }
2816 
2817 /*****************************************************************************/
2818 /* osl_getSocketType  */
2819 /*****************************************************************************/
2820 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2821 {
2822 	int	Type=0;
2823 	socklen_t TypeSize= sizeof(Type);
2824 
2825 	OSL_ASSERT(pSocket);
2826 	if ( pSocket == 0 )
2827 	{
2828 		return osl_Socket_TypeInvalid;
2829 	}
2830 
2831     pSocket->m_nLastError=0;
2832 
2833 	if(getsockopt(pSocket->m_Socket,
2834 				  OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2835 				  OPTION_TO_NATIVE(osl_Socket_OptionType),
2836 				  (sal_Char*)&Type,
2837 				  &TypeSize) == -1)
2838 	{
2839 		/* error */
2840         pSocket->m_nLastError=errno;
2841 		return osl_Socket_TypeInvalid;
2842 	}
2843 
2844 	return TYPE_FROM_NATIVE(Type);
2845 
2846 }
2847 
2848 /*****************************************************************************/
2849 /* osl_getLastSocketErrorDescription  */
2850 /*****************************************************************************/
2851 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2852 {
2853     sal_Char pszError[1024];
2854 
2855     pszError[0] = '\0';
2856 
2857     osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2858 
2859     rtl_uString_newFromAscii(ustrError,pszError);
2860 
2861     return;
2862 }
2863 
2864 
2865 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2866 {
2867 	/* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2868 	pBuffer[BufferSize-1]= '\0';
2869 
2870     if ( pSocket == 0 )
2871     {
2872         strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2873         return;
2874     }
2875 
2876     strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2877     return;
2878 }
2879 
2880 /*****************************************************************************/
2881 /* osl_getLastSocketError  */
2882 /*****************************************************************************/
2883 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2884 {
2885     if ( pSocket == 0 )
2886     {
2887         return ERROR_FROM_NATIVE(EINVAL);
2888     }
2889 
2890 	return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2891 }
2892 
2893 /*****************************************************************************/
2894 /* SocketSet                                                                 */
2895 /*****************************************************************************/
2896 typedef struct _TSocketSetImpl
2897 {
2898 	int		m_MaxHandle;	/* for select(), the largest descriptor in the set */
2899 	fd_set	m_Set;			/* the set of descriptors */
2900 
2901 } TSocketSetImpl;
2902 
2903 /*****************************************************************************/
2904 /* osl_createSocketSet  */
2905 /*****************************************************************************/
2906 oslSocketSet SAL_CALL osl_createSocketSet()
2907 {
2908 	TSocketSetImpl* pSet;
2909 
2910 	pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2911 
2912 	OSL_ASSERT(pSet);
2913 
2914 	if(pSet)
2915 	{
2916 		pSet->m_MaxHandle= 0;
2917 		FD_ZERO(&pSet->m_Set);
2918 	}
2919 
2920 	return (oslSocketSet)pSet;
2921 }
2922 
2923 /*****************************************************************************/
2924 /* osl_destroySocketSet  */
2925 /*****************************************************************************/
2926 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2927 {
2928 	if(Set)
2929 		free(Set);
2930 }
2931 
2932 /*****************************************************************************/
2933 /* osl_clearSocketSet  */
2934 /*****************************************************************************/
2935 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2936 {
2937 	TSocketSetImpl* pSet;
2938 	OSL_ASSERT(Set);
2939 	if ( Set == 0 )
2940 	{
2941 		return;
2942 	}
2943 
2944 	pSet= (TSocketSetImpl*)Set;
2945 	pSet->m_MaxHandle= 0;
2946 
2947 	FD_ZERO(&pSet->m_Set);
2948 }
2949 
2950 /*****************************************************************************/
2951 /* osl_addToSocketSet  */
2952 /*****************************************************************************/
2953 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2954 {
2955 	TSocketSetImpl* pSet;
2956 
2957 	OSL_ASSERT(Set);
2958 	OSL_ASSERT(pSocket);
2959 
2960 	if ( Set == 0 || pSocket == 0)
2961 	{
2962 		return;
2963 	}
2964 
2965 	pSet= (TSocketSetImpl*)Set;
2966 
2967 	/* correct max handle */
2968 	if(pSocket->m_Socket > pSet->m_MaxHandle)
2969 		pSet->m_MaxHandle= pSocket->m_Socket;
2970 	FD_SET(pSocket->m_Socket, &pSet->m_Set);
2971 
2972 }
2973 
2974 /*****************************************************************************/
2975 /* osl_removeFromSocketSet  */
2976 /*****************************************************************************/
2977 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
2978 {
2979 	TSocketSetImpl* pSet;
2980 
2981 	OSL_ASSERT(Set);
2982 	OSL_ASSERT(pSocket);
2983 
2984 	if ( Set == 0 || pSocket == 0)
2985 	{
2986 		return;
2987 	}
2988 
2989 	pSet= (TSocketSetImpl*)Set;
2990 
2991 	/* correct max handle */
2992 	if(pSocket->m_Socket == pSet->m_MaxHandle)
2993 	{
2994 		/* not optimal, since the next used descriptor might be */
2995 		/* much smaller than m_Socket-1, but it will do */
2996 		pSet->m_MaxHandle--;
2997 		if(pSet->m_MaxHandle < 0)
2998 		{
2999 			pSet->m_MaxHandle= 0;	/* avoid underflow */
3000 		}
3001 	}
3002 
3003 	FD_CLR(pSocket->m_Socket, &pSet->m_Set);
3004 }
3005 
3006 /*****************************************************************************/
3007 /* osl_isInSocketSet  */
3008 /*****************************************************************************/
3009 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
3010 {
3011 	TSocketSetImpl* pSet;
3012 
3013 	OSL_ASSERT(Set);
3014 	OSL_ASSERT(pSocket);
3015 	if ( Set == 0 || pSocket == 0 )
3016 	{
3017 		return sal_False;
3018 	}
3019 
3020 	pSet= (TSocketSetImpl*)Set;
3021 
3022 	return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
3023 }
3024 
3025 /*****************************************************************************/
3026 /* osl_demultiplexSocketEvents  */
3027 /*****************************************************************************/
3028 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
3029 								    oslSocketSet OutgoingSet,
3030 								    oslSocketSet OutOfBandSet,
3031 								    const TimeValue* pTimeout)
3032 {
3033 	int MaxHandle= 0;
3034 	struct timeval 	tv;
3035 	TSocketSetImpl* pInSet;
3036 	TSocketSetImpl* pOutSet;
3037 	TSocketSetImpl* pOOBSet;
3038 
3039 	if (pTimeout)
3040 	{
3041 	    /* non-blocking call */
3042 	    tv.tv_sec  = pTimeout->Seconds;
3043 	    tv.tv_usec = pTimeout->Nanosec / 1000L;
3044 	}
3045 
3046 	/* map opaque data to impl-types */
3047 	pInSet=  (TSocketSetImpl*)IncomingSet;
3048 	pOutSet= (TSocketSetImpl*)OutgoingSet;
3049 	pOOBSet= (TSocketSetImpl*)OutOfBandSet;
3050 
3051 	/* get max handle from all sets */
3052 	if (pInSet)
3053 		MaxHandle= pInSet->m_MaxHandle;
3054 
3055 	if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
3056 		MaxHandle= pOutSet->m_MaxHandle;
3057 
3058 	if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
3059 		MaxHandle= pOOBSet->m_MaxHandle;
3060 
3061 	return select(MaxHandle+1,
3062 				  pInSet  ? PTR_FD_SET(pInSet->m_Set)  : 0,
3063 				  pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
3064 				  pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
3065 				  pTimeout ? &tv : 0);
3066 }
3067 
3068