kdecore Library API Documentation

ksockaddr.cpp

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