kdecore Library API Documentation

kreverseresolver.cpp

00001 /*  -*- C++ -*-
00002  *  Copyright (C) 2003 Thiago Macieira <thiago.macieira@kdemail.net>
00003  *
00004  *
00005  *  Permission is hereby granted, free of charge, to any person obtaining
00006  *  a copy of this software and associated documentation files (the
00007  *  "Software"), to deal in the Software without restriction, including
00008  *  without limitation the rights to use, copy, modify, merge, publish,
00009  *  distribute, sublicense, and/or sell copies of the Software, and to
00010  *  permit persons to whom the Software is furnished to do so, subject to
00011  *  the following conditions:
00012  *
00013  *  The above copyright notice and this permission notice shall be included 
00014  *  in all copies or substantial portions of the Software.
00015  *
00016  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00017  *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00018  *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00019  *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00020  *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00021  *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00022  *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023  */
00024 
00025 #include "config.h"
00026 
00027 // System includes
00028 #include <sys/types.h>
00029 #include <sys/socket.h>
00030 #include <netdb.h>
00031 #include <signal.h>
00032 
00033 // Qt
00034 #include <qevent.h>
00035 #include <qmutex.h>
00036 #include <qapplication.h>
00037 
00038 // Us
00039 #include "kreverseresolver.h"
00040 #include "kresolver_p.h"
00041 #include "kresolverworkerbase.h"
00042 #include "ksocketaddress.h"
00043 
00044 using namespace KNetwork;
00045 using namespace KNetwork::Internal;
00046 
00047 namespace
00048 {
00049   class ReverseThread: public KResolverWorkerBase
00050   {
00051   public:
00052     ReverseThread(const KSocketAddress& addr, int flags)
00053       : m_addr(addr), m_flags(flags), m_parent(0L)
00054     { }
00055 
00056     virtual ~ReverseThread()
00057     { }
00058 
00059     virtual bool preprocess()
00060     { return true; }
00061     virtual bool run();
00062     virtual bool postprocess();
00063 
00064     // input:
00065     KSocketAddress m_addr;
00066     int m_flags;
00067     KReverseResolver *m_parent;
00068 
00069     // output:
00070     QString node;
00071     QString service;
00072     bool success;
00073   };
00074 
00075   class KReverseResolverEvent: public QEvent
00076   {
00077   public:
00078     static const int myType = QEvent::User + 63; // arbitrary value
00079     QString node;
00080     QString service;
00081     bool success;
00082 
00083     KReverseResolverEvent(const QString& _node, const QString& _service,
00084               bool _success)
00085       : QEvent((Type)myType), node(_node), 
00086     service(_service), success(_success)
00087     { }
00088   };
00089 }
00090 
00091 class KNetwork::KReverseResolverPrivate
00092 {
00093 public:
00094   QString node;
00095   QString service;
00096   KSocketAddress addr;
00097   int flags;
00098 
00099   ReverseThread* worker;
00100   bool success;
00101 
00102   inline KReverseResolverPrivate(const KSocketAddress& _addr)
00103     : addr(_addr), worker(0L), success(false)
00104   { }
00105 };
00106 
00107 KReverseResolver::KReverseResolver(const KSocketAddress& addr, int flags,
00108                    QObject *parent, const char* name)
00109   : QObject(parent, name), d(new KReverseResolverPrivate(addr))
00110 {
00111   d->flags = flags;
00112 }
00113 
00114 KReverseResolver::~KReverseResolver()
00115 {
00116   if (d->worker)
00117     d->worker->m_parent = 0L;
00118 }
00119 
00120 bool KReverseResolver::isRunning() const
00121 {
00122   return d->worker != 0L;
00123 }
00124 
00125 bool KReverseResolver::success() const
00126 {
00127   return !isRunning() && d->success;
00128 }
00129 
00130 bool KReverseResolver::failure() const
00131 {
00132   return !isRunning() && !d->success;
00133 }
00134 
00135 QString KReverseResolver::node() const
00136 {
00137   return d->node;
00138 }
00139 
00140 QString KReverseResolver::service() const
00141 {
00142   return d->service;
00143 }
00144 
00145 const KSocketAddress& KReverseResolver::address() const
00146 {
00147   return d->addr;
00148 }
00149 
00150 bool KReverseResolver::start()
00151 {
00152   if (d->worker != 0L)
00153     return true;        // already started
00154 
00155   d->worker = new ReverseThread(d->addr, d->flags);
00156   d->worker->m_parent = this;
00157 
00158   RequestData *req = new RequestData;
00159   req->obj = 0L;
00160   req->input = 0L;
00161   req->requestor = 0L;
00162   req->worker = d->worker;
00163   KResolverManager::manager()->dispatch(req);
00164   return true;
00165 }
00166 
00167 bool KReverseResolver::event(QEvent *e)
00168 {
00169   if (e->type() != KReverseResolverEvent::myType)
00170     return QObject::event(e);   // call parent
00171 
00172   KReverseResolverEvent *re = static_cast<KReverseResolverEvent*>(e);
00173   d->node = re->node;
00174   d->service = re->service;
00175   d->success = re->success;
00176 
00177   // don't delete d->worker!
00178   // KResolverManager::doNotifying takes care of that, if it hasn't already
00179   d->worker = 0L;
00180 
00181   // emit signal
00182   emit finished(*this); 
00183 
00184   return true;
00185 }
00186 
00187 bool KReverseResolver::resolve(const KSocketAddress& addr, QString& node,
00188                    QString& serv, int flags)
00189 {
00190   ReverseThread th(addr, flags);
00191   if (th.run())
00192     {
00193       node = th.node;
00194       serv = th.service;
00195       return true;
00196     }
00197   return false;
00198 }
00199 
00200 bool KReverseResolver::resolve(const struct sockaddr* sa, Q_UINT16 salen,
00201                    QString& node, QString& serv, int flags)
00202 {
00203   return resolve(KSocketAddress(sa, salen), node, serv, flags);
00204 }
00205 
00206 bool ReverseThread::run()
00207 {
00208   int err;
00209   char h[NI_MAXHOST], s[NI_MAXSERV];
00210   int niflags = 0;
00211 
00212   h[0] = s[0] = '\0';
00213 
00214   if (m_flags & KReverseResolver::NumericHost)
00215     niflags |= NI_NUMERICHOST;
00216   if (m_flags & KReverseResolver::NumericService)
00217     niflags |= NI_NUMERICSERV;
00218   if (m_flags & KReverseResolver::NodeNameOnly)
00219     niflags |= NI_NOFQDN;
00220   if (m_flags & KReverseResolver::Datagram)
00221     niflags |= NI_DGRAM;
00222   if (m_flags & KReverseResolver::ResolutionRequired)
00223     niflags |= NI_NAMEREQD;
00224 
00225   {
00226 #ifdef NEED_MUTEX
00227     QMutexLocker locker(&getXXbyYYmutex);
00228 #endif
00229     err = ::getnameinfo(m_addr, m_addr.length(),
00230             h, sizeof(h) - 1, s, sizeof(s) - 1, niflags);
00231   }
00232 
00233   if (err == 0)
00234     {
00235       node = KResolver::domainToUnicode(QString::fromLatin1(h));
00236       service = QString::fromLatin1(s);
00237       success = true;
00238     }
00239   else
00240     {
00241       node = service = QString::null;
00242       success = false;
00243     }
00244 
00245   return success;
00246 }
00247 
00248 bool ReverseThread::postprocess()
00249 {
00250   // post an event
00251   if (m_parent)
00252     QApplication::postEvent(m_parent,
00253                 new KReverseResolverEvent(node, service, success));
00254   return true;
00255 }
00256 
00257 #include "kreverseresolver.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 Fri Feb 18 15:10:00 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003