diff options
Diffstat (limited to 'src/scanviewer.cpp')
-rw-r--r-- | src/scanviewer.cpp | 1014 |
1 files changed, 1014 insertions, 0 deletions
diff --git a/src/scanviewer.cpp b/src/scanviewer.cpp new file mode 100644 index 0000000..19d1f09 --- /dev/null +++ b/src/scanviewer.cpp @@ -0,0 +1,1014 @@ +/* + * 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" |