File indexing completed on 2024-09-29 09:25:06
0001 /* -*- C++ -*- 0002 * Copyright (C) 2003 Thiago Macieira <thiago@kde.org> 0003 * 0004 * 0005 * Permission is hereby granted, free of charge, to any person obtaining 0006 * a copy of this software and associated documentation files (the 0007 * "Software"), to deal in the Software without restriction, including 0008 * without limitation the rights to use, copy, modify, merge, publish, 0009 * distribute, sublicense, and/or sell copies of the Software, and to 0010 * permit persons to whom the Software is furnished to do so, subject to 0011 * the following conditions: 0012 * 0013 * The above copyright notice and this permission notice shall be included 0014 * in all copies or substantial portions of the Software. 0015 * 0016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 0017 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 0018 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 0019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 0020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 0021 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 0022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0023 */ 0024 0025 #include "k3reverseresolver.h" 0026 0027 #include <config-network.h> 0028 0029 // System includes 0030 #include <sys/types.h> 0031 #include <sys/socket.h> 0032 #include <netdb.h> 0033 #include <signal.h> 0034 0035 // Qt 0036 #include <QEvent> 0037 #include <QMutex> 0038 #include <QCoreApplication> 0039 0040 // Us 0041 #include "k3resolver_p.h" 0042 #include "k3resolverworkerbase.h" 0043 0044 #if !HAVE_GETNAMEINFO 0045 // FIXME KDE4: 0046 // move to syssocket or adapt 0047 # include "netsupp.h" 0048 #endif 0049 0050 using namespace KNetwork; 0051 using namespace KNetwork::Internal; 0052 0053 namespace 0054 { 0055 class ReverseThread: public KResolverWorkerBase 0056 { 0057 public: 0058 ReverseThread(const KSocketAddress &addr, int flags) 0059 : m_addr(addr), m_flags(flags), m_parent(nullptr) 0060 { } 0061 0062 ~ReverseThread() override 0063 { } 0064 0065 bool preprocess() override 0066 { 0067 return true; 0068 } 0069 bool run() override; 0070 bool postprocess() override; 0071 0072 // input: 0073 KSocketAddress m_addr; 0074 int m_flags; 0075 KReverseResolver *m_parent; 0076 0077 // output: 0078 QString node; 0079 QString service; 0080 bool success; 0081 }; 0082 0083 class KReverseResolverEvent: public QEvent 0084 { 0085 public: 0086 static const int myType = QEvent::User + 63; // arbitrary value 0087 QString node; 0088 QString service; 0089 bool success; 0090 0091 KReverseResolverEvent(const QString &_node, const QString &_service, 0092 bool _success) 0093 : QEvent((Type)myType), node(_node), 0094 service(_service), success(_success) 0095 { } 0096 }; 0097 } 0098 0099 class KNetwork::KReverseResolverPrivate 0100 { 0101 public: 0102 QString node; 0103 QString service; 0104 KSocketAddress addr; 0105 int flags; 0106 0107 ReverseThread *worker; 0108 bool success; 0109 0110 inline KReverseResolverPrivate(const KSocketAddress &_addr) 0111 : addr(_addr), worker(nullptr), success(false) 0112 { } 0113 }; 0114 0115 KReverseResolver::KReverseResolver(const KSocketAddress &addr, int flags, 0116 QObject *parent) 0117 : QObject(parent), d(new KReverseResolverPrivate(addr)) 0118 { 0119 d->flags = flags; 0120 } 0121 0122 KReverseResolver::~KReverseResolver() 0123 { 0124 if (d->worker) { 0125 d->worker->m_parent = nullptr; 0126 } 0127 delete d; 0128 } 0129 0130 bool KReverseResolver::isRunning() const 0131 { 0132 return d->worker != nullptr; 0133 } 0134 0135 bool KReverseResolver::success() const 0136 { 0137 return !isRunning() && d->success; 0138 } 0139 0140 bool KReverseResolver::failure() const 0141 { 0142 return !isRunning() && !d->success; 0143 } 0144 0145 QString KReverseResolver::node() const 0146 { 0147 return d->node; 0148 } 0149 0150 QString KReverseResolver::service() const 0151 { 0152 return d->service; 0153 } 0154 0155 const KSocketAddress &KReverseResolver::address() const 0156 { 0157 return d->addr; 0158 } 0159 0160 bool KReverseResolver::start() 0161 { 0162 if (d->worker != nullptr) { 0163 return true; // already started 0164 } 0165 0166 d->worker = new ReverseThread(d->addr, d->flags); 0167 d->worker->m_parent = this; 0168 0169 RequestData *req = new RequestData; 0170 req->obj = nullptr; 0171 req->input = nullptr; 0172 req->requestor = nullptr; 0173 req->worker = d->worker; 0174 KResolverManager::manager()->dispatch(req); 0175 return true; 0176 } 0177 0178 bool KReverseResolver::event(QEvent *e) 0179 { 0180 if (e->type() != KReverseResolverEvent::myType) { 0181 return QObject::event(e); // call parent 0182 } 0183 0184 KReverseResolverEvent *re = static_cast<KReverseResolverEvent *>(e); 0185 d->node = re->node; 0186 d->service = re->service; 0187 d->success = re->success; 0188 0189 // don't delete d->worker! 0190 // KResolverManager::doNotifying takes care of that, if it hasn't already 0191 d->worker = nullptr; 0192 0193 // emit signal 0194 emit finished(*this); 0195 0196 return true; 0197 } 0198 0199 bool KReverseResolver::resolve(const KSocketAddress &addr, QString &node, 0200 QString &serv, int flags) 0201 { 0202 ReverseThread th(addr, flags); 0203 if (th.run()) { 0204 node = th.node; 0205 serv = th.service; 0206 return true; 0207 } 0208 return false; 0209 } 0210 0211 bool KReverseResolver::resolve(const struct sockaddr *sa, quint16 salen, 0212 QString &node, QString &serv, int flags) 0213 { 0214 return resolve(KSocketAddress(sa, salen), node, serv, flags); 0215 } 0216 0217 bool ReverseThread::run() 0218 { 0219 int err; 0220 char h[NI_MAXHOST], s[NI_MAXSERV]; 0221 int niflags = 0; 0222 0223 h[0] = s[0] = '\0'; 0224 0225 if (m_flags & KReverseResolver::NumericHost) { 0226 niflags |= NI_NUMERICHOST; 0227 } 0228 if (m_flags & KReverseResolver::NumericService) { 0229 niflags |= NI_NUMERICSERV; 0230 } 0231 if (m_flags & KReverseResolver::NodeNameOnly) { 0232 niflags |= NI_NOFQDN; 0233 } 0234 if (m_flags & KReverseResolver::Datagram) { 0235 niflags |= NI_DGRAM; 0236 } 0237 if (m_flags & KReverseResolver::ResolutionRequired) { 0238 niflags |= NI_NAMEREQD; 0239 } 0240 0241 { 0242 #ifdef NEED_MUTEX 0243 QMutexLocker locker(&::getXXbyYYmutex); 0244 #endif 0245 err = ::getnameinfo(m_addr, m_addr.length(), 0246 h, sizeof(h) - 1, s, sizeof(s) - 1, niflags); 0247 } 0248 0249 if (err == 0) { 0250 node = KResolver::domainToUnicode(QLatin1String(h)); 0251 service = QLatin1String(s); 0252 success = true; 0253 } else { 0254 node.clear(); service.clear(); 0255 success = false; 0256 } 0257 0258 return success; 0259 } 0260 0261 bool ReverseThread::postprocess() 0262 { 0263 // post an event 0264 if (m_parent) 0265 QCoreApplication::postEvent(m_parent, 0266 new KReverseResolverEvent(node, service, success)); 0267 return true; 0268 } 0269 0270 #include "moc_k3reverseresolver.cpp"