2
* This file is a part of KleanSweep.
4
* Copyright (C) 2005 Pawel Stolowski <pawel.stolowski@wp.pl>
6
* KleanSweep is free software; you can redestribute it and/or modify it
7
* under terms of GNU General Public License by Free Software Foundation.
9
* This program is distributed in the hope that it will be useful, but
10
* WITHOUT ANY WARRANTY. See GPL for more details.
13
#include "sweepscanner.h"
14
#include "sweepfileinfo.h"
15
#include "kleansweepcfg.h"
17
#include <kstandarddirs.h>
18
#include <qtextstream.h>
23
#include <qvaluelist.h>
27
#define MAX_LINE_LEN 1024
29
SweepScanner::SweepScanner(): QObject(), lineptr(0), writable(false)
31
line = new char [MAX_LINE_LEN];
32
for (int i=0; i<NONE; i++)
34
files.setAutoDelete(true);
36
proc = new KProcess(this);
37
connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)), this, SLOT(onProcessData(KProcess *, char *, int)));
38
connect(proc, SIGNAL(processExited(KProcess *)), this, SLOT(helperExited(KProcess *)));
41
SweepScanner::~SweepScanner()
47
void SweepScanner::enableFileType(FileType f, bool enable)
49
if (ftypes[f] != enable)
53
void SweepScanner::setOnlyWritable(bool f)
59
bool SweepScanner::getOnlyWritable() const
64
bool SweepScanner::isEnabled(FileType f)
69
void SweepScanner::clear()
75
bool SweepScanner::start(const QString &path)
77
if (proc->isRunning())
81
lineptr = totalitems = totalsize = 0;
83
KleanSweepConfig *cfg = &KleanSweepConfig::instance();
84
const QString bl = ::locate("data", "kleansweep/kleansweep-blacklist");
85
const QString ru = ::locate("data", "kleansweep/kleansweep-rules");
87
proc->clearArguments();
88
*proc << "kleansweep-helper";
90
*proc << "--blacklist" << bl;
92
*proc << "--scoring" << ru;
93
if (cfg->showProgress())
94
*proc << "--progress";
96
*proc << "--writable";
97
if (isEnabled(EMPTY_FILE)) *proc << "-z";
98
if (isEnabled(BACKUP_FILE)) *proc << "-b";
99
if (isEnabled(EMPTY_DIR)) *proc << "-y";
100
if (isEnabled(BROKEN_SYMLINK)) *proc << "-s";
101
//if (isEnabled(OLD_FILE)) *proc << "--unused" << QString::number(cfg->oldFilesAge());
102
if (isEnabled(DUPLICATED_FILE)) *proc << "-d";
103
if (isEnabled(ORPHAN_FILE))
105
const DistroPkg pkg = cfg->distroPackageManager();
108
else if (pkg == DPKG)
111
if (isEnabled(DEAD_MENUENTRY)) *proc << "-m";
112
if (isEnabled(DEAD_THUMBNAIL)) *proc << "-t";
113
if (isEnabled(BROKEN_EXEC)) *proc << "-x";
114
if (isEnabled(UNUSED_LOCALE)) *proc << "-l";
116
QStringList paths = cfg->globalExcludePaths();
117
for (QStringList::iterator it = paths.begin(); it != paths.end(); ++it)
118
*proc << "--exclude" << *it;
120
if (isEnabled(ORPHAN_FILE))
122
paths = cfg->orphansExcludePaths();
123
for (QStringList::iterator it = paths.begin(); it != paths.end(); ++it)
124
*proc << "--orphans-exclude" << *it;
125
paths = cfg->orphansIncludePaths();
126
for (QStringList::iterator it = paths.begin(); it != paths.end(); ++it)
127
*proc << "--orphans-include" << *it;
131
proc->setPriority(10);
135
// print helper arguments
136
const QValueList<QCString> alist = proc->args();
137
for (QValueList<QCString>::const_iterator it = alist.begin(); it != alist.end(); it++)
138
std::cerr << *it << " ";
139
std::cerr << std::endl;
142
if (!proc->start(KProcess::NotifyOnExit, KProcess::Stdout))
148
bool SweepScanner::isRunning()
150
return proc->isRunning();
153
bool SweepScanner::stop()
160
void SweepScanner::onProcessData(KProcess *proc, char *buf, int len)
162
for (int i=0; i<len; i++)
172
line[lineptr++] = buf[i];
173
if (lineptr == MAX_LINE_LEN-1)
181
void SweepScanner::extractFileInfo()
186
SweepFileInfo *f = NULL;
187
SweepFileInfo *dupparent = NULL;
190
std::cerr << line << std::endl;
195
emit currentPath(line + 2);
198
if (isdigit(line[pos]))
200
score = line[pos++] - '0';
201
if (isdigit(line[pos]))
203
id = atol(line + pos);
204
while (isdigit(line[pos])) //skip digits
212
while (line[namepos])
214
if (line[namepos] == ':')
219
else if (line[namepos] == '\\')
228
path.setPath(line + namepos);
230
if (filemap.contains(id))
232
if (filemap[id]->url().path() == (line + namepos))
238
dupparent = filemap[id];
239
f = new SweepFileInfo(path, score);
241
totalsize += f->size();
242
emit updateTotals(++totalitems, totalsize);
247
f = new SweepFileInfo(path, score);
248
filemap.insert(id, f);
250
totalsize += f->size();
251
emit updateTotals(++totalitems, totalsize);
254
for (pos=0; line[pos];)
259
case 'y': ft = EMPTY_DIR; break;
260
case 'z': ft = EMPTY_FILE; break;
261
case 'l': ft = UNUSED_LOCALE; break;
262
case 'b': ft = BACKUP_FILE; break;
263
case 'm': ft = DEAD_MENUENTRY; break;
264
case 'd': ft = DUPLICATED_FILE; break;
265
case 's': ft = BROKEN_SYMLINK; break;
266
case 't': ft = DEAD_THUMBNAIL; break;
267
case 'x': ft = BROKEN_EXEC; break;
268
//case 'U': ft = OLD_FILE; break;
269
case 'O': ft = ORPHAN_FILE; break;
270
default: ft = NONE; break;
273
if (ft == DUPLICATED_FILE)
277
emit newFileEntry(ft, f, dupparent);
281
emit newFileEntry(ft, f);
285
if (ft == DEAD_MENUENTRY || ft == DEAD_THUMBNAIL || ft == BROKEN_SYMLINK || ft == BROKEN_EXEC)
290
// - puts \0 in place of closing ','
291
// - removes escape backslash-characters (replaces original string)
292
for (int dst = pos; line[pos]; dst++)
294
if (line[pos] == ',')
300
if (line[pos] == '\\') //backslash found - take next character 'as is'
301
line[dst] = line[++pos];
303
line[dst] = line[pos];
306
f->setTarget(line + targetpos);
308
if (ft != NONE && ftypes[ft])
309
emit newFileEntry(ft, f);
313
void SweepScanner::helperExited(KProcess *proc)
315
filemap.clear(); //no longer needed
319
QPtrList<SweepFileInfo> SweepScanner::getFilesForRemoval()
321
QPtrList<SweepFileInfo> remfiles;
322
remfiles.setAutoDelete(false);
323
for (SweepFileInfo *finfo = files.first(); finfo; finfo = files.next())
324
if (finfo->isMarkedForRemoval() && finfo->getScore()>0) //score can't be 0 if file is marked for removal -- sanity check...
325
remfiles.append(finfo);
329
QString SweepScanner::lastScanPath() const
334
void SweepScanner::writeLog(QTextStream &str)
336
for (SweepFileInfo *finfo = files.first(); finfo; finfo = files.next())
337
str << (finfo->isMarkedForRemoval() ? "[+] " : "[-] ") << finfo->getScore() << ' ' << QString(finfo->url().path()) << "\n";
340
#include "sweepscanner.moc"