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 delete d; 00127 } 00128 00129 bool KReverseResolver::isRunning() const 00130 { 00131 return d->worker != 0L; 00132 } 00133 00134 bool KReverseResolver::success() const 00135 { 00136 return !isRunning() && d->success; 00137 } 00138 00139 bool KReverseResolver::failure() const 00140 { 00141 return !isRunning() && !d->success; 00142 } 00143 00144 QString KReverseResolver::node() const 00145 { 00146 return d->node; 00147 } 00148 00149 QString KReverseResolver::service() const 00150 { 00151 return d->service; 00152 } 00153 00154 const KSocketAddress& KReverseResolver::address() const 00155 { 00156 return d->addr; 00157 } 00158 00159 bool KReverseResolver::start() 00160 { 00161 if (d->worker != 0L) 00162 return true; // already started 00163 00164 d->worker = new ReverseThread(d->addr, d->flags); 00165 d->worker->m_parent = this; 00166 00167 RequestData *req = new RequestData; 00168 req->obj = 0L; 00169 req->input = 0L; 00170 req->requestor = 0L; 00171 req->worker = d->worker; 00172 KResolverManager::manager()->dispatch(req); 00173 return true; 00174 } 00175 00176 bool KReverseResolver::event(QEvent *e) 00177 { 00178 if (e->type() != KReverseResolverEvent::myType) 00179 return QObject::event(e); // call parent 00180 00181 KReverseResolverEvent *re = static_cast<KReverseResolverEvent*>(e); 00182 d->node = re->node; 00183 d->service = re->service; 00184 d->success = re->success; 00185 00186 // don't delete d->worker! 00187 // KResolverManager::doNotifying takes care of that, if it hasn't already 00188 d->worker = 0L; 00189 00190 // emit signal 00191 emit finished(*this); 00192 00193 return true; 00194 } 00195 00196 bool KReverseResolver::resolve(const KSocketAddress& addr, QString& node, 00197 QString& serv, int flags) 00198 { 00199 ReverseThread th(addr, flags); 00200 if (th.run()) 00201 { 00202 node = th.node; 00203 serv = th.service; 00204 return true; 00205 } 00206 return false; 00207 } 00208 00209 bool KReverseResolver::resolve(const struct sockaddr* sa, quint16 salen, 00210 QString& node, QString& serv, int flags) 00211 { 00212 return resolve(KSocketAddress(sa, salen), node, serv, flags); 00213 } 00214 00215 bool ReverseThread::run() 00216 { 00217 int err; 00218 char h[NI_MAXHOST], s[NI_MAXSERV]; 00219 int niflags = 0; 00220 00221 h[0] = s[0] = '\0'; 00222 00223 if (m_flags & KReverseResolver::NumericHost) 00224 niflags |= NI_NUMERICHOST; 00225 if (m_flags & KReverseResolver::NumericService) 00226 niflags |= NI_NUMERICSERV; 00227 if (m_flags & KReverseResolver::NodeNameOnly) 00228 niflags |= NI_NOFQDN; 00229 if (m_flags & KReverseResolver::Datagram) 00230 niflags |= NI_DGRAM; 00231 if (m_flags & KReverseResolver::ResolutionRequired) 00232 niflags |= NI_NAMEREQD; 00233 00234 { 00235 #ifdef NEED_MUTEX 00236 QMutexLocker locker(&::getXXbyYYmutex); 00237 #endif 00238 err = ::getnameinfo(m_addr, m_addr.length(), 00239 h, sizeof(h) - 1, s, sizeof(s) - 1, niflags); 00240 } 00241 00242 if (err == 0) 00243 { 00244 node = KResolver::domainToUnicode(QLatin1String(h)); 00245 service = QLatin1String(s); 00246 success = true; 00247 } 00248 else 00249 { 00250 node.clear(); service.clear(); 00251 success = false; 00252 } 00253 00254 return success; 00255 } 00256 00257 bool ReverseThread::postprocess() 00258 { 00259 // post an event 00260 if (m_parent) 00261 QCoreApplication::postEvent(m_parent, 00262 new KReverseResolverEvent(node, service, success)); 00263 return true; 00264 } 00265 00266 #include "k3reverseresolver.moc"
KDE 4.7 API Reference