You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1015 lines
33 KiB
1015 lines
33 KiB
/*
|
|
* Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
|
|
*/
|
|
|
|
#include "scanviewer.h"
|
|
#include "klamav.h"
|
|
#include "freshklam.h"
|
|
#include "directorylist.h"
|
|
#include "dbviewer.h"
|
|
#include "collectiondb.h"
|
|
#include "klamd.h"
|
|
|
|
#include <config.h>
|
|
#include "klamavconfig.h"
|
|
|
|
|
|
#include <klocale.h>
|
|
#include <kiconloader.h>
|
|
#include <kmenubar.h>
|
|
#include <kstatusbar.h>
|
|
#include <kio/netaccess.h>
|
|
#include <knotifyclient.h>
|
|
#include <kprocio.h>
|
|
#include <qlayout.h>
|
|
#include <kcmdlineargs.h>
|
|
#include <kmessagebox.h>
|
|
#include <kstandarddirs.h>
|
|
#include <ksystemtray.h>
|
|
#include <kprogress.h>
|
|
|
|
#include <qtimer.h>
|
|
#include <qpushbutton.h>
|
|
#include <qcolor.h>
|
|
#include <qtooltip.h> //QToolTip::palette()
|
|
#include <kdebug.h>
|
|
|
|
static int counter = 0;
|
|
|
|
ScanViewer::ScanViewer(QWidget *parent, const char *name)
|
|
: QWidget(parent, name)
|
|
{
|
|
|
|
scanInProgress = TRUE;
|
|
multiScan = FALSE;
|
|
|
|
//QGridLayout *layout = new QGridLayout(this, 6, 3, 10, 4);
|
|
layout = new QGridLayout(this, 6, 3, 10, 4);
|
|
layout->setColStretch(0, 10);
|
|
layout->addColSpacing(1, 10);
|
|
layout->setColStretch(1, 0);
|
|
layout->setColStretch(2, 1);
|
|
layout->addRowSpacing(1, 10);
|
|
layout->setRowStretch(1, 0);
|
|
layout->setRowStretch(2, 10);
|
|
layout->addRowSpacing(4, 10);
|
|
layout->setRowStretch(4, 0);
|
|
|
|
|
|
|
|
resultview = new QListView(this);
|
|
resultview->setShowSortIndicator(true);
|
|
|
|
QFontMetrics rb_fm(resultview->fontMetrics());
|
|
//resultview->setMinimumSize(rb_fm.width("0")*55,
|
|
// rb_fm.lineSpacing()*15);
|
|
resultview->addColumn( i18n( "Name of File" ),(resultview->width()/3));
|
|
resultview->addColumn( i18n( "Name of Problem Found" ),(resultview->width()/3));
|
|
resultview->addColumn( i18n( "Status" ),(resultview->width()/3));
|
|
resultview->setResizeMode(QListView::AllColumns);
|
|
resultview->setSelectionMode( QListView::Extended );
|
|
resultview->setAllColumnsShowFocus(true);
|
|
layout->addMultiCellWidget(resultview, 2, 2, 0, 2);
|
|
|
|
connect( resultview, SIGNAL(onItem ( QListViewItem * )),
|
|
SLOT(slotOnItem ( QListViewItem * )));
|
|
connect( resultview, SIGNAL(onViewport ( )),
|
|
SLOT(slotOffItem ( )));
|
|
|
|
menu = new QPopupMenu( resultview );
|
|
|
|
connect(resultview, SIGNAL( contextMenuRequested( QListViewItem *, const QPoint& , int ) ),
|
|
this, SLOT( slotRMB( QListViewItem *, const QPoint &, int ) ) );
|
|
|
|
status_frame = new QFrame(this);
|
|
status_frame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
|
QBoxLayout *status_layout = new QHBoxLayout(status_frame, 2);
|
|
|
|
|
|
status_label = new QLabel("", status_frame);
|
|
status_layout->addWidget(status_label, 10);
|
|
|
|
//matches_label = new QLabel(status_frame);
|
|
//QFontMetrics ml_fm(matches_label->fontMetrics());
|
|
//matches_label->setFixedWidth(ml_fm.width(i18n("9999 viruseses/errors found")));
|
|
//matches_label->setFixedHeight(ml_fm.lineSpacing());
|
|
//status_layout->addWidget(matches_label, 0);
|
|
|
|
|
|
status_layout->activate();
|
|
status_frame->adjustSize();
|
|
status_frame->setMinimumSize(status_frame->size());
|
|
layout->addMultiCellWidget(status_frame, 3, 3, 0, 2);
|
|
|
|
status2_frame = new QFrame(this);
|
|
status2_frame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
|
|
status2_layout = new QHBoxLayout(status2_frame, 2);
|
|
|
|
status2_label = new QLabel(i18n("Files scanned: 0"), status2_frame);
|
|
status2_layout->addWidget(status2_label, 10);
|
|
status2_label->hide();
|
|
|
|
prog = new KProgress(status2_frame);
|
|
progosd = new K3bJobProgressOSD();
|
|
progosd->setText("Scanning..");
|
|
progosd->readSettings(KGlobal::config());
|
|
|
|
status2_layout->addWidget(prog, 10);
|
|
prog->adjustSize();
|
|
prog->hide();
|
|
progosd->hide();
|
|
|
|
scan_time = new QPushButton( status2_frame );
|
|
scan_time->setText(i18n("Calculating Scan Time... (Click To By-Pass)"));
|
|
status2_layout->addWidget(scan_time,10);
|
|
scan_time->adjustSize();
|
|
scan_time->show();
|
|
|
|
//status_frame->setPaletteBackgroundColor(QColor::Yellow);
|
|
connect( scan_time, SIGNAL(clicked()),
|
|
SLOT(slotCancelScanTime()) );
|
|
|
|
|
|
|
|
matches2_label = new QLabel(status2_frame);
|
|
QFontMetrics ml_fm2(matches2_label->fontMetrics());
|
|
matches2_label->setFixedWidth(ml_fm2.width(i18n("9999 viruseses/problems found")));
|
|
matches2_label->setFixedHeight(ml_fm2.lineSpacing());
|
|
status2_layout->addWidget(matches2_label, 0);
|
|
|
|
QToolTip::add(matches2_label, i18n("cf. 'Flanderseses' - Homer Simpson. This childish joke will be removed when KlamAV is more mature."));
|
|
|
|
status2_layout->activate();
|
|
status2_frame->adjustSize();
|
|
status2_frame->setMinimumSize(status2_frame->size());
|
|
|
|
layout->addMultiCellWidget(status2_frame, 4, 4, 0, 2);
|
|
|
|
|
|
layout->activate();
|
|
|
|
|
|
}
|
|
|
|
ScanViewer::~ScanViewer()
|
|
{
|
|
|
|
scanCancelled = TRUE;
|
|
|
|
if ((childproc) && (scanInProgress)){
|
|
delete childproc;
|
|
childproc = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void ScanViewer::processOutput()
|
|
{
|
|
int pos;
|
|
QString item2;
|
|
|
|
if (!(childproc))
|
|
return;
|
|
|
|
if ((showProgress) && prog->isHidden()){
|
|
status2_label->hide();
|
|
scan_time->hide();
|
|
prog->show();
|
|
progosd->show();
|
|
}
|
|
|
|
|
|
//buf.replace("//","/"); // don't know why they're getting two slashes
|
|
while ((childproc) && ((pos = (childproc->readln(item2,true))) != -1)) {
|
|
QListViewItem* tm;
|
|
//item2 = (buf.section('\n',j,j)).stripWhiteSpace();
|
|
item2 = item2.stripWhiteSpace();
|
|
int fnameStartPoint = 0;
|
|
int fnameEndPoint = item2.findRev(":");
|
|
QString tmpFName = item2.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
|
|
tmpFName = i18n(tmpFName);
|
|
if ((pos = (item2.find(" FOUND"))) != -1){
|
|
//if ((pos = buf.section('\n',j,j).find("FOUND")) != -1){
|
|
QString tmpVirusName = item2.mid((fnameEndPoint+1),(item2.length() - (fnameEndPoint+1)));
|
|
QDate today = QDate::currentDate();
|
|
QTime now = QTime::currentTime();
|
|
QString suffix = QString(":%1 %2")
|
|
.arg(today.toString("ddd MMMM d yyyy"))
|
|
.arg(now.toString("hh-mm-ss-zzz ap"));
|
|
|
|
if ((tmpVirusName.find("FOUND")) != -1){
|
|
tmpVirusName.replace("FOUND","");
|
|
tm = new QListViewItem( resultview, tmpFName, tmpVirusName.stripWhiteSpace(),"Loose");
|
|
tm->setPixmap( 0, SmallIcon("klamav_virus") );
|
|
//resultview->insertItem(buf.section('\n',j,j));
|
|
QuarantineList.append(tmpFName+":"+tmpVirusName+suffix);
|
|
CollectionDB::instance()->insertEvent("Virus Found",tmpVirusName,tmpFName);
|
|
|
|
}
|
|
filesscanned++;
|
|
if (!(showProgress))
|
|
status2_label->setText(i18n("Files scanned: %1").arg(filesscanned));
|
|
|
|
//}else if ((pos = buf.section('\n',j,j).find("ERROR:")) != -1){
|
|
}else if ((pos = (item2.find("ERROR:"))) != -1){
|
|
QString tmpVirusName = item2.mid((fnameEndPoint+1),(item2.length() - (fnameEndPoint+1)));
|
|
tm = new QListViewItem( resultview, tmpFName, tmpVirusName.stripWhiteSpace(),"Not a Virus");
|
|
tm->setPixmap( 0, SmallIcon("klamav_error") );
|
|
//resultview->insertItem(buf.section('\n',j,j));
|
|
CollectionDB::instance()->insertEvent("Error Found",tmpVirusName,tmpFName);
|
|
|
|
errorsEncountered = TRUE;
|
|
filesscanned++;
|
|
if (!(showProgress))
|
|
status2_label->setText(i18n("Files scanned: %1").arg(filesscanned));
|
|
//}else if ((pos = buf.section('\n',j,j).find("Scanning ")) != -1){
|
|
}else if ((pos = (item2.find("Scanning"))) != -1){
|
|
if (status_label->palette() != QToolTip::palette())
|
|
status_label->setText(item2);
|
|
//}else if ((pos = buf.section('\n',j,j).find(": OK")) != -1){
|
|
}else if ((pos = (item2.find(": OK"))) != -1){
|
|
filesscanned++;
|
|
if (!(showProgress))
|
|
status2_label->setText(i18n("Files scanned: %1").arg(filesscanned));
|
|
|
|
//}else if ((pos = buf.section('\n',j,j).find(": Access denied")) != -1){
|
|
}else if ((pos = (item2.find(": Access denied"))) != -1){
|
|
filesscanned++;
|
|
if (!(showProgress))
|
|
status2_label->setText(i18n("Files scanned: %1").arg(filesscanned));
|
|
KNotifyClient::event(kmain->_tray->winId(),"ScanAccessDenied", QString("Can't scan %1 "
|
|
"- Access Denied!").arg(tmpFName));
|
|
CollectionDB::instance()->insertEvent("Error Found","Access Denied",tmpFName);
|
|
//}else if ((pos = buf.section('\n',j,j).find(": Can't open")) != -1){
|
|
|
|
}else if ((pos = (item2.find(": Can't open"))) != -1){
|
|
//status2_label->setText(i18n("Files scanned: %1").arg(++filesscanned));
|
|
filesscanned++;
|
|
if (!(showProgress))
|
|
status2_label->setText(i18n("Files scanned: %1").arg(filesscanned));
|
|
KNotifyClient::event(kmain->_tray->winId(),"ScanAccessDenied", QString("Can't scan %1 "
|
|
"- Access Denied!").arg(tmpFName));
|
|
CollectionDB::instance()->insertEvent("Error Found","Access Denied",tmpFName);
|
|
}else if ((pos = (item2.find(": Empty file"))) != -1){
|
|
//status2_label->setText(i18n("Files scanned: %1").arg(++filesscanned));
|
|
filesscanned++;
|
|
if (!(showProgress))
|
|
status2_label->setText(i18n("Files scanned: %1").arg(filesscanned));
|
|
//KNotifyClient::event(kmain->_tray->winId(),"ScanAccessDenied", QString("Can't scan %1 "
|
|
// "- Empty File!").arg(tmpFName));
|
|
CollectionDB::instance()->insertEvent("Error Found","Empty File",tmpFName);
|
|
}
|
|
item2 = "";
|
|
}
|
|
|
|
QString str;
|
|
str.setNum(resultview->childCount());
|
|
|
|
str += i18n(" viruseses/problems found");
|
|
matches2_label->setText(str);
|
|
|
|
if (showProgress){
|
|
prog->setProgress (filesscanned);
|
|
progosd->setProgress ((int)(100 * (float)filesscanned/cnt));
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void ScanViewer::slotScan(const QStringList & filepattern, int mode, bool recursive, bool dcopscan)
|
|
{
|
|
|
|
//KMessageBox::information (this, filepattern);
|
|
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
|
|
|
if(( args->isSet( "scanthis" ) ) || (dcopscan)) {
|
|
calculateTime = FALSE;
|
|
showProgress = FALSE;
|
|
scan_time->hide();
|
|
status2_label->show();
|
|
|
|
}else{
|
|
calculateTime = TRUE;
|
|
showProgress = TRUE;
|
|
scan_time->show();
|
|
status2_label->hide();
|
|
}
|
|
|
|
scanCancelled = FALSE;
|
|
scanInProgress = FALSE;
|
|
|
|
m_mode = mode;
|
|
m_filepattern = filepattern;
|
|
m_recursive = recursive;
|
|
|
|
|
|
//kdDebug() << "m_filepattern *" << m_filepattern << "*" << endl;
|
|
|
|
prog->hide();
|
|
progosd->hide();
|
|
|
|
|
|
matches2_label->setText("");
|
|
status_label->setText( i18n("Preparing To Scan ") + m_filepattern.join(" "));
|
|
status2_label->setText(i18n("Files scanned:")+" 0");
|
|
prog->setProgress(0);
|
|
//progosd->setProgress(0);
|
|
|
|
kdDebug() << filepattern << endl;
|
|
QStringList tmpfilepattern = filepattern;
|
|
|
|
cnt = 0;
|
|
//QStringList temp = QStringList::split(" ", tmpfilepattern.replace("\"",""));
|
|
//kdDebug() << temp << endl;
|
|
if (calculateTime){
|
|
for ( QStringList::Iterator it = tmpfilepattern.begin(); it != tmpfilepattern.end(); ++it ){
|
|
QDir d( QString((*it).latin1()).stripWhiteSpace() );
|
|
kdDebug() << "dir " << QString((*it).latin1()).stripWhiteSpace() << endl;
|
|
counter = 0;
|
|
cnt = cnt + countFiles(d);
|
|
if (scanCancelled)
|
|
break;
|
|
}
|
|
}
|
|
//kdDebug() << scanCancelled << endl;
|
|
|
|
calculateTime = FALSE;
|
|
if (scanCancelled)
|
|
return;
|
|
|
|
//kdDebug() << filepattern << endl;
|
|
|
|
prog->setTotalSteps(cnt);
|
|
kdDebug() << "COUNT" << cnt << endl;
|
|
|
|
config = KGlobal::config();
|
|
|
|
slotClear();
|
|
QuarantineList.clear();
|
|
|
|
errorsEncountered = FALSE;
|
|
filesscanned = 0;
|
|
//status2_label->setText(i18n("Scan in Progress..."));
|
|
|
|
QString db;
|
|
|
|
if(!( args->isSet( "scanthis" ) ) )
|
|
db = kmain->freshklam->getCurrentDBDir();
|
|
else{
|
|
config->setGroup("Freshklam");
|
|
QStringList lastDownloadPaths = config->readListEntry("lastDownloadPaths");
|
|
for (QStringList::Iterator ita = lastDownloadPaths.begin(); ita == lastDownloadPaths.begin() ; ita++){
|
|
db = *ita;
|
|
}
|
|
}
|
|
|
|
////kdDebug() << "here 2" << endl;
|
|
QString dbpath;
|
|
QString excludes;
|
|
QString options;
|
|
|
|
if (!(db.isEmpty()))
|
|
dbpath = QString(" -d %1 ").arg(db);
|
|
|
|
config->setGroup("Klamscan");
|
|
|
|
if (config->readEntry("ExcludeQuarantine") == "Yes"){
|
|
config->setGroup("Kuarantine");
|
|
QStringList lastQuarLocations = config->readListEntry("KuarantineLocations");
|
|
QString quarloc;
|
|
for (QStringList::Iterator ita = lastQuarLocations.begin(); ita == lastQuarLocations.begin() ; ita++){
|
|
quarloc = *ita;
|
|
}
|
|
excludes += QString(" --exclude=%1 ").arg(quarloc);
|
|
}
|
|
|
|
|
|
//if ((recursive_box->isChecked() && !(multiScan)) || (multi_recursive && multiScan))
|
|
if (recursive)
|
|
options += " -r ";
|
|
|
|
//config->setGroup("Klamscan");
|
|
|
|
|
|
if (KlamavConfig::noFilesToExtract() > 0)
|
|
options += "--max-files=" + QString("%1").arg(KlamavConfig::noFilesToExtract()) + " ";
|
|
|
|
// if (KlamavConfig::mBsToExtract() > 0)
|
|
// options += "--max-space=" + QString("%1").arg(KlamavConfig::mBsToExtract()) + " ";
|
|
//
|
|
// if (KlamavConfig::compressionRatio() > 0)
|
|
// options += "--max-ratio=" + QString("%1").arg(KlamavConfig::compressionRatio()) + " ";
|
|
|
|
if (KlamavConfig::recursionLevel() > 0)
|
|
options += "--max-recursion=" + QString("%1").arg(KlamavConfig::recursionLevel()) + " ";
|
|
|
|
|
|
if (KlamavConfig::maxFileSize() > 0)
|
|
options += "--max-filesize=" + QString("%1").arg(KlamavConfig::maxFileSize()) + "M ";
|
|
|
|
if (KlamavConfig::maxScanSize() > 0)
|
|
options += "--max-scansize=" + QString("%1").arg(KlamavConfig::maxScanSize()) + "M ";
|
|
|
|
//config->setGroup("Klamscan");
|
|
// if (KlamavConfig::virusLimitsExceeded())
|
|
// options += "--block-max ";
|
|
|
|
if (KlamavConfig::virusEncrypted())
|
|
options += "--block-encrypted ";
|
|
|
|
if (!(KlamavConfig::scanMail()))
|
|
options += "--no-mail ";
|
|
|
|
if (!(KlamavConfig::scanHTML()))
|
|
options += "--no-html ";
|
|
|
|
if (!(KlamavConfig::scanPE()))
|
|
options += "--no-pe ";
|
|
|
|
if (!(KlamavConfig::scanMacros()))
|
|
options += "--no-ole2 ";
|
|
|
|
if (KlamavConfig::virusBroken())
|
|
options += "--detect-broken ";
|
|
|
|
|
|
if (KlamavConfig::scanZip()){
|
|
options += "--unzip";
|
|
if ((KlamavConfig::zipUsing()) != "")
|
|
options += "="+(KlamavConfig::zipUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanRar()){
|
|
options += "--unrar";
|
|
if ((KlamavConfig::rarUsing()) != "")
|
|
options += "="+(KlamavConfig::rarUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanArj()){
|
|
options += "--arj";
|
|
if ((KlamavConfig::arjUsing()) != "")
|
|
options += "="+(KlamavConfig::arjUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanZoo()){
|
|
options += "--unzoo";
|
|
if ((KlamavConfig::zooUsing()) != "")
|
|
options += "="+(KlamavConfig::zooUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanLzh()){
|
|
options += "--lha";
|
|
if ((KlamavConfig::lzhUsing()) != "")
|
|
options += "="+(KlamavConfig::lzhUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanJar()){
|
|
options += "--jar";
|
|
if ((KlamavConfig::jarUsing()) != "")
|
|
options += "="+(KlamavConfig::jarUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanDeb()){
|
|
options += "--deb";
|
|
if ((KlamavConfig::debUsing()) != "")
|
|
options += "="+(KlamavConfig::debUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanTar()){
|
|
options += "--tar";
|
|
if ((KlamavConfig::tarUsing()) != "")
|
|
options += "="+(KlamavConfig::tarUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
if (KlamavConfig::scanTgz()){
|
|
options += "--tgz";
|
|
if ((KlamavConfig::tgzUsing()) != "")
|
|
options += "="+(KlamavConfig::tgzUsing())+" ";
|
|
else
|
|
options+=" ";
|
|
}
|
|
|
|
kdDebug() << "clamscan -v "
|
|
<< excludes << " "
|
|
<< dbpath << " "
|
|
<< options << " "
|
|
<< "'" + m_filepattern.join("' '") + "'" << endl;
|
|
|
|
childproc = new KProcIO();
|
|
childproc->setUseShell(TRUE);
|
|
childproc->setUsePty (KProcIO::Stdout,TRUE);
|
|
|
|
*childproc << "clamscan -v ";
|
|
*childproc << excludes << " ";
|
|
*childproc << dbpath << " ";
|
|
*childproc << options << " ";
|
|
|
|
*childproc << "'" + m_filepattern.join("' '") + "'";
|
|
|
|
|
|
/* connect( childproc, SIGNAL(processExited(KProcess *)),
|
|
SLOT(childExited()) );
|
|
connect( childproc, SIGNAL(receivedStdout(KProcess *, char *, int)),
|
|
SLOT(receivedOutput(KProcess *, char *, int)) );
|
|
childproc->start(KProcess::NotifyOnExit, KProcess::Stdout);*/
|
|
|
|
connect( childproc, SIGNAL(readReady(KProcIO *)),
|
|
SLOT(receivedOutput(KProcIO *)) );
|
|
childproc->start(KProcIO::NotifyOnExit);
|
|
connect( childproc, SIGNAL(processExited(KProcess *)),
|
|
SLOT(childExited()) );
|
|
|
|
scanInProgress = TRUE;
|
|
|
|
menu->setEnabled(FALSE);
|
|
|
|
|
|
}
|
|
|
|
|
|
void ScanViewer::finish()
|
|
{
|
|
// search_button->setEnabled(true);
|
|
// cancel_button->setEnabled(false);
|
|
|
|
|
|
if ((childproc) && (scanInProgress)){
|
|
//processOutput();
|
|
kdDebug() << "deleting childproc" << endl;
|
|
delete childproc;
|
|
childproc = 0;
|
|
kdDebug() << "deleted childproc" << endl;
|
|
}
|
|
|
|
scanInProgress = FALSE;
|
|
|
|
status_label->setText(i18n( "If viruses were found, you can right-click to quarantine selected files." ));
|
|
menu->setEnabled(TRUE);
|
|
//dir_combo->setEnabled(TRUE);
|
|
|
|
scan_time->hide();
|
|
prog->hide();
|
|
progosd->hide();
|
|
progosd->saveSettings(KGlobal::config());
|
|
status2_label->show();
|
|
|
|
multiScan = FALSE;
|
|
calculateTime = FALSE;
|
|
|
|
emit scanFinished(this);
|
|
|
|
}
|
|
|
|
|
|
void ScanViewer::slotCancel()
|
|
{
|
|
|
|
scanCancelled = TRUE;
|
|
finish();
|
|
|
|
//status2_frame->adjustSize();
|
|
status2_label->setText(i18n("Cancelled"));
|
|
|
|
CollectionDB::instance()->insertEvent("Manual Scan",QString("Scan Cancelled"),m_filepattern.join(" "));
|
|
|
|
}
|
|
|
|
void ScanViewer::resetSysTray()
|
|
{
|
|
if (kmain->klamd->isKlamdAlive())
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_enabled"));
|
|
else
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled"));
|
|
}
|
|
|
|
void ScanViewer::childExited()
|
|
{
|
|
int status = childproc->exitStatus();
|
|
|
|
int result;
|
|
|
|
status2_label->setText( i18n("Scan Complete") );
|
|
CollectionDB::instance()->insertEvent("Manual Scan",QString("Scan Complete"),m_filepattern.join(" "));
|
|
|
|
if (status == 0){
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_scan_safe"));
|
|
QTimer::singleShot( 10000, this, SLOT(resetSysTray()) );
|
|
if (!(errorsEncountered))
|
|
KNotifyClient::event(kmain->_tray->winId(),i18n( "ScanCompleteNoVirus" ), i18n( "Scan Complete - No Viruses Found!" ));
|
|
else
|
|
KNotifyClient::event(kmain->_tray->winId(),i18n( "ScanCompleteNoVirusButErrors" ), i18n( "Scan Complete - No Viruses Found But Some Errors Encountered!" ));
|
|
|
|
}else if(status == 1){
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_scan_found"));
|
|
switch (m_mode) {
|
|
case 0:
|
|
progosd->setText("Problems found!");
|
|
result = KMessageBox::warningContinueCancelList(this, i18n( "I'm going to quarantine this lot, you can restore them later if you want. If you don't want to quarantine, just press cancel."),QuarantineList,i18n( "Quarantine Infected Files" ),i18n( "Quarantine" ));
|
|
switch (result) {
|
|
case 2 :KNotifyClient::event(kmain->_tray->winId(),"ScanAccessDenied", QString("Suspicious Items Not "
|
|
"Quarantined!")); break;
|
|
case 5 : Quarantine(); break;
|
|
}
|
|
break;
|
|
case 1:
|
|
Quarantine(); break;
|
|
default:
|
|
KMessageBox::information (this,i18n( "Scan Complete - Viruses Found!") );break;
|
|
}
|
|
}else if (status ==40){ KMessageBox::information (this,i18n( "Unknown option passed.") );
|
|
|
|
}else if (status ==50){ KMessageBox::information (this,i18n( "Database initialization error.") );
|
|
|
|
}else if (status ==52){ KMessageBox::information (this,i18n( "Not supported file type.") );
|
|
|
|
}else if (status ==53){ KMessageBox::information (this,i18n( "Can't open directory.") );
|
|
|
|
}else if (status ==54){ KMessageBox::information (this,i18n( "Can't open file. (ofm)") );
|
|
|
|
}else if (status ==55){ KMessageBox::information (this,i18n( "Error reading file. (ofm)") );
|
|
|
|
}else if (status ==56){ KMessageBox::information (this,i18n( "Can't stat input file / directory.") );
|
|
|
|
}else if (status ==57){ KMessageBox::information (this,i18n( "Can't get absolute path name of current working directory." ));
|
|
|
|
}else if (status ==58){ KMessageBox::information (this,i18n( "I/O error, please check your filesystem." ));
|
|
|
|
}else if (status ==59){ KMessageBox::information (this,i18n( "Can't get information about current user from /etc/passwd.") );
|
|
|
|
}else if (status ==60){ KMessageBox::information (this,i18n( "Can't get information about user 'clamav' (default name) from /etc/passwd.") );
|
|
|
|
}else if (status ==61){ KMessageBox::information (this,i18n( "Can't fork.") );
|
|
|
|
}else if (status ==63){ KMessageBox::information (this, i18n("Can't create temporary files/directories (check permissions)."));
|
|
|
|
}else if (status ==64){ KMessageBox::information (this, i18n("Can't write to temporary directory (please specify another one)."));
|
|
|
|
}else if (status ==70){ KMessageBox::information (this, i18n("Can't allocate and clear memory (calloc)."));
|
|
|
|
}else if (status ==71){ KMessageBox::information (this, i18n("Can't allocate memory (malloc)."));
|
|
|
|
}else if (status ==71){KMessageBox::information (this, i18n("Unspecified Error!"));
|
|
}
|
|
|
|
status2_label->setText( i18n("Files scanned: %1").arg(filesscanned) );
|
|
|
|
finish();
|
|
|
|
//if (status != 0)
|
|
//matches_label->setText("");
|
|
|
|
}
|
|
|
|
|
|
void ScanViewer::receivedOutput(KProcIO *)
|
|
{
|
|
//buf += QCString(buffer, buflen+1);
|
|
processOutput();
|
|
//childproc->ackRead();
|
|
|
|
}
|
|
|
|
|
|
void ScanViewer::slotClear()
|
|
{
|
|
//finish();
|
|
resultview->clear();
|
|
|
|
// status2_label->setText(i18n("Ready"));
|
|
matches2_label->setText(i18n("0 viruseses/problems found"));
|
|
|
|
}
|
|
|
|
|
|
// void ScanViewer::setDirName(QString dir){
|
|
// // dir_combo->setEditText(dir);
|
|
// dir_combo->setCurrentText(dir);
|
|
// }
|
|
|
|
void ScanViewer::Quarantine(){
|
|
bool allQuarantined=TRUE;
|
|
config->setGroup("Kuarantine");
|
|
QStringList lastQuarLocations = config->readListEntry("KuarantineLocations");
|
|
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_quarantining"));
|
|
|
|
QString quarloc;
|
|
for (QStringList::Iterator it = lastQuarLocations.begin(); it == lastQuarLocations.begin() ; it++){
|
|
quarloc = *it;
|
|
}
|
|
lastQuarItems = config->readListEntry(QString("Items %1").arg(quarloc));
|
|
|
|
for (QStringList::Iterator it = QuarantineList.begin(); it != QuarantineList.end(); it++ ){
|
|
if (lastQuarItems.contains(*it) != 0) {
|
|
lastQuarItems.remove(*it);
|
|
}
|
|
QString item2 = (*it).stripWhiteSpace();
|
|
int fnameStartPoint = 0;
|
|
int dtStartPoint = item2.findRev(":");
|
|
int fnameEndPoint = item2.findRev(":", (signed int)-((item2.length() - dtStartPoint)+1));
|
|
QString fname = item2.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
|
|
QString itemName = item2.mid((fnameEndPoint+1),((dtStartPoint+1) - (fnameEndPoint+2)));
|
|
QString when = item2.mid((dtStartPoint+1),(item2.length() - (dtStartPoint+1)));
|
|
if (!(fname.isEmpty())){
|
|
QStringList tokens = QStringList::split ( "/", fname, FALSE );
|
|
QString qname = tokens.last();
|
|
qname.prepend("/");
|
|
qname.prepend(quarloc);
|
|
qname.append(":"+when);
|
|
if (KIO::NetAccess::file_move(fname,qname)){
|
|
if (lastQuarItems.contains(item2))
|
|
lastQuarItems.remove(item2);
|
|
lastQuarItems.prepend(item2);
|
|
(resultview->findItem(fname,0))->setText(2,"Quarantined");
|
|
(resultview->findItem(fname,0))->setPixmap( 0, SmallIcon("klamav") );
|
|
chmod((const char *)qname,0400);
|
|
CollectionDB::instance()->insertEvent("Quarantine",QString("Quarantined"),fname);
|
|
|
|
}else{
|
|
KMessageBox::information (this,i18n("<p>There was a problem quarantining <b>%1</b>. Check your diskspace, the permissions on your quarantine location and whether a file with the same name already exists in the quarantine. </p>").arg(fname));
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
if (allQuarantined) {
|
|
if (kmain->klamd->isKlamdAlive())
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_enabled"));
|
|
else
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled"));
|
|
}else
|
|
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_scan_found"));
|
|
config->writeEntry(QString("Items %1").arg(quarloc), lastQuarItems);
|
|
config->sync();
|
|
|
|
//kmain->kuarantine->refresh();
|
|
|
|
|
|
|
|
}
|
|
|
|
void ScanViewer::slotRMB( QListViewItem* Item, const QPoint & point, int )
|
|
{
|
|
|
|
if( Item ){
|
|
QPixmap gicon;
|
|
QPixmap vicon;
|
|
QPixmap vlicon;
|
|
QPixmap ticon;
|
|
|
|
QString iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruspool.net")+".png");
|
|
if ( iconPath.isEmpty() )
|
|
vicon = SmallIcon("find");
|
|
else
|
|
vicon = QPixmap( iconPath );
|
|
|
|
iconPath = locate("cache", KMimeType::favIconForURL("http://www.google.com")+".png");
|
|
if ( iconPath.isEmpty() )
|
|
gicon = SmallIcon("find");
|
|
else
|
|
gicon = QPixmap( iconPath );
|
|
|
|
iconPath = locate("cache", KMimeType::favIconForURL("http://www.trendmicro.com")+".png");
|
|
if ( iconPath.isEmpty() )
|
|
ticon = SmallIcon("find");
|
|
else
|
|
ticon = QPixmap( iconPath );
|
|
|
|
iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruslist.com")+".png");
|
|
if ( iconPath.isEmpty() )
|
|
vlicon = SmallIcon("find");
|
|
else
|
|
vlicon = QPixmap( iconPath );
|
|
|
|
menu->clear();
|
|
menu->insertItem( "Quarantine Selected", this,SLOT(slotQuarantineSelected()) );
|
|
menu->insertItem( vlicon,i18n("Search for %1 with VirusList").arg(Item->text(1)), this, SLOT(slotVirusList()) );
|
|
|
|
menu->insertItem( vicon,i18n("Search for %1 with VirusPool").arg(Item->text(1)), this, SLOT(slotVirusPool()) );
|
|
menu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, SLOT(slotTrendMicro()) );
|
|
|
|
menu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, SLOT(slotGoogle()) );
|
|
menu->popup( point );
|
|
}
|
|
}
|
|
|
|
void ScanViewer::slotQuarantineSelected()
|
|
{
|
|
|
|
QPtrList<QListViewItem> list;
|
|
QListViewItemIterator it( resultview, QListViewItemIterator::Selected );
|
|
|
|
QuarantineList = "";
|
|
while ( it.current() ) {
|
|
QListViewItem* tItem = it.current();
|
|
|
|
QDate today = QDate::currentDate();
|
|
QTime now = QTime::currentTime();
|
|
QString suffix = QString(":%1 %2")
|
|
.arg(today.toString("ddd MMMM d yyyy"))
|
|
.arg(now.toString("hh-mm-ss ap"));
|
|
|
|
QuarantineList.append(tItem->text(0)+":"+tItem->text(1)+suffix);
|
|
++it;
|
|
}
|
|
|
|
Quarantine();
|
|
}
|
|
|
|
|
|
|
|
void ScanViewer::slotGoogle()
|
|
{
|
|
QString name = resultview->currentItem()->text(1);
|
|
kmain->klamdb->slotExternal(name, "Google");
|
|
}
|
|
|
|
void ScanViewer::slotVirusPool()
|
|
{
|
|
QString name = resultview->currentItem()->text(1);
|
|
kmain->klamdb->slotExternal(name, "VirusPool");
|
|
}
|
|
|
|
void ScanViewer::slotTrendMicro()
|
|
{
|
|
QString name = resultview->currentItem()->text(1);
|
|
kmain->klamdb->slotExternal(name, "TrendMicro");
|
|
}
|
|
|
|
void ScanViewer::slotVirusList()
|
|
{
|
|
QString name = resultview->currentItem()->text(1);
|
|
kmain->klamdb->slotExternal(name, "VirusList");
|
|
}
|
|
|
|
void ScanViewer::slotStartAgain()
|
|
{
|
|
calculateTime = TRUE;
|
|
emit scanStartingAgain(this);
|
|
slotScan(m_filepattern, m_mode, m_recursive,false);
|
|
|
|
|
|
}
|
|
|
|
bool ScanViewer::scanGoingOn()
|
|
{
|
|
return (scanInProgress || calculateTime);
|
|
}
|
|
|
|
void ScanViewer::slotCancelScanTime()
|
|
{
|
|
calculateTime = FALSE;
|
|
showProgress = FALSE;
|
|
status2_label->show();
|
|
scan_time->hide();
|
|
|
|
}
|
|
|
|
|
|
// void ScanViewer::startProgress()
|
|
// {
|
|
//
|
|
// cnt = 0;
|
|
// //kdDebug() << "m_filepattern" << m_filepattern << endl;
|
|
// QDir d( m_filepattern );
|
|
// // int num = countFiles(d);
|
|
// // if (countFiles(d) > 0)
|
|
// // //kdDebug() << "count" << num << endl;
|
|
//
|
|
// progress = new KProgressDialog (this, "progress", i18n( "Loading .." ), i18n( "Loading..." ), true);
|
|
// progress->setAllowCancel(false);
|
|
// prog = progress->progressBar();
|
|
// progress->setLabel(i18n( "Loading lots and lots and lots of virus information" ));
|
|
// //int cnt = countFiles(d);
|
|
// prog->setTotalSteps(countFiles(d));
|
|
// //kdDebug() << "COUNT" << countFiles(d) << endl;
|
|
//
|
|
// }
|
|
|
|
int ScanViewer::countFiles( QDir & root)
|
|
{
|
|
|
|
kapp->processEvents();
|
|
|
|
if (!(calculateTime) || (scanCancelled)){
|
|
// kapp->processEvents();
|
|
return 0;
|
|
}
|
|
QStringList entries = root.entryList( QDir::Dirs | QDir::Files | QDir::Hidden);
|
|
|
|
|
|
////kdDebug() << "count" << counter << endl;
|
|
for (QStringList::size_type j = 0; j < entries.size(); j++ )
|
|
{
|
|
QString entry = entries[j];
|
|
|
|
if( entry == "." || entry == "..")
|
|
continue;
|
|
|
|
|
|
QFileInfo fi(root, entry );
|
|
entry = fi.absFilePath();
|
|
entry = QDir::convertSeparators(entry);
|
|
|
|
if ((fi.isFile()) && !(fi.isSymLink())){
|
|
counter++;
|
|
}else if ((fi.isDir()) && !(fi.isSymLink())){
|
|
QDir temp(entry);
|
|
countFiles(temp);
|
|
}
|
|
}
|
|
return counter;
|
|
}
|
|
|
|
void ScanViewer::startProgressDialog( const QString & text )
|
|
{
|
|
//if ( progressDialog )
|
|
// delete progressDialog;
|
|
|
|
progressDialog = new KProgressDialog( this, "progress_dialog", QString::null, text, false );
|
|
|
|
progressDialog->setAllowCancel( true );
|
|
progressDialog->showCancelButton( true );
|
|
progressDialog->setPlainCaption( i18n( "Please Wait" ) );
|
|
|
|
progressDialog->progressBar()->setTotalSteps( 0 );
|
|
progressDialog->progressBar()->setPercentageVisible( false );
|
|
|
|
progressDialog->setMinimumDuration( 500 );
|
|
progressDialog->show();
|
|
|
|
timer = new QTimer( this );
|
|
connect( timer, SIGNAL( timeout() ), this, SLOT( slotProg() ) );
|
|
|
|
timer->start( 200, FALSE );
|
|
}
|
|
|
|
void ScanViewer::slotProg()
|
|
{
|
|
|
|
if (progressDialog)
|
|
progressDialog->progressBar()->setProgress(progressDialog->progressBar()->progress() + 4 );
|
|
}
|
|
|
|
void ScanViewer::slotOnItem( QListViewItem * lineitem)
|
|
{
|
|
|
|
|
|
status_label->setPalette(QToolTip::palette());
|
|
|
|
QString problem = lineitem->text(1).stripWhiteSpace();
|
|
QString message = problem + " is probably a virus. Right-click and select a service to research it.";
|
|
|
|
QString path( lineitem->text(0).stripWhiteSpace() );
|
|
QString file = path.section( '/', -1 );
|
|
|
|
if ((problem.contains("ExceededFile")) ||
|
|
(problem == "Archive.ExceededRecursionLimit") ||
|
|
(problem == "Oversized.Zip") ||
|
|
(problem == "Oversized.RAR"))
|
|
message = problem +": " + i18n("Attempts to scan ") + file + i18n(" resulted in exceeding a limit you set in 'Archive Limits'.");
|
|
else if (problem == "ClamAV-Test-File")
|
|
message = problem +": " + file + i18n(" contains the ClamAV test signature. It's not a virus.");
|
|
else if (problem == "Broken.Executable")
|
|
message = problem +": " + file + i18n(" is a damaged exectuable. Some viruses use this to conceal themselves.");
|
|
else if (problem == "Suspect.zip")
|
|
message = problem +": " + file + i18n(" has a form of zip compression sometimes used by viruses.");
|
|
else if (problem == "Encrypted.zip")
|
|
message = problem +": " + file + i18n(" is an encrypted zip file.");
|
|
else if (problem == "Encrypted.RAR")
|
|
message = problem +": " + file + i18n(" is an encrypted RAR file.");
|
|
else if (problem == "Exploit.Zip.ModifiedHeaders")
|
|
message = problem +": " + file + i18n(" is mis-formatted in a way sometimes used by viruses.");
|
|
|
|
|
|
status_label->setText( message);
|
|
|
|
}
|
|
|
|
void ScanViewer::slotOffItem( )
|
|
{
|
|
|
|
status_label->unsetPalette();
|
|
status_label->setText(i18n("Hover over each entry for more info. Right-click on entries for more options."));
|
|
|
|
}
|
|
#include "scanviewer.moc"
|