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 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 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 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 /*****************************************************************************/ 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 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 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 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 1589 void SAL_CALL osl_destroySocketAddr(oslSocketAddr pAddr) 1590 { 1591 __osl_destroySocketAddr( pAddr ); 1592 } 1593 1594 /*****************************************************************************/ 1595 /* osl_getFamilyOfSocketAddr */ 1596 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 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 /*****************************************************************************/ 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 1839 void SAL_CALL osl_acquireSocket(oslSocket pSocket) 1840 { 1841 osl_incrementInterlockedCount( &(pSocket->m_nRefCount ) ); 1842 } 1843 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 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 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 2891 void SAL_CALL osl_psz_getLastSocketErrorDescription(oslSocket pSocket, sal_Char* pBuffer, sal_uInt32 BufferSize) 2892 { 2893 /* make shure pBuffer will be a zero-terminated string even when strncpy has to cut */ 2894 pBuffer[BufferSize-1]= '\0'; 2895 2896 if ( pSocket == 0 ) 2897 { 2898 strncpy(pBuffer, strerror(EINVAL), BufferSize-1); 2899 return; 2900 } 2901 2902 strncpy(pBuffer, strerror(pSocket->m_nLastError), BufferSize-1); 2903 return; 2904 } 2905 2906 /*****************************************************************************/ 2907 /* osl_getLastSocketError */ 2908 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 2952 void SAL_CALL osl_destroySocketSet(oslSocketSet Set) 2953 { 2954 if(Set) 2955 free(Set); 2956 } 2957 2958 /*****************************************************************************/ 2959 /* osl_clearSocketSet */ 2960 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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 /*****************************************************************************/ 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