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.1.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat Jan 22 16:43:46 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003