xref: /trunk/main/sal/osl/os2/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 	struct sockaddr* pAddr1= &(Addr1->m_sockaddr);
609 	struct sockaddr* pAddr2= &(Addr2->m_sockaddr);
610 
611 	OSL_ASSERT(pAddr1);
612 	OSL_ASSERT(pAddr2);
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, Addr2, 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 
800 #ifdef LINUX
801 	struct hostent *__result; /* will be the same as result */
802 	int __error;
803 	__error = gethostbyname_r (name, result, buffer, buflen,
804 				 &__result, h_errnop);
805 	return __error ? NULL : __result ;
806 #elif defined OS2
807 	// YD FIXME!!!
808 	return 0;
809 #else
810 	return gethostbyname_r( name, result, buffer, buflen, h_errnop);
811 #endif
812 }
813 
814 static sal_Bool  _osl_getDomainName (sal_Char *buffer, sal_Int32 bufsiz)
815 {
816 	sal_Bool result;
817 	int      p[2];
818 
819     result = sal_False;
820 
821 #if 0 // YD 17/04/06 libc panic for fork() from thread!=1
822 
823 	if (pipe (p) == 0)
824 	{
825 		pid_t pid;
826         int nStatus;
827 
828 		pid = fork();
829 		if (pid == 0)
830 		{
831 			char *argv[] =
832 			{
833 				"/bin/domainname",
834 				NULL
835 			};
836 
837 			close (p[0]);
838 			dup2  (p[1], 1);
839 			close (p[1]);
840 
841 			execv ("/bin/domainname", argv);
842             // arriving here means exec failed
843             _exit(-1);
844 		}
845 		else if (pid > 0)
846 		{
847 			sal_Int32 k = 0, n = bufsiz;
848 
849 			close (p[1]);
850 			if ((k = read (p[0], buffer, n - 1)) > 0)
851 			{
852 				buffer[k] = 0;
853 				if (buffer[k - 1] == '\n')
854 					buffer[k - 1] = 0;
855 				result = sal_True;
856 			}
857 			close (p[0]);
858             waitpid (pid, &nStatus, 0);
859 		}
860 		else
861 		{
862 			close (p[0]);
863 			close (p[1]);
864 		}
865 	}
866 #endif // 0
867 
868 	return (result);
869 }
870 
871 static sal_Char* _osl_getFullQualifiedDomainName (const sal_Char *pHostName)
872 {
873 #	define DOMAINNAME_LENGTH 512
874 	sal_uInt32 			nLengthOfHostName;
875 	static sal_uInt32 	nLengthOfDomainName = 0;
876 	static sal_Char    *pDomainName = NULL;
877 
878 	sal_Char  *pFullQualifiedName;
879 #if 0  /* OBSOLETE */
880 	FILE      *pPipeToDomainnameExe;
881 #endif /* OBSOLETE */
882 
883 	/* get a '\0' terminated domainname */
884 
885 	/* read default domainname default from environment */
886 	if (nLengthOfDomainName == 0)
887 	{
888 	    sal_Char *pEnvDomain;
889 
890 	    pEnvDomain = getenv ("STAR_OVERRIDE_DOMAINNAME");
891 		if (pEnvDomain)
892 		{
893 		    pDomainName = strdup (pEnvDomain);
894 		    nLengthOfDomainName = strlen (pDomainName);
895 		}
896 	}
897 
898 #if 1  /* NEW */
899 	if (nLengthOfDomainName == 0)
900 	{
901 		sal_Char pDomainNameBuffer[ DOMAINNAME_LENGTH ];
902 
903         pDomainNameBuffer[0] = '\0';
904 
905 		if (_osl_getDomainName (pDomainNameBuffer, DOMAINNAME_LENGTH))
906 		{
907 			pDomainName = strdup (pDomainNameBuffer);
908 			nLengthOfDomainName = strlen (pDomainName);
909 		}
910 	}
911 
912 #endif /* NEW */
913 #if 0  /* OBSOLETE */
914 #ifdef SCO
915 
916 	/* call 'domainname > /usr/tmp/some-tmp-file', since
917 	   popen read pclose do block or core-dump,
918 	   (even the pipe-stuff that comes with pthreads) */
919 	if (nLengthOfDomainName == 0)
920 	{
921 		sal_Char  tmp_name[ L_tmpnam ];
922         FILE 	 *tmp_file;
923 		sal_Char  domain_call [ L_tmpnam + 16 ] = "domainname > ";
924 
925         tmp_name[0] = '\0';
926 
927 		tmpnam ( tmp_name );
928 		strcat ( domain_call, tmp_name );
929 		if (   (system ( domain_call ) == 0)
930 			&& ((tmp_file = fopen( tmp_name, "r" )) != NULL ) )
931 		{
932 			sal_Char  pDomainNameBuffer[ DOMAINNAME_LENGTH ];
933 
934             pDomainNameBuffer[0] = '\0';
935 
936 			if ( fgets ( pDomainNameBuffer, DOMAINNAME_LENGTH, tmp_file ) )
937 			{
938 				pDomainName = strdup( pDomainNameBuffer );
939 				nLengthOfDomainName = strlen( pDomainName );
940 				if (   ( nLengthOfDomainName > 0 )
941 					&& ( pDomainName[ nLengthOfDomainName - 1] == '\n' ) )
942 					pDomainName[ --nLengthOfDomainName ] = '\0';
943 			}
944 			fclose ( tmp_file );
945 		}
946 		unlink( tmp_name );
947 	}
948 
949 #else /* !SCO */
950 
951 	/* read the domainname from pipe to the program domainname */
952 	if (   (nLengthOfDomainName == 0)
953 		&& (pPipeToDomainnameExe = popen( "domainname", "r")) )
954 	{
955 		sal_Char  c;
956 		sal_Char  pDomainNameBuffer[ DOMAINNAME_LENGTH ];
957 		sal_Char *pDomainNamePointer;
958 
959         pDomainNameBuffer[0] = '\0';
960 
961 		pDomainNamePointer = pDomainNameBuffer;
962     	while (    ((c = getc( pPipeToDomainnameExe )) != EOF)
963 				&& (nLengthOfDomainName < (DOMAINNAME_LENGTH - 1)) )
964         {
965         	if (! isspace(c))
966 			{
967 				 nLengthOfDomainName++ ;
968            		*pDomainNamePointer++ = (sal_Char)c;
969 			}
970 		}
971         *pDomainNamePointer = '\0';
972 		pDomainName = strdup( pDomainNameBuffer );
973 
974 		pclose( pPipeToDomainnameExe );
975 	}
976 
977 #endif /* !SCO */
978 #endif /* OBSOLETE */
979 
980 	/* compose hostname and domainname */
981 	nLengthOfHostName = strlen( pHostName );
982 	pFullQualifiedName = (sal_Char*) malloc( (nLengthOfHostName + 1
983 							+ nLengthOfDomainName + 1) * sizeof(sal_Char) );
984 	memcpy( pFullQualifiedName, pHostName,
985 		(nLengthOfHostName + 1) * sizeof(sal_Char) );
986 
987 	if ( nLengthOfDomainName > 0 )
988 	{
989 		/* fqdn = hostname + '.' + domainname + '\0' */
990 		pFullQualifiedName[ nLengthOfHostName ] = '.';
991 		memcpy( pFullQualifiedName + nLengthOfHostName + 1, pDomainName,
992 			nLengthOfDomainName + 1 );
993 	}
994 
995 	/* check whether full-qualified name and hostname point to the same host
996 	 * should almost always be true */
997 	if ( nLengthOfDomainName > 0 )
998 	{
999 		struct hostent *pQualifiedHostByName;
1000 		struct hostent *pHostByName;
1001 		sal_Bool        bHostsAreEqual;
1002 
1003 		/* buffer for calls to reentrant version of gethostbyname */
1004 		struct hostent 	aHostByName, aQualifiedHostByName;
1005 		sal_Char		pHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1006         sal_Char        pQualifiedHostBuffer[ MAX_HOSTBUFFER_SIZE ];
1007 		int		nErrorNo;
1008 
1009         pHostBuffer[0] = '\0';
1010         pQualifiedHostBuffer[0] = '\0';
1011 
1012         /* get list of addresses */
1013 		pQualifiedHostByName = _osl_gethostbyname_r (
1014 			pFullQualifiedName,
1015 			&aQualifiedHostByName, pQualifiedHostBuffer,
1016 			sizeof(pQualifiedHostBuffer), &nErrorNo );
1017 		pHostByName = _osl_gethostbyname_r (
1018 			pHostName,
1019 			&aHostByName, pHostBuffer,
1020 			sizeof(pHostBuffer), &nErrorNo );
1021 
1022 		/* compare addresses */
1023 		bHostsAreEqual = sal_False;
1024 		if ( pQualifiedHostByName && pHostByName )
1025 		{
1026 			sal_Char **p, **q;
1027 			struct in_addr in;
1028 
1029 			/* lists are expected to be (very) short */
1030 			for ( p = pQualifiedHostByName->h_addr_list; *p != NULL; p++ )
1031 			{
1032 				for ( q = pHostByName->h_addr_list; *q != NULL; q++ )
1033 				{
1034 					/* in.s_addr may be in_addr_t or uint32_t or heaven knows */
1035 					if ( memcmp( *p, *q, sizeof(in.s_addr) ) == 0 )
1036 					{
1037 						bHostsAreEqual = sal_True;
1038 						break;
1039 					}
1040 				}
1041 				if ( bHostsAreEqual )
1042 					break;
1043 			}
1044 		}
1045 
1046 		/* very strange case, but have to believe it: reduce the
1047 		 * full qualified name to the unqualified host name */
1048 		if ( !bHostsAreEqual )
1049 		{
1050 			OSL_TRACE("_osl_getFullQualifiedDomainName: "
1051 					  "suspect FQDN: %s\n", pFullQualifiedName);
1052 
1053 			pFullQualifiedName[ nLengthOfHostName ] = '\0';
1054 			pFullQualifiedName = (sal_Char*)realloc ( pFullQualifiedName,
1055 								(nLengthOfHostName + 1) * sizeof( sal_Char ));
1056 		}
1057 	}
1058 
1059 	/* always return a hostname looked up as carefully as possible
1060 	 * this string must be freed by the caller */
1061 	return pFullQualifiedName;
1062 }
1063 
1064 /*****************************************************************************/
1065 /* _osl_isFullQualifiedDomainName */
1066 /*****************************************************************************/
1067 static sal_Bool _osl_isFullQualifiedDomainName (const sal_Char *pHostName)
1068 {
1069 	/* a FQDN (aka 'hostname.domain.top_level_domain' )
1070 	 * is a name which contains a dot '.' in it ( would
1071 	 * match as well for 'hostname.' but is good enough
1072 	 * for now )*/
1073 	return (sal_Bool)( strchr( pHostName, (int)'.' ) != NULL );
1074 }
1075 
1076 /*****************************************************************************/
1077 /* oslHostAddr */
1078 /*****************************************************************************/
1079 struct oslHostAddrImpl
1080 {
1081 	sal_Char        *pHostName;
1082 	oslSocketAddr   pSockAddr;
1083 };
1084 
1085 static oslHostAddr _osl_hostentToHostAddr (const struct hostent *he)
1086 {
1087 	oslHostAddr pAddr= NULL;
1088 	oslSocketAddr pSockAddr = 0;
1089 
1090 
1091 	if ((he == NULL) || (he->h_name == NULL) || (he->h_addr_list[0] == NULL))
1092 		return ((oslHostAddr)NULL);
1093 
1094 	//YD 18/06/2006 win32 does this with unicode, see socket.cxx
1095 	sal_Char        *cn;
1096 	cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1097 	OSL_ASSERT(cn);
1098 	if (cn == NULL)
1099 		return ((oslHostAddr)NULL);
1100 
1101 	strcpy(cn, he->h_name);
1102 
1103 #if 0 // YD 17/04/06 win32 doesn't it.
1104 	if (_osl_isFullQualifiedDomainName(he->h_name))
1105 	{
1106 		cn= (sal_Char *)malloc(strlen (he->h_name) + 1);
1107 		OSL_ASSERT(cn);
1108 		if (cn == NULL)
1109 			return ((oslHostAddr)NULL);
1110 
1111 		strcpy(cn, he->h_name);
1112 	}
1113 	else
1114 	{
1115 		cn =_osl_getFullQualifiedDomainName (he->h_name);
1116 		OSL_ASSERT(cn);
1117 		if (cn == NULL)
1118 			return ((oslHostAddr)NULL);
1119 	}
1120 #endif
1121 
1122 	pSockAddr = __osl_createSocketAddr();
1123 	OSL_ASSERT(pSockAddr);
1124 	if (pSockAddr == NULL)
1125 	{
1126 		free(cn);
1127 		return ((oslHostAddr)NULL);
1128 	}
1129 
1130 	pSockAddr->m_sockaddr.sa_family= he->h_addrtype;
1131 	if (pSockAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1132 	{
1133 		struct sockaddr_in *sin= (struct sockaddr_in *)&(pSockAddr->m_sockaddr);
1134 		memcpy (
1135 			&(sin->sin_addr.s_addr),
1136 			he->h_addr_list[0],
1137 			he->h_length);
1138 	}
1139 	else
1140 	{
1141 		/* unknown address family */
1142 		/* future extensions for new families might be implemented here */
1143 
1144 		OSL_TRACE("_osl_hostentToHostAddr: unknown address family.\n");
1145 		OSL_ASSERT(sal_False);
1146 
1147 		__osl_destroySocketAddr( pSockAddr );
1148 		free (cn);
1149 		return ((oslHostAddr)NULL);
1150 	}
1151 
1152 	pAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1153 	OSL_ASSERT(pAddr);
1154 	if (pAddr == NULL)
1155 	{
1156 		__osl_destroySocketAddr( pSockAddr );
1157 		free (cn);
1158 		return ((oslHostAddr)NULL);
1159 	}
1160 
1161 	pAddr->pHostName= cn;
1162 	pAddr->pSockAddr= pSockAddr;
1163 
1164 	return pAddr;
1165 }
1166 
1167 /*****************************************************************************/
1168 /* osl_createHostAddr */
1169 /*****************************************************************************/
1170 oslHostAddr SAL_CALL osl_createHostAddr (
1171 	rtl_uString        *ustrHostname,
1172 	const oslSocketAddr Addr)
1173 {
1174     oslHostAddr HostAddr;
1175     rtl_String* strHostname=0;
1176     sal_Char* pszHostName=0;
1177 
1178     if ( ustrHostname != 0 )
1179     {
1180         rtl_uString2String( &strHostname,
1181                             rtl_uString_getStr(ustrHostname),
1182                             rtl_uString_getLength(ustrHostname),
1183                             RTL_TEXTENCODING_UTF8,
1184                             OUSTRING_TO_OSTRING_CVTFLAGS );
1185         pszHostName = rtl_string_getStr(strHostname);
1186     }
1187 
1188     HostAddr = osl_psz_createHostAddr(pszHostName,Addr);
1189 
1190     if ( strHostname != 0 )
1191     {
1192         rtl_string_release(strHostname);
1193     }
1194 
1195 
1196     return HostAddr;
1197 }
1198 
1199 oslHostAddr SAL_CALL osl_psz_createHostAddr (
1200 	const sal_Char     *pszHostname,
1201 	const oslSocketAddr pAddr)
1202 {
1203 	oslHostAddr pHostAddr;
1204 	sal_Char            *cn;
1205 
1206 	OSL_ASSERT(pszHostname && pAddr);
1207 	if ((pszHostname == NULL) || (pAddr == NULL))
1208 		return ((oslHostAddr)NULL);
1209 
1210 	cn = (sal_Char *)malloc(strlen (pszHostname) + 1);
1211 	OSL_ASSERT(cn);
1212 	if (cn == NULL)
1213 		return ((oslHostAddr)NULL);
1214 
1215 	strcpy (cn, pszHostname);
1216 
1217 	pHostAddr= (oslHostAddr) malloc(sizeof(struct oslHostAddrImpl));
1218 	OSL_ASSERT(pHostAddr);
1219 	if (pAddr == NULL)
1220 	{
1221 		free (cn);
1222 		return ((oslHostAddr)NULL);
1223 	}
1224 
1225 	pHostAddr->pHostName= cn;
1226 	pHostAddr->pSockAddr= osl_copySocketAddr( pAddr );
1227 
1228 	return pHostAddr;
1229 }
1230 
1231 /*****************************************************************************/
1232 /* osl_createHostAddrByName */
1233 /*****************************************************************************/
1234 oslHostAddr SAL_CALL osl_createHostAddrByName(rtl_uString *ustrHostname)
1235 {
1236     oslHostAddr HostAddr;
1237     rtl_String* strHostname=0;
1238     sal_Char* pszHostName=0;
1239 
1240     if ( ustrHostname != 0 )
1241     {
1242         rtl_uString2String( &strHostname,
1243                             rtl_uString_getStr(ustrHostname),
1244                             rtl_uString_getLength(ustrHostname),
1245                             RTL_TEXTENCODING_UTF8,
1246                             OUSTRING_TO_OSTRING_CVTFLAGS );
1247         pszHostName=rtl_string_getStr(strHostname);
1248     }
1249 
1250     HostAddr = osl_psz_createHostAddrByName(pszHostName);
1251 
1252     if ( strHostname != 0 )
1253     {
1254         rtl_string_release(strHostname);
1255     }
1256 
1257     return HostAddr;
1258 }
1259 
1260 oslHostAddr SAL_CALL osl_psz_createHostAddrByName (const sal_Char *pszHostname)
1261 {
1262 	struct hostent *he;
1263         oslHostAddr	addr;
1264 
1265 	static oslMutex mutex = NULL;
1266 
1267 	if (mutex == NULL)
1268 		mutex = osl_createMutex();
1269 
1270 	osl_acquireMutex(mutex);
1271 
1272 	he = gethostbyname((sal_Char *)pszHostname);
1273 	addr = _osl_hostentToHostAddr (he);
1274 
1275 	osl_releaseMutex(mutex);
1276 
1277 	return addr;
1278 }
1279 
1280 /*****************************************************************************/
1281 /* osl_createHostAddrByAddr */
1282 /*****************************************************************************/
1283 oslHostAddr SAL_CALL osl_createHostAddrByAddr (const oslSocketAddr pAddr)
1284 {
1285 	OSL_ASSERT(pAddr);
1286 
1287 	if (pAddr == NULL)
1288 		return ((oslHostAddr)NULL);
1289 
1290 	if (pAddr->m_sockaddr.sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1291 	{
1292 		const struct sockaddr_in *sin= (const struct sockaddr_in *)&(pAddr->m_sockaddr);
1293 		struct hostent *he;
1294 
1295 		if (sin->sin_addr.s_addr == htonl(INADDR_ANY))
1296 			return ((oslHostAddr)NULL);
1297 
1298 		he= gethostbyaddr((sal_Char *)&(sin->sin_addr),
1299 						  sizeof (sin->sin_addr),
1300 						  sin->sin_family);
1301 		return _osl_hostentToHostAddr (he);
1302 	}
1303 
1304 	return ((oslHostAddr)NULL);
1305 }
1306 
1307 /*****************************************************************************/
1308 /* osl_copyHostAddr */
1309 /*****************************************************************************/
1310 oslHostAddr SAL_CALL osl_copyHostAddr (const oslHostAddr pAddr)
1311 {
1312 	OSL_ASSERT(pAddr);
1313 
1314 	if (pAddr)
1315 		return osl_psz_createHostAddr (pAddr->pHostName, pAddr->pSockAddr);
1316 	else
1317 		return ((oslHostAddr)NULL);
1318 }
1319 
1320 /*****************************************************************************/
1321 /* osl_getHostnameOfHostAddr */
1322 /*****************************************************************************/
1323 void SAL_CALL osl_getHostnameOfHostAddr (
1324 	const oslHostAddr   Addr,
1325 	rtl_uString       **ustrHostname)
1326 {
1327     const sal_Char* pHostname=0;
1328 
1329     pHostname = osl_psz_getHostnameOfHostAddr(Addr);
1330 
1331     rtl_uString_newFromAscii (ustrHostname, pHostname);
1332 
1333     return;
1334 }
1335 
1336 const sal_Char* SAL_CALL osl_psz_getHostnameOfHostAddr (const oslHostAddr pAddr)
1337 {
1338 	OSL_ASSERT(pAddr);
1339 
1340 	if (pAddr)
1341 		return pAddr->pHostName;
1342 	else
1343 		return NULL;
1344 }
1345 
1346 /*****************************************************************************/
1347 /* osl_getSocketAddrOfHostAddr */
1348 /*****************************************************************************/
1349 oslSocketAddr SAL_CALL osl_getSocketAddrOfHostAddr (const oslHostAddr pAddr)
1350 {
1351 	OSL_ASSERT(pAddr);
1352 
1353 	if (pAddr)
1354 		return ((oslSocketAddr)(pAddr->pSockAddr));
1355 	else
1356 		return NULL;
1357 }
1358 
1359 /*****************************************************************************/
1360 /* osl_destroyHostAddr */
1361 /*****************************************************************************/
1362 void SAL_CALL osl_destroyHostAddr (oslHostAddr pAddr)
1363 {
1364 	if (pAddr)
1365 	{
1366 		if (pAddr->pHostName)
1367 			free (pAddr->pHostName);
1368 		if (pAddr->pSockAddr)
1369 			osl_destroySocketAddr (pAddr->pSockAddr);
1370 		free (pAddr);
1371 	}
1372 }
1373 
1374 /*****************************************************************************/
1375 /* osl_getLocalHostname */
1376 /*****************************************************************************/
1377 oslSocketResult SAL_CALL osl_getLocalHostname(rtl_uString **ustrLocalHostname)
1378 {
1379     oslSocketResult Result;
1380     sal_Char pszHostname[1024];
1381 
1382     pszHostname[0] = '\0';
1383 
1384     Result = osl_psz_getLocalHostname(pszHostname,sizeof(pszHostname));
1385 
1386     rtl_uString_newFromAscii(ustrLocalHostname,pszHostname);
1387 
1388     return Result;
1389 }
1390 
1391 oslSocketResult SAL_CALL osl_psz_getLocalHostname (
1392 	sal_Char *pBuffer, sal_uInt32 nBufLen)
1393 {
1394 	static sal_Char LocalHostname[256] = "";
1395 
1396 	if (strlen(LocalHostname) == 0)
1397 	{
1398 		const sal_Char *pStr;
1399 
1400 #ifdef SYSV
1401 		struct utsname uts;
1402 
1403 		if (uname(&uts) < 0)
1404 			return osl_Socket_Error;
1405 
1406 		if ((strlen(uts.nodename) + 1) > nBufLen)
1407 			return osl_Socket_Error;
1408 
1409 		strncpy(LocalHostname, uts.nodename, sizeof( LocalHostname ));
1410 #else  /* BSD compatible */
1411 
1412 		if (gethostname(LocalHostname, sizeof(LocalHostname)-1) != 0)
1413 			return osl_Socket_Error;
1414         LocalHostname[sizeof(LocalHostname)-1] = 0;
1415 #endif /* SYSV */
1416 
1417 		/* check if we have an FQDN */
1418     	if (strchr(LocalHostname, '.') == NULL)
1419         {
1420 			oslHostAddr Addr;
1421 
1422 			/* no, determine it via dns */
1423 			Addr = osl_psz_createHostAddrByName(LocalHostname);
1424 
1425 			if (Addr && (pStr = osl_psz_getHostnameOfHostAddr(Addr)) != NULL)
1426 			{
1427 #if 0  /* OBSOLETE */
1428 				sal_Char* pChr;
1429 #endif /* OBSOLETE */
1430 				strcpy(LocalHostname, pStr);
1431 
1432 #if 0  /* OBSOLETE */
1433 				/* already done by _osl_getFullQualifiedDomainName() with
1434 				   much better heuristics, so this may be contraproductive */
1435 
1436 				/* no FQDN, last try append domain name */
1437 		    	if ((pChr = strchr(LocalHostname, '.')) == NULL)
1438 		        {
1439                     FILE *fp;
1440 
1441 					pChr = &LocalHostname[strlen(LocalHostname)];
1442 
1443                     if ( (fp = popen("domainname", "r")) != 0 )
1444                     {
1445                         int c;
1446 
1447 						*pChr++ = '.';
1448 
1449                         while ((c = getc(fp)) != EOF)
1450                         {
1451                             if (! isspace(c))
1452                             	*pChr++ = (sal_Char)c;
1453                         }
1454 
1455                         *pChr = '\0';
1456 
1457                         fclose(fp);
1458                     }
1459                     else
1460 						LocalHostname[0] = '\0';
1461 				}
1462 #endif /* OBSOLETE */
1463 
1464 			}
1465 			if (Addr)
1466 				osl_destroyHostAddr(Addr);
1467 		}
1468 	}
1469 
1470 	if (strlen(LocalHostname) > 0)
1471 	{
1472 		strncpy(pBuffer, LocalHostname, nBufLen);
1473 		pBuffer[nBufLen - 1] = '\0';
1474 
1475 		return osl_Socket_Ok;
1476 	}
1477 
1478 	return osl_Socket_Error;
1479 }
1480 
1481 /*****************************************************************************/
1482 /* osl_resolveHostname */
1483 /*****************************************************************************/
1484 oslSocketAddr SAL_CALL osl_resolveHostname(rtl_uString *ustrHostname)
1485 {
1486     oslSocketAddr Addr;
1487     rtl_String* strHostname=0;
1488     sal_Char* pszHostName=0;
1489 
1490     if ( ustrHostname != 0 )
1491     {
1492         rtl_uString2String( &strHostname,
1493                             rtl_uString_getStr(ustrHostname),
1494                             rtl_uString_getLength(ustrHostname),
1495                             RTL_TEXTENCODING_UTF8,
1496                             OUSTRING_TO_OSTRING_CVTFLAGS );
1497         pszHostName = rtl_string_getStr(strHostname);
1498     }
1499 
1500 
1501     Addr = osl_psz_resolveHostname(pszHostName);
1502 
1503     if ( strHostname != 0 )
1504     {
1505         rtl_string_release(strHostname);
1506     }
1507 
1508 
1509     return Addr;
1510 }
1511 
1512 
1513 oslSocketAddr SAL_CALL osl_psz_resolveHostname(const sal_Char* pszHostname)
1514 {
1515 	struct oslHostAddrImpl *pAddr = (oslHostAddr)osl_psz_createHostAddrByName(pszHostname);
1516 
1517 	if (pAddr)
1518 	{
1519 		oslSocketAddr SockAddr = osl_copySocketAddr(pAddr->pSockAddr);
1520 
1521 		osl_destroyHostAddr(pAddr);
1522 
1523 		return (SockAddr);
1524 	}
1525 
1526 	return ((oslSocketAddr)NULL);
1527 }
1528 
1529 /*****************************************************************************/
1530 /* osl_getServicePort */
1531 /*****************************************************************************/
1532 sal_Int32 SAL_CALL osl_getServicePort(rtl_uString *ustrServicename, rtl_uString *ustrProtocol)
1533 {
1534     sal_Int32 nPort;
1535     rtl_String* strServicename=0;
1536     rtl_String* strProtocol=0;
1537     sal_Char* pszServiceName=0;
1538     sal_Char* pszProtocol=0;
1539 
1540     if ( ustrServicename != 0 )
1541     {
1542         rtl_uString2String( &strServicename,
1543                             rtl_uString_getStr(ustrServicename),
1544                             rtl_uString_getLength(ustrServicename),
1545                             RTL_TEXTENCODING_UTF8,
1546                             OUSTRING_TO_OSTRING_CVTFLAGS );
1547         pszServiceName = rtl_string_getStr(strServicename);
1548     }
1549 
1550     if ( ustrProtocol != 0 )
1551     {
1552         rtl_uString2String( &strProtocol,
1553                             rtl_uString_getStr(ustrProtocol),
1554                             rtl_uString_getLength(ustrProtocol),
1555                             RTL_TEXTENCODING_UTF8,
1556                             OUSTRING_TO_OSTRING_CVTFLAGS );
1557         pszProtocol = rtl_string_getStr(strProtocol);
1558     }
1559 
1560     nPort = osl_psz_getServicePort(pszServiceName,pszProtocol);
1561 
1562     if ( strServicename != 0 )
1563     {
1564         rtl_string_release(strServicename);
1565     }
1566 
1567     if ( strProtocol != 0 )
1568     {
1569         rtl_string_release(strProtocol);
1570     }
1571 
1572 
1573     return nPort;
1574 }
1575 
1576 
1577 sal_Int32 SAL_CALL osl_psz_getServicePort(const sal_Char* pszServicename,
1578 						const sal_Char* pszProtocol)
1579 {
1580 	struct servent* ps;
1581 
1582 	ps= getservbyname(pszServicename, pszProtocol);
1583 
1584 	if (ps != 0)
1585 		return ntohs(ps->s_port);
1586 
1587 	return OSL_INVALID_PORT;
1588 }
1589 
1590 /*****************************************************************************/
1591 /* osl_destroySocketAddr */
1592 /*****************************************************************************/
1593 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr)
1594 {
1595 	__osl_destroySocketAddr( pAddr );
1596 }
1597 
1598 /*****************************************************************************/
1599 /* osl_getFamilyOfSocketAddr */
1600 /*****************************************************************************/
1601 oslAddrFamily SAL_CALL osl_getFamilyOfSocketAddr(oslSocketAddr pAddr)
1602 {
1603 	OSL_ASSERT(pAddr);
1604 
1605 	if (pAddr)
1606 		return FAMILY_FROM_NATIVE(pAddr->m_sockaddr.sa_family);
1607 	else
1608 		return osl_Socket_FamilyInvalid;
1609 }
1610 
1611 /*****************************************************************************/
1612 /* osl_getInetPortOfSocketAddr */
1613 /*****************************************************************************/
1614 sal_Int32 SAL_CALL osl_getInetPortOfSocketAddr(oslSocketAddr pAddr)
1615 {
1616 	OSL_ASSERT(pAddr);
1617 	if( pAddr )
1618 	{
1619 		struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1620 
1621 		if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1622 			return ntohs(pSystemInetAddr->sin_port);
1623 	}
1624 	return OSL_INVALID_PORT;
1625 }
1626 
1627 /*****************************************************************************/
1628 /* osl_setInetPortOfSocketAddr */
1629 /*****************************************************************************/
1630 sal_Bool SAL_CALL osl_setInetPortOfSocketAddr(oslSocketAddr pAddr, sal_Int32 Port)
1631 {
1632 	OSL_ASSERT(pAddr);
1633 	if( pAddr )
1634 	{
1635 		struct sockaddr_in* pSystemInetAddr= (struct sockaddr_in*)&(pAddr->m_sockaddr);
1636 		if ( pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1637 		{
1638 			pSystemInetAddr->sin_port= htons((short)Port);
1639 			return sal_True;
1640 		}
1641 	}
1642 
1643 	/* this is not a inet-addr => can't set port */
1644 	return sal_False;
1645 }
1646 
1647 /*****************************************************************************/
1648 /* osl_getHostnameOfSocketAddr */
1649 /*****************************************************************************/
1650 oslSocketResult	SAL_CALL osl_getHostnameOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrHostname)
1651 {
1652     oslSocketResult Result;
1653     sal_Char pszHostname[1024];
1654 
1655     pszHostname[0] = '\0';
1656 
1657     Result = osl_psz_getHostnameOfSocketAddr(Addr,pszHostname,sizeof(pszHostname));
1658 
1659     rtl_uString_newFromAscii(ustrHostname,pszHostname);
1660 
1661     return Result;
1662 }
1663 
1664 
1665 oslSocketResult SAL_CALL osl_psz_getHostnameOfSocketAddr(oslSocketAddr pAddr,
1666                                             sal_Char *pBuffer, sal_uInt32 BufferSize)
1667 {
1668 	oslHostAddr pHostAddr= (oslHostAddr )osl_createHostAddrByAddr(pAddr);
1669 
1670 	if (pHostAddr)
1671 	{
1672 		strncpy(pBuffer, pHostAddr->pHostName, BufferSize);
1673 
1674 		pBuffer[BufferSize - 1] = '\0';
1675 
1676 		osl_destroyHostAddr(pHostAddr);
1677 
1678 		return osl_Socket_Ok;
1679 	}
1680 
1681 	return osl_Socket_Error;
1682 }
1683 
1684 /*****************************************************************************/
1685 /* osl_getDottedInetAddrOfSocketAddr */
1686 /*****************************************************************************/
1687 oslSocketResult	SAL_CALL osl_getDottedInetAddrOfSocketAddr(oslSocketAddr Addr, rtl_uString **ustrDottedInetAddr)
1688 {
1689     oslSocketResult Result;
1690     sal_Char pszDottedInetAddr[1024];
1691 
1692     pszDottedInetAddr[0] = '\0';
1693 
1694     Result = osl_psz_getDottedInetAddrOfSocketAddr(Addr,pszDottedInetAddr,sizeof(pszDottedInetAddr));
1695 
1696     rtl_uString_newFromAscii(ustrDottedInetAddr,pszDottedInetAddr);
1697 
1698     return Result;
1699 
1700 }
1701 
1702 oslSocketResult	SAL_CALL osl_psz_getDottedInetAddrOfSocketAddr(oslSocketAddr pAddr,
1703 												  sal_Char *pBuffer, sal_uInt32 BufferSize)
1704 {
1705 	OSL_ASSERT(pAddr);
1706 
1707 	if( pAddr )
1708 	{
1709 		struct sockaddr_in* pSystemInetAddr = ( struct sockaddr_in * ) &(pAddr->m_sockaddr);
1710 
1711 		if (pSystemInetAddr->sin_family == FAMILY_TO_NATIVE(osl_Socket_FamilyInet))
1712 		{
1713 			strncpy(pBuffer, inet_ntoa(pSystemInetAddr->sin_addr), BufferSize);
1714 			pBuffer[BufferSize - 1] = '\0';
1715 
1716 			return osl_Socket_Ok;
1717 		}
1718 	}
1719 
1720 	return osl_Socket_Error;
1721 }
1722 
1723 #if 0  /* OBSOLETE */
1724 /*****************************************************************************/
1725 /* osl_getIpxNetNumber  */
1726 /*****************************************************************************/
1727 oslSocketResult SAL_CALL osl_getIpxNetNumber(oslSocketAddr Addr,
1728                                     oslSocketIpxNetNumber NetNumber)
1729 
1730 {
1731 	struct sockaddr_ipx* pAddr;
1732 
1733 	pAddr= (struct sockaddr_ipx*)Addr;
1734 
1735 	OSL_ASSERT(pAddr);
1736 
1737 	if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1738  	{
1739  		memcpy(NetNumber, pAddr->sa_netnum, sizeof(NetNumber));
1740 
1741   		return osl_Socket_Ok;
1742   	}
1743   	else
1744   		return osl_Socket_Error;
1745 }
1746 
1747 
1748 /*****************************************************************************/
1749 /* osl_getIpxNodeNumber  */
1750 /*****************************************************************************/
1751 oslSocketResult SAL_CALL osl_getIpxNodeNumber(oslSocketAddr Addr,
1752                                      oslSocketIpxNodeNumber NodeNumber)
1753 
1754 {
1755   	struct sockaddr_ipx* pAddr;
1756 
1757   	pAddr= (struct sockaddr_ipx*)Addr;
1758 
1759   	OSL_ASSERT(pAddr);
1760 
1761   	if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1762   	{
1763   		memcpy(NodeNumber, pAddr->sa_nodenum, sizeof(NodeNumber));
1764 
1765   		return osl_Socket_Ok;
1766   	}
1767   	else
1768   		return osl_Socket_Error;
1769 }
1770 
1771 
1772 /*****************************************************************************/
1773 /* osl_getIpxSocketNumber  */
1774 /*****************************************************************************/
1775 sal_Int32 SAL_CALL osl_getIpxSocketNumber(oslSocketAddr Addr)
1776 {
1777 	struct sockaddr_ipx* pAddr= (struct sockaddr_ipx*)Addr;
1778 	OSL_ASSERT(pAddr);
1779 
1780  	if (pAddr && (pAddr->sa_family == FAMILY_TO_NATIVE(osl_Socket_FamilyIpx)))
1781   		return pAddr->sa_socket;
1782   	else
1783   		return OSL_INVALID_IPX_SOCKET_NO;
1784 }
1785 
1786 #endif /* OBSOLETE */
1787 
1788 /*****************************************************************************/
1789 /* osl_createSocket  */
1790 /*****************************************************************************/
1791 oslSocket SAL_CALL osl_createSocket(oslAddrFamily	Family,
1792 						   oslSocketType	Type,
1793 						   oslProtocol		Protocol)
1794 {
1795 	int 		   Flags;
1796 	oslSocket pSocket;
1797 
1798 	/* alloc memory */
1799 	pSocket= __osl_createSocketImpl(OSL_INVALID_SOCKET);
1800 
1801 	/* create socket */
1802 	pSocket->m_Socket= socket(FAMILY_TO_NATIVE(Family),
1803 								TYPE_TO_NATIVE(Type),
1804 								PROTOCOL_TO_NATIVE(Protocol));
1805 
1806 	/* creation failed => free memory */
1807 	if(pSocket->m_Socket == OSL_INVALID_SOCKET)
1808 	{
1809 	    OSL_TRACE("osl_createSocket failed. Errno: %d; %s\n",
1810 			      errno,
1811 			      strerror(errno));
1812 
1813 		__osl_destroySocketImpl((pSocket));
1814 		pSocket= 0;
1815 	}
1816 	else
1817 	{
1818 		/* set close-on-exec flag */
1819 		if ((Flags = fcntl(pSocket->m_Socket, F_GETFD, 0)) != -1)
1820 		{
1821 			Flags |= FD_CLOEXEC;
1822 			if (fcntl(pSocket->m_Socket, F_SETFD, Flags) == -1)
1823             {
1824                 pSocket->m_nLastError=errno;
1825 				OSL_TRACE("osl_createSocket failed changing socket flags. Errno: %d; %s\n",
1826                           errno,
1827                           strerror(errno));
1828             }
1829 		}
1830         else
1831         {
1832             pSocket->m_nLastError=errno;
1833         }
1834 
1835 
1836 		pSocket->m_CloseCallback 	= NULL;
1837 		pSocket->m_CallbackArg	= NULL;
1838 	}
1839 
1840 	return pSocket;
1841 }
1842 
1843 void SAL_CALL osl_acquireSocket(oslSocket pSocket)
1844 {
1845 	osl_incrementInterlockedCount( &(pSocket->m_nRefCount ) );
1846 }
1847 
1848 void SAL_CALL osl_releaseSocket( oslSocket pSocket )
1849 {
1850 	if( pSocket && 0 == osl_decrementInterlockedCount( &(pSocket->m_nRefCount) ) )
1851 	{
1852 #if defined(LINUX)
1853     if ( pSocket->m_bIsAccepting == sal_True )
1854     {
1855         OSL_ENSURE(0, "osl_destroySocket : attempt to destroy socket while accepting\n");
1856         return;
1857     }
1858 #endif /* LINUX */
1859 		osl_closeSocket( pSocket );
1860 		__osl_destroySocketImpl( pSocket );
1861 	}
1862 }
1863 
1864 
1865 
1866 /*****************************************************************************/
1867 /* osl_closeSocket  */
1868 /*****************************************************************************/
1869 void SAL_CALL osl_closeSocket(oslSocket pSocket)
1870 {
1871     int nRet;
1872     int nFD;
1873 
1874     /* socket already invalid */
1875 	if(pSocket==0)
1876 		return;
1877 
1878     pSocket->m_nLastError=0;
1879     nFD = pSocket->m_Socket;
1880 
1881     pSocket->m_Socket = OSL_INVALID_SOCKET;
1882 
1883 #if defined(LINUX)
1884     pSocket->m_bIsInShutdown = sal_True;
1885 
1886     if ( pSocket->m_bIsAccepting == sal_True )
1887     {
1888         int nConnFD;
1889         struct sockaddr aSockAddr;
1890         socklen_t nSockLen = sizeof(aSockAddr);
1891 
1892         nRet = getsockname(nFD, &aSockAddr, &nSockLen);
1893 #if OSL_DEBUG_LEVEL > 1
1894         if ( nRet < 0 )
1895         {
1896             perror("getsockname");
1897         }
1898 #endif /* OSL_DEBUG_LEVEL */
1899 
1900         if ( aSockAddr.sa_family == AF_INET )
1901         {
1902             struct sockaddr_in* pSockAddrIn = (struct sockaddr_in*) &aSockAddr;
1903 
1904             if ( pSockAddrIn->sin_addr.s_addr == htonl(INADDR_ANY) )
1905             {
1906                 pSockAddrIn->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1907             }
1908 
1909             nConnFD = socket(AF_INET, SOCK_STREAM, 0);
1910 #if OSL_DEBUG_LEVEL > 1
1911             if ( nConnFD < 0 )
1912             {
1913                 perror("socket");
1914             }
1915 #endif /* OSL_DEBUG_LEVEL */
1916 
1917             nRet = connect(nConnFD, &aSockAddr, sizeof(aSockAddr));
1918 #if OSL_DEBUG_LEVEL > 1
1919             if ( nRet < 0 )
1920             {
1921                 perror("connect");
1922             }
1923 #endif /* OSL_DEBUG_LEVEL */
1924             close(nConnFD);
1925         }
1926     }
1927 #endif /* LINUX */
1928 
1929 	/* registrierten Callback ausfuehren */
1930 	if (pSocket->m_CloseCallback != NULL)
1931 	{
1932 		pSocket->m_CloseCallback(pSocket->m_CallbackArg);
1933 	}
1934 
1935     nRet=close(nFD);
1936     if ( nRet != 0 )
1937     {
1938         pSocket->m_nLastError=errno;
1939         OSL_TRACE("closeSocket close error '%s'\n",strerror(errno));
1940     }
1941 
1942     pSocket->m_Socket = OSL_INVALID_SOCKET;
1943 }
1944 
1945 /*****************************************************************************/
1946 /* osl_getLocalAddrOfSocket  */
1947 /* Note that I rely on the fact that oslSocketAddr and struct sockaddr */
1948 /* are the same! I don't like it very much but see no other easy way to conceal */
1949 /* the struct sockaddr from the eyes of the user. */
1950 /*****************************************************************************/
1951 oslSocketAddr SAL_CALL osl_getLocalAddrOfSocket(oslSocket pSocket)
1952 {
1953 #if defined(LINUX) || defined(FREEBSD)
1954 	socklen_t AddrLen;
1955 #else
1956 	/* mfe: Solaris 'cc +w' means Addrlen should be signed! */
1957 	/*      it's really defined as 'int*' in /usr/include/sys/socket.h! */
1958 	/*      the man page says it expects a 'size_t' */
1959 	int AddrLen;
1960 #endif
1961 	struct sockaddr Addr;
1962 	oslSocketAddr  pAddr;
1963 
1964 	if (pSocket == NULL) /* ENOTSOCK */
1965 		return ((oslSocketAddr)NULL);
1966 
1967 	AddrLen= sizeof(struct sockaddr);
1968 
1969 	if (getsockname(pSocket->m_Socket, &Addr, PTR_SIZE_T(AddrLen)) == OSL_SOCKET_ERROR)
1970 		return ((oslSocketAddr)NULL);
1971 
1972 	pAddr = __osl_createSocketAddrFromSystem( &Addr );
1973 	return pAddr;
1974 }
1975 
1976 /*****************************************************************************/
1977 /* osl_getPeerAddrOfSocket  */
1978 /*****************************************************************************/
1979 oslSocketAddr SAL_CALL osl_getPeerAddrOfSocket(oslSocket pSocket)
1980 {
1981 	sal_uInt32 AddrLen;
1982 	struct sockaddr Addr;
1983 
1984 	OSL_ASSERT(pSocket);
1985 	if ( pSocket == 0 )
1986 	{
1987 		return 0;
1988 	}
1989 
1990     pSocket->m_nLastError=0;
1991 	AddrLen= sizeof(struct sockaddr);
1992 
1993 	if(getpeername(pSocket->m_Socket, &Addr, (int*)PTR_SIZE_T(AddrLen)) == OSL_SOCKET_ERROR)
1994     {
1995         pSocket->m_nLastError=errno;
1996 		return 0;
1997     }
1998 	return __osl_createSocketAddrFromSystem( &Addr );
1999 }
2000 
2001 /*****************************************************************************/
2002 /* osl_bindAddrToSocket  */
2003 /*****************************************************************************/
2004 sal_Bool SAL_CALL osl_bindAddrToSocket(oslSocket pSocket,
2005 							 oslSocketAddr pAddr)
2006 {
2007     int nRet;
2008 
2009 	OSL_ASSERT(pSocket && pAddr );
2010 	if ( pSocket == 0 || pAddr == 0 )
2011 	{
2012 		return sal_False;
2013 	}
2014 
2015     pSocket->m_nLastError=0;
2016 
2017     nRet = bind(pSocket->m_Socket, &(pAddr->m_sockaddr), sizeof(struct sockaddr));
2018 
2019     if ( nRet == OSL_SOCKET_ERROR)
2020     {
2021         pSocket->m_nLastError=errno;
2022         return sal_False;
2023     }
2024 
2025 	return sal_True;
2026 }
2027 
2028 
2029 /*****************************************************************************/
2030 /* osl_listenOnSocket  */
2031 /*****************************************************************************/
2032 sal_Bool SAL_CALL osl_listenOnSocket(oslSocket pSocket,
2033 						   sal_Int32 MaxPendingConnections)
2034 {
2035     int nRet;
2036 
2037 	OSL_ASSERT(pSocket);
2038 	if ( pSocket == 0 )
2039 	{
2040 		return sal_False;
2041 	}
2042 
2043     pSocket->m_nLastError=0;
2044 
2045     nRet = listen(pSocket->m_Socket,
2046                   MaxPendingConnections == -1 ?
2047                   SOMAXCONN :
2048                   MaxPendingConnections);
2049     if ( nRet == OSL_SOCKET_ERROR)
2050     {
2051         pSocket->m_nLastError=errno;
2052         return sal_False;
2053     }
2054 
2055     return sal_True;
2056 }
2057 
2058 
2059 /*****************************************************************************/
2060 /* osl_connectSocketTo  */
2061 /*****************************************************************************/
2062 oslSocketResult SAL_CALL osl_connectSocketTo(oslSocket pSocket,
2063 									oslSocketAddr pAddr,
2064 									const TimeValue* pTimeout)
2065 {
2066 	fd_set   WriteSet;
2067 	fd_set   ExcptSet;
2068 	int      ReadyHandles;
2069     struct timeval  tv;
2070 	oslSocketResult Result= osl_Socket_Ok;
2071 
2072 	OSL_PRECOND(pSocket, "osl_connectSocketTo(): need a valid socket!\n");
2073 
2074     if ( pSocket == 0 )
2075     {
2076         return osl_Socket_Error;
2077     }
2078 
2079     pSocket->m_nLastError=0;
2080 
2081 	if (osl_isNonBlockingMode(pSocket))
2082     {
2083 		if (connect(pSocket->m_Socket,
2084 				    &(pAddr->m_sockaddr),
2085 				    sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2086 			return osl_Socket_Ok;
2087 		else
2088 			if (errno == EWOULDBLOCK || errno == EINPROGRESS)
2089             {
2090                 pSocket->m_nLastError=EINPROGRESS;
2091 				return osl_Socket_InProgress;
2092             }
2093 
2094 
2095         pSocket->m_nLastError=errno;
2096         OSL_TRACE("can't connect : '%s'",strerror(errno));
2097 		return osl_Socket_Error;
2098 	}
2099 
2100 	/* set socket temporarily to non-blocking */
2101 	OSL_VERIFY(osl_enableNonBlockingMode(pSocket, sal_True));
2102 
2103 	/* initiate connect */
2104 	if(connect(pSocket->m_Socket,
2105 			   &(pAddr->m_sockaddr),
2106 			   sizeof(struct sockaddr)) != OSL_SOCKET_ERROR)
2107 	{
2108 	   /* immediate connection */
2109 		osl_enableNonBlockingMode(pSocket, sal_False);
2110 
2111 		return osl_Socket_Ok;
2112     }
2113 	else
2114 	{
2115 	    /* really an error or just delayed? */
2116 	    if (errno != EINPROGRESS)
2117 	    {
2118             pSocket->m_nLastError=errno;
2119 			OSL_TRACE(
2120 				"osl_connectSocketTo(): connect failed: errno: %d (%s)\n",
2121 				errno, strerror(errno));
2122 
2123 			osl_enableNonBlockingMode(pSocket, sal_False);
2124 			return osl_Socket_Error;
2125 	    }
2126 	}
2127 
2128 
2129 	/* prepare select set for socket  */
2130 	FD_ZERO(&WriteSet);
2131 	FD_ZERO(&ExcptSet);
2132 	FD_SET(pSocket->m_Socket, &WriteSet);
2133 	FD_SET(pSocket->m_Socket, &ExcptSet);
2134 
2135 	/* prepare timeout */
2136 	if (pTimeout)
2137 	{
2138 		/* divide milliseconds into seconds and microseconds */
2139 		tv.tv_sec=	pTimeout->Seconds;
2140 		tv.tv_usec=	pTimeout->Nanosec / 1000L;
2141 	}
2142 
2143 	/* select */
2144     ReadyHandles= select(pSocket->m_Socket+1,
2145 						 0,
2146 						 PTR_FD_SET(WriteSet),
2147 						 PTR_FD_SET(ExcptSet),
2148 						 (pTimeout) ? &tv : 0);
2149 
2150 	if (ReadyHandles > 0)  /* connected */
2151 	{
2152 		if ( FD_ISSET(pSocket->m_Socket, &WriteSet ) )
2153 		{
2154 			int nErrorCode = 0;
2155 #ifdef SOLARIS
2156 /*  mfe: Solaris 'cc +w' means 5th argument should be a 'int*'!
2157 	     it's really defined as 'int*' in /usr/include/sys/socket.h!
2158 	     the man page says it expects a 'size_t*'
2159 */
2160 			int nErrorSize = sizeof( nErrorCode );
2161 #else
2162 			size_t nErrorSize = sizeof( nErrorCode );
2163 #endif
2164 
2165 			int nSockOpt;
2166 
2167 			nSockOpt = getsockopt ( pSocket->m_Socket, SOL_SOCKET, SO_ERROR,
2168 #ifdef SOLARIS
2169 /*  mfe: Solaris 'cc +w' means 4th argument should be a 'char*'!
2170 	     it's really defined as 'char*' in /usr/include/sys/socket.h!
2171 	     the man page says it expects a 'void*'
2172 */
2173 									(char*)
2174 #endif
2175 									&nErrorCode, (int*)&nErrorSize );
2176 			if ( (nSockOpt == 0) && (nErrorCode == 0))
2177 				Result = osl_Socket_Ok;
2178 			else
2179 				Result = osl_Socket_Error;
2180 		}
2181 		else
2182 		{
2183 			Result= osl_Socket_Error;
2184 		}
2185 	}
2186 	else if (ReadyHandles < 0)  /* error */
2187 	{
2188 	    if (errno == EBADF) /* most probably interrupted by close() */
2189 		{
2190 		    /* do not access pSockImpl because it is about to be or */
2191 		    /* already destroyed */
2192 		    return osl_Socket_Interrupted;
2193 		}
2194 		else
2195         {
2196             pSocket->m_nLastError=errno;
2197 		    Result= osl_Socket_Error;
2198         }
2199 	}
2200 	else    /* timeout */
2201 	{
2202         pSocket->m_nLastError=errno;
2203 	    Result= osl_Socket_TimedOut;
2204 	}
2205 
2206 	osl_enableNonBlockingMode(pSocket, sal_False);
2207 
2208 	return Result;
2209 }
2210 
2211 
2212 /*****************************************************************************/
2213 /* osl_acceptConnectionOnSocket  */
2214 /*****************************************************************************/
2215 oslSocket SAL_CALL osl_acceptConnectionOnSocket(oslSocket pSocket,
2216 						oslSocketAddr* ppAddr)
2217 {
2218 	struct sockaddr Addr;
2219 	int Connection, Flags;
2220 	sal_uInt32 AddrLen = sizeof(struct sockaddr);
2221 	oslSocket pConnectionSockImpl;
2222 
2223 	OSL_ASSERT(pSocket);
2224 	if ( pSocket == 0 )
2225 	{
2226 		return 0;
2227 	}
2228 
2229     pSocket->m_nLastError=0;
2230 #if defined(LINUX)
2231     pSocket->m_bIsAccepting = sal_True;
2232 #endif /* LINUX */
2233 
2234 	if( ppAddr && *ppAddr )
2235 	{
2236 		osl_destroySocketAddr( *ppAddr );
2237 		*ppAddr = 0;
2238 	}
2239 
2240     /* prevent Linux EINTR behaviour */
2241     do
2242     {
2243         Connection = accept(pSocket->m_Socket, &Addr, (int*)PTR_SIZE_T(AddrLen));
2244     } while (Connection == -1 && errno == EINTR);
2245 
2246 
2247     /* accept failed? */
2248     if( Connection == OSL_SOCKET_ERROR )
2249     {
2250         pSocket->m_nLastError=errno;
2251 		OSL_TRACE("osl_acceptConnectionOnSocket : accept error '%s'\n",strerror(errno));
2252 
2253 #if defined(LINUX)
2254         pSocket->m_bIsAccepting = sal_False;
2255 #endif /* LINUX */
2256         return 0;
2257     }
2258 
2259     OSL_ASSERT(AddrLen == sizeof(struct sockaddr));
2260 
2261 
2262 #if defined(LINUX)
2263     if ( pSocket->m_bIsInShutdown == sal_True )
2264     {
2265         close(Connection);
2266 		OSL_TRACE("osl_acceptConnectionOnSocket : close while accept\n");
2267         return 0;
2268     }
2269 #endif /* LINUX */
2270 
2271 
2272 	if(ppAddr)
2273 	{
2274 		*ppAddr= __osl_createSocketAddrFromSystem(&Addr);
2275     }
2276 
2277 	/* alloc memory */
2278 	pConnectionSockImpl= __osl_createSocketImpl(OSL_INVALID_SOCKET);
2279 
2280 	/* set close-on-exec flag */
2281 	if ((Flags = fcntl(Connection, F_GETFD, 0)) != -1)
2282 	{
2283 		Flags |= FD_CLOEXEC;
2284 		if (fcntl(Connection, F_SETFD, Flags) == -1)
2285         {
2286             pSocket->m_nLastError=errno;
2287 			OSL_TRACE("osl_acceptConnectionOnSocket failed changing socket flags. Errno: %d (%s)\n",
2288                       errno,
2289                       strerror(errno));
2290         }
2291 
2292 	}
2293 
2294 	pConnectionSockImpl->m_Socket			= Connection;
2295 	pConnectionSockImpl->m_nLastError		= 0;
2296 	pConnectionSockImpl->m_CloseCallback	= NULL;
2297 	pConnectionSockImpl->m_CallbackArg		= NULL;
2298 #if defined(LINUX)
2299 	pConnectionSockImpl->m_bIsAccepting		= sal_False;
2300 
2301     pSocket->m_bIsAccepting = sal_False;
2302 #endif /* LINUX */
2303 	return pConnectionSockImpl;
2304 }
2305 
2306 /*****************************************************************************/
2307 /* osl_receiveSocket  */
2308 /*****************************************************************************/
2309 sal_Int32 SAL_CALL osl_receiveSocket(oslSocket pSocket,
2310 					      void* pBuffer,
2311 					      sal_uInt32 BytesToRead,
2312 					      oslSocketMsgFlag Flag)
2313 {
2314     int nRead;
2315 
2316 	OSL_ASSERT(pSocket);
2317 	if ( pSocket == 0 )
2318 	{
2319         OSL_TRACE("osl_receiveSocket : Invalid socket");
2320 		return -1;
2321 	}
2322 
2323     pSocket->m_nLastError=0;
2324 
2325     do
2326     {
2327         nRead =  recv(pSocket->m_Socket,
2328                       (sal_Char*)pBuffer,
2329                       BytesToRead,
2330                       MSG_FLAG_TO_NATIVE(Flag));
2331     } while ( nRead < 0 && errno == EINTR );
2332 
2333     if ( nRead < 0 )
2334     {
2335         pSocket->m_nLastError=errno;
2336         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,strerror(errno));
2337     }
2338     else if ( nRead == 0 )
2339     {
2340         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2341     }
2342 
2343     return nRead;
2344 }
2345 
2346 
2347 /*****************************************************************************/
2348 /* osl_receiveFromSocket  */
2349 /*****************************************************************************/
2350 sal_Int32 SAL_CALL osl_receiveFromSocket(oslSocket pSocket,
2351 						      oslSocketAddr pSenderAddr,
2352 						      void* pBuffer,
2353 						      sal_uInt32 BufferSize,
2354 						      oslSocketMsgFlag Flag)
2355 {
2356     int nRead;
2357 	struct sockaddr *pSystemSockAddr = 0;
2358 	int AddrLen = 0;
2359 	if( pSenderAddr )
2360 	{
2361 		AddrLen = sizeof( struct sockaddr );
2362 		pSystemSockAddr = &(pSenderAddr->m_sockaddr);
2363 	}
2364 
2365 	OSL_ASSERT(pSocket);
2366 	if ( pSocket == 0 )
2367 	{
2368         OSL_TRACE("osl_receiveFromSocket : Invalid socket");
2369         return -1;
2370 	}
2371 
2372     pSocket->m_nLastError=0;
2373 
2374     nRead = recvfrom(pSocket->m_Socket,
2375 					 (sal_Char*)pBuffer,
2376 					 BufferSize,
2377 					 MSG_FLAG_TO_NATIVE(Flag),
2378 					 pSystemSockAddr,
2379 					 PTR_SIZE_T(AddrLen));
2380 
2381     if ( nRead < 0 )
2382     {
2383         pSocket->m_nLastError=errno;
2384         OSL_TRACE("osl_receiveFromSocket failed : %i '%s'",nRead,strerror(errno));
2385     }
2386     else if ( nRead == 0 )
2387     {
2388         OSL_TRACE("osl_receiveSocket failed : %i '%s'",nRead,"EOL");
2389     }
2390 
2391 	return nRead;
2392 }
2393 
2394 
2395 /*****************************************************************************/
2396 /* osl_sendSocket  */
2397 /*****************************************************************************/
2398 sal_Int32 SAL_CALL osl_sendSocket(oslSocket pSocket,
2399 				       const void* pBuffer,
2400 				       sal_uInt32 BytesToSend,
2401 				       oslSocketMsgFlag Flag)
2402 {
2403     int nWritten;
2404 
2405 	OSL_ASSERT(pSocket);
2406 	if ( pSocket == 0 )
2407 	{
2408         OSL_TRACE("osl_sendSocket : Invalid socket");
2409 		return -1;
2410 	}
2411 
2412     pSocket->m_nLastError=0;
2413 
2414     do
2415     {
2416         nWritten = send(pSocket->m_Socket,
2417                         (sal_Char*)pBuffer,
2418                         BytesToSend,
2419                         MSG_FLAG_TO_NATIVE(Flag));
2420     } while ( nWritten < 0 && errno == EINTR );
2421 
2422 
2423     if ( nWritten < 0 )
2424     {
2425         pSocket->m_nLastError=errno;
2426         OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,strerror(errno));
2427     }
2428     else if ( nWritten == 0 )
2429     {
2430         OSL_TRACE("osl_sendSocket failed : %i '%s'",nWritten,"EOL");
2431     }
2432 
2433 	return nWritten;
2434 }
2435 
2436 /*****************************************************************************/
2437 /* osl_sendToSocket  */
2438 /*****************************************************************************/
2439 sal_Int32 SAL_CALL osl_sendToSocket(oslSocket pSocket,
2440 					     oslSocketAddr ReceiverAddr,
2441 					     const void* pBuffer,
2442 					     sal_uInt32 BytesToSend,
2443 					     oslSocketMsgFlag Flag)
2444 {
2445     int nWritten;
2446 
2447 	struct sockaddr *pSystemSockAddr = 0;
2448 	int AddrLen = 0;
2449 	if( ReceiverAddr )
2450 	{
2451 		pSystemSockAddr = &(ReceiverAddr->m_sockaddr);
2452 		AddrLen = sizeof( struct sockaddr );
2453 	}
2454 
2455 	OSL_ASSERT(pSocket);
2456 	if ( pSocket == 0 )
2457 	{
2458         OSL_TRACE("osl_sendToSocket : Invalid socket");
2459 		return -1;
2460 	}
2461 
2462     pSocket->m_nLastError=0;
2463 
2464 	/* ReceiverAddr might be 0 when used on a connected socket. */
2465 	/* Then sendto should behave like send. */
2466 
2467     nWritten = sendto(pSocket->m_Socket,
2468                       (sal_Char*)pBuffer,
2469                       BytesToSend,
2470                       MSG_FLAG_TO_NATIVE(Flag),
2471                       pSystemSockAddr,
2472                       AddrLen);
2473 
2474     if ( nWritten < 0 )
2475     {
2476         pSocket->m_nLastError=errno;
2477         OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,strerror(errno));
2478     }
2479     else if ( nWritten == 0 )
2480     {
2481         OSL_TRACE("osl_sendToSocket failed : %i '%s'",nWritten,"EOL");
2482     }
2483 
2484 	return nWritten;
2485 }
2486 
2487 /*****************************************************************************/
2488 /* osl_readSocket  */
2489 /*****************************************************************************/
2490 sal_Int32 SAL_CALL osl_readSocket (
2491 	oslSocket pSocket, void *pBuffer, sal_Int32 n )
2492 {
2493 	sal_uInt8 * Ptr = (sal_uInt8 *)pBuffer;
2494 	sal_uInt32 BytesRead= 0;
2495 	sal_uInt32 BytesToRead= n;
2496 
2497 	OSL_ASSERT( pSocket);
2498 
2499 	/* loop until all desired bytes were read or an error occured */
2500 	while (BytesToRead > 0)
2501 	{
2502 		sal_Int32 RetVal;
2503 		RetVal= osl_receiveSocket(pSocket,
2504 								   Ptr,
2505 								   BytesToRead,
2506 								   osl_Socket_MsgNormal);
2507 
2508 		/* error occured? */
2509 		if(RetVal <= 0)
2510 		{
2511 			break;
2512 		}
2513 
2514 		BytesToRead -= RetVal;
2515 		BytesRead += RetVal;
2516 		Ptr += RetVal;
2517 	}
2518 
2519 	return BytesRead;
2520 }
2521 
2522 /*****************************************************************************/
2523 /* osl_writeSocket  */
2524 /*****************************************************************************/
2525 sal_Int32 SAL_CALL osl_writeSocket(
2526 	oslSocket pSocket, const void *pBuffer, sal_Int32 n )
2527 {
2528 	/* loop until all desired bytes were send or an error occured */
2529 	sal_uInt32 BytesSend= 0;
2530 	sal_uInt32 BytesToSend= n;
2531 	sal_uInt8 *Ptr = ( sal_uInt8 * )pBuffer;
2532 
2533 	OSL_ASSERT( pSocket );
2534 
2535 	while (BytesToSend > 0)
2536 	{
2537 		sal_Int32 RetVal;
2538 
2539 		RetVal= osl_sendSocket( pSocket,Ptr,BytesToSend,osl_Socket_MsgNormal);
2540 
2541 		/* error occured? */
2542 		if(RetVal <= 0)
2543 		{
2544 			break;
2545 		}
2546 
2547 		BytesToSend -= RetVal;
2548 		BytesSend += RetVal;
2549 		Ptr += RetVal;
2550 
2551 	}
2552 	return BytesSend;
2553 }
2554 
2555 /*****************************************************************************/
2556 /* __osl_socket_poll */
2557 /*****************************************************************************/
2558 
2559 #ifdef HAVE_POLL_H /* poll() */
2560 
2561 sal_Bool __osl_socket_poll (
2562 	oslSocket        pSocket,
2563 	const TimeValue* pTimeout,
2564 	short            nEvent)
2565 {
2566 	struct pollfd fds;
2567 	int           timeout;
2568 	int           result;
2569 
2570 	OSL_ASSERT(pSocket);
2571 	pSocket->m_nLastError = 0;
2572 
2573 	fds.fd      = pSocket->m_Socket;
2574 	fds.events  = nEvent;
2575 	fds.revents = 0;
2576 
2577 	timeout = -1;
2578 	if (pTimeout)
2579 	{
2580 		/* Convert to [ms] */
2581 		timeout  = pTimeout->Seconds * 1000;
2582 		timeout += pTimeout->Nanosec / (1000 * 1000);
2583 	}
2584 
2585 	result = poll (&fds, 1, timeout);
2586 	if (result < 0)
2587 	{
2588 		pSocket->m_nLastError = errno;
2589 		OSL_TRACE("__osl_socket_poll(): poll error: %d (%s)",
2590 				  errno, strerror(errno));
2591 		return sal_False;
2592 	}
2593 	if (result == 0)
2594 	{
2595 		/* Timeout */
2596 		return sal_False;
2597 	}
2598 
2599 	return ((fds.revents & nEvent) == nEvent);
2600 }
2601 
2602 #else  /* select() */
2603 
2604 sal_Bool __osl_socket_poll (
2605 	oslSocket        pSocket,
2606 	const TimeValue* pTimeout,
2607 	short            nEvent)
2608 {
2609 	fd_set         fds;
2610 	struct timeval tv;
2611 	int            result;
2612 
2613 	OSL_ASSERT(pSocket);
2614 	pSocket->m_nLastError = 0;
2615 
2616 	FD_ZERO(&fds);
2617 	FD_SET(pSocket->m_Socket, &fds);
2618 
2619 	if (pTimeout)
2620 	{
2621 		/* Convert to 'timeval' */
2622 		tv.tv_sec  = pTimeout->Seconds;
2623 		tv.tv_usec = pTimeout->Nanosec / 1000;
2624 	}
2625 
2626 	result = select (
2627 		pSocket->m_Socket + 1,
2628 		(nEvent == POLLIN ) ? PTR_FD_SET(fds) : NULL,
2629 		(nEvent == POLLOUT) ? PTR_FD_SET(fds) : NULL,
2630 		(nEvent == POLLPRI) ? PTR_FD_SET(fds) : NULL,
2631 		(pTimeout)          ? &tv             : NULL);
2632 
2633 	if (result < 0)
2634 	{
2635 		pSocket->m_nLastError = errno;
2636         OSL_TRACE("__osl_socket_poll(): select error: %d (%s)",
2637 				  errno, strerror(errno));
2638 		return sal_False;
2639 	}
2640 	if (result == 0)
2641 	{
2642 		/* Timeout */
2643 		return sal_False;
2644 	}
2645 
2646 	return (FD_ISSET(pSocket->m_Socket, &fds) ? sal_True : sal_False);
2647 }
2648 
2649 #endif /* HAVE_POLL_H */
2650 
2651 /*****************************************************************************/
2652 /* osl_isReceiveReady  */
2653 /*****************************************************************************/
2654 sal_Bool SAL_CALL osl_isReceiveReady (
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, POLLIN);
2665 }
2666 
2667 /*****************************************************************************/
2668 /* osl_isSendReady  */
2669 /*****************************************************************************/
2670 sal_Bool SAL_CALL osl_isSendReady (
2671 	oslSocket pSocket, const TimeValue* pTimeout)
2672 {
2673 	OSL_ASSERT(pSocket);
2674 	if (pSocket == NULL)
2675 	{
2676 		/* ENOTSOCK */
2677 		return sal_False;
2678 	}
2679 
2680 	return __osl_socket_poll (pSocket, pTimeout, POLLOUT);
2681 }
2682 
2683 /*****************************************************************************/
2684 /* osl_isExceptionPending  */
2685 /*****************************************************************************/
2686 sal_Bool SAL_CALL osl_isExceptionPending (
2687 	oslSocket pSocket, const TimeValue* pTimeout)
2688 {
2689 	OSL_ASSERT(pSocket);
2690 	if (pSocket == NULL)
2691 	{
2692 		/* ENOTSOCK */
2693 		return sal_False;
2694 	}
2695 
2696 	return __osl_socket_poll (pSocket, pTimeout, POLLPRI);
2697 }
2698 
2699 /*****************************************************************************/
2700 /* osl_shutdownSocket  */
2701 /*****************************************************************************/
2702 sal_Bool SAL_CALL osl_shutdownSocket(oslSocket pSocket,
2703 						   oslSocketDirection Direction)
2704 {
2705     int nRet;
2706 
2707 	OSL_ASSERT(pSocket);
2708 	if ( pSocket == 0 )
2709 	{
2710 		return sal_False;
2711 	}
2712 
2713     pSocket->m_nLastError=0;
2714 
2715     nRet=shutdown(pSocket->m_Socket, DIRECTION_TO_NATIVE(Direction));
2716     if (nRet != 0 )
2717     {
2718         pSocket->m_nLastError=errno;
2719         OSL_TRACE("shutdown error '%s'\n",strerror(errno));
2720     }
2721     return (nRet==0);
2722 }
2723 
2724 
2725 /*****************************************************************************/
2726 /* osl_getSocketOption  */
2727 /*****************************************************************************/
2728 sal_Int32 SAL_CALL osl_getSocketOption(oslSocket pSocket,
2729 					    	oslSocketOptionLevel	Level,
2730 							oslSocketOption			Option,
2731 							void*					pBuffer,
2732 							sal_uInt32  				BufferLen)
2733 {
2734 	OSL_ASSERT(pSocket);
2735 	if ( pSocket == 0 )
2736 	{
2737 		return -1;
2738 	}
2739 
2740     pSocket->m_nLastError=0;
2741 
2742 	if(getsockopt(pSocket->m_Socket,
2743 				  OPTION_LEVEL_TO_NATIVE(Level),
2744 				  OPTION_TO_NATIVE(Option),
2745 				  (sal_Char*)pBuffer,
2746 				  (int*)PTR_SIZE_T(BufferLen)) == -1)
2747 	{
2748         pSocket->m_nLastError=errno;
2749 		return -1;
2750 	}
2751 
2752 	return BufferLen;
2753 }
2754 
2755 /*****************************************************************************/
2756 /* osl_setSocketOption  */
2757 /*****************************************************************************/
2758 sal_Bool SAL_CALL osl_setSocketOption(oslSocket pSocket,
2759 							oslSocketOptionLevel	Level,
2760 							oslSocketOption			Option,
2761 							void*					pBuffer,
2762 							sal_uInt32					BufferLen)
2763 {
2764     int nRet;
2765 
2766 	OSL_ASSERT(pSocket);
2767 	if ( pSocket == 0 )
2768 	{
2769 		return sal_False;
2770 	}
2771 
2772     pSocket->m_nLastError=0;
2773 
2774     nRet = setsockopt(pSocket->m_Socket,
2775 					  OPTION_LEVEL_TO_NATIVE(Level),
2776 					  OPTION_TO_NATIVE(Option),
2777 					  (sal_Char*)pBuffer,
2778 					  BufferLen);
2779 
2780     if ( nRet < 0 )
2781     {
2782         pSocket->m_nLastError=errno;
2783         return sal_False;
2784     }
2785 
2786 	return sal_True;
2787 }
2788 
2789 /*****************************************************************************/
2790 /* osl_enableNonBlockingMode  */
2791 /*****************************************************************************/
2792 sal_Bool SAL_CALL osl_enableNonBlockingMode(oslSocket pSocket,
2793 								  sal_Bool On)
2794 {
2795 	int flags;
2796     int nRet;
2797 
2798 	OSL_ASSERT(pSocket);
2799 	if ( pSocket == 0 )
2800 	{
2801 		return sal_False;
2802 	}
2803 
2804     pSocket->m_nLastError=0;
2805 
2806 	flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2807 
2808 	if (On)
2809 		flags |= O_NONBLOCK;
2810 	else
2811 		flags &= ~(O_NONBLOCK);
2812 
2813     nRet = fcntl(pSocket->m_Socket, F_SETFL, flags);
2814 
2815     if  ( nRet < 0 )
2816     {
2817         pSocket->m_nLastError=errno;
2818         return sal_False;
2819     }
2820 
2821     return sal_True;
2822 }
2823 
2824 /*****************************************************************************/
2825 /* osl_isNonBlockingMode  */
2826 /*****************************************************************************/
2827 sal_Bool SAL_CALL osl_isNonBlockingMode(oslSocket pSocket)
2828 {
2829 	int flags;
2830 
2831 	OSL_ASSERT(pSocket);
2832 	if ( pSocket == 0 )
2833 	{
2834 		return sal_False;
2835 	}
2836 
2837     pSocket->m_nLastError=0;
2838 
2839 	flags = fcntl(pSocket->m_Socket, F_GETFL, 0);
2840 
2841 	if (flags == -1 || !(flags & O_NONBLOCK))
2842 		return sal_False;
2843 	else
2844 		return sal_True;
2845 }
2846 
2847 /*****************************************************************************/
2848 /* osl_getSocketType  */
2849 /*****************************************************************************/
2850 oslSocketType SAL_CALL osl_getSocketType(oslSocket pSocket)
2851 {
2852 	int	Type=0;
2853 	sal_uInt32 TypeSize= sizeof(Type);
2854 
2855 	OSL_ASSERT(pSocket);
2856 	if ( pSocket == 0 )
2857 	{
2858 		return osl_Socket_TypeInvalid;
2859 	}
2860 
2861     pSocket->m_nLastError=0;
2862 
2863 	if(getsockopt(pSocket->m_Socket,
2864 				  OPTION_LEVEL_TO_NATIVE(osl_Socket_LevelSocket),
2865 				  OPTION_TO_NATIVE(osl_Socket_OptionType),
2866 				  (sal_Char*)&Type,
2867 				  (int*)PTR_SIZE_T(TypeSize)) == -1)
2868 	{
2869 		/* error */
2870         pSocket->m_nLastError=errno;
2871 		return osl_Socket_TypeInvalid;
2872 	}
2873 
2874 	return TYPE_FROM_NATIVE(Type);
2875 
2876 }
2877 
2878 /*****************************************************************************/
2879 /* osl_getLastSocketErrorDescription  */
2880 /*****************************************************************************/
2881 void SAL_CALL osl_getLastSocketErrorDescription(oslSocket Socket, rtl_uString **ustrError)
2882 {
2883     sal_Char pszError[1024];
2884 
2885     pszError[0] = '\0';
2886 
2887     osl_psz_getLastSocketErrorDescription(Socket,pszError,sizeof(pszError));
2888 
2889     rtl_uString_newFromAscii(ustrError,pszError);
2890 
2891     return;
2892 }
2893 
2894 
2895 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize)
2896 {
2897 	/* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */
2898 	pBuffer[BufferSize-1]= '\0';
2899 
2900     if ( pSocket == 0 )
2901     {
2902         strncpy(pBuffer, strerror(EINVAL), BufferSize-1);
2903         return;
2904     }
2905 
2906     strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1);
2907     return;
2908 }
2909 
2910 /*****************************************************************************/
2911 /* osl_getLastSocketError  */
2912 /*****************************************************************************/
2913 oslSocketError SAL_CALL osl_getLastSocketError(oslSocket pSocket)
2914 {
2915     if ( pSocket == 0 )
2916     {
2917         return ERROR_FROM_NATIVE(EINVAL);
2918     }
2919 
2920 	return ERROR_FROM_NATIVE(pSocket->m_nLastError);
2921 }
2922 
2923 /*****************************************************************************/
2924 /* SocketSet                                                                 */
2925 /*****************************************************************************/
2926 typedef struct _TSocketSetImpl
2927 {
2928 	int		m_MaxHandle;	/* for select(), the largest descriptor in the set */
2929 	fd_set	m_Set;			/* the set of descriptors */
2930 
2931 } TSocketSetImpl;
2932 
2933 /*****************************************************************************/
2934 /* osl_createSocketSet  */
2935 /*****************************************************************************/
2936 oslSocketSet SAL_CALL osl_createSocketSet()
2937 {
2938 	TSocketSetImpl* pSet;
2939 
2940 	pSet= (TSocketSetImpl*)malloc(sizeof(TSocketSetImpl));
2941 
2942 	OSL_ASSERT(pSet);
2943 
2944 	if(pSet)
2945 	{
2946 		pSet->m_MaxHandle= 0;
2947 		FD_ZERO(&pSet->m_Set);
2948 	}
2949 
2950 	return (oslSocketSet)pSet;
2951 }
2952 
2953 /*****************************************************************************/
2954 /* osl_destroySocketSet  */
2955 /*****************************************************************************/
2956 void SAL_CALL osl_destroySocketSet(oslSocketSet Set)
2957 {
2958 	if(Set)
2959 		free(Set);
2960 }
2961 
2962 /*****************************************************************************/
2963 /* osl_clearSocketSet  */
2964 /*****************************************************************************/
2965 void SAL_CALL osl_clearSocketSet(oslSocketSet Set)
2966 {
2967 	TSocketSetImpl* pSet;
2968 	OSL_ASSERT(Set);
2969 	if ( Set == 0 )
2970 	{
2971 		return;
2972 	}
2973 
2974 	pSet= (TSocketSetImpl*)Set;
2975 	pSet->m_MaxHandle= 0;
2976 
2977 	FD_ZERO(&pSet->m_Set);
2978 }
2979 
2980 /*****************************************************************************/
2981 /* osl_addToSocketSet  */
2982 /*****************************************************************************/
2983 void SAL_CALL osl_addToSocketSet(oslSocketSet Set, oslSocket pSocket)
2984 {
2985 	TSocketSetImpl* pSet;
2986 
2987 	OSL_ASSERT(Set);
2988 	OSL_ASSERT(pSocket);
2989 
2990 	if ( Set == 0 || pSocket == 0)
2991 	{
2992 		return;
2993 	}
2994 
2995 	pSet= (TSocketSetImpl*)Set;
2996 
2997 	/* correct max handle */
2998 	if(pSocket->m_Socket > pSet->m_MaxHandle)
2999 		pSet->m_MaxHandle= pSocket->m_Socket;
3000 	FD_SET(pSocket->m_Socket, &pSet->m_Set);
3001 
3002 }
3003 
3004 /*****************************************************************************/
3005 /* osl_removeFromSocketSet  */
3006 /*****************************************************************************/
3007 void SAL_CALL osl_removeFromSocketSet(oslSocketSet Set, oslSocket pSocket)
3008 {
3009 	TSocketSetImpl* pSet;
3010 
3011 	OSL_ASSERT(Set);
3012 	OSL_ASSERT(pSocket);
3013 
3014 	if ( Set == 0 || pSocket == 0)
3015 	{
3016 		return;
3017 	}
3018 
3019 	pSet= (TSocketSetImpl*)Set;
3020 
3021 	/* correct max handle */
3022 	if(pSocket->m_Socket == pSet->m_MaxHandle)
3023 	{
3024 		/* not optimal, since the next used descriptor might be */
3025 		/* much smaller than m_Socket-1, but it will do */
3026 		pSet->m_MaxHandle--;
3027 		if(pSet->m_MaxHandle < 0)
3028 		{
3029 			pSet->m_MaxHandle= 0;	/* avoid underflow */
3030 		}
3031 	}
3032 
3033 	FD_CLR(pSocket->m_Socket, &pSet->m_Set);
3034 }
3035 
3036 /*****************************************************************************/
3037 /* osl_isInSocketSet  */
3038 /*****************************************************************************/
3039 sal_Bool SAL_CALL osl_isInSocketSet(oslSocketSet Set, oslSocket pSocket)
3040 {
3041 	TSocketSetImpl* pSet;
3042 
3043 	OSL_ASSERT(Set);
3044 	OSL_ASSERT(pSocket);
3045 	if ( Set == 0 || pSocket == 0 )
3046 	{
3047 		return sal_False;
3048 	}
3049 
3050 	pSet= (TSocketSetImpl*)Set;
3051 
3052 	return (FD_ISSET(pSocket->m_Socket, &pSet->m_Set) != 0);
3053 }
3054 
3055 /*****************************************************************************/
3056 /* osl_demultiplexSocketEvents  */
3057 /*****************************************************************************/
3058 sal_Int32 SAL_CALL osl_demultiplexSocketEvents(oslSocketSet IncomingSet,
3059 								    oslSocketSet OutgoingSet,
3060 								    oslSocketSet OutOfBandSet,
3061 								    const TimeValue* pTimeout)
3062 {
3063 	int MaxHandle= 0;
3064 	struct timeval 	tv;
3065 	TSocketSetImpl* pInSet;
3066 	TSocketSetImpl* pOutSet;
3067 	TSocketSetImpl* pOOBSet;
3068 
3069 	if (pTimeout)
3070 	{
3071 	    /* non-blocking call */
3072 	    tv.tv_sec  = pTimeout->Seconds;
3073 	    tv.tv_usec = pTimeout->Nanosec / 1000L;
3074 	}
3075 
3076 	/* map opaque data to impl-types */
3077 	pInSet=  (TSocketSetImpl*)IncomingSet;
3078 	pOutSet= (TSocketSetImpl*)OutgoingSet;
3079 	pOOBSet= (TSocketSetImpl*)OutOfBandSet;
3080 
3081 	/* get max handle from all sets */
3082 	if (pInSet)
3083 		MaxHandle= pInSet->m_MaxHandle;
3084 
3085 	if (pOutSet && (pOutSet->m_MaxHandle > MaxHandle))
3086 		MaxHandle= pOutSet->m_MaxHandle;
3087 
3088 	if (pOOBSet && (pOOBSet->m_MaxHandle > MaxHandle))
3089 		MaxHandle= pOOBSet->m_MaxHandle;
3090 
3091 	return select(MaxHandle+1,
3092 				  pInSet  ? PTR_FD_SET(pInSet->m_Set)  : 0,
3093 				  pOutSet ? PTR_FD_SET(pOutSet->m_Set) : 0,
3094 				  pOOBSet ? PTR_FD_SET(pOOBSet->m_Set) : 0,
3095 				  pTimeout ? &tv : 0);
3096 }
3097 
3098