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