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