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