kioslave
http_cache_cleaner.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <time.h>
00029 #include <stdlib.h>
00030
00031 #include <qdir.h>
00032 #include <qstring.h>
00033 #include <qptrlist.h>
00034
00035 #include <kinstance.h>
00036 #include <klocale.h>
00037 #include <kcmdlineargs.h>
00038 #include <kglobal.h>
00039 #include <kstandarddirs.h>
00040 #include <dcopclient.h>
00041 #include <kprotocolmanager.h>
00042
00043 #include <unistd.h>
00044
00045 #include <kdebug.h>
00046
00047 time_t currentDate;
00048 int m_maxCacheAge;
00049 int m_maxCacheSize;
00050
00051 static const char appName[] = "kio_http_cache_cleaner";
00052
00053 static const char description[] = I18N_NOOP("KDE HTTP cache maintenance tool");
00054
00055 static const char version[] = "1.0.0";
00056
00057 static const KCmdLineOptions options[] =
00058 {
00059 {"clear-all", I18N_NOOP("Empty the cache"), 0},
00060 KCmdLineLastOption
00061 };
00062
00063 struct FileInfo {
00064 QString name;
00065 int size;
00066 int age;
00067 };
00068
00069 template class QPtrList<FileInfo>;
00070
00071 class FileInfoList : public QPtrList<FileInfo>
00072 {
00073 public:
00074 FileInfoList() : QPtrList<FileInfo>() { }
00075 int compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2)
00076 { return ((FileInfo *)item1)->age - ((FileInfo *)item2)->age; }
00077 };
00078
00079
00080
00081 #define CACHE_REVISION "7\n"
00082
00083 FileInfo *readEntry( const QString &filename)
00084 {
00085 QCString CEF = QFile::encodeName(filename);
00086 FILE *fs = fopen( CEF.data(), "r");
00087 if (!fs)
00088 return 0;
00089
00090 char buffer[401];
00091 bool ok = true;
00092
00093
00094 if (ok && (!fgets(buffer, 400, fs)))
00095 ok = false;
00096 if (ok && (strcmp(buffer, CACHE_REVISION) != 0))
00097 ok = false;
00098
00099
00100 if (ok && (!fgets(buffer, 400, fs)))
00101 ok = false;
00102
00103 time_t creationDate;
00104 int age =0;
00105
00106
00107 if (ok && (!fgets(buffer, 400, fs)))
00108 ok = false;
00109 if (ok)
00110 {
00111 creationDate = (time_t) strtoul(buffer, 0, 10);
00112 age = (int) difftime(currentDate, creationDate);
00113 if ( m_maxCacheAge && ( age > m_maxCacheAge))
00114 {
00115 ok = false;
00116 }
00117 }
00118
00119
00120 if (ok && (!fgets(buffer, 400, fs)))
00121 ok = false;
00122 if (ok)
00123 {
00124
00125 #if 0
00126 time_t expireDate;
00127 expireDate = (time_t) strtoul(buffer, 0, 10);
00128 if (expireDate && (expireDate < currentDate))
00129 ok = false;
00130 #endif
00131 }
00132
00133
00134 if (ok && (!fgets(buffer, 400, fs)))
00135 ok = false;
00136 if (ok)
00137 {
00138
00139 }
00140
00141
00142 if (ok && (!fgets(buffer, 400, fs)))
00143 ok = false;
00144 if (ok)
00145 {
00146
00147 }
00148
00149
00150 fclose(fs);
00151 if (ok)
00152 {
00153 FileInfo *info = new FileInfo;
00154 info->age = age;
00155 return info;
00156 }
00157
00158 unlink( CEF.data());
00159 return 0;
00160 }
00161
00162
00163
00164 void scanDirectory(FileInfoList &fileEntries, const QString &name, const QString &strDir)
00165 {
00166 QDir dir(strDir);
00167 if (!dir.exists()) return;
00168
00169 QFileInfoList *newEntries = (QFileInfoList *) dir.entryInfoList();
00170
00171 if (!newEntries) return;
00172
00173 for(QFileInfo *qFileInfo = newEntries->first();
00174 qFileInfo;
00175 qFileInfo = newEntries->next())
00176 {
00177 if (qFileInfo->isFile())
00178 {
00179 FileInfo *fileInfo = readEntry( strDir + "/" + qFileInfo->fileName());
00180 if (fileInfo)
00181 {
00182 fileInfo->name = name + "/" + qFileInfo->fileName();
00183 fileInfo->size = (qFileInfo->size() + 1023) / 1024;
00184 fileEntries.append(fileInfo);
00185 }
00186 }
00187 }
00188 }
00189
00190 extern "C" KDE_EXPORT int kdemain(int argc, char **argv)
00191 {
00192 KLocale::setMainCatalogue("kdelibs");
00193 KCmdLineArgs::init( argc, argv, appName,
00194 I18N_NOOP("KDE HTTP cache maintenance tool"),
00195 description, version, true);
00196
00197 KCmdLineArgs::addCmdLineOptions( options );
00198
00199 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
00200
00201 bool deleteAll = args->isSet("clear-all");
00202
00203 KInstance ins( appName );
00204
00205 if (!deleteAll)
00206 {
00207 DCOPClient *dcop = new DCOPClient();
00208 QCString name = dcop->registerAs(appName, false);
00209 if (!name.isEmpty() && (name != appName))
00210 {
00211 fprintf(stderr, "%s: Already running! (%s)\n", appName, name.data());
00212 return 0;
00213 }
00214 }
00215
00216 currentDate = time(0);
00217 m_maxCacheAge = KProtocolManager::maxCacheAge();
00218 m_maxCacheSize = KProtocolManager::maxCacheSize();
00219
00220 if (deleteAll)
00221 m_maxCacheSize = -1;
00222
00223 QString strCacheDir = KGlobal::dirs()->saveLocation("cache", "http");
00224
00225 QDir cacheDir( strCacheDir );
00226 if (!cacheDir.exists())
00227 {
00228 fprintf(stderr, "%s: '%s' does not exist.\n", appName, strCacheDir.ascii());
00229 return 0;
00230 }
00231
00232 QStringList dirs = cacheDir.entryList( );
00233
00234 FileInfoList cachedEntries;
00235
00236 for(QStringList::Iterator it = dirs.begin();
00237 it != dirs.end();
00238 it++)
00239 {
00240 if ((*it)[0] != '.')
00241 {
00242 scanDirectory( cachedEntries, *it, strCacheDir + "/" + *it);
00243 }
00244 }
00245
00246 cachedEntries.sort();
00247
00248 int maxCachedSize = m_maxCacheSize / 2;
00249
00250 for(FileInfo *fileInfo = cachedEntries.first();
00251 fileInfo;
00252 fileInfo = cachedEntries.next())
00253 {
00254 if (fileInfo->size > maxCachedSize)
00255 {
00256 QCString filename = QFile::encodeName( strCacheDir + "/" + fileInfo->name);
00257 unlink(filename.data());
00258
00259 }
00260 }
00261
00262 int totalSize = 0;
00263
00264 for(FileInfo *fileInfo = cachedEntries.first();
00265 fileInfo;
00266 fileInfo = cachedEntries.next())
00267 {
00268 if ((totalSize + fileInfo->size) > m_maxCacheSize)
00269 {
00270 QCString filename = QFile::encodeName( strCacheDir + "/" + fileInfo->name);
00271 unlink(filename.data());
00272
00273 }
00274 else
00275 {
00276 totalSize += fileInfo->size;
00277
00278 }
00279 }
00280 kdDebug () << appName << ": Current size of cache = " << totalSize << " kB." << endl;
00281 return 0;
00282 }
00283
00284