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"