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

KIOSlave

http_cache_cleaner.cpp

Go to the documentation of this file.
00001 /*
00002 This file is part of KDE
00003 
00004  Copyright (C) 1999-2000 Waldo Bastian (bastian@kde.org)
00005 
00006 Permission is hereby granted, free of charge, to any person obtaining a copy
00007 of this software and associated documentation files (the "Software"), to deal
00008 in the Software without restriction, including without limitation the rights
00009 to use, copy, modify, merge, publish, distribute, and/or sell
00010 copies of the Software, and to permit persons to whom the Software is
00011 furnished to do so, subject to the following conditions:
00012 
00013 The above copyright notice and this permission notice shall be included in
00014 all copies or substantial portions of the Software.
00015 
00016 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00017 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00018 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
00019 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00020 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00021 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00022 */
00023 //----------------------------------------------------------------------------
00024 //
00025 // KDE Http Cache cleanup tool
00026 
00027 #include <time.h>
00028 #include <stdlib.h>
00029 #include <zlib.h>
00030 
00031 #include <QtCore/QDir>
00032 #include <QtCore/QString>
00033 #include <QtDBus/QtDBus>
00034 
00035 #include <kcomponentdata.h>
00036 #include <klocale.h>
00037 #include <kcmdlineargs.h>
00038 #include <kglobal.h>
00039 #include <kstandarddirs.h>
00040 #include <kprotocolmanager.h>
00041 
00042 #include <unistd.h>
00043 
00044 #include <kdebug.h>
00045 
00046 time_t currentDate;
00047 int m_maxCacheAge;
00048 int m_maxCacheSize;
00049 
00050 static const char appFullName[] = "org.kde.kio_http_cache_cleaner";
00051 static const char appName[] = "kio_http_cache_cleaner";
00052 
00053 static const char version[] = "9";
00054 
00055 struct FileInfo {
00056    QString name;
00057    int size; // Size in Kb.
00058 //    int age;
00059    int rating;
00060 
00061    bool operator<( const struct FileInfo &info )
00062    {
00063      return ( rating < info.rating);
00064    }
00065 };
00066 
00067 template class QList<FileInfo*>;
00068 
00069 class FileInfoList : public QList<FileInfo*>
00070 {
00071 public:
00072    FileInfoList() : QList<FileInfo*>() { }
00073 };
00074 
00075 // !START OF SYNC!
00076 // Keep the following in sync with the cache code in http.cpp
00077 #define CACHE_REVISION "9\n"
00078 
00079 FileInfo *readEntry( const QString &filename)
00080 {
00081    QByteArray CEF = QFile::encodeName(filename);
00082    gzFile fs = gzopen( CEF.data(), "r");
00083    if (!fs)
00084       return 0;
00085 
00086    char buffer[401];
00087    bool ok = true;
00088 
00089   // CacheRevision
00090   if (ok && (!gzgets(fs, buffer, 400)))
00091       ok = false;
00092    if (ok && (strcmp(buffer, CACHE_REVISION) != 0))
00093       ok = false;
00094 
00095    // Full URL
00096    if (ok && (!gzgets(fs, buffer, 400)))
00097       ok = false;
00098 
00099    time_t creationDate;
00100    int age =0;
00101 
00102    // Creation Date
00103    if (ok && (!gzgets(fs, buffer, 400)))
00104       ok = false;
00105    if (ok)
00106    {
00107       creationDate = (time_t) strtoul(buffer, 0, 10);
00108       age = (int) difftime(currentDate, creationDate);
00109       if ( m_maxCacheAge && ( age > m_maxCacheAge))
00110       {
00111          ok = false; // Expired
00112       }
00113    }
00114 
00115    // Expiration Date
00116    if (ok && (!gzgets(fs, buffer, 400)))
00117       ok = false;
00118    if (ok)
00119    {
00120 //WABA: It seems I slightly misunderstood the meaning of "Expire:" header.
00121 #if 0
00122       time_t expireDate;
00123       expireDate = (time_t) strtoul(buffer, 0, 10);
00124       if (expireDate && (expireDate < currentDate))
00125          ok = false; // Expired
00126 #endif
00127    }
00128 
00129    // ETag
00130    if (ok && (!gzgets(fs, buffer, 400)))
00131       ok = false;
00132    if (ok)
00133    {
00134       // Ignore ETag
00135    }
00136 
00137    // Last-Modified
00138    if (ok && (!gzgets(fs, buffer, 400)))
00139       ok = false;
00140    if (ok)
00141    {
00142       // Ignore Last-Modified
00143    }
00144 
00145 
00146    gzclose(fs);
00147    if (ok)
00148    {
00149       FileInfo *info = new FileInfo;
00150 
00151       int freq=0;
00152       FILE* hitdata = fopen( QFile::encodeName(CEF+"_freq"), "r+");
00153       if (hitdata && (freq=fgetc(hitdata))!=EOF)
00154       {
00155          freq+=fgetc(hitdata)<<8;
00156          if (freq>0)
00157             info->rating=age/freq;
00158          else
00159             info->rating=age;
00160          fclose(hitdata);
00161       }
00162       else
00163          info->rating = age;
00164       return info;
00165    }
00166 
00167    unlink( CEF.data());
00168    return 0;
00169 }
00170 // Keep the above in sync with the cache code in http.cc
00171 // !END OF SYNC!
00172 
00173 void scanDirectory(FileInfoList &fileEntries, const QString &name, const QString &strDir)
00174 {
00175    QDir dir(strDir);
00176    if (!dir.exists()) return;
00177 
00178    QFileInfoList newEntries = dir.entryInfoList();
00179 
00180    if (newEntries.count()==0) return; // Directory not accessible ??
00181 
00182    foreach ( const QFileInfo &qFileInfo, newEntries ) {
00183        if (qFileInfo.isFile())
00184        {
00185           FileInfo *fileInfo = readEntry( strDir + '/' + qFileInfo.fileName());
00186           if (fileInfo)
00187           {
00188              fileInfo->name = name + '/' + qFileInfo.fileName();
00189              fileInfo->size = (qFileInfo.size() + 1023) / 1024;
00190              fileEntries.append(fileInfo);
00191           }
00192        }
00193    }
00194 }
00195 
00196 extern "C" KDE_EXPORT int kdemain(int argc, char **argv)
00197 {
00198    KCmdLineArgs::init( argc, argv, appName, "kdelibs4",
00199                ki18n("KDE HTTP cache maintenance tool"), version,
00200                ki18n("KDE HTTP cache maintenance tool"), KCmdLineArgs::CmdLineArgNone);
00201 
00202    KCmdLineOptions options;
00203    options.add("clear-all", ki18n("Empty the cache"));
00204 
00205    KCmdLineArgs::addCmdLineOptions( options );
00206 
00207    KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00208 
00209    bool deleteAll = args->isSet("clear-all");
00210 
00211    KComponentData ins( appName );
00212 
00213    if (!deleteAll)
00214    {
00215       if (!QDBusConnection::sessionBus().isConnected())
00216       {
00217          QDBusError error(QDBusConnection::sessionBus().lastError());
00218          fprintf(stderr, "%s: Could not connect to D-Bus! (%s: %s)\n", appName,
00219                  qPrintable(error.name()), qPrintable(error.message()));
00220          return 1;
00221       }
00222 
00223       if (!QDBusConnection::sessionBus().registerService(appFullName))
00224       {
00225          fprintf(stderr, "%s: Already running!\n", appName);
00226          return 0;
00227       }
00228    }
00229 
00230    currentDate = time(0);
00231    m_maxCacheAge = KProtocolManager::maxCacheAge();
00232    m_maxCacheSize = KProtocolManager::maxCacheSize();
00233 
00234    if (deleteAll)
00235       m_maxCacheSize = -1;
00236 
00237    QString strCacheDir = KGlobal::dirs()->saveLocation("cache", "http");
00238 
00239    QDir cacheDir( strCacheDir );
00240    if (!cacheDir.exists())
00241    {
00242       fprintf(stderr, "%s: '%s' does not exist.\n", appName, qPrintable(strCacheDir));
00243       return 0;
00244    }
00245 
00246    const QStringList dirs = cacheDir.entryList( );
00247 
00248    FileInfoList cachedEntries;
00249 
00250    for(QStringList::ConstIterator it = dirs.begin();
00251        it != dirs.end();
00252        ++it)
00253    {
00254       if (it->at(0) != '.')
00255       {
00256          scanDirectory( cachedEntries, *it, strCacheDir + '/' + *it);
00257       }
00258    }
00259 
00260    qSort(cachedEntries.begin(), cachedEntries.end());
00261 
00262    int maxCachedSize = m_maxCacheSize / 2;
00263 
00264    Q_FOREACH( FileInfo *fileInfo , cachedEntries )
00265    {
00266       if (fileInfo->size > maxCachedSize)
00267       {
00268          QByteArray filename = QFile::encodeName( strCacheDir + '/' + fileInfo->name);
00269          unlink(filename.data());
00270 //         kDebug (7113) << appName << ": Object too big, deleting '" << filename.data() << "' (" << result<< ")";
00271       }
00272    }
00273 
00274    int totalSize = 0;
00275 
00276    Q_FOREACH( FileInfo *fileInfo , cachedEntries )
00277    {
00278       if ((totalSize + fileInfo->size) > m_maxCacheSize)
00279       {
00280          QByteArray filename = QFile::encodeName( strCacheDir + '/' + fileInfo->name);
00281          unlink(filename.data());
00282 //         kDebug (7113) << appName << ": Cache too big, deleting '" << filename.data() << "' (" << fileInfo->size << ")";
00283       }
00284       else
00285       {
00286          totalSize += fileInfo->size;
00287 // fprintf(stderr, "Keep in cache: %s %d %d total = %d\n", fileInfo->name.toAscii().constData(), fileInfo->size, fileInfo->age, totalSize);
00288       }
00289    }
00290    kDebug (7113) << appName << ": Current size of cache = " << totalSize << " kB.";
00291    return 0;
00292 }

KIOSlave

Skip menu "KIOSlave"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • 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