kdecore Library API Documentation

ksockaddr.cpp

00001 /* 00002 * This file is part of the KDE libraries 00003 * Copyright (C) 2000-2002 Thiago Macieira <thiagom@mail.com> 00004 * 00005 * $Id: ksockaddr.cpp,v 1.29 2003/11/15 22:07:57 thiago Exp $ 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Library General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Library General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Library General Public License 00018 * along with this library; see the file COPYING.LIB. If not, write to 00019 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 * Boston, MA 02111-1307, USA. 00021 **/ 00022 00023 #include <config.h> 00024 00025 #include <sys/types.h> 00026 00027 #include <arpa/inet.h> 00028 #include <netinet/in.h> 00029 00030 #include <limits.h> 00031 #include <stdlib.h> 00032 #include <string.h> 00033 #include <sys/un.h> 00034 #include <unistd.h> 00035 00036 #include <qglobal.h> 00037 #include <qfile.h> 00038 00039 #include "kdebug.h" 00040 #include "klocale.h" 00041 #include "ksockaddr.h" 00042 //#include "kextsock.h" 00043 00044 #ifndef HAVE_SOCKADDR_IN6 00045 // The system doesn't have sockaddr_in6 00046 // But we can tell netsupp.h to define it for us, according to the RFC 00047 #define CLOBBER_IN6 00048 #endif 00049 00050 #include "netsupp.h" 00051 00052 #define V6_CAN_CONVERT_TO_V4(addr) (KDE_IN6_IS_ADDR_V4MAPPED(addr) || KDE_IN6_IS_ADDR_V4COMPAT(addr)) 00053 00054 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00055 # define MY_MAX(a, b) ((a) > (b) ? (a) : (b)) 00056 # define MIN_SOCKADDR_LEN MY_MAX(offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family), \ 00057 offsetof(sockaddr, sa_len) + sizeof(((sockaddr*)0)->sa_len)) 00058 #else 00059 # define MIN_SOCKADDR_LEN (offsetof(sockaddr, sa_family) + sizeof(((sockaddr*)0)->sa_family)) 00060 #endif 00061 00062 // Minimum size accepted for sockaddr_in6 sockets. 00063 // The scopeid field is missing from some implementations 00064 // that conform to the obsoleted RFC 2133, e.g. Linux glibc 2.1 00065 #define MIN_SOCKADDR_IN6_LEN (offsetof(sockaddr_in6, sin6_addr) + sizeof(((sockaddr_in6*)0)->sin6_addr)) 00066 00067 #ifdef offsetof 00068 #undef offsetof 00069 #endif 00070 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 00071 00072 // This is how it is 00073 // 46 == strlen("1234:5678:9abc:def0:1234:5678:255.255.255.255") 00074 #ifndef INET6_ADDRSTRLEN 00075 #define INET6_ADDRSTRLEN 46 00076 #endif 00077 00078 00083 KSocketAddress::KSocketAddress(const sockaddr* sa, ksocklen_t size) 00084 { 00085 if ( !sa ) 00086 init(); 00087 else { 00088 data = (sockaddr*)malloc(size); 00089 if (data == NULL) 00090 return; 00091 memcpy(data, sa, size); 00092 datasize = size; 00093 owndata = true; 00094 } 00095 } 00096 00097 void KSocketAddress::init() 00098 { 00099 data = NULL; 00100 datasize = 0; 00101 owndata = false; 00102 } 00103 00104 KSocketAddress::~KSocketAddress() 00105 { 00106 if (owndata && data != NULL) 00107 free(data); 00108 } 00109 00110 QString KSocketAddress::pretty() const 00111 { 00112 return i18n("<unknown socket>"); 00113 } 00114 00115 int KSocketAddress::family() const 00116 { 00117 if (data != NULL) 00118 return data->sa_family; 00119 return AF_UNSPEC; 00120 } 00121 00122 // This creates a new KSocketAddress with given sockaddr 00123 KSocketAddress* KSocketAddress::newAddress(const struct sockaddr* sa, ksocklen_t size) 00124 { 00125 if (size == 0) 00126 { 00127 kdWarning() << "KSocketAddress::newAddress called with size = 0!\n"; 00128 return NULL; 00129 } 00130 00131 // make sure we have the right stuff 00132 if (size < MIN_SOCKADDR_LEN) 00133 { 00134 kdWarning() << "KSocketAddress::newAddress called with invalid size\n"; 00135 return NULL; 00136 } 00137 00138 switch (sa->sa_family) 00139 { 00140 case AF_INET: 00141 if (size >= sizeof(sockaddr_in)) 00142 return new KInetSocketAddress((const sockaddr_in*)sa, size); 00143 return NULL; 00144 00145 #ifdef AF_INET6 00146 case AF_INET6: 00147 if (size >= MIN_SOCKADDR_IN6_LEN) 00148 return new KInetSocketAddress((const sockaddr_in6*)sa, size); 00149 return NULL; 00150 #endif 00151 00152 case AF_UNIX: // AF_LOCAL 00153 return new KUnixSocketAddress((const sockaddr_un*)sa, size); 00154 } 00155 00156 return new KSocketAddress(sa, size); 00157 } 00158 00159 bool KSocketAddress::isEqual(const KSocketAddress& other) const 00160 { 00161 switch(family()) 00162 { 00163 case AF_INET: 00164 return KInetSocketAddress::areEqualInet(*this, other, false); 00165 #ifdef AF_INET6 00166 case AF_INET6: 00167 return KInetSocketAddress::areEqualInet6(*this, other, false); 00168 #endif 00169 case AF_UNIX: // AF_LOCAL 00170 return KUnixSocketAddress::areEqualUnix(*this, other, false); 00171 } 00172 00173 // This is not a known socket type 00174 if (other.datasize != datasize) 00175 return false; // can't be equal 00176 return memcmp(data, other.data, datasize) == 0; 00177 } 00178 00179 bool KSocketAddress::isCoreEqual(const KSocketAddress& other) const 00180 { 00181 switch(family()) 00182 { 00183 case AF_INET: 00184 return KInetSocketAddress::areEqualInet(*this, other, true); 00185 #ifdef AF_INET6 00186 case AF_INET6: 00187 return KInetSocketAddress::areEqualInet6(*this, other, true); 00188 #endif 00189 case AF_UNIX: // AF_LOCAL 00190 return KUnixSocketAddress::areEqualUnix(*this, other, true); 00191 } 00192 00193 return false; 00194 } 00195 00196 QString KSocketAddress::nodeName() const 00197 { 00198 return QString::null; 00199 } 00200 00201 QString KSocketAddress::serviceName() const 00202 { 00203 return QString::null; 00204 } 00205 00206 int KSocketAddress::ianaFamily(int af) 00207 { 00208 switch (af) 00209 { 00210 case AF_INET: 00211 return 1; 00212 #ifdef AF_INET6 00213 case AF_INET6: 00214 return 2; 00215 #endif 00216 default: 00217 return 0; 00218 } 00219 } 00220 00221 int KSocketAddress::fromIanaFamily(int iana) 00222 { 00223 switch (iana) 00224 { 00225 case 1: 00226 return AF_INET; 00227 #ifdef AF_INET6 00228 case 2: 00229 return AF_INET6; 00230 #endif 00231 default: 00232 return AF_UNSPEC; 00233 } 00234 } 00235 00239 class KInetSocketAddressPrivate 00240 { 00241 public: 00242 int sockfamily; 00243 sockaddr_in sin; 00244 #ifdef AF_INET6 00245 sockaddr_in6 sin6; 00246 #endif 00247 00248 KInetSocketAddressPrivate() : 00249 sockfamily(AF_UNSPEC) 00250 { 00251 sin.sin_family = AF_INET; 00252 sin.sin_port = 0; 00253 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00254 sin.sin_len = sizeof(sin); 00255 #endif 00256 #ifdef AF_INET6 00257 sin6.sin6_family = AF_INET6; 00258 sin6.sin6_port = 0; 00259 sin6.sin6_flowinfo = 0; 00260 # ifdef HAVE_SOCKADDR_IN6_SCOPE_ID 00261 sin6.sin6_scope_id = 0; 00262 # endif 00263 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00264 sin6.sin6_len = sizeof(sin6); 00265 # endif 00266 #endif 00267 } 00268 00269 }; 00270 00271 KInetSocketAddress::KInetSocketAddress() : 00272 d(new KInetSocketAddressPrivate) 00273 { 00274 } 00275 00276 KInetSocketAddress::KInetSocketAddress(const KInetSocketAddress &other) : 00277 KSocketAddress(), d(new KInetSocketAddressPrivate) 00278 { 00279 setAddress(other); 00280 } 00281 00282 KInetSocketAddress::KInetSocketAddress(const sockaddr_in* sin, ksocklen_t len) : 00283 d(new KInetSocketAddressPrivate) 00284 { 00285 setAddress(sin, len); 00286 } 00287 00288 KInetSocketAddress::KInetSocketAddress(const sockaddr_in6* sin6, ksocklen_t len) : 00289 d(new KInetSocketAddressPrivate) 00290 { 00291 setAddress(sin6, len); 00292 } 00293 00294 KInetSocketAddress::KInetSocketAddress(const in_addr& addr, unsigned short port) : 00295 d(new KInetSocketAddressPrivate) 00296 { 00297 setAddress(addr, port); 00298 } 00299 00300 KInetSocketAddress::KInetSocketAddress(const in6_addr& addr, unsigned short port) : 00301 d(new KInetSocketAddressPrivate) 00302 { 00303 setAddress(addr, port); 00304 } 00305 00306 KInetSocketAddress::KInetSocketAddress(const QString& addr, unsigned short port, int family) : 00307 d(new KInetSocketAddressPrivate) 00308 { 00309 setAddress(addr, port, family); 00310 } 00311 00312 KInetSocketAddress::~KInetSocketAddress() 00313 { 00314 delete d; 00315 00316 // KSocketAddress::~KSocketAddress(); 00317 } 00318 00319 bool KInetSocketAddress::setAddress(const KInetSocketAddress &other) 00320 { 00321 if (other.family() == AF_INET) 00322 return setAddress(other.addressV4(), other.size()); 00323 #ifdef AF_INET6 00324 else if (other.family() == AF_INET6) 00325 return setAddress(other.addressV6(), other.size()); 00326 #endif 00327 return false; 00328 } 00329 00330 bool KInetSocketAddress::setAddress(const sockaddr_in* sin, ksocklen_t len) 00331 { 00332 // This is supposed to be a AF_INET socket 00333 if ((len < sizeof(sockaddr_in)) || (sin->sin_family != AF_INET)) 00334 { 00335 kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in*) called with invalid sockaddr_in\n"; 00336 return false; 00337 } 00338 00339 return setHost(sin->sin_addr) && setPort(ntohs(sin->sin_port)); 00340 } 00341 00342 bool KInetSocketAddress::setAddress(const sockaddr_in6* sin6, ksocklen_t len) 00343 { 00344 #ifdef AF_INET6 00345 // should be family AF_INET6 00346 if ((len < MIN_SOCKADDR_IN6_LEN) || (sin6->sin6_family != AF_INET6)) 00347 { 00348 kdWarning() << "KInetSocketAddress::setAddress(sockaddr_in6*) called with invalid sockaddr_in6\n"; 00349 return 0; 00350 } 00351 00352 memset(&d->sin6, 0, sizeof(d->sin6)); 00353 if (len > sizeof(d->sin6)) 00354 len = sizeof(d->sin6); 00355 memcpy(&d->sin6, sin6, len); 00356 00357 /* Now make a sanity check */ 00358 d->sockfamily = d->sin6.sin6_family = AF_INET6; 00359 # ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00360 d->sin6.sin6_len = sizeof(d->sin6); 00361 # endif 00362 00363 fromV6(); 00364 return true; 00365 #else // !AF_INET6 00366 return false; 00367 #endif 00368 } 00369 00370 bool KInetSocketAddress::setAddress(const in_addr& addr, unsigned short port) 00371 { 00372 return setHost(addr) && setPort(port); 00373 } 00374 00375 bool KInetSocketAddress::setAddress(const in6_addr& addr, unsigned short port) 00376 { 00377 return setHost(addr) && setPort(port); 00378 } 00379 00380 bool KInetSocketAddress::setAddress(const QString& addr, unsigned short port, int family) 00381 { 00382 return setHost(addr, family) && setPort(port); 00383 } 00384 00385 bool KInetSocketAddress::setHost(const in_addr& addr) 00386 { 00387 d->sockfamily = AF_INET; // set address to IPv4 type 00388 d->sin.sin_addr = addr; 00389 fromV4(); 00390 return true; 00391 } 00392 00393 bool KInetSocketAddress::setHost(const in6_addr& addr) 00394 { 00395 #ifdef AF_INET6 00396 d->sockfamily = AF_INET6; // set address to IPv6 type 00397 d->sin6.sin6_addr = addr; 00398 fromV6(); 00399 return true; 00400 #else 00401 return false; 00402 #endif 00403 } 00404 00405 bool KInetSocketAddress::setHost(const QString& addr, int family) 00406 { 00407 // if family == -1, we'll try to guess the host name 00408 if ((family != -1) && (family != AF_INET) 00409 #ifdef AF_INET6 00410 && (family != AF_INET6) 00411 #endif 00412 ) 00413 { 00414 kdWarning() << "KInetSocketAddress::setHost(QString, int) called with unknown family address\n"; 00415 return false; 00416 } 00417 00418 if (family == -1) 00419 { 00420 // guess the family type 00421 00422 #ifdef AF_INET6 00423 // IPv6 addresses MUST contain colons (:) and IPv4 addresses must not 00424 if (addr.find(':') != -1) 00425 family = AF_INET6; 00426 else 00427 family = AF_INET; 00428 #else 00429 00430 // There's only one guess: 00431 family = AF_INET; 00432 #endif 00433 } 00434 00435 /* 00436 * FIXME! What is the decoding process for hostnames? 00437 */ 00438 if (family == AF_INET) 00439 { 00440 inet_pton(family, addr.latin1(), (void*)&(d->sin.sin_addr)); 00441 fromV4(); 00442 } 00443 #ifdef AF_INET6 00444 else 00445 { 00446 inet_pton(family, addr.latin1(), (void*)&(d->sin6.sin6_addr)); 00447 fromV6(); 00448 } 00449 #endif 00450 d->sockfamily = family; 00451 return true; 00452 } 00453 00454 bool KInetSocketAddress::setPort(unsigned short port) 00455 { 00456 // set port on all socket types 00457 d->sin.sin_port = htons(port); 00458 #ifdef AF_INET6 00459 d->sin6.sin6_port = htons(port); 00460 #endif 00461 00462 return true; 00463 } 00464 00465 bool KInetSocketAddress::setFamily(int _family) 00466 { 00467 if (_family != AF_INET 00468 #ifdef AF_INET6 00469 && _family != AF_INET6 00470 #endif 00471 ) 00472 { 00473 kdWarning() << "KInetSocketAddress::setFamily(int) called with unknown family\n"; 00474 return false; 00475 } 00476 00477 d->sockfamily = _family; 00478 if (_family == AF_INET) 00479 fromV4(); 00480 #ifdef AF_INET6 00481 else if (_family == AF_INET6) 00482 fromV6(); 00483 #endif 00484 00485 return true; 00486 } 00487 00488 bool KInetSocketAddress::setFlowinfo(Q_UINT32 flowinfo) 00489 { 00490 #ifdef AF_INET6 00491 if (d->sockfamily == AF_INET6) 00492 { 00493 d->sin6.sin6_flowinfo = flowinfo; 00494 return true; 00495 } 00496 #endif 00497 return false; 00498 } 00499 00500 bool KInetSocketAddress::setScopeId(int scopeid) 00501 { 00502 #if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6_SCOPE_ID) 00503 if (d->sockfamily == AF_INET6) 00504 { 00505 d->sin6.sin6_scope_id = scopeid; 00506 return true; 00507 } 00508 #endif 00509 (void)scopeid; 00510 return false; 00511 } 00512 00513 const sockaddr_in* KInetSocketAddress::addressV4() const 00514 { 00515 if (d->sockfamily == AF_INET) 00516 return &d->sin; 00517 #ifdef AF_INET6 00518 else if (d->sockfamily == AF_INET6) 00519 { 00520 // check if this IPv6 address was converted without loss 00521 if (V6_CAN_CONVERT_TO_V4(&d->sin6.sin6_addr)) 00522 return &d->sin; 00523 else 00524 return NULL; // there was loss, so return nothing 00525 } 00526 #endif 00527 00528 kdWarning() << "KInetSocketAddress::addressV4() called on uninitialized socket\n"; 00529 return NULL; 00530 } 00531 00532 const sockaddr_in6* KInetSocketAddress::addressV6() const 00533 { 00534 #ifdef AF_INET6 00535 return &d->sin6; 00536 #else 00537 return NULL; 00538 #endif 00539 } 00540 00541 in_addr KInetSocketAddress::hostV4() const 00542 { 00543 // this might be empty 00544 return d->sin.sin_addr; 00545 } 00546 00547 /* 00548 * ATTENTION 00549 * This function is left undefined if no IPv6 support exists 00550 * This is intentional 00551 */ 00552 #ifdef AF_INET6 00553 in6_addr KInetSocketAddress::hostV6() const 00554 { 00555 return d->sin6.sin6_addr; 00556 } 00557 #endif 00558 00559 QString KInetSocketAddress::pretty() const 00560 { 00561 if (d->sockfamily != AF_INET 00562 #ifdef AF_INET6 00563 && d->sockfamily != AF_INET6 00564 #endif 00565 ) 00566 { 00567 kdWarning() << "KInetSocketAddress::pretty() called on uninitialized class\n"; 00568 return i18n("<empty>"); 00569 } 00570 00571 return i18n("1: hostname, 2: port number", "%1 port %2").arg(nodeName()).arg(serviceName()); 00572 } 00573 00574 QString KInetSocketAddress::nodeName() const 00575 { 00576 char buf[INET6_ADDRSTRLEN]; // INET6_ADDRSTRLEN > INET_ADDRSTRLEN 00577 00578 if (d->sockfamily == AF_INET) 00579 inet_ntop(d->sockfamily, (void*)&d->sin.sin_addr, buf, sizeof(buf)); 00580 #ifdef AF_INET6 00581 else if (d->sockfamily == AF_INET6) 00582 inet_ntop(d->sockfamily, (void*)&d->sin6.sin6_addr, buf, sizeof(buf)); 00583 #endif 00584 else 00585 { 00586 kdWarning() << "KInetSocketAddress::nodeName() called on uninitialized class\n"; 00587 return i18n("<empty>"); 00588 } 00589 00590 return QString::fromLatin1(buf); // FIXME! What's the encoding? 00591 } 00592 00593 QString KInetSocketAddress::serviceName() const 00594 { 00595 return QString::number(port()); 00596 } 00597 00598 unsigned short KInetSocketAddress::port() const 00599 { 00600 #ifdef AF_INET6 00601 // we prefer sin6 here because fromV6() might make sin.sin_port be 0 00602 return ntohs(d->sin6.sin6_port); 00603 #else 00604 return ntohs(d->sin.sin_port); 00605 #endif 00606 } 00607 00608 Q_UINT32 KInetSocketAddress::flowinfo() const 00609 { 00610 #ifdef AF_INET6 00611 if (d->sockfamily == AF_INET6) 00612 return (Q_UINT32)d->sin6.sin6_flowinfo; 00613 #endif 00614 return 0; 00615 } 00616 00617 ksocklen_t KInetSocketAddress::size() const 00618 { 00619 if (d->sockfamily == AF_INET) 00620 return sizeof(d->sin); 00621 #ifdef AF_INET6 00622 else if (d->sockfamily == AF_INET6) 00623 return sizeof(d->sin6); 00624 #endif 00625 else 00626 return 0; 00627 } 00628 00629 bool KInetSocketAddress::areEqualInet(const KSocketAddress &s1, const KSocketAddress &s2, bool coreOnly) 00630 { 00631 if (s1.family() != s2.family()) 00632 return false; 00633 if ((s1.size() < sizeof(sockaddr_in)) || (s2.size() < sizeof(sockaddr_in))) 00634 return false; 00635 00636 struct sockaddr_in *sin1 = (sockaddr_in *) s1.address(); 00637 struct sockaddr_in *sin2 = (sockaddr_in *) s2.address(); 00638 00639 if (coreOnly) 00640 return (memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(struct in_addr)) == 0); 00641 else 00642 return (sin1->sin_port == sin2->sin_port) && 00643 (memcmp(&sin1->sin_addr, &sin2->sin_addr, sizeof(struct in_addr)) == 0); 00644 } 00645 00646 bool KInetSocketAddress::areEqualInet6(const KSocketAddress &s1, const KSocketAddress &s2, bool coreOnly) 00647 { 00648 #ifdef AF_INET6 00649 if (s1.family() != s2.family()) 00650 return false; 00651 00652 if ((s1.size() < sizeof(sockaddr_in6)) || (s2.size() < sizeof(sockaddr_in6))) 00653 return false; 00654 00655 struct sockaddr_in6 *sin1 = (sockaddr_in6 *) s1.address(); 00656 struct sockaddr_in6 *sin2 = (sockaddr_in6 *) s2.address(); 00657 00658 if (coreOnly) 00659 return (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof(struct in6_addr)) == 0); 00660 else 00661 return (sin1->sin6_port == sin2->sin6_port) && 00662 (sin1->sin6_flowinfo == sin2->sin6_flowinfo) && 00663 #ifdef HAVE_SOCKADDR_IN6_SCOPE_ID 00664 (sin1->sin6_scope_id == sin2->sin6_scope_id) && 00665 #endif 00666 (memcmp(&sin1->sin6_addr, &sin2->sin6_addr, sizeof(struct in6_addr)) == 0); 00667 #else 00668 return false; 00669 #endif 00670 } 00671 00672 void KInetSocketAddress::fromV4() 00673 { 00674 // converts an address from v4 00675 00676 #ifdef AF_INET6 00677 d->sin6.sin6_port = d->sin.sin_port; 00678 00679 // Make this a v4-mapped address 00680 ((Q_UINT32*)&d->sin6.sin6_addr)[0] = ((Q_UINT32*)&d->sin6.sin6_addr)[1] = 0; 00681 ((Q_UINT32*)&d->sin6.sin6_addr)[2] = htonl(0xffff); 00682 ((Q_UINT32*)&d->sin6.sin6_addr)[3] = *(Q_UINT32*)&d->sin.sin_addr; 00683 00684 // Clear flowinfo and scopeid 00685 d->sin6.sin6_flowinfo = 0; 00686 # ifdef HAVE_SOCKADDR_IN6_SCOPE_ID 00687 d->sin6.sin6_scope_id = 0; 00688 # endif 00689 #endif 00690 00691 // data == KSocketAddress::data 00692 data = (sockaddr*)&d->sin; 00693 datasize = sizeof( sockaddr_in ); 00694 } 00695 00696 void KInetSocketAddress::fromV6() 00697 { 00698 #ifdef AF_INET6 00699 // convert to v4 only if this is a v4-mapped or v4-compat address 00700 if (V6_CAN_CONVERT_TO_V4(&d->sin6.sin6_addr)) 00701 { 00702 d->sin.sin_port = d->sin6.sin6_port; 00703 *(Q_UINT32*)&d->sin.sin_addr = ((Q_UINT32*)&d->sin6.sin6_addr)[3]; 00704 } 00705 else 00706 { 00707 d->sin.sin_port = 0; 00708 memset(&d->sin.sin_addr, 0, sizeof(d->sin.sin_addr)); 00709 } 00710 00711 data = (sockaddr*)&d->sin6; 00712 datasize = sizeof( d->sin6 ); 00713 #endif 00714 } 00715 00716 QString KInetSocketAddress::addrToString(int family, const void* addr) 00717 { 00718 char buf[INET6_ADDRSTRLEN+1]; 00719 00720 return QString::fromLatin1(inet_ntop(family, addr, buf, INET6_ADDRSTRLEN)); 00721 } 00722 00723 bool KInetSocketAddress::stringToAddr(int family, const char *text, void *dest) 00724 { 00725 return inet_pton(family, text, dest) != 0; 00726 } 00727 00732 class KUnixSocketAddressPrivate 00733 { 00734 public: 00735 sockaddr_un *m_sun; 00736 00737 KUnixSocketAddressPrivate() : m_sun(NULL) 00738 { } 00739 }; 00740 00741 KUnixSocketAddress::KUnixSocketAddress() : 00742 d(new KUnixSocketAddressPrivate) 00743 { 00744 } 00745 00746 KUnixSocketAddress::KUnixSocketAddress(const sockaddr_un* _sun, ksocklen_t size) : 00747 d(new KUnixSocketAddressPrivate) 00748 { 00749 setAddress(_sun, size); 00750 } 00751 00752 KUnixSocketAddress::KUnixSocketAddress(QCString pathname) : 00753 d(new KUnixSocketAddressPrivate) 00754 { 00755 setAddress(pathname); 00756 } 00757 00758 KUnixSocketAddress::~KUnixSocketAddress() 00759 { 00760 delete d; 00761 } 00762 00763 bool KUnixSocketAddress::setAddress(const sockaddr_un* _sun, ksocklen_t _size) 00764 { 00765 if (_sun->sun_family != AF_UNIX) 00766 { 00767 kdWarning() << "KUnixSocketAddress::setAddress called with invalid socket\n"; 00768 return false; 00769 } 00770 00771 if (owndata && (d->m_sun != NULL) && (datasize >= _size)) 00772 { 00773 // reuse this without reallocating 00774 memcpy(d->m_sun, _sun, _size); 00775 } 00776 else 00777 { 00778 if (owndata && (d->m_sun != NULL)) 00779 free(d->m_sun); 00780 00781 d->m_sun = (sockaddr_un*)malloc(_size); 00782 00783 if (d->m_sun == NULL) 00784 { 00785 // problems 00786 owndata = false; 00787 return false; 00788 } 00789 00790 memcpy(d->m_sun, _sun, _size); 00791 } 00792 00793 datasize = _size; 00794 data = (sockaddr*)d->m_sun; 00795 owndata = true; 00796 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00797 data->sa_len = _size; 00798 #endif 00799 return 1; 00800 } 00801 00802 bool KUnixSocketAddress::setAddress(QCString path) 00803 { 00804 // the +1 is necessary for the ending zero 00805 ksocklen_t newsize = offsetof(sockaddr_un, sun_path) + path.length() + 1; 00806 00807 if (owndata && (d->m_sun != NULL) && (datasize >= newsize)) 00808 { 00809 // we can reuse this 00810 strcpy(d->m_sun->sun_path, path); 00811 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00812 data->sa_len = newsize; 00813 #endif 00814 return true; 00815 } 00816 00817 // nah, we have to do better 00818 if (owndata && (d->m_sun != NULL)) 00819 free(d->m_sun); 00820 00821 d->m_sun = (sockaddr_un*) malloc(newsize); 00822 if (d->m_sun == NULL) 00823 { 00824 owndata = false; 00825 return false; 00826 } 00827 00828 d->m_sun->sun_family = AF_UNIX; 00829 strcpy(d->m_sun->sun_path, path); 00830 data = (sockaddr*)d->m_sun; 00831 datasize = newsize; 00832 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN 00833 data->sa_len = newsize; 00834 #endif 00835 return 1; 00836 } 00837 00838 QCString KUnixSocketAddress::pathname() const 00839 { 00840 if (d->m_sun != NULL) 00841 { 00842 if (datasize > offsetof(sockaddr_un, sun_path)) 00843 return d->m_sun->sun_path; 00844 return ""; 00845 } 00846 return QCString(0); 00847 } 00848 00849 QString KUnixSocketAddress::pretty() const 00850 { 00851 QCString pname = pathname(); 00852 if (pname.isEmpty()) 00853 return i18n("<empty UNIX socket>"); 00854 return QFile::decodeName(pathname()); 00855 } 00856 00857 QString KUnixSocketAddress::serviceName() const 00858 { 00859 return QString::fromUtf8(pathname()); 00860 } 00861 00862 const sockaddr_un* KUnixSocketAddress::address() const 00863 { 00864 return d->m_sun; 00865 } 00866 00867 bool KUnixSocketAddress::areEqualUnix(const KSocketAddress &s1, const KSocketAddress &s2, bool /* coreOnly */) 00868 { 00869 if (s1.family() != s2.family()) 00870 return false; 00871 00872 if ((s1.size() < MIN_SOCKADDR_LEN) || (s2.size() < MIN_SOCKADDR_LEN)) 00873 return false; 00874 00875 struct sockaddr_un *sun1 = (sockaddr_un *) s1.address(); 00876 struct sockaddr_un *sun2 = (sockaddr_un *) s2.address(); 00877 00878 if (s1.size() == MIN_SOCKADDR_LEN && s2.size() == MIN_SOCKADDR_LEN) 00879 return true; // unnamed Unix sockets 00880 00881 return (strcmp(sun1->sun_path, sun2->sun_path) == 0); 00882 } 00883 00884 void KSocketAddress::virtual_hook( int, void* ) 00885 { /*BASE::virtual_hook( id, data );*/ } 00886 00887 void KInetSocketAddress::virtual_hook( int id, void* data ) 00888 { KSocketAddress::virtual_hook( id, data ); } 00889 00890 void KUnixSocketAddress::virtual_hook( int id, void* data ) 00891 { KSocketAddress::virtual_hook( id, data ); } 00892 00893 00894 #include "ksockaddr.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Mon Aug 30 22:53:32 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003