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