KDECore
k3reverseresolver.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "k3reverseresolver.h"
00026
00027 #include <config.h>
00028 #include <config-network.h>
00029
00030
00031 #include <sys/types.h>
00032 #include <sys/socket.h>
00033 #include <netdb.h>
00034 #include <signal.h>
00035
00036
00037 #include <QEvent>
00038 #include <QMutex>
00039 #include <QCoreApplication>
00040
00041
00042 #include "k3resolver_p.h"
00043 #include "k3resolverworkerbase.h"
00044 #include "k3socketaddress.h"
00045
00046 #ifndef HAVE_GETNAMEINFO
00047
00048
00049 # include "netsupp.h"
00050 #endif
00051
00052 using namespace KNetwork;
00053 using namespace KNetwork::Internal;
00054
00055 namespace
00056 {
00057 class ReverseThread: public KResolverWorkerBase
00058 {
00059 public:
00060 ReverseThread(const KSocketAddress& addr, int flags)
00061 : m_addr(addr), m_flags(flags), m_parent(0L)
00062 { }
00063
00064 virtual ~ReverseThread()
00065 { }
00066
00067 virtual bool preprocess()
00068 { return true; }
00069 virtual bool run();
00070 virtual bool postprocess();
00071
00072
00073 KSocketAddress m_addr;
00074 int m_flags;
00075 KReverseResolver *m_parent;
00076
00077
00078 QString node;
00079 QString service;
00080 bool success;
00081 };
00082
00083 class KReverseResolverEvent: public QEvent
00084 {
00085 public:
00086 static const int myType = QEvent::User + 63;
00087 QString node;
00088 QString service;
00089 bool success;
00090
00091 KReverseResolverEvent(const QString& _node, const QString& _service,
00092 bool _success)
00093 : QEvent((Type)myType), node(_node),
00094 service(_service), success(_success)
00095 { }
00096 };
00097 }
00098
00099 class KNetwork::KReverseResolverPrivate
00100 {
00101 public:
00102 QString node;
00103 QString service;
00104 KSocketAddress addr;
00105 int flags;
00106
00107 ReverseThread* worker;
00108 bool success;
00109
00110 inline KReverseResolverPrivate(const KSocketAddress& _addr)
00111 : addr(_addr), worker(0L), success(false)
00112 { }
00113 };
00114
00115 KReverseResolver::KReverseResolver(const KSocketAddress& addr, int flags,
00116 QObject *parent)
00117 : QObject(parent), d(new KReverseResolverPrivate(addr))
00118 {
00119 d->flags = flags;
00120 }
00121
00122 KReverseResolver::~KReverseResolver()
00123 {
00124 if (d->worker)
00125 d->worker->m_parent = 0L;
00126 }
00127
00128 bool KReverseResolver::isRunning() const
00129 {
00130 return d->worker != 0L;
00131 }
00132
00133 bool KReverseResolver::success() const
00134 {
00135 return !isRunning() && d->success;
00136 }
00137
00138 bool KReverseResolver::failure() const
00139 {
00140 return !isRunning() && !d->success;
00141 }
00142
00143 QString KReverseResolver::node() const
00144 {
00145 return d->node;
00146 }
00147
00148 QString KReverseResolver::service() const
00149 {
00150 return d->service;
00151 }
00152
00153 const KSocketAddress& KReverseResolver::address() const
00154 {
00155 return d->addr;
00156 }
00157
00158 bool KReverseResolver::start()
00159 {
00160 if (d->worker != 0L)
00161 return true;
00162
00163 d->worker = new ReverseThread(d->addr, d->flags);
00164 d->worker->m_parent = this;
00165
00166 RequestData *req = new RequestData;
00167 req->obj = 0L;
00168 req->input = 0L;
00169 req->requestor = 0L;
00170 req->worker = d->worker;
00171 KResolverManager::manager()->dispatch(req);
00172 return true;
00173 }
00174
00175 bool KReverseResolver::event(QEvent *e)
00176 {
00177 if (e->type() != KReverseResolverEvent::myType)
00178 return QObject::event(e);
00179
00180 KReverseResolverEvent *re = static_cast<KReverseResolverEvent*>(e);
00181 d->node = re->node;
00182 d->service = re->service;
00183 d->success = re->success;
00184
00185
00186
00187 d->worker = 0L;
00188
00189
00190 emit finished(*this);
00191
00192 return true;
00193 }
00194
00195 bool KReverseResolver::resolve(const KSocketAddress& addr, QString& node,
00196 QString& serv, int flags)
00197 {
00198 ReverseThread th(addr, flags);
00199 if (th.run())
00200 {
00201 node = th.node;
00202 serv = th.service;
00203 return true;
00204 }
00205 return false;
00206 }
00207
00208 bool KReverseResolver::resolve(const struct sockaddr* sa, quint16 salen,
00209 QString& node, QString& serv, int flags)
00210 {
00211 return resolve(KSocketAddress(sa, salen), node, serv, flags);
00212 }
00213
00214 bool ReverseThread::run()
00215 {
00216 int err;
00217 char h[NI_MAXHOST], s[NI_MAXSERV];
00218 int niflags = 0;
00219
00220 h[0] = s[0] = '\0';
00221
00222 if (m_flags & KReverseResolver::NumericHost)
00223 niflags |= NI_NUMERICHOST;
00224 if (m_flags & KReverseResolver::NumericService)
00225 niflags |= NI_NUMERICSERV;
00226 if (m_flags & KReverseResolver::NodeNameOnly)
00227 niflags |= NI_NOFQDN;
00228 if (m_flags & KReverseResolver::Datagram)
00229 niflags |= NI_DGRAM;
00230 if (m_flags & KReverseResolver::ResolutionRequired)
00231 niflags |= NI_NAMEREQD;
00232
00233 {
00234 #ifdef NEED_MUTEX
00235 QMutexLocker locker(&::getXXbyYYmutex);
00236 #endif
00237 err = ::getnameinfo(m_addr, m_addr.length(),
00238 h, sizeof(h) - 1, s, sizeof(s) - 1, niflags);
00239 }
00240
00241 if (err == 0)
00242 {
00243 node = KResolver::domainToUnicode(QLatin1String(h));
00244 service = QLatin1String(s);
00245 success = true;
00246 }
00247 else
00248 {
00249 node.clear(); service.clear();
00250 success = false;
00251 }
00252
00253 return success;
00254 }
00255
00256 bool ReverseThread::postprocess()
00257 {
00258
00259 if (m_parent)
00260 QCoreApplication::postEvent(m_parent,
00261 new KReverseResolverEvent(node, service, success));
00262 return true;
00263 }
00264
00265 #include "k3reverseresolver.moc"