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
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
00065
KSocketAddress m_addr;
00066
int m_flags;
00067
KReverseResolver *m_parent;
00068
00069
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;
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;
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);
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
00178
00179 d->worker = 0L;
00180
00181
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
00251
if (m_parent)
00252 QApplication::postEvent(m_parent,
00253
new KReverseResolverEvent(node, service, success));
00254
return true;
00255 }
00256
00257
#include "kreverseresolver.moc"