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