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