KDECore
k3reverseresolver.cpp
Go to the documentation of this file.
00001 /* -*- C++ -*- 00002 * Copyright (C) 2003 Thiago Macieira <thiago@kde.org> 00003 * 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining 00006 * a copy of this software and associated documentation files (the 00007 * "Software"), to deal in the Software without restriction, including 00008 * without limitation the rights to use, copy, modify, merge, publish, 00009 * distribute, sublicense, and/or sell copies of the Software, and to 00010 * permit persons to whom the Software is furnished to do so, subject to 00011 * the following conditions: 00012 * 00013 * The above copyright notice and this permission notice shall be included 00014 * in all copies or substantial portions of the Software. 00015 * 00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 #include "k3reverseresolver.h" 00026 00027 #include <config.h> 00028 #include <config-network.h> 00029 00030 // System includes 00031 #include <sys/types.h> 00032 #include <sys/socket.h> 00033 #include <netdb.h> 00034 #include <signal.h> 00035 00036 // Qt 00037 #include <QEvent> 00038 #include <QMutex> 00039 #include <QCoreApplication> 00040 00041 // Us 00042 #include "k3resolver_p.h" 00043 #include "k3resolverworkerbase.h" 00044 #include "k3socketaddress.h" 00045 00046 #ifndef HAVE_GETNAMEINFO 00047 // FIXME KDE4: 00048 // move to syssocket or adapt 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 // input: 00073 KSocketAddress m_addr; 00074 int m_flags; 00075 KReverseResolver *m_parent; 00076 00077 // output: 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; // arbitrary value 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; // already started 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); // call parent 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 // don't delete d->worker! 00186 // KResolverManager::doNotifying takes care of that, if it hasn't already 00187 d->worker = 0L; 00188 00189 // emit signal 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 // post an event 00259 if (m_parent) 00260 QCoreApplication::postEvent(m_parent, 00261 new KReverseResolverEvent(node, service, success)); 00262 return true; 00263 } 00264 00265 #include "k3reverseresolver.moc"
KDE 4.6 API Reference