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.
klamav/src/scanviewer.cpp

979 lines
32 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 <config.h>
#include "klamavconfig.h"
#include <tdelocale.h>
#include <kiconloader.h>
#include <tdemenubar.h>
#include <kstatusbar.h>
#include <tdeio/netaccess.h>
#include <knotifyclient.h>
#include <kprocio.h>
#include <tqlayout.h>
#include <tdecmdlineargs.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
#include <ksystemtray.h>
#include <kprogress.h>
#include <tqtimer.h>
#include <tqpushbutton.h>
#include <tqcolor.h>
#include <tqtooltip.h> //TQToolTip::palette()
#include <kdebug.h>
static int counter = 0;
ScanViewer::ScanViewer(TQWidget *parent, const char *name)
: TQWidget(parent, name)
{
scanInProgress = TRUE;
multiScan = FALSE;
//TQGridLayout *layout = new TQGridLayout(this, 6, 3, 10, 4);
layout = new TQGridLayout(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 TQListView(this);
resultview->setShowSortIndicator(true);
TQFontMetrics 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(TQListView::AllColumns);
resultview->setSelectionMode( TQListView::Extended );
resultview->setAllColumnsShowFocus(true);
layout->addMultiCellWidget(resultview, 2, 2, 0, 2);
connect( resultview, TQ_SIGNAL(onItem ( TQListViewItem * )),
TQ_SLOT(slotOnItem ( TQListViewItem * )));
connect( resultview, TQ_SIGNAL(onViewport ( )),
TQ_SLOT(slotOffItem ( )));
menu = new TQPopupMenu( resultview );
connect(resultview, TQ_SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ),
this, TQ_SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );
status_frame = new TQFrame(this);
status_frame->setFrameStyle(TQFrame::Panel | TQFrame::Sunken);
TQBoxLayout *status_layout = new TQHBoxLayout(status_frame, 2);
status_label = new TQLabel("", status_frame);
status_layout->addWidget(status_label, 10);
//matches_label = new TQLabel(status_frame);
//TQFontMetrics ml_fm(matches_label->fontMetrics());
//matches_label->setFixedWidth(ml_fm.width(i18n("9999 viruses/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 TQFrame(this);
status2_frame->setFrameStyle(TQFrame::Panel | TQFrame::Sunken);
status2_layout = new TQHBoxLayout(status2_frame, 2);
status2_label = new TQLabel(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( i18n("Scanning..") );
progosd->readSettings(TDEGlobal::config());
status2_layout->addWidget(prog, 10);
prog->adjustSize();
prog->hide();
progosd->hide();
scan_time = new TQPushButton( 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(TQColor::Yellow);
connect( scan_time, TQ_SIGNAL(clicked()),
TQ_SLOT(slotCancelScanTime()) );
matches2_label = new TQLabel(status2_frame);
TQFontMetrics ml_fm2(matches2_label->fontMetrics());
matches2_label->setFixedWidth(ml_fm2.width(i18n("9999 viruses/problems found")));
matches2_label->setFixedHeight(ml_fm2.lineSpacing());
status2_layout->addWidget(matches2_label, 0);
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;
TQString 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)) {
TQListViewItem* tm;
//item2 = (buf.section('\n',j,j)).stripWhiteSpace();
item2 = item2.stripWhiteSpace();
int fnameStartPoint = 0;
int fnameEndPoint = item2.findRev(":");
TQString tmpFName = item2.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
tmpFName = i18n(tmpFName.ascii());
if ((pos = (item2.find(" FOUND"))) != -1){
//if ((pos = buf.section('\n',j,j).find("FOUND")) != -1){
TQString tmpVirusName = item2.mid((fnameEndPoint+1),(item2.length() - (fnameEndPoint+1)));
TQDate today = TQDate::currentDate();
TQTime now = TQTime::currentTime();
TQString suffix = TQString(":%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 TQListViewItem( resultview, tmpFName, tmpVirusName.stripWhiteSpace(), i18n("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){
TQString tmpVirusName = item2.mid((fnameEndPoint+1),(item2.length() - (fnameEndPoint+1)));
tm = new TQListViewItem( resultview, tmpFName, tmpVirusName.stripWhiteSpace(), i18n("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() != TQToolTip::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(tdemain->_tray->winId(),"ScanAccessDenied", TQString("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(tdemain->_tray->winId(),"ScanAccessDenied", TQString("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(tdemain->_tray->winId(),"ScanAccessDenied", TQString("Can't scan %1 "
// "- Empty File!").arg(tmpFName));
CollectionDB::instance()->insertEvent("Error Found","Empty File",tmpFName);
}
item2 = "";
}
TQString str;
str.setNum(resultview->childCount());
str += i18n(" viruses/problems found");
matches2_label->setText(str);
if (showProgress){
prog->setProgress (filesscanned);
progosd->setProgress ((int)(100 * (float)filesscanned/cnt));
}
}
void ScanViewer::slotScan(const TQStringList & filepattern, int mode, bool recursive, bool dcopscan)
{
//KMessageBox::information (this, filepattern);
TDECmdLineArgs *args = TDECmdLineArgs::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;
TQStringList tmpfilepattern = filepattern;
cnt = 0;
//TQStringList temp = TQStringList::split(" ", tmpfilepattern.replace("\"",""));
//kdDebug() << temp << endl;
if (calculateTime){
for ( TQStringList::Iterator it = tmpfilepattern.begin(); it != tmpfilepattern.end(); ++it ){
TQDir d( TQString((*it).latin1()).stripWhiteSpace() );
kdDebug() << "dir " << TQString((*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 = TDEGlobal::config();
config->setGroup("KlamavBackend");
clamdscan = config->readBoolEntry("ScannerClamdscan", false);
slotClear();
QuarantineList.clear();
errorsEncountered = FALSE;
filesscanned = 0;
//status2_label->setText(i18n("Scan in Progress..."));
TQString db;
if(!( args->isSet( "scanthis" ) ) )
db = tdemain->freshklam->getCurrentDBDir();
else{
config->setGroup("Freshklam");
TQStringList lastDownloadPaths = config->readListEntry("lastDownloadPaths");
for (TQStringList::Iterator ita = lastDownloadPaths.begin(); ita == lastDownloadPaths.begin() ; ita++){
db = *ita;
}
}
////kdDebug() << "here 2" << endl;
TQString dbpath;
TQString excludes;
TQString options; // can not be used for clamdscan
if (!(db.isEmpty()))
dbpath = TQString(" -d %1 ").arg(db);
config->setGroup("Klamscan");
if (config->readEntry("ExcludeQuarantine") == "Yes"){
config->setGroup("Kuarantine");
TQStringList lastQuarLocations = config->readListEntry("KuarantineLocations");
TQString quarloc;
for (TQStringList::Iterator ita = lastQuarLocations.begin(); ita == lastQuarLocations.begin() ; ita++){
quarloc = *ita;
}
excludes += TQString(" --exclude-dir=%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=" + TQString("%1").arg(KlamavConfig::noFilesToExtract()) + " ";
// if (KlamavConfig::mBsToExtract() > 0)
// options += "--max-space=" + TQString("%1").arg(KlamavConfig::mBsToExtract()) + " ";
//
// if (KlamavConfig::compressionRatio() > 0)
// options += "--max-ratio=" + TQString("%1").arg(KlamavConfig::compressionRatio()) + " ";
if (KlamavConfig::recursionLevel() > 0)
options += "--max-recursion=" + TQString("%1").arg(KlamavConfig::recursionLevel()) + " ";
if (KlamavConfig::maxFileSize() > 0)
options += "--max-filesize=" + TQString("%1").arg(KlamavConfig::maxFileSize()) + "M ";
if (KlamavConfig::maxScanSize() > 0)
options += "--max-scansize=" + TQString("%1").arg(KlamavConfig::maxScanSize()) + "M ";
//config->setGroup("Klamscan");
// if (KlamavConfig::virusLimitsExceeded())
// options += "--block-max ";
if (!(KlamavConfig::scanArchives()))
options += "--scan-archive=no ";
if (KlamavConfig::virusEncrypted())
options += "--alert-encrypted ";
if (!(KlamavConfig::scanMail()))
options += "--scan-mail=no ";
if (!(KlamavConfig::scanHTML()))
options += "--scan-html=no ";
if (!(KlamavConfig::scanPE()))
options += "--scan-pe=no ";
if (!(KlamavConfig::scanMacros()))
options += "--scan-ole2=no ";
if(!(KlamavConfig::scanELF()))
options += "--scan-elf=no ";
if(!(KlamavConfig::scanPDF()))
options += "--scan-pdf=no ";
if(!(KlamavConfig::scanHWP3()))
options += "--scan-hwp3=no ";
if(!(KlamavConfig::scanSWF()))
options += "--scan-pdf=no ";
if(!(KlamavConfig::scanXML()))
options += "--scan-xmldocs=no ";
if (KlamavConfig::virusBroken())
options += "--alert-broken ";
if(clamdscan) {
// make sure that clamd is running
FILE* clamdpid;
if( clamdpid = fopen("/run/clamav/clamd.pid","r") )
fclose(clamdpid); // it's ok
else {
int choice = KMessageBox::warningYesNoCancel(
this,
i18n("The ClamAV daemon does not seem to be running on this system. Do you really want to continue with this scan or would you like to launch a standalone scan instead?"),
i18n("Clamd not running"),
i18n("Continue this scan"),
i18n("Launch standalone scan"),
i18n("Do not ask me again")
);
switch(choice) {
case 2: // cancel
return;
break;
case 4: // launch standalone scan
clamdscan = false;
break;
}
}
}
childproc = new KProcIO();
childproc->setUseShell(TRUE);
childproc->setUsePty (KProcIO::Stdout,TRUE);
if(clamdscan) {
config->setGroup("KlamavBackend");
TQString multiscanOption = config->readBoolEntry("ClamdMultiscan", true) ? " -m " : "";
kdDebug() << "clamdscan -v --fdpass "
<< multiscanOption
<< "'" + m_filepattern.join("' '") + "'" << endl;
*childproc << "clamdscan -v ";
*childproc << multiscanOption;
} else {
kdDebug() << "clamscan -v "
<< excludes << " "
<< dbpath << " "
<< options << " "
<< "'" + m_filepattern.join("' '") + "'" << endl;
*childproc << "clamscan -v ";
*childproc << excludes << " ";
*childproc << dbpath << " ";
*childproc << options << " ";
}
*childproc << "'" + m_filepattern.join("' '") + "'";
/* connect( childproc, TQ_SIGNAL(processExited(TDEProcess *)),
TQ_SLOT(childExited()) );
connect( childproc, TQ_SIGNAL(receivedStdout(TDEProcess *, char *, int)),
TQ_SLOT(receivedOutput(TDEProcess *, char *, int)) );
childproc->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout);*/
connect( childproc, TQ_SIGNAL(readReady(KProcIO *)),
TQ_SLOT(receivedOutput(KProcIO *)) );
childproc->start(KProcIO::NotifyOnExit);
connect( childproc, TQ_SIGNAL(processExited(TDEProcess *)),
TQ_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(TDEGlobal::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",TQString("Scan Cancelled"),m_filepattern.join(" "));
}
void ScanViewer::resetSysTray()
{
tdemain->_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",TQString("Scan Complete"),m_filepattern.join(" "));
if (status == 0){
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_scan_safe"));
TQTimer::singleShot( 10000, this, TQ_SLOT(resetSysTray()) );
if (!(errorsEncountered))
KNotifyClient::event(tdemain->_tray->winId(),"Scan Complete - No Virus Found", i18n("Scan Complete - No Viruses Found!"));
else
KNotifyClient::event(tdemain->_tray->winId(),"Scan Complete - No Virus But Errors", i18n("Scan Complete - No Viruses Found But Some Errors Encountered!"));
}else if(status == 1){
tdemain->_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(tdemain->_tray->winId(),"ScanAccessDenied", TQString("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 += TQCString(buffer, buflen+1);
processOutput();
//childproc->ackRead();
}
void ScanViewer::slotClear()
{
//finish();
resultview->clear();
// status2_label->setText(i18n("Ready"));
matches2_label->setText(i18n("0 viruses/problems found"));
}
// void ScanViewer::setDirName(TQString dir){
// // dir_combo->setEditText(dir);
// dir_combo->setCurrentText(dir);
// }
void ScanViewer::Quarantine(){
bool allQuarantined=TRUE;
config->setGroup("Kuarantine");
TQStringList lastQuarLocations = config->readListEntry("KuarantineLocations");
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_quarantining"));
TQString quarloc;
for (TQStringList::Iterator it = lastQuarLocations.begin(); it == lastQuarLocations.begin() ; it++){
quarloc = *it;
}
lastQuarItems = config->readListEntry(TQString("Items %1").arg(quarloc));
for (TQStringList::Iterator it = QuarantineList.begin(); it != QuarantineList.end(); it++ ){
if (lastQuarItems.contains(*it) != 0) {
lastQuarItems.remove(*it);
}
TQString item2 = (*it).stripWhiteSpace();
int fnameStartPoint = 0;
int dtStartPoint = item2.findRev(":");
int fnameEndPoint = item2.findRev(":", (signed int)-((item2.length() - dtStartPoint)+1));
TQString fname = item2.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
TQString itemName = item2.mid((fnameEndPoint+1),((dtStartPoint+1) - (fnameEndPoint+2)));
TQString when = item2.mid((dtStartPoint+1),(item2.length() - (dtStartPoint+1)));
if (!(fname.isEmpty())){
TQStringList tokens = TQStringList::split ( "/", fname, FALSE );
TQString qname = tokens.last();
qname.prepend("/");
qname.prepend(quarloc);
qname.append(":"+when);
if (TDEIO::NetAccess::file_move(fname,qname)){
if (lastQuarItems.contains(item2))
lastQuarItems.remove(item2);
lastQuarItems.prepend(item2);
(resultview->findItem(fname,0))->setText(2,i18n("Quarantined"));
(resultview->findItem(fname,0))->setPixmap( 0, SmallIcon("klamav") );
chmod(qname.ascii(),0400);
CollectionDB::instance()->insertEvent("Quarantine",TQString("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)
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled"));
else
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_scan_found"));
config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
config->sync();
//tdemain->kuarantine->refresh();
}
void ScanViewer::slotRMB( TQListViewItem* Item, const TQPoint & point, int )
{
if( Item ){
TQPixmap gicon;
TQPixmap vicon;
TQPixmap vlicon;
TQPixmap ticon;
TQString iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruspool.net")+".png");
if ( iconPath.isEmpty() )
vicon = SmallIcon("edit-find");
else
vicon = TQPixmap( iconPath );
iconPath = locate("cache", KMimeType::favIconForURL("http://www.google.com")+".png");
if ( iconPath.isEmpty() )
gicon = SmallIcon("edit-find");
else
gicon = TQPixmap( iconPath );
iconPath = locate("cache", KMimeType::favIconForURL("http://www.trendmicro.com")+".png");
if ( iconPath.isEmpty() )
ticon = SmallIcon("edit-find");
else
ticon = TQPixmap( iconPath );
iconPath = locate("cache", KMimeType::favIconForURL("http://www.viruslist.com")+".png");
if ( iconPath.isEmpty() )
vlicon = SmallIcon("edit-find");
else
vlicon = TQPixmap( iconPath );
menu->clear();
menu->insertItem( "Quarantine Selected", this,TQ_SLOT(slotQuarantineSelected()) );
menu->insertItem( ticon,i18n("Search for %1 with Trend Micro").arg(Item->text(1)), this, TQ_SLOT(slotTrendMicro()) );
menu->insertItem( gicon,i18n("Search for %1 with Google").arg(Item->text(1)), this, TQ_SLOT(slotGoogle()) );
menu->popup( point );
}
}
void ScanViewer::slotQuarantineSelected()
{
TQPtrList<TQListViewItem> list;
TQListViewItemIterator it( resultview, TQListViewItemIterator::Selected );
QuarantineList = "";
while ( it.current() ) {
TQListViewItem* tItem = it.current();
TQDate today = TQDate::currentDate();
TQTime now = TQTime::currentTime();
TQString suffix = TQString(":%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()
{
TQString name = resultview->currentItem()->text(1);
tdemain->klamdb->slotExternal(name, "Google");
}
void ScanViewer::slotTrendMicro()
{
TQString name = resultview->currentItem()->text(1);
tdemain->klamdb->slotExternal(name, "TrendMicro");
}
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;
// TQDir 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( TQDir & root)
{
kapp->processEvents();
if (!(calculateTime) || (scanCancelled)){
// kapp->processEvents();
return 0;
}
TQStringList entries = root.entryList( TQDir::Dirs | TQDir::Files | TQDir::Hidden);
////kdDebug() << "count" << counter << endl;
for (TQStringList::size_type j = 0; j < entries.size(); j++ )
{
TQString entry = entries[j];
if( entry == "." || entry == "..")
continue;
TQFileInfo fi(root, entry );
entry = fi.absFilePath();
entry = TQDir::convertSeparators(entry);
if ((fi.isFile()) && !(fi.isSymLink())){
counter++;
}else if ((fi.isDir()) && !(fi.isSymLink())){
TQDir temp(entry);
countFiles(temp);
}
}
return counter;
}
void ScanViewer::startProgressDialog( const TQString & text )
{
//if ( progressDialog )
// delete progressDialog;
progressDialog = new KProgressDialog( this, "progress_dialog", TQString::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 TQTimer( this );
connect( timer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( slotProg() ) );
timer->start( 200, FALSE );
}
void ScanViewer::slotProg()
{
if (progressDialog)
progressDialog->progressBar()->setProgress(progressDialog->progressBar()->progress() + 4 );
}
void ScanViewer::slotOnItem( TQListViewItem * lineitem)
{
status_label->setPalette(TQToolTip::palette());
TQString problem = lineitem->text(1).stripWhiteSpace();
TQString message = problem + " is probably a virus. Right-click and select a service to research it.";
TQString path( lineitem->text(0).stripWhiteSpace() );
TQString 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"