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