summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMavridis Philippe <mavridisf@gmail.com>2021-02-26 19:34:09 +0200
committerMavridis Philippe <mavridisf@gmail.com>2021-03-03 17:44:31 +0200
commit13cb4a5e7dc1c22d25c51da52156a558be0b7d05 (patch)
treee013fb1be4c88430b4be1ef21acb656c7f91eb5d /src
parent8300c80d583320087d844b9f0ad0025d4a60aa10 (diff)
downloadklamav-13cb4a5e7dc1c22d25c51da52156a558be0b7d05.tar.gz
klamav-13cb4a5e7dc1c22d25c51da52156a558be0b7d05.zip
Added On-Access Scanner.
There are still a few TODOs, but it seems to work quite well already. This relates to issue #10. Signed-off-by: Mavridis Philippe <mavridisf@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/configdialog.cpp46
-rw-r--r--src/configdialog.h7
-rw-r--r--src/klamav.h14
-rw-r--r--src/klamavconfig.kcfg47
-rw-r--r--src/klamonacc.cpp387
-rw-r--r--src/klamonacc.h73
-rw-r--r--src/klamonacc_alert.ui212
-rw-r--r--src/klamonacc_config.ui253
-rw-r--r--src/klamonacc_config.ui.h54
10 files changed, 1064 insertions, 32 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2275778..046fe3e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,6 +32,7 @@ tde_add_executable( ${PROJECT_NAME} AUTOMOC
klamscan.cpp kuarantine.cpp welcome.cpp dbviewer.cpp
frame.cpp tabwidget.cpp viewer.cpp pageviewer.cpp
klamav_run.cpp dcopklamscan.skel directorylist.cpp
+ klamonacc.cpp klamonacc_alert.ui
scanviewer.cpp schedule.cpp datepicker.cpp
cthost.cpp ctcron.cpp ctmonth.cpp ctdom.cpp
ctdow.cpp cttask.cpp ctvariable.cpp
@@ -39,7 +40,7 @@ tde_add_executable( ${PROJECT_NAME} AUTOMOC
ktview.cpp ktlistcron.cpp kticon.cpp
activityviewer.cpp collectiondb.cpp
configdialog.cpp klamavconfig.kcfgc
- archives.ui specialfiletypes.ui
+ archives.ui specialfiletypes.ui klamonacc_config.ui
firstrunwizard.ui logoptions.ui backend.ui
k3bjobprogressosd_mod.cpp
diff --git a/src/configdialog.cpp b/src/configdialog.cpp
index 5cd76ac..43a0fe8 100644
--- a/src/configdialog.cpp
+++ b/src/configdialog.cpp
@@ -13,11 +13,13 @@ email : markey@web.de
* *
***************************************************************************/
+#include "klamav.h"
#include "configdialog.h"
#include "backend.h"
#include "archives.h"
#include "specialfiletypes.h"
-/* #include "autoscanoptions.h" */
+#include "klamonacc.h"
+#include "klamonacc_config.h"
#include "logoptions.h"
#include "sigtool.h"
@@ -42,6 +44,7 @@ email : markey@web.de
#include <klineedit.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
+#include <tdemessagebox.h>
//////////////////////////////////////////////////////////////////////////////////////////
// PUBLIC
@@ -57,7 +60,7 @@ KlamavConfigDialog::KlamavConfigDialog( TQWidget *parent, const char* name, TDEC
m_archives = new ArchiveOptions( 0, "Archives" );
m_emailprotection = new Sigtool ( 0, "E-mail protection" );
m_specialfiletypes = new SpecialFileTypes( 0, "File Types" );
- /* m_autoscanoptions = new AutoScanOptions( 0, "Auto-Scan" ); */
+ m_klamonacc = new KlamOnAccConfig( 0, "On-Access Scanner" );
m_logoptions = new LogOptions( 0, "Event Logging" );
// add pages
@@ -68,7 +71,13 @@ KlamavConfigDialog::KlamavConfigDialog( TQWidget *parent, const char* name, TDEC
addPage( m_archives, i18n( "Archives" ), "ark", i18n( "Configure Archive Scanning" ) );
addPage( m_emailprotection, i18n( "E-mail protection" ), "email", i18n( "Set up your e-mail client to use Klammail" ) );
addPage( m_specialfiletypes, i18n( "File Types" ), "folder", i18n( "Configure File Types" ) );
- /* addPage( m_autoscanoptions, i18n( "Auto-Scan" ), "filefind", i18n( "Configure Auto-Scan" ) ); */
+
+ addPage( m_klamonacc, i18n( "On-Access Scanner" ), "filefind", i18n( "Configure On-Access Scanning" ) );
+ connect( m_klamonacc, SIGNAL(directoriesModified()), tdemain->klamonacc, SLOT(restart()) );
+ connect( tdemain->klamonacc, SIGNAL(stateUpdated()), this, SLOT(slotToggleKlamOnAccCheckbox()) );
+ connect( m_klamonacc->kcfg_EnableOnAccess, SIGNAL(toggled(bool)), this, SLOT(slotToggleKlamOnAcc(bool)) );
+ slotToggleKlamOnAcc( m_klamonacc->kcfg_EnableOnAccess->isOn() ); // initial state
+
addPage( m_logoptions, i18n( "Event Logging" ), "kate", i18n( "Configure Events to Log" ) );
TQObjectList *list = queryList( "TQLabel", "infoPixmap" );
@@ -82,7 +91,7 @@ KlamavConfigDialog::KlamavConfigDialog( TQWidget *parent, const char* name, TDEC
static_cast<TQLabel*>(label)->setMaximumWidth( 250 );
delete list;
-
+ connect( this, SIGNAL(settingsChanged()), SLOT(applySettings()) );
}
KlamavConfigDialog::~KlamavConfigDialog()
@@ -96,6 +105,19 @@ void KlamavConfigDialog::slotToggleClamdscan(bool on)
m_specialfiletypes->setEnabled(!on);
}
+void KlamavConfigDialog::slotToggleKlamOnAcc(bool on)
+{
+ m_klamonacc->kcfg_ExtraScanning->setEnabled(on);
+ m_klamonacc->kcfg_OnAccessMaxFile->setEnabled(on);
+// m_klamonacc->kcfg_ExcludeConfDir->setEnabled(on);
+ m_klamonacc->GroupWatchDirs->setEnabled(on);
+}
+
+void KlamavConfigDialog::slotToggleKlamOnAccCheckbox()
+{
+ m_klamonacc->kcfg_EnableOnAccess->setChecked( tdemain->klamonacc->isEnabled() );
+}
+
/** Show page by object name */
void KlamavConfigDialog::showPage( const TQCString& page )
{
@@ -116,6 +138,22 @@ void KlamavConfigDialog::addPage( TQWidget *page, const TQString &itemName, cons
TDEConfigDialog::addPage( page, itemName, pixmapName, header, manage );
}
+void KlamavConfigDialog::applySettings() {
+ // Some precautions
+ // if(! m_klamonacc->kcfg_ExcludeConfDir->isOn() )
+ // KMessageBox::information(this, i18n("You have chosen not to exclude the TDE configuration directory from the on-access scanner's watchlist. Be warned that watching this directory can severely impact your computer's performance and cause instability."), i18n("Warning!") );
+
+ // Toggle/restart Klamonacc
+ bool oldState = tdemain->klamonacc->isEnabled();
+ bool newState = m_klamonacc->kcfg_EnableOnAccess->isOn();
+
+ if( oldState != newState ) // If Klamonacc's state changed
+ tdemain->klamonacc->toggle( newState );
+ else if( newState && m_klamonacc->needsRestart() ) { // If KlamOnAcc's settings were changed
+ tdemain->klamonacc->restart();
+ m_klamonacc->slotSettingsApplied();
+ }
+}
diff --git a/src/configdialog.h b/src/configdialog.h
index ad906c9..a943492 100644
--- a/src/configdialog.h
+++ b/src/configdialog.h
@@ -42,6 +42,8 @@ class KlamavConfigDialog : public TDEConfigDialog
public slots:
void slotToggleClamdscan( bool on );
+ void slotToggleKlamOnAcc( bool on );
+ void slotToggleKlamOnAccCheckbox();
private:
bool clamdscan;
@@ -50,12 +52,15 @@ class KlamavConfigDialog : public TDEConfigDialog
class ArchiveOptions *m_archives;
class SpecialFileTypes *m_specialfiletypes;
class Sigtool *m_emailprotection;
- class AutoScanOptions *m_autoscanoptions;
+ class KlamOnAccConfig *m_klamonacc;
class LogOptions *m_logoptions;
TQValueList<TQWidget*> m_pageList;
TQMap<TQString, TQString> m_pluginName;
TQMap<TQString, TQString> m_pluginKlamavName;
+
+ private slots:
+ void applySettings();
};
diff --git a/src/klamav.h b/src/klamav.h
index f3d2960..210934b 100644
--- a/src/klamav.h
+++ b/src/klamav.h
@@ -37,6 +37,7 @@ class Activityviewer;
class Aboutklamav;
class KlamDB;
class KSystemTray;
+class KlamOnAcc;
/**
* This class serves as the main window for Klamav. It handles the
@@ -69,6 +70,8 @@ public:
KSystemTray *_tray;
TDEAction *EnableFreshklam;
TDEAction *DisableFreshklam;
+ TDEAction *EnableKlamOnAcc;
+ TDEAction *DisableKlamOnAcc;
Freshklam *freshklam;
bool firstDownload;
bool downloadDBForWizard;
@@ -78,6 +81,7 @@ public:
Activityviewer *activityviewer;
void showVirusBrowser();
TQTabWidget *tab;
+ KlamOnAcc *klamonacc;
protected:
@@ -104,7 +108,6 @@ protected:
//void readProperties(TDEConfig *);
public slots:
- void clamdStopped();
void slotConfigKlamav( const TQCString& page );
private slots:
void slotScanFile();
@@ -115,9 +118,12 @@ private slots:
void slotToggleQuarantine();
void slotToggleDBViewer();
void slotToggleEvents();
+ void slotKOAStateUpdate();
void contextEnableFK();
- void contextUpdateFK();
- void contextDisableFK();
+ void contextUpdateFK();
+ void contextDisableFK();
+ void contextEnableKOA();
+ void contextDisableKOA();
void tabClosed(TQString name);
private:
@@ -158,7 +164,7 @@ private:
TQStringList lastSearchPaths;
Sigtool *sigtool;
Aboutklamav *aboutklamav;
-
+
TDEPopupMenu *tabs_menu;
int showWelcomeTab;
int showQuarantineTab;
diff --git a/src/klamavconfig.kcfg b/src/klamavconfig.kcfg
index 8a2c55c..4646d32 100644
--- a/src/klamavconfig.kcfg
+++ b/src/klamavconfig.kcfg
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE kcfg SYSTEM "http://www.kde.org/standards/kcfg/1.0/kcfg.dtd">
-<kcfg>
-<kcfgfile name="klamavrc"/>
+<kcfg>
+<kcfgfile name="klamavrc"/>
<group name="KlamavBackend">
<entry name="ScannerClamscan" type="Bool">
@@ -30,17 +30,17 @@
<label>Maximum Recursion Level</label>
<whatsthis>The maximum number of subdirectories in a zip file to open before .</whatsthis>
<default>0</default>
- </entry>
+ </entry>
<entry name="MaxFileSize" type="Int">
<label>Maximum MBs to Extract</label>
<whatsthis>The maximum number of megabytes to extract from a zip file before marking it as suspicious.</whatsthis>
<default>0</default>
- </entry>
+ </entry>
<entry name="MaxScanSize" type="Int">
<label>Maximum MBs to Extract</label>
<whatsthis>The maximum number of megabytes to extract from a zip file before marking it as suspicious.</whatsthis>
<default>0</default>
- </entry>
+ </entry>
<entry name="NoFilesToExtract" type="Int">
<label>Maximum Number of Files to Extract</label>
<whatsthis>The maximum number of file to extract from a zip file before marking it as suspicious.</whatsthis>
@@ -48,7 +48,7 @@
</entry>
</group>
-<group name="FileTypes">
+<group name="FileTypes">
<entry name="VirusEncrypted" type="Bool">
<label>Mark Encrypted Files as Suspicious</label>
<default>true</default>
@@ -101,27 +101,30 @@
</group>
-<group name="Autoscan">
- <entry name="Executed" type="Bool">
- <label>Scan Files When They Are Executed</label>
- <default>true</default>
+<group name="OnAccess">
+ <entry name="EnableOnAccess" type="Bool">
+ <label>Enable On-Access Scanner</label>
+ <default>false</default>
</entry>
- <entry name="Opened" type="Bool">
- <label>Scan Files When They Are Opened</label>
- <default>true</default>
+ <entry name="ExtraScanning" type="Bool">
+ <label>Scan Files/Directories When They Are Created or Moved</label>
+ <default>false</default>
</entry>
- <entry name="Closed" type="Bool">
- <label>Scan Files When They Are Closed</label>
- <default>true</default>
+ <entry name="ExcludeConfDir" type="Bool">
+ <label>Exclude TDE Configuration Directory</label>
+ <default>true</default>
</entry>
- <entry name="Created" type="Bool">
- <label>Scan Files When They Are Created or Modified</label>
- <default>false</default>
+ <entry name="OnAccessMaxFile" type="Int">
+ <label>Maximum File Size</label>
+ <default>5</default>
+ </entry>
+ <entry name="Watchlist" type="StringList">
+ <label>Directories to Watch</label>
+ <default></default>
</entry>
-
</group>
-<group name="EventLogging">
+<group name="EventLogging">
<entry name="ExpireDays" type="Int">
<label>Expire Events After the Specified Number of Days</label>
<default>30</default>
@@ -158,7 +161,7 @@
</group>
-<group name="Misc">
+<group name="Misc">
<entry name="ClamAVVersion" type="String">
<label>Expire Events After the Specified Number of Days</label>
</entry>
diff --git a/src/klamonacc.cpp b/src/klamonacc.cpp
new file mode 100644
index 0000000..76a41d8
--- /dev/null
+++ b/src/klamonacc.cpp
@@ -0,0 +1,387 @@
+/*
+ * KlamOnAcc class -- the non-graphical class which manages clamonacc.
+ *
+ * Copyright (C) 2021 Mavridis Philippe <mavridisf@gmail.com>
+ *
+ * Portions taken from freshklam.cpp and scanviewer.cpp
+ */
+
+/* TODO:
+ - Implement a separate start/stop daemon process so that we don't need to
+ ask for root privgileges every time we start or kill clamonacc
+ - processOutput: [Initializing] and [Scanner ready] notifications
+ */
+
+#include "klamonacc.h"
+#include "klamonacc_alert.h"
+#include "klamav.h"
+#include "klamavconfig.h"
+#include "collectiondb.h"
+#include "directorylist.h"
+
+#include <tdeglobal.h>
+#include <tdelocale.h>
+#include <tdeconfig.h>
+#include <tdetempfile.h>
+#include <kprocess.h>
+#include <tdemessagebox.h>
+#include <ksystemtray.h>
+#include <knotifyclient.h>
+
+/* Required by quarantine() function */
+#include <kiconloader.h>
+#include <tdeio/netaccess.h>
+
+KlamOnAcc::KlamOnAcc( TQWidget *parent, const char *name )
+ : TQObject( parent, name )
+{
+ config = TDEGlobal::config();
+ config->setGroup("OnAccess");
+
+ // Initial state
+ toggle( config->readBoolEntry("EnableOnAccess", false) );
+}
+
+KlamOnAcc::~KlamOnAcc()
+{
+}
+
+TQString KlamOnAcc::tdesu(TQString command, TQString caption, bool terminal)
+{
+ TQString sucommand;
+
+ if(terminal)
+ sucommand = TQString("tdesu --caption \"%1\" --ignorebutton -t ").arg( caption );
+ else
+ sucommand = TQString("tdesu --caption \"%1\" --ignorebutton ").arg( caption );
+
+ sucommand += "\"" + command + "\"";
+
+ return sucommand;
+}
+
+TQString KlamOnAcc::startPrepare()
+{
+ // Determine and write configuration
+ TQString daemonOpts;
+ TQStringList daemonConfig;
+
+ // Create a config file based on the default one
+ TQFile defaultConfigFile( "/etc/clamav/clamd.conf" );
+
+ if( defaultConfigFile.open(IO_ReadOnly) )
+ {
+ TQTextStream in_stream( &defaultConfigFile );
+ TQString in_line;
+ int in_line_n = 0;
+
+ while(! in_stream.atEnd() )
+ {
+ daemonConfig += in_stream.readLine();
+ ++in_line_n;
+ }
+
+ defaultConfigFile.close();
+ }
+
+ // Set up ClamOnAcc's config
+ daemonConfig += "OnAccessPrevention yes";
+
+ config->setGroup("OnAccess");
+
+ if ( config->readBoolEntry("ExtraScanning", false) )
+ daemonConfig += "OnAccessExtraScanning yes";
+
+ daemonConfig += TQString("OnAccessMaxFileSize %1M").arg(
+ config->readNumEntry("OnAccessMaxFile", 5)
+ );
+
+ daemonConfig += "OnAccessExcludeUname clamav";
+
+ // Specify directories to watch
+ TQStringList dirs = CollectionSetup::pruneSelectedDirs( config->readListEntry("Watchlist") );
+
+ if (! dirs.count() ) {
+ fatalError( i18n("Please select the directories you want to watch from the Options dialog.") );
+ return TQString::null;
+ }
+
+ for ( TQStringList::Iterator it = dirs.begin(); it != dirs.end(); it++ )
+ daemonConfig += TQString("OnAccessIncludePath %1").arg(*it);
+
+ /* BUG: DOES NOT WORK (why do they have this option then?)
+ "ERROR: ClamInotif: can't exclude '/home/user/.trinity'" */
+ // if ( config->readBoolEntry("ExcludeConfDir", true) )
+ // daemonConfig += TQString("OnAccessExcludePath %1/.trinity").arg(getenv("HOME"));
+
+ // Write the config
+ KTempFile tf;
+
+ if ( tf.status() != 0 ) {
+ tf.close();
+
+ fatalError( i18n("Could not create temporary configuration file for ClamOnAcc!") );
+ return TQString::null;
+ }
+
+ TQString tempFileName = tf.name();
+
+ TQTextStream &ts = *(tf.textStream());
+
+ for ( TQStringList::Iterator it = daemonConfig.begin(); it != daemonConfig.end(); it++ )
+ ts << (*it) << endl;
+
+ tf.close();
+
+ // Set up ClamOnAcc's command-line options
+ daemonOpts += " --fdpass -v --stdout --foreground";
+ daemonOpts += TQString(" --config-file=%1").arg(tempFileName);
+
+ // Make the start command
+ TQString command = "clamonacc";
+ command += daemonOpts;
+
+ return command;
+}
+
+void KlamOnAcc::startProcess( TQString command )
+{
+ childproc = new KShellProcess();
+ *childproc << command;
+ childproc->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout);
+
+ connect( childproc, SIGNAL(receivedStdout(TDEProcess*, char*, int)), SLOT(processOutput(TDEProcess*, char*, int)) );
+ connect( childproc, SIGNAL(processExited(TDEProcess*)), SLOT(childExited()) );
+
+ emit stateUpdated();
+}
+
+void KlamOnAcc::start()
+{
+ if( active || !enabled ) return;
+ active = true;
+ crashed = false;
+
+ // Log this event
+ CollectionDB::instance()->insertEvent("On-Access Scanner","Starting On-Access Scanner",0);
+
+ startProcess( tdesu(startPrepare(), i18n("Start On-Access Scanner"), true) );
+}
+
+TQString KlamOnAcc::stopPrepare()
+{
+ disconnect( childproc, 0, 0, 0 );
+
+ // It's like this until a proper start/stop daemon is implemented
+ return TQString("killall -9 clamonacc");
+}
+
+void KlamOnAcc::stopProcess( TQString command )
+{
+ if( childproc->isRunning() ) {
+ TDEProcess *terminator = new KShellProcess();
+ *terminator << command;
+ terminator->start();
+ }
+
+ emit stateUpdated();
+}
+
+void KlamOnAcc::stop()
+{
+ if( !active || !enabled ) return;
+ active = false;
+
+ // Log this event
+ CollectionDB::instance()->insertEvent("On-Access Scanner","Stopping On-Access Scanner",0);
+
+ stopProcess( tdesu(stopPrepare(), i18n("Stop On-Access Scanner")) );
+}
+
+
+void KlamOnAcc::restart()
+{
+ kdDebug() << "restart()" << endl;
+ if( isActive() )
+ {
+ active = false;
+
+ // We combine two commands here
+ TQString command = stopPrepare() + TQString("; ") + startPrepare();
+ kdDebug() << "restart(): " << command << endl;
+ startProcess( tdesu(command, i18n("Restart On-Access Scanner"), true) );
+
+ active = true;
+ }
+}
+
+void KlamOnAcc::toggle( bool on ) {
+ kdDebug() << "toggle()" << endl;
+
+ if ( !on && isEnabled() )
+ disable();
+ else if ( on && !isEnabled() )
+ enable();
+}
+
+void KlamOnAcc::childExited() {
+ if(active) // died too early
+ fatalError( i18n("ClamOnAcc has died unexpectedly. If you did not kill it yourself, please check your ClamAV installation.") );
+}
+
+void KlamOnAcc::fatalError(TQString descr)
+{
+ if( crashed ) return; // do not display further errors
+
+ active = false;
+ crashed = true;
+
+ CollectionDB::instance()->insertEvent("On-Access Scanner","On-Access Scanner has died!",0);
+
+ disable();
+
+ KMessageBox::sorry(
+ 0,
+ descr,
+ i18n("Fatal Error")
+ );
+}
+
+void KlamOnAcc::processOutput(TDEProcess*, char* buffer, int buffSize)
+{
+
+ TQString buff( buffer );
+ buff = buff.mid( 0, buff.find("\n") ).stripWhiteSpace();
+
+ kdDebug() << "KLAMONACC " << buff << endl;
+
+ int pos;
+
+ if( buff.find("Could not connect to clamd") != -1 )
+ {
+ fatalError( i18n("The ClamAV daemon is unavailable! Please ensure that it is running and try again.") );
+ return;
+ }
+ else if( buff.find("ClamInotif: watching") != -1 )
+ {
+ // TODO: "initialization complete" notification
+ }
+ else if( (pos = buff.find("FOUND")) != -1 )
+ {
+ fname = buff.mid( 0, buff.find(":") );
+ vname = buff.mid( buff.find(":")+2, pos );
+
+ if( shownAlerts.find(fname) != shownAlerts.end() )
+ return; // alert already shown for this file
+
+ TQListViewItem *virusItem;
+ alert = new KlamOnAccAlert();
+ alert->setModal(false);
+ alert->setActiveWindow();
+
+ TQListViewItem *virus = new TQListViewItem( alert->VirusList, fname, vname, i18n("Loose") );
+ virus->setPixmap( 0, SmallIcon("klamav_virus") );
+
+ shownAlerts << fname;
+ alert->exec();
+
+ if( alert->result() == TQDialog::Accepted )
+ quarantine();
+ }
+}
+
+void KlamOnAcc::enable()
+{
+ kdDebug() << "% ENABLE()" << endl;
+
+ config->setGroup("OnAccess");
+ config->writeEntry("EnableOnAccess", true);
+ config->sync();
+
+ enabled = true;
+
+ if(! isActive() ) start();
+
+ emit stateUpdated();
+}
+
+void KlamOnAcc::disable()
+{
+ kdDebug() << "% DISABLE()" << endl;
+ if( isActive() ) stop();
+
+ config->setGroup("OnAccess");
+ config->writeEntry("EnableOnAccess", false);
+ config->sync();
+
+ enabled = false;
+
+ emit stateUpdated();
+}
+
+void KlamOnAcc::quarantine()
+{
+ 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"));
+
+ TQStringList QuarantineList;
+ QuarantineList.append(fname+":"+vname+suffix);
+
+ /* The following has been taken nearly verbatim from scanviewer.cpp */
+ 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;
+ }
+ TQStringList 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);
+ (alert->VirusList->findItem(fname,0))->setText(2,"Quarantined");
+ (alert->VirusList->findItem(fname,0))->setPixmap( 0, SmallIcon("klamav") );
+ chmod(qname.ascii(),0400);
+ CollectionDB::instance()->insertEvent("Quarantine",TQString("Quarantined"),fname);
+
+ }else{
+ KMessageBox::information (tdemain, 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));
+ }
+
+
+ }
+ }
+
+ emit stateUpdated();
+
+ config->writeEntry(TQString("Items %1").arg(quarloc), lastQuarItems);
+ config->sync();
+
+}
+
+#include "klamonacc.moc" \ No newline at end of file
diff --git a/src/klamonacc.h b/src/klamonacc.h
new file mode 100644
index 0000000..3938bc1
--- /dev/null
+++ b/src/klamonacc.h
@@ -0,0 +1,73 @@
+/*
+ * KlamOnAcc class -- the non-graphical class which manages clamonacc.
+ *
+ * Copyright (C) 2021 Mavridis Philippe <mavridisf@gmail.com>
+ */
+
+#ifndef _KLAMONACC_H_
+#define _KLAMONACC_H_
+
+#include <tdeapplication.h>
+
+class TDEProcess;
+class KlamOnAccAlert;
+
+class KlamOnAcc : public TQObject {
+ Q_OBJECT
+
+ public:
+ KlamOnAcc( TQWidget *parent, const char *name = 0 );
+ virtual ~KlamOnAcc();
+
+ const TQObject* object() { return static_cast<TQObject*>(this); };
+ const bool isActive() { return active; };
+ const bool isEnabled() { return enabled; };
+
+ public slots:
+ void start();
+ void stop();
+ void enable();
+ void disable();
+ void restart();
+ void toggle( bool on );
+
+ private:
+ TDEConfig *config;
+ TDEProcess *childproc;
+ KlamOnAccAlert *alert;
+ bool enabled = false;
+ bool active = false;
+ bool crashed = false;
+
+ /* These contain information about the file which triggered the alert */
+ TQString vname;
+ TQString fname;
+
+ void quarantine();
+
+ /* We use this to avoid showing two alerts for the same file, as clamonacc
+ often scans the same file multiple times, triggering the alert */
+ TQStringList shownAlerts;
+
+ /* This is a wrapper for tdesu */
+ TQString tdesu( TQString command, TQString caption, bool terminal = false );
+
+ private slots:
+ /* These functions are responsible for interfacing with clamonacc */
+ void childExited();
+ void fatalError( TQString descr );
+ void processOutput( TDEProcess*, char*, int );
+
+ /* These functions are responsible for preparing and executing the start/stop/restart commands
+ They are reused by restart() to avoid calling tdesu twice */
+ TQString startPrepare();
+ TQString stopPrepare();
+ void startProcess( TQString command );
+ void stopProcess( TQString command );
+
+ signals:
+ /* This signal causes some GUI elements to update */
+ void stateUpdated();
+};
+
+#endif /* _KLAMONACC_H_ */ \ No newline at end of file
diff --git a/src/klamonacc_alert.ui b/src/klamonacc_alert.ui
new file mode 100644
index 0000000..e4c7fcb
--- /dev/null
+++ b/src/klamonacc_alert.ui
@@ -0,0 +1,212 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KlamOnAccAlert</class>
+<widget class="TQDialog">
+ <property name="name">
+ <cstring>KlamOnAccAlert</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>600</width>
+ <height>450</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>600</width>
+ <height>450</height>
+ </size>
+ </property>
+ <property name="caption">
+ <string>Suspicious File Found! - KlamOnAcc</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>5</number>
+ </property>
+ <widget class="TQFrame">
+ <property name="name">
+ <cstring>AttentionFrame</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>AttentionIcon</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="pixmap">
+ <pixmap>image0</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>AttentionLabel</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>7</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Your attention, please!&lt;/b&gt;&lt;br&gt;
+The file you tried to access appears to be infected.</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="TQListView">
+ <column>
+ <property name="text">
+ <string>Name of File</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Name of Problem Found</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Status</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>VirusList</cstring>
+ </property>
+ <property name="selectionMode">
+ <enum>NoSelection</enum>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <property name="resizeMode">
+ <enum>LastColumn</enum>
+ </property>
+ </widget>
+ <widget class="KTextBrowser">
+ <property name="name">
+ <cstring>KlamTip</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;p&gt;KlamAV has prevented access to this file because &lt;b&gt;this file might potentially harm your system&lt;/b&gt;.&lt;/p&gt;
+&lt;p&gt;You are advised to &lt;i&gt;quarantine this file&lt;/i&gt; and inspect it in the Virus Browser.&lt;/p&gt;</string>
+ </property>
+ </widget>
+ <widget class="TQButtonGroup">
+ <property name="name">
+ <cstring>ActionGroup</cstring>
+ </property>
+ <property name="title">
+ <string>Action</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>ActionQuarantine</cstring>
+ </property>
+ <property name="focusPolicy">
+ <enum>StrongFocus</enum>
+ </property>
+ <property name="text">
+ <string>&amp;Quarantine</string>
+ </property>
+ <property name="accel">
+ <string>Alt+Q</string>
+ </property>
+ </widget>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>ActionDismiss</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Dismiss</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<images>
+ <image name="image0">
+ <data format="PNG" length="2309">89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7af40000000473424954080808087c086488000008bc494441545885bd975b8c5d5519c77fdfdab773e69c33b7339d4b874e5ba62d6db95f1a042aa8107da80f3ee00d1fc01862d4f84004313e68d404a2263e98a8408d91e88b574c006f118422985268c1964e67da613af7393367e69c33e7b2cfbeade5c399d2d24e018df14b7676b2b3d6faffbfebfe2fe17f6c33b7dd8164232417df22a9e44fe2e81c02460b269437a2ba757ba544e1aa675f0440decba1079ede2f8003786b8fb3b6370122a0090499e39349ff0b07b64a67f47d9589f76199d4f96799484a41c5da3fbb601ebee5b983e575091c787a3fc6184f27e1e628a85d9b44f56b74ec0f63c27ea3e31c26f1c088412522962fca2989959a6d6bcad8b6975e7abfe5f91f1165d479d02dca023a96a0b2a4be77aa107ee30202cf3df9a81734caef8bfca5bb494a1f705463a3e744aee320b6054ab5b618035a6be25893c4863881ece9d85c32bd8252fa42c79446ac160903840d299c9a892fb3cff53a0afdbedaf29b0fe860e69e8e4c339febb2715c1b11afb56b1d33c690241add4ce85ca98b840a50e7af6a254e34ace5ce71e84dbbf2e3b70844a1dfeb57a67ee0e8c98fe77b95a32c1730186d504a9d415b5b7dd6410194650160970dd4ed0bb9da09e22690a873f7896be94fdbadb03fe2d5564e3fe8574e7ea2e037ec978fd6a8d60330906d73d8349063fb962eba3a52c89ad7c680284110e244535cf471ab06ab6aadd15acbb99720690d5a61f4db79692d6203542b2b7b47468edd3d363e6197ab2189d62002c6a0b5e1c8f1221bba17f8d04d9bd8bea58b175f2d305308b8e99a6e06fb323cfff23423c78adca33a19ce7a2d4fc5208e0157230844721e38acd493451be0efff78e533232323f944c764db3d366eeea1b3a703cb7258592c313b59647caa42a1d860f7b61e5e38d220d42ea7262b6cd9e87074b488089ceace326c7b88738eabb15ab77cc2484713e5e021d973fdb5227169c2b682cddb2eeb65cfde9d0c0e6d219dce8181c5a5091666e7397a68868953458220a1dc7010e5a24c9dae9c904a395c7dc3107b862f65cf2b2b64571beb409e3563e078b9f6ea5f168a7b6dadf577033fdcb4754b965b3e7805976edb85eb7a8880ef5770ac90dede1cd7dd3844b9e4333b5bc1b39a244913d78128b6b86a573f37de7c2df99e01169c4506fe36465b2d5a77ca6963cc84df98f8c3ece2433f9e9a6cda49a21fd04673d9ae01b66e19a62d954630945796989b1e2568fa28cba63d9b6278db06a6a72b88806db5f2984e3b5c71e5a57464f384f5267e5f9ad9abd3f4bdd660b06693d68218888c66298a1869d45f7ba1b8f4f5df2ccc3d0360c7498252167d7d79b26d391486f9a929e6a64e902421c640d3af61b0684b5988b4c65926e3525ef5696bf348bb596aa53a4a691af54556dc65662e0f391941679422ac861c1e2bf0f2a24fd5765f9aaeadfeb59a24bad5a189062d448146744ce097a8ae9ca6a7274347f700464369a54661b644d4f449b421dfd5c61d7b87f9c513afb58650ac71ec8454ba49366bd1d5b591e2e20ab6e3d0966f27ae864c2ecc515c005ba970e3e04653ae545a23426b6db456327a6292cb777793cbd80c6deec5b22d3010c7867cb78dc2e3d8e8184110d39bcfb07b7b2f29cfa15c69b25c5ca0bfd76089e03a366d29875c364d1c2744b1a65af229147c0c4e92683da6947aab319481fb0c7672fcc432c78fce103422c42848c0c4606243d088191f2f327a7291c4c0f5570eb27d6b0f5b2ee9a4520b38f2fa3485850a3a34985820169456a015955293c347e6289662105930c6bc343232f256515af97cfe20c2c7eaf56060b552030d9628746468d4230a8b358ebe31c73f0f4d323d576178a89bcf7ef2067aba32d8b6e2d0eb332c971a34fd0841504a11479a6a3560726a85570ecf70f0c83c7ee4c696b27f8af0ebe5e595e40c0101d8b163c7877512fd24092b97f6f6a419ecefa03de7014279b5c97c619595b24f5f4f96afdcbb973d575d02024110f3f8ef0ef3db3f1ec31843ff861cbd1bb2b4a51dc230a658aa333b57a1e65bb193ca3d29a2be343636367f6e5b0ac0ce9d9729adf56d24fe77c4346f4610cb528021490c8eadb87c471f77df791d57ef1e40c9d90e6ff8114f3e738227fe7c8cc252ad15564ba1b526d11a11a7ae49ff5cd9dec302b3274647b98000c0ae9d3bb9f3a3b75ce1a9eaafcae599dd353fc218e8db90e39addfd5cb5ab9f9463234a61dbad1f8e3186288c50965028d638f4af1946c78bac567d5229876ccad39df96d8f8d4e2cdf7ff0f058fdf839b9bf8000c081a7f7ab242c7fca93e91f6d1a743b3dcf4529858810853127474e03425f7f1ec775a856eb2c2d2cb3a1bf9bc14dbd6b934e932409a5528dc272f620eed05dca72dfbc75dfbdebccc5f394c3adfbeed5cae9f87da0fb7fb8b8143695806d2b94126cc7a2bd2b8beffb8c9f9c6474649cd9a9792c5b916bcfa09442590ac7510441c87229358133f03565b9131703bf200267ecf9a71e6937e1d2b73ad2c52f6cda94f11cc7c198960ea8d77caaab759238c14bb9b47766f13c973365b15aa9313567a62306bfac9cf6276fdd77af5e0fe38cd9eb7d14b15671367cbbe20b7a6ae9f3434399b4e7b960845c47865c47665d2f4aa51a33f33211b1f17eb1734fbd1bf845237036128f664db4fc6057a6f0d52d5b3b5da5d4fada50a0516f32fe663415cae0e7949d7df6bd80c345220067a4b906f10a512c31e0aefd87d658afc92ec0c89a4236ce2aca5e35c6bca7fbc699532eb0e79f7a4c99a47183242bf765bcd57d839778b9f6f3c2de423e7b82d69ac27cc52c16add3a1eefe99d89dfb453985772a40b84804e2b0768d63667f39b8516febce67c576ce2e7b5b06e4ec4b94a277a05dda3bc2adf3f30bdf5c5e0d7658dee01781da7f4c001ddcd8960986bb7bf2224ad01ab45c28c9cf9a016330086eda6343afb6cbabd5dbc0f4fd5704949d7eb5da681b1d7fb3b42393b12dd7b3b02d69c970a55a2ab7a5cf5b125db7d473146b023fa65a4dfc84fc010b597a27f08b12b09ccccb5a0dedaed46b779557fdc721b05b7d9e0009724e224ceb6a0228b4b111e9185556dbed96db362bf2eeb528c65ce4cef57fb27f037bd249327d42e1690000000049454e44ae426082</data>
+ </image>
+</images>
+<connections>
+ <connection>
+ <sender>ActionDismiss</sender>
+ <signal>clicked()</signal>
+ <receiver>KlamOnAccAlert</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>ActionQuarantine</sender>
+ <signal>clicked()</signal>
+ <receiver>KlamOnAccAlert</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>ktextbrowser.h</includehint>
+</includehints>
+</UI>
diff --git a/src/klamonacc_config.ui b/src/klamonacc_config.ui
new file mode 100644
index 0000000..97e9fe5
--- /dev/null
+++ b/src/klamonacc_config.ui
@@ -0,0 +1,253 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>KlamOnAccConfig</class>
+<widget class="TQWidget">
+ <property name="name">
+ <cstring>KlamOnAccConfig</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>712</width>
+ <height>647</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Form1</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>GroupScannerOpts</cstring>
+ </property>
+ <property name="title">
+ <string>Scanner Settings</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>kcfg_EnableOnAccess</cstring>
+ </property>
+ <property name="text">
+ <string>Enable &amp;On-Access Scanner</string>
+ </property>
+ <property name="accel">
+ <string>Alt+O</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>kcfg_ExtraScanning</cstring>
+ </property>
+ <property name="text">
+ <string>Scan Files/Directories When They Are &amp;Created or Moved</string>
+ </property>
+ <property name="accel">
+ <string>Alt+C</string>
+ </property>
+ </widget>
+ <widget class="TQCheckBox">
+ <property name="name">
+ <cstring>kcfg_ExcludeConfDir</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>E&amp;xclude TDE Configuration Directory</string>
+ </property>
+ <property name="accel">
+ <string>Alt+X</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Limits</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLayoutWidget">
+ <property name="name">
+ <cstring>MaxFileHBox</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="TQLabel">
+ <property name="name">
+ <cstring>MaxFileLabel</cstring>
+ </property>
+ <property name="text">
+ <string>Max File Size:</string>
+ </property>
+ </widget>
+ <widget class="TQSpinBox">
+ <property name="name">
+ <cstring>kcfg_OnAccessMaxFile</cstring>
+ </property>
+ <property name="suffix">
+ <string> M</string>
+ </property>
+ <property name="value">
+ <number>5</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>MaxFileSpacer</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <widget class="TQFrame">
+ <property name="name">
+ <cstring>GroupWatchDirs</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Raised</enum>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>WatchDirsSpacerLeft</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="TQPushButton">
+ <property name="name">
+ <cstring>SetUpWatchDirs</cstring>
+ </property>
+ <property name="text">
+ <string>Set up &amp;Directories to Watch</string>
+ </property>
+ <property name="accel">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>WatchDirsSpacerRight</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="TQTextEdit">
+ <property name="name">
+ <cstring>textEdit1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;html&gt;&lt;head&gt;&lt;meta name="qrichtext" content="1" /&gt;&lt;/head&gt;&lt;body style="font-size:12pt;font-family:Arial"&gt;
+&lt;p align="center"&gt;&lt;span style="font-weight:600;text-decoration:underline;color:#ff0000"&gt;Warning!&lt;/span&gt; This function is experimental. Use with caution.&lt;/p&gt;
+&lt;p&gt;The &lt;span style="font-weight:600"&gt;On-Access Scanner&lt;/span&gt; can scan files and directories as you open them, or even as you create them.&lt;/p&gt;
+&lt;p&gt;This function requires the &lt;span style="font-style:italic"&gt;ClamAV Daemon&lt;/span&gt; to be already running in the background and requires root permissions to start.&lt;/p&gt;
+&lt;/body&gt;&lt;/html&gt;
+</string>
+ </property>
+ <property name="wordWrap">
+ <enum>WidgetWidth</enum>
+ </property>
+ </widget>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>SetUpWatchDirs</sender>
+ <signal>clicked()</signal>
+ <receiver>KlamOnAccConfig</receiver>
+ <slot>reconfigurePaths()</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_ExtraScanning</sender>
+ <signal>clicked()</signal>
+ <receiver>KlamOnAccConfig</receiver>
+ <slot>slotSettingsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_ExcludeConfDir</sender>
+ <signal>clicked()</signal>
+ <receiver>KlamOnAccConfig</receiver>
+ <slot>slotSettingsChanged()</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_OnAccessMaxFile</sender>
+ <signal>valueChanged(const TQString&amp;)</signal>
+ <receiver>KlamOnAccConfig</receiver>
+ <slot>slotSettingsChanged()</slot>
+ </connection>
+</connections>
+<includes>
+ <include location="local" impldecl="in implementation">klamonacc_config.ui.h</include>
+</includes>
+<variables>
+ <variable>bool restart;</variable>
+</variables>
+<signals>
+ <signal>directoriesModified()</signal>
+</signals>
+<slots>
+ <slot>reconfigurePaths()</slot>
+ <slot access="private">slotSettingsChanged()</slot>
+ <slot>slotSettingsApplied()</slot>
+</slots>
+<functions>
+ <function returnType="bool">needsRestart()</function>
+</functions>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/src/klamonacc_config.ui.h b/src/klamonacc_config.ui.h
new file mode 100644
index 0000000..7201e8d
--- /dev/null
+++ b/src/klamonacc_config.ui.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+** ui.h extension file, included from the uic-generated form implementation.
+**
+** If you want to add, delete, or rename functions or slots, use
+** TQt Designer to update this file, preserving your code.
+**
+** You should not define a constructor or destructor in this file.
+** Instead, write your code in functions called init() and destroy().
+** These will automatically be called by the form's constructor and
+** destructor.
+*****************************************************************************/
+
+#include "directorylist.h"
+
+#include <kdialogbase.h>
+#include <tdeconfig.h>
+#include <tdeglobal.h>
+
+void KlamOnAccConfig::reconfigurePaths() {
+ // Borrowed from amaroK (collectionbrowser.cpp)
+ KDialogBase dialog( this, 0, false );
+ // kapp->setTopWidget( &dialog );
+ dialog.setCaption( "Configure Directories Watchlist" );
+
+ TDEConfig *config = TDEGlobal::config();
+ config->setGroup("OnAccess");
+ TQStringList dirs = config->readListEntry("Watchlist");
+
+ CollectionSetup *setup = new CollectionSetup( &dialog, true, false, dirs );
+ dialog.setMainWidget( setup );
+ dialog.showButtonApply( false );
+ dialog.adjustSize();
+
+ // Make the dialog a bit bigger, default is too small to be useful
+ dialog.resize( dialog.width() + 50, dialog.height() + 150 );
+
+ if ( dialog.exec() != TQDialog::Rejected ) {
+ setup->writeConfig("OnAccess","Watchlist");
+ }
+
+ restart = true;
+}
+
+void KlamOnAccConfig::slotSettingsChanged() {
+ restart = true;
+}
+
+void KlamOnAccConfig::slotSettingsApplied() {
+ restart = false;
+}
+
+bool KlamOnAccConfig::needsRestart() {
+ return restart;
+}