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"