/* * Copyright (C) 2004 Robert Hogan */ #include "klamscan.h" #include "klamav.h" #include "klamscanoptions.h" #include "schedule.h" #include "directorylist.h" #include "tabwidget.h" #include "scanviewer.h" #include "collectiondb.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // TDEIO does not seem to have what we need using namespace KlamAV; Klamscan::Klamscan(TQWidget *parent, const char *name) : TQWidget(parent, name), DCOPObject( "DCOPKlamscan" ) { /* scanInProgress = FALSE; multiScan = FALSE; */ setDefaults(); TQBoxLayout *top = new TQVBoxLayout(this,10,10); tabBrowser = new TabWidget(this, "Klamscan", TQStringList( i18n("Launcher") )); tabBrowser->setMargin(5); top->addWidget(tabBrowser); /* dblayout->addMultiCellWidget( tabBrowser, 0, 1, 1, 1 );*/ //TQGridLayout *layout = new TQGridLayout(this, 6, 3, 10, 4); TQWidget* privateLayoutWidget2 = new TQWidget( this, "dblayout" ); TQGridLayout *layout = new TQGridLayout(privateLayoutWidget2, 6, 6, 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); TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); TQLabel *combo_label = new TQLabel(i18n("When a virus is found:"), privateLayoutWidget2); //combo_label->setFixedSize(combo_label->sizeHint()); layout->addWidget(combo_label,0,0); combo_label->adjustSize(); check_combo = new TQComboBox(false, privateLayoutWidget2); check_combo->insertItem( i18n( "Ask me" ) ); check_combo->insertItem( i18n( "Quarantine file" ) ); check_combo->insertItem( i18n( "Just report" ) ); check_combo->adjustSize(); //check_combo->setFixedSize(check_combo->size()); layout->addWidget(check_combo,0,1); recursive_box = new TQCheckBox(i18n("&Scan Folders Recursively"), privateLayoutWidget2); recursive_box->setMinimumWidth(recursive_box->sizeHint().width()); recursive_box->setChecked(true); // dir_layout2->addSpacing(10); layout->addWidget(recursive_box,0,3); TQToolTip::add( recursive_box, i18n( "Scan all directories under the specified path." ) ); TQToolButton* schedule = new TQToolButton( privateLayoutWidget2,"play" ); schedule->setIconSet( SmallIconSet( "xclock" ) ); schedule->setTextLabel(i18n( "Schedule" )); schedule->setTextPosition(TQToolButton::Right); schedule->setUsesTextLabel(true); schedule->adjustSize(); layout->addWidget(schedule,0,4); connect( schedule, SIGNAL(clicked()), SLOT(slotSchedule()) ); TQToolButton* adv_options = new TQToolButton( privateLayoutWidget2,"play" ); adv_options->setIconSet( SmallIconSet( "configure" ) ); adv_options->setTextLabel(i18n("Options")); adv_options->setTextPosition(TQToolButton::Right); adv_options->setUsesTextLabel(true); layout->addWidget(adv_options,0,5); //adv_options->setFixedSize(adv_options->sizeHint()); adv_options->adjustSize(); connect( adv_options, SIGNAL(clicked()), SLOT(slotAdvOptions()) ); setup = new CollectionSetup( privateLayoutWidget2, recursive_box->isChecked() ); layout->addMultiCellWidget(setup, 1, 6,0,6); connect( recursive_box, SIGNAL(toggled(bool)),setup, SLOT(slotRecursiveToggled(bool)) ); TQHBox* controls = new TQHBox(tabBrowser); //controls->setSpacing(5); controls->setMargin(2); play = new TQToolButton( controls,"play" ); play->setIconSet( SmallIconSet( "media-playback-start" ) ); play->setTextLabel(i18n( "Scan" )); play->setTextPosition(TQToolButton::Right); play->setUsesTextLabel(true); play->adjustSize(); play->setFixedHeight(play->height() - 1); stop = new TQToolButton( controls,"stop" ); stop->setIconSet( SmallIconSet( "media-playback-stop" ) ); stop->setTextLabel(i18n( "Stop" )); stop->setTextPosition(TQToolButton::Right); stop->setUsesTextLabel(true); stop->adjustSize(); stop->setFixedHeight(stop->height() - 1); m_tabsClose = new TQToolButton( controls,"tab_remove" ); m_tabsClose->setIconSet( SmallIconSet( "tab_remove" ) ); m_tabsClose->setTextLabel(i18n( "Close" )); m_tabsClose->setTextPosition(TQToolButton::Right); m_tabsClose->setUsesTextLabel(true); m_tabsClose->adjustSize(); m_tabsClose->setFixedHeight(m_tabsClose->height() - 1); connect( play, SIGNAL( clicked() ), this, SLOT( slotStartAgain() ) ); connect( stop, SIGNAL( clicked() ), this, SLOT( slotStopScanning() ) ); connect( m_tabsClose, SIGNAL( clicked() ), this, SLOT( slotRemoveTab() ) ); controls->adjustSize(); tabBrowser->setCornerWidget( controls, TopRight ); ////kdDebug() << "pos: " << controls->pos() << endl; //controls->move(controls->pos()); tabBrowser->addTab(privateLayoutWidget2, i18n( "Launcher")); layout->activate(); connect(tabBrowser, SIGNAL(currentChanged(TQWidget *)),this, SLOT(slotManageButtons(TQWidget *)) ); // Register with DCOP if ( !kapp->dcopClient()->isRegistered() ) { kapp->dcopClient()->registerAs( "dcopklamscan" ); kapp->dcopClient()->setDefaultObject( objId() ); } if( args->isSet( "scanthis" ) ) { slotScan(); } } Klamscan::~Klamscan() { } bool Klamscan::scanGoingOn() { // Find any tab in which scanning hasn't finished yet for( int i = 1; i < tabBrowser->count(); i++ ) { if( dynamic_cast( tabBrowser->page(i) )->scanGoingOn() ) return true; } return false; } void Klamscan::scan( TQStringList filepattern ) { ScanViewer* homepage = new ScanViewer(this, "page"); connect( homepage, SIGNAL( scanFinished(TQWidget *) ), this, SLOT( slotManageButtons(TQWidget *) ) ); connect( homepage, SIGNAL( scanStartingAgain(TQWidget *) ), this, SLOT( slotManageButtons(TQWidget *) ) ); tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_scanning")); 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 ap")); tabBrowser->addTab(homepage,suffix); tabBrowser->setCurrentPage(tabBrowser->count() - 1); CollectionDB::instance()->insertEvent("Manual Scan",TQString("Commencing Scan"),filepattern.join(" ")); homepage->slotScan(filepattern, check_combo->currentItem(),setup->recursive(),false); } void Klamscan::slotScan() { TQStringList filepattern; TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); if( args->isSet( "scanthis" ) ) { listOfUrlsToScan.clear(); for( int i = 0; i < args->count(); i++ ) { //KMessageBox::information (this,TQString(args->arg(i))); filepattern.append(args->arg(i)); listOfUrlsToScan.prepend(TQString(args->arg(i))); } prevdir = listOfUrlsToScan.first(); }else{ filepattern = pruneSelectedDirs(); } scan( filepattern ); } void Klamscan::slotScanFile() { KURL::List urls( KFileDialog::getOpenURLs(TQString::null,TQString::null,this) ); TQStringList filepattern; KURL::List::iterator it; for( it = urls.begin(); it != urls.end(); ++it ) { filepattern.append( (*it).pathOrURL() ); } if( filepattern.count() == 0 ) return; scan( filepattern ); } void Klamscan::slotScanDir() { TQString dir=KFileDialog::getExistingDirectory(TQString::null,this); if( dir == TQString::null ) return; scan( TQStringList(dir) ); } void Klamscan::slotAdvOptions(){ /* KlamscanOptions *dialog = new KlamscanOptions( this, "settings"); dialog->show(); dialog->raise(); dialog->setActiveWindow();*/ tdemain->slotConfigKlamav( "Archive Limits" ); } void Klamscan::slotSchedule(){ TQStringList filepattern = pruneSelectedDirs(); if (filepattern.isEmpty()){ KMessageBox::error(this, i18n( "Please select something to scan!") ); return; } Schedule *dialog = new Schedule( this, filepattern, "settings"); dialog->show(); dialog->raise(); dialog->setActiveWindow(); } void Klamscan::setDefaults(){ config = TDEGlobal::config(); config->setGroup("ScanPaths"); config->setGroup("Klamscan"); if ((config->readEntry("NoFilesToExtract")).isEmpty()) config->writeEntry("NoFilesToExtract","500"); if ((config->readEntry("RecursionLevel")).isEmpty()) config->writeEntry("RecursionLevel","8"); // if ((config->readEntry("MBsToExtract")).isEmpty()) // config->writeEntry("MBsToExtract","10M"); // // if ((config->readEntry("CompressionRatio")).isEmpty()) // config->writeEntry("CompressionRatio","250"); if ((config->readEntry("MaxFileSize")).isEmpty()) config->writeEntry("MaxFileSize","25M"); if ((config->readEntry("MaxScanSize")).isEmpty()) config->writeEntry("MaxScanSize","25M"); // if ((config->readEntry("VirusLimitsExceeded")).isEmpty()) // config->writeEntry("VirusLimitsExceeded", "Yes"); if ((config->readEntry("VirusEncrypted")).isEmpty()) config->writeEntry("VirusEncrypted", "Yes"); if ((config->readEntry("ScanMail")).isEmpty()) config->writeEntry("ScanMail", "Yes"); if ((config->readEntry("ScanPE")).isEmpty()) config->writeEntry("ScanPE", "Yes"); if ((config->readEntry("ScanOle")).isEmpty()) config->writeEntry("ScanOle", "Yes"); if ((config->readEntry("ScanHTML")).isEmpty()) config->writeEntry("ScanHTML", "Yes"); if ((config->readEntry("VirusBroken")).isEmpty()) config->writeEntry("VirusBroken", "Yes"); if ((config->readEntry("ExcludeQuarantine")).isEmpty()) config->writeEntry("ExcludeQuarantine", "Yes"); if ((config->readEntry("ScanMail")).isEmpty()) config->writeEntry("ScanMail", "Yes"); config->sync(); } void Klamscan::scanURLs(const TQString &urls) { setActiveWindow(); raise(); tdemain->tab->setCurrentPage(0); TQString tmpurls = urls; //urlsToScan = urlsToScan.replace("*"," "); urlsToScan = TQStringList::split("*", tmpurls); //for ( TQStringList::Iterator it = temp.begin(); it != temp.end(); ++it ) // (*it).sprintf("\"%s\"", (*it).latin1()); //urlsToScan = temp; ScanViewer* homepage = new ScanViewer(this, "page"); connect( homepage, SIGNAL( scanFinished(TQWidget *) ), this, SLOT( slotManageButtons(TQWidget *) ) ); connect( homepage, SIGNAL( scanStartingAgain(TQWidget *) ), this, SLOT( slotManageButtons(TQWidget *) ) ); 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 ap")); tabBrowser->addTab(homepage,suffix); tabBrowser->setCurrentPage(tabBrowser->count() - 1); CollectionDB::instance()->insertEvent("Manual Scan",TQString("Commencing Scan"),urlsToScan.join(" ")); homepage->slotScan(urlsToScan, check_combo->currentItem(),setup->recursive(),true); } void Klamscan::slotStopScanning(){ tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled")); ////kdDebug() << tabBrowser->currentPage()->name() << endl; ScanViewer* cur = static_cast(tabBrowser->currentPage()); cur->slotCancel(); } void Klamscan::slotStartAgain(){ ////kdDebug() << tabBrowser->currentPage()->name() << endl; if (tabBrowser->currentPageIndex() != 0){ ScanViewer* cur = static_cast(tabBrowser->currentPage()); cur->slotStartAgain(); }else slotScan(); //slotManageButtons(tabBrowser->currentPage()); } void Klamscan::slotRemoveTab(){ tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled")); ////kdDebug() << tabBrowser->currentPage()->name() << endl; if (tabBrowser->currentPageIndex() != 0){ slotStopScanning(); tabBrowser->removePage(tabBrowser->currentPage()); } } void Klamscan::slotManageButtons(TQWidget * current){ ScanViewer* cur = static_cast(current); if (tabBrowser->currentPageIndex() == 0){ play->setEnabled(true); stop->setEnabled(false); m_tabsClose->setEnabled(false); return; } if (cur->scanGoingOn()){ play->setEnabled(false); stop->setEnabled(true); }else{ play->setEnabled(true); stop->setEnabled(false); } m_tabsClose->setEnabled(true); } TQStringList Klamscan::pruneSelectedDirs(){ //This gets rid of redundant sub-directories from the list of dirs to be scanned. TQStringList filepattern; TQStringList listOfUrlsToScan = setup->dirs(); listOfUrlsToScan.sort(); TQString prev; TQStringList prevdirs; struct stat sb; for (TQStringList::Iterator it = listOfUrlsToScan.begin(); it != listOfUrlsToScan.end(); it++ ){ //kdDebug() << "dir: " << (*it) << endl; (*it) = (*it).stripWhiteSpace(); // replace block devices with mountpoints lstat( (*it), &sb ); if ( (sb.st_mode & S_IFMT) == S_IFBLK ) { // This is actually from directorylist.cpp DCOPRef mediamanager("kded", "mediamanager"); DCOPReply reply = mediamanager.call( "properties", (*it) ); TQStringList properties; reply.get( properties, "TQStringList" ); (*it) = * (properties.at(7) ); } else { (*it) = (*it) + "/"; } if (prevdirs.isEmpty()){ //kdDebug() << (*it) << endl; filepattern.append(*it); prevdirs.append((*it)); }else{ filepattern.append(*it); bool shouldappend = true; for (TQStringList::Iterator it2 = prevdirs.begin(); it2 != prevdirs.end(); it2++ ){ if ((*it).contains(*it2)){ //kdDebug() << (*it) << endl; filepattern.remove((*it)); shouldappend = false; break; } } if (shouldappend) prevdirs.append((*it)); } } return filepattern; } #include "klamscan.moc"