/* * Copyright (C) 2004 Robert Hogan */ #include "klamav.h" #include "freshklam.h" #include "sigtool.h" #include "klamscan.h" #include "schedule.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 #include #include #include #include #include #include #include #include #include #include #include #include #include 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("

KlamAV will stay open in the system tray.

" " Remember - you can't quit KlamAV while
" " a scan, Fresklam or KlamOnAcc is active!

"),"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() { Schedule *schedule_dlg = new Schedule(this, "scheduler"); schedule_dlg->show(); schedule_dlg->raise(); schedule_dlg->setActiveWindow(); } 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"