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