• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KIO

hostinfo.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2008 Roland Harnau <tau@gmx.eu>
00003 
00004 This library is free software; you can redistribute it and/or
00005 modify it under the terms of the GNU Lesser General Public
00006 License as published by the Free Software Foundation; either
00007 version 2.1 of the License, or (at your option) version 3, or any
00008 later version accepted by the membership of KDE e.V. (or its
00009 successor approved by the membership of KDE e.V.), which shall
00010 act as a proxy defined in Section 6 of version 3 of the license.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "hostinfo_p.h"
00022 
00023 #include <kglobal.h>
00024 #include <QtCore/QString>
00025 #include <QtCore/QHash>
00026 #include <QtCore/QCache>
00027 #include <QtCore/QTime>
00028 #include <QtCore/QList>
00029 #include <QtCore/QPair>
00030 #include <QtCore/QFutureWatcher>
00031 #include <QtCore/QtConcurrentRun>
00032 #include <QtNetwork/QHostInfo>
00033 #include "kdebug.h"
00034 
00035 #ifdef Q_OS_UNIX
00036 # include <QtCore/QFileInfo>
00037 # include <netinet/in.h>
00038 # include <arpa/nameser.h>
00039 # include <resolv.h>            // for _PATH_RESCONF
00040 # ifndef _PATH_RESCONF
00041 #  define _PATH_RESCONF         "/etc/resolv.conf"
00042 # endif
00043 #endif
00044 
00045 #define TTL 300
00046 
00047 namespace KIO
00048 {
00049     class HostInfoAgentPrivate : public QObject
00050     {
00051         Q_OBJECT
00052     public:
00053         HostInfoAgentPrivate(int cacheSize = 100);
00054         virtual ~HostInfoAgentPrivate() {};
00055         void lookupHost(const QString& hostName, QObject* receiver, const char* member);
00056         void setCacheSize(int s) { dnsCache.setMaxCost(s); }
00057         void setTTL(int _ttl) { ttl = _ttl; }
00058     private slots:
00059         void queryFinished(const QHostInfo&);
00060     private:
00061         class Result;
00062         class Query;
00063 
00064         QHash<QString, Query*> openQueries;
00065         QCache<QString, QPair<QHostInfo, QTime> > dnsCache;
00066         time_t resolvConfMTime;
00067         int ttl;
00068     };
00069 
00070     class HostInfoAgentPrivate::Result : public QObject
00071     {
00072         Q_OBJECT
00073     signals:
00074         void result(QHostInfo);
00075     private:
00076         friend class HostInfoAgentPrivate;
00077     };
00078 
00079     class HostInfoAgentPrivate::Query : public QObject
00080     {
00081         Q_OBJECT
00082     public:
00083         Query(): m_watcher(), m_hostName()
00084         {
00085             connect(&m_watcher, SIGNAL(finished()), this, SLOT(relayFinished()));
00086         }
00087         void start(const QString& hostName)
00088         {
00089             m_hostName = hostName;
00090             QFuture<QHostInfo> future = QtConcurrent::run(&QHostInfo::fromName, hostName);
00091             m_watcher.setFuture(future);
00092         }
00093         QString hostName() const
00094         {
00095             return m_hostName;
00096         }
00097     signals:
00098         void result(QHostInfo);
00099     private slots:
00100         void relayFinished()
00101         {
00102             emit result(m_watcher.result());
00103         }
00104     private:
00105         QFutureWatcher<QHostInfo> m_watcher;
00106         QString m_hostName;
00107     };
00108 }
00109 
00110 using namespace KIO;
00111 
00112 K_GLOBAL_STATIC(HostInfoAgentPrivate, hostInfoAgentPrivate)
00113 
00114 void HostInfo::lookupHost(const QString& hostName, QObject* receiver,
00115     const char* member)
00116 {
00117     hostInfoAgentPrivate->lookupHost(hostName, receiver, member);
00118 }
00119 
00120 void HostInfo::prefetchHost(const QString& hostName)
00121 {
00122     hostInfoAgentPrivate->lookupHost(hostName, 0, 0);
00123 }
00124 
00125 void HostInfo::setCacheSize(int s)
00126 {
00127     hostInfoAgentPrivate->setCacheSize(s);
00128 }
00129 
00130 void HostInfo::setTTL(int ttl)
00131 {
00132     hostInfoAgentPrivate->setTTL(ttl);
00133 }
00134 
00135 HostInfoAgentPrivate::HostInfoAgentPrivate(int cacheSize)
00136     : openQueries(),
00137       dnsCache(cacheSize),
00138       resolvConfMTime(0),
00139       ttl(TTL)
00140 {}
00141 
00142 void HostInfoAgentPrivate::lookupHost(const QString& hostName,
00143     QObject* receiver, const char* member)
00144 {
00145 #ifdef _PATH_RESCONF
00146     QFileInfo resolvConf(QFile::decodeName(_PATH_RESCONF));
00147     time_t currentMTime = resolvConf.lastModified().toTime_t();
00148     if (resolvConf.exists() && currentMTime != resolvConfMTime) {
00149         // /etc/resolv.conf has been modified
00150         // clear our cache
00151         resolvConfMTime = currentMTime;
00152         dnsCache.clear();
00153     }
00154 #endif
00155 
00156     if (QPair<QHostInfo, QTime>* info = dnsCache.object(hostName)) {
00157         if (QTime::currentTime() <= info->second.addSecs(ttl)) {
00158             Result result;
00159             if (receiver) {
00160                 QObject::connect(&result, SIGNAL(result(QHostInfo)),receiver, member);
00161                 emit result.result(info->first);
00162             }
00163             return;
00164         }
00165         dnsCache.remove(hostName);
00166     }
00167 
00168     if (Query* query = openQueries.value(hostName)) {
00169         if (receiver) {
00170             connect(query, SIGNAL(result(QHostInfo)), receiver, member);
00171         }
00172         return;
00173     }
00174 
00175     Query* query = new Query();
00176     openQueries.insert(hostName, query);
00177     connect(query, SIGNAL(result(QHostInfo)), this, SLOT(queryFinished(QHostInfo)));
00178     if (receiver) {
00179         connect(query, SIGNAL(result(QHostInfo)), receiver, member);
00180     }
00181     query->start(hostName);
00182 }
00183 
00184 void HostInfoAgentPrivate::queryFinished(const QHostInfo& info)
00185 {
00186     Query* query = static_cast<Query* >(sender());
00187     openQueries.remove(query->hostName());
00188     if (info.error() == QHostInfo::NoError) {
00189         dnsCache.insert(query->hostName(),
00190             new QPair<QHostInfo, QTime>(info, QTime::currentTime()));
00191     }
00192     query->deleteLater();
00193 }
00194 
00195 #include "hostinfo.moc"

KIO

Skip menu "KIO"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal