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