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