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.
503 lines
14 KiB
503 lines
14 KiB
/*
|
|
* Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
|
|
*/
|
|
|
|
#include "klamav.h"
|
|
#include "freshklam.h"
|
|
#include "sigtool.h"
|
|
#include "klamscan.h"
|
|
#include "kuarantine.h"
|
|
#include "welcome.h"
|
|
#include "dbviewer.h"
|
|
#include "activityviewer.h"
|
|
#include "version.h"
|
|
#include "firstrunwizard.h"
|
|
#include "collectiondb.h"
|
|
#include "configdialog.h"
|
|
#include "tabwidget.h"
|
|
#include "klamavconfig.h"
|
|
#include "klamonacc.h"
|
|
|
|
#include <tdelocale.h>
|
|
|
|
|
|
#include <tdeaction.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqtooltip.h>
|
|
#include <tqlayout.h>
|
|
#include <ksystemtray.h>
|
|
#include <tdemenubar.h>
|
|
#include <tdepopupmenu.h>
|
|
#include <kdebug.h>
|
|
#include <tdemessagebox.h>
|
|
#include <kurl.h>
|
|
#include <kiconloader.h>
|
|
|
|
#include <tqdir.h>
|
|
#include <tqfile.h>
|
|
|
|
Klamav *tdemain = 0L;
|
|
|
|
using namespace KlamAV;
|
|
|
|
Klamav::Klamav()
|
|
: TDEMainWindow( 0, "KlamAV " )
|
|
{
|
|
|
|
downloadDBForWizard = false;
|
|
|
|
tdemain = this;
|
|
TQVBoxLayout *top = new TQVBoxLayout(this,3,0);
|
|
|
|
// We don't want these tabs closed
|
|
TQStringList fixedTabs;
|
|
fixedTabs << i18n("Scan") << i18n("Update");
|
|
|
|
tab = new TabWidget(this, "KlamAV", fixedTabs);
|
|
connect( tab, SIGNAL(tabClosed(TQString)), this, SLOT(tabClosed(TQString)) );
|
|
|
|
_tray = new KSystemTray(tdemain, "klamav tray");
|
|
_tray->setPixmap( KSystemTray::loadIcon("klamav") );
|
|
connect(_tray,SIGNAL(quitSelected()),SLOT(shuttingDown()));
|
|
|
|
TDEPopupMenu *conf_menu = _tray->contextMenu();
|
|
|
|
EnableFreshklam = new TDEAction(i18n("&Enable Auto-Updates"), "system-software-update", 0,this, SLOT(contextEnableFK()),actionCollection(),"fk_enable");
|
|
DisableFreshklam = new TDEAction(i18n("&Disable Auto-Updates"), 0, 0, this, SLOT(contextDisableFK()),actionCollection(),"fk_disable");
|
|
|
|
EnableFreshklam->plug(conf_menu);
|
|
DisableFreshklam->plug(conf_menu);
|
|
|
|
EnableKlamOnAcc = new TDEAction(i18n("&Start On-Access Scanner"), "filefind", 0,this, SLOT(contextEnableKOA()),actionCollection(),"koa_enable");
|
|
DisableKlamOnAcc = new TDEAction(i18n("&Stop On-Access Scanner"), 0, 0, this, SLOT(contextDisableKOA()),actionCollection(),"koa_disable");
|
|
|
|
EnableKlamOnAcc->plug(conf_menu);
|
|
DisableKlamOnAcc->plug(conf_menu);
|
|
|
|
TQToolTip::add( _tray, i18n( "KlamAV - Virus Protection for TDE" ) );
|
|
_tray->show();
|
|
|
|
DisableFreshklam->setEnabled(FALSE);
|
|
EnableFreshklam->setEnabled(TRUE);
|
|
|
|
config = TDEGlobal::config();
|
|
config->setGroup("Freshklam");
|
|
TQStringList DatabasePaths = config->readListEntry("lastDownloadPaths");
|
|
|
|
config->setGroup("Kuarantine");
|
|
TQStringList QuarantinePaths = config->readListEntry("KuarantineLocations");
|
|
|
|
if ((DatabasePaths.isEmpty()) && (QuarantinePaths.isEmpty())){
|
|
|
|
firstRunWizard();
|
|
}
|
|
|
|
// Menus
|
|
TDEPopupMenu *scanner_menu = new TDEPopupMenu(this);
|
|
scanner_menu->insertItem( SmallIcon("document-open"), i18n("Scan &File..."), this, SLOT(slotScanFile()), CTRL+Key_O );
|
|
scanner_menu->insertItem( SmallIcon("folder_open"), i18n("Scan &Directory..."), this, SLOT(slotScanDir()) );
|
|
scanner_menu->insertSeparator();
|
|
scanner_menu->insertItem( SmallIcon("xclock"), i18n("&Schedule scan..."), this, SLOT(slotScheduleScan()) );
|
|
scanner_menu->insertItem( SmallIcon("configure"), i18n("&Options..."), this, SLOT(slotOptions()) );
|
|
scanner_menu->insertSeparator();
|
|
scanner_menu->insertItem( SmallIcon("application-exit"), i18n("&Quit"), kapp, SLOT(quit()) );
|
|
|
|
tabs_menu = new TDEPopupMenu(this);
|
|
tabs_menu->setCheckable(true);
|
|
showWelcomeTab = tabs_menu->insertItem( SmallIcon("klamav"), i18n("Show &Welcome tab"), this, SLOT(slotToggleWelcome()) );
|
|
showQuarantineTab = tabs_menu->insertItem( SmallIcon("encrypted"), i18n("Show &Quarantine tab"), this, SLOT(slotToggleQuarantine()) );
|
|
showDBViewerTab = tabs_menu->insertItem( SmallIcon("system-search"), i18n("Show &Virus Browser tab"), this, SLOT(slotToggleDBViewer()) );
|
|
showEventsTab = tabs_menu->insertItem( SmallIcon("toggle_log"), i18n("Show &Events tab"), this, SLOT(slotToggleEvents()) );
|
|
|
|
|
|
// Menu bar
|
|
KMenuBar *menubar = this->menuBar();
|
|
menubar->insertItem( i18n("&Scanner"), scanner_menu );
|
|
menubar->insertItem( i18n("&Tabs"), tabs_menu );
|
|
menubar->insertItem( i18n("&Help"), helpMenu(NULL,false) );
|
|
|
|
top->setMenuBar(menubar);
|
|
|
|
activityviewer = new Activityviewer(this, "Events");
|
|
|
|
aboutklamav = new Aboutklamav(this, "Welcome");
|
|
updateTabState(0, true); // Welcome tab
|
|
|
|
klamscan = new Klamscan(this);
|
|
tab->addTab(klamscan, i18n("Scan"));
|
|
|
|
freshklam = new Freshklam(this);
|
|
tab->addTab(freshklam, i18n("Update"));
|
|
|
|
connect(freshklam->search_button,SIGNAL(clicked()),SLOT(contextUpdateFK()));
|
|
connect(freshklam->cancel_button,SIGNAL(clicked()),SLOT(contextDisableFK()));
|
|
|
|
|
|
|
|
kuarantine = new Kuarantine(this, "Quarantine");
|
|
updateTabState(1, true); // Quarantine tab
|
|
|
|
klamdb = new KlamDB(this, "DBViewer");
|
|
updateTabState(2, true); // Virus Browser tab
|
|
|
|
updateTabState(3, true); // Events tab
|
|
|
|
|
|
top->addWidget(tab);
|
|
|
|
// On-Access scanner
|
|
klamonacc = new KlamOnAcc(this);
|
|
connect( klamonacc, SIGNAL(stateUpdated()), this, SLOT(slotKOAStateUpdate()) );
|
|
|
|
slotKOAStateUpdate(); // initial state
|
|
|
|
connect(tab,SIGNAL(currentChanged ( TQWidget * ) ),klamdb,SLOT(shouldIShow(TQWidget *)));
|
|
|
|
KStdAction::quit(this, SLOT(shuttingDown()), actionCollection());
|
|
|
|
if (TDEApplication::kApplication()->isRestored()){
|
|
hide();
|
|
}else{
|
|
show();
|
|
}
|
|
|
|
|
|
if ((firstDownload) || (downloadDBForWizard)){
|
|
kdDebug() << "firstdownload" << firstDownload << endl;
|
|
kdDebug() << "downloadDBForWizard" << downloadDBForWizard << endl;
|
|
tab->setCurrentPage(2);
|
|
freshklam->slotSearch();
|
|
}
|
|
//klamdb->shouldIShow();
|
|
|
|
CollectionDB::instance()->insertEvent("Launch","KlamAV Launched");
|
|
|
|
setCaption(TQString("KlamAV %1 (Using ClamAV %2)").arg(KLAMAV_VERSION).arg(KlamavConfig::clamAVVersion()));
|
|
}
|
|
|
|
Klamav::~Klamav()
|
|
{
|
|
klamonacc->stop();
|
|
KlamavConfig::writeConfig();
|
|
kapp->quit();
|
|
}
|
|
|
|
void Klamav::shuttingDown(){
|
|
|
|
this->topLevelWidget()->hide();
|
|
|
|
}
|
|
|
|
bool Klamav::queryClose() {
|
|
if ( freshklam->isFreshklamAlive() || klamscan->scanGoingOn() || klamonacc->isActive() ){
|
|
KMessageBox::information (this,i18n("<p>KlamAV will stay open in the system tray. <br><br>"
|
|
" <b>Remember</b> - you can't quit KlamAV while <br> "
|
|
" a scan, Fresklam or KlamOnAcc is active!</p>"),"KlamAV","dontshow");
|
|
hide();
|
|
return false;
|
|
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Klamav::updateTabState( int tabId, bool init ) {
|
|
if( config->group() != "Tabs" )
|
|
config->setGroup("Tabs");
|
|
|
|
TQString optionName, tabName;
|
|
TQWidget* tabWidget;
|
|
int itemId;
|
|
|
|
switch(tabId) {
|
|
case 0: // Welcome tab
|
|
optionName="ShowWelcomeTab";
|
|
tabName=i18n("Welcome");
|
|
tabWidget=aboutklamav;
|
|
itemId=showWelcomeTab;
|
|
break;
|
|
|
|
case 1: // Quarantine tab
|
|
optionName="ShowQuarantineTab";
|
|
tabName=i18n("Quarantine");
|
|
tabWidget=kuarantine;
|
|
itemId=showQuarantineTab;
|
|
break;
|
|
|
|
case 2: // DBViewer tab
|
|
optionName="ShowDBViewerTab";
|
|
tabName=i18n("Virus Browser");
|
|
tabWidget=klamdb;
|
|
itemId=showDBViewerTab;
|
|
break;
|
|
|
|
case 3: // Events tab
|
|
optionName="ShowEventsTab";
|
|
tabName=i18n("Events");
|
|
tabWidget=activityviewer;
|
|
itemId=showEventsTab;
|
|
break;
|
|
}
|
|
|
|
if( config->readBoolEntry(optionName, true) ) {
|
|
tab->insertTab(tabWidget, tabName.ascii());
|
|
tabWidget->show();
|
|
|
|
if(!init) tab->setCurrentPage( tab->indexOf(tabWidget) );
|
|
} else {
|
|
if( tab->currentPageIndex() == tabId )
|
|
tab->setCurrentPage(0);
|
|
|
|
if( tab->indexOf( tabWidget ) != -1 ) {
|
|
tab->removePage( tabWidget );
|
|
}
|
|
tabWidget->hide();
|
|
}
|
|
|
|
tabs_menu->setItemChecked(itemId, config->readBoolEntry(optionName, true) );
|
|
}
|
|
|
|
void Klamav::tabClosed(TQString name) {
|
|
int uncheck;
|
|
TQString optionName;
|
|
|
|
if ( name == "Welcome" ) {
|
|
uncheck=showWelcomeTab;
|
|
optionName="ShowWelcomeTab";
|
|
} else if ( name == "Quarantine" ) {
|
|
uncheck=showQuarantineTab;
|
|
optionName="ShowQuarantineTab";
|
|
} else if ( name == "DBViewer" ) {
|
|
uncheck=showDBViewerTab;
|
|
optionName="ShowDBViewerTab";
|
|
} else if ( name == "Events" ) {
|
|
uncheck=showEventsTab;
|
|
optionName="ShowEventsTab";
|
|
}
|
|
|
|
tabs_menu->setItemChecked(uncheck, false);
|
|
config->setGroup("Tabs");
|
|
config->writeEntry(optionName, false);
|
|
}
|
|
|
|
// Menu slots
|
|
void Klamav::slotScanFile() {
|
|
klamscan->slotScanFile();
|
|
}
|
|
|
|
void Klamav::slotScanDir() {
|
|
klamscan->slotScanDir();
|
|
}
|
|
|
|
void Klamav::slotScheduleScan() {
|
|
klamscan->slotSchedule();
|
|
}
|
|
void Klamav::slotOptions() {
|
|
slotConfigKlamav("Scanning Backend");
|
|
}
|
|
|
|
void Klamav::slotToggleWelcome() {
|
|
if( config->group() != "Tabs" )
|
|
config->setGroup("Tabs");
|
|
|
|
bool newState = ! config->readBoolEntry("ShowWelcomeTab", true);
|
|
config->writeEntry("ShowWelcomeTab", newState);
|
|
config->sync();
|
|
|
|
updateTabState(0, false);
|
|
}
|
|
void Klamav::slotToggleQuarantine() {
|
|
if( config->group() != "Tabs" )
|
|
config->setGroup("Tabs");
|
|
|
|
bool newState = ! config->readBoolEntry("ShowQuarantineTab", true);
|
|
config->writeEntry("ShowQuarantineTab", newState);
|
|
config->sync();
|
|
|
|
updateTabState(1, false);
|
|
}
|
|
void Klamav::slotToggleDBViewer() {
|
|
if( config->group() != "Tabs" )
|
|
config->setGroup("Tabs");
|
|
|
|
bool newState = ! config->readBoolEntry("ShowDBViewerTab", true);
|
|
config->writeEntry("ShowDBViewerTab", newState);
|
|
config->sync();
|
|
|
|
updateTabState(2, false);
|
|
}
|
|
void Klamav::slotToggleEvents() {
|
|
if( config->group() != "Tabs" )
|
|
config->setGroup("Tabs");
|
|
|
|
bool newState = ! config->readBoolEntry("ShowEventsTab", true);
|
|
config->writeEntry("ShowEventsTab", newState);
|
|
config->sync();
|
|
|
|
updateTabState(3, false);
|
|
}
|
|
|
|
void Klamav::slotKOAStateUpdate()
|
|
{
|
|
kdDebug() << "slotKOAStateUpdate" << endl;
|
|
bool on = klamonacc->isActive();
|
|
bool enabled = klamonacc->isEnabled();
|
|
|
|
_tray->setPixmap(
|
|
KSystemTray::loadIcon(
|
|
(on ? "klamav_on_acc_enabled"
|
|
: "klamav_on_acc_disabled")
|
|
)
|
|
);
|
|
|
|
if(enabled) {
|
|
EnableKlamOnAcc->setEnabled(!on);
|
|
DisableKlamOnAcc->setEnabled(on);
|
|
} else {
|
|
EnableKlamOnAcc->setEnabled(false);
|
|
DisableKlamOnAcc->setEnabled(false);
|
|
}
|
|
}
|
|
|
|
void Klamav::contextUpdateFK() {
|
|
|
|
freshklam->slotSearch();
|
|
}
|
|
|
|
void Klamav::contextEnableFK() {
|
|
|
|
freshklam->enableAutoUpdates();
|
|
}
|
|
|
|
void Klamav::contextDisableFK() {
|
|
|
|
freshklam->slotCancel();
|
|
// DisableFreshklam->setEnabled(FALSE);
|
|
// EnableFreshklam->setEnabled(TRUE);
|
|
|
|
}
|
|
|
|
void Klamav::contextEnableKOA() {
|
|
klamonacc->start();
|
|
}
|
|
|
|
void Klamav::contextDisableKOA() {
|
|
klamonacc->stop();
|
|
}
|
|
|
|
void Klamav::showVirusBrowser() {
|
|
tab->setCurrentPage(5);
|
|
}
|
|
|
|
void Klamav::firstRunWizard() {
|
|
|
|
FirstRunWizard wizard;
|
|
wizard.setCaption( i18n( "First-Run Wizard" ));
|
|
|
|
TQString homepath = getenv("HOME");
|
|
TQString defaultdb = homepath + "/.klamav/database";
|
|
TQString defaultquar = homepath + "/.klamav/quarantine";
|
|
|
|
// Execute wizard
|
|
wizard.exec();
|
|
|
|
// These are run after the wizard is finished
|
|
TDEConfig* config = TDEGlobal::config();
|
|
|
|
config->setGroup("Freshklam");
|
|
|
|
TQString wizardDBPath = wizard.databasePath().path(-1);
|
|
TQString wizardTQRPath = wizard.quarantinePath().path(-1);
|
|
|
|
//Configure Database Path
|
|
TQStringList lastDownloadPaths;
|
|
if ((wizardDBPath != "") && (TQDir::cleanDirPath(wizardDBPath) != defaultdb)){
|
|
lastDownloadPaths.prepend( TQString("%1").arg(wizardDBPath));
|
|
checkDir(wizardDBPath);
|
|
}else{
|
|
lastDownloadPaths.prepend( TQString("%1").arg(wizard.defaultDatabasePath()));
|
|
createDefaultKlamAVDir("database");
|
|
}
|
|
config->writeEntry("lastDownloadPaths", lastDownloadPaths);
|
|
config->sync();
|
|
|
|
//Configure Quarantine Path
|
|
TQStringList lastQuarLocations;
|
|
|
|
config->setGroup("Kuarantine");
|
|
|
|
if ((wizardTQRPath != "") && (TQDir::cleanDirPath(wizardTQRPath) != defaultquar)){
|
|
lastQuarLocations.prepend( TQString("%1").arg(wizardTQRPath));
|
|
checkDir(wizardTQRPath);
|
|
}else{
|
|
lastQuarLocations.prepend( TQString("%1").arg(wizard.defaultQuarantinePath()));
|
|
createDefaultKlamAVDir("quarantine");
|
|
}
|
|
config->writeEntry("KuarantineLocations", lastQuarLocations);
|
|
config->sync();
|
|
|
|
if (wizard.downloadDatabase()){
|
|
kdDebug() << "downloading database" << endl;
|
|
downloadDBForWizard = true;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void Klamav::createDefaultKlamAVDir(TQString type){
|
|
|
|
TQString path = getenv("HOME");
|
|
bool ok = true;
|
|
// directory exist?
|
|
path += "/.klamav";
|
|
TQDir klamavdir(path);
|
|
if (!klamavdir.exists() && !klamavdir.mkdir(path))
|
|
ok = false;
|
|
|
|
path += "/" + type;
|
|
if (ok)
|
|
{
|
|
TQDir klamavqdir(path);
|
|
if (!klamavqdir.exists() && !klamavqdir.mkdir(path))
|
|
ok = false;
|
|
else
|
|
chmod(path.ascii(),0700);
|
|
}
|
|
|
|
}
|
|
|
|
void Klamav::checkDir(TQString path){
|
|
|
|
TQDir klamavdir(path);
|
|
TQFile f1( path );
|
|
if ((!klamavdir.exists()) || (f1.open( IO_ReadWrite )))
|
|
KMessageBox::information(this, i18n("Either the directory %1 does not exist or you are not able to write to it. Either way, you will have to change it as it cannot be used. Sorry!").arg(path));
|
|
f1.close();
|
|
|
|
}
|
|
|
|
void Klamav::slotConfigKlamav( const TQCString& page )
|
|
{
|
|
KlamavConfigDialog* dialog = (KlamavConfigDialog*) TDEConfigDialog::exists( "settings" );
|
|
|
|
if( !dialog )
|
|
{
|
|
//TDEConfigDialog didn't find an instance of this dialog, so lets create it :
|
|
dialog = new KlamavConfigDialog( this, "settings", KlamavConfig::self() );
|
|
//connect( dialog, SIGNAL(settingsChanged()), SLOT(applySettings()) );
|
|
}
|
|
|
|
//FIXME it seems that if the dialog is on a different desktop it gets lost
|
|
// what do to? detect and move it?
|
|
|
|
dialog->show();
|
|
dialog->raise();
|
|
dialog->setActiveWindow();
|
|
|
|
//so that if the engine page is needed to be shown it works
|
|
|
|
if ( !page.isNull() ) dialog->showPage( page );
|
|
}
|
|
|
|
|
|
#include "klamav.moc"
|