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>pull/24/head
parent
8300c80d58
commit
13cb4a5e7d
@ -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"
|
@ -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_ */
|
@ -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><b>Your attention, please!</b><br>
|
||||
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><p>KlamAV has prevented access to this file because <b>this file might potentially harm your system</b>.</p>
|
||||
<p>You are advised to <i>quarantine this file</i> and inspect it in the Virus Browser.</p></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>&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>&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>
|
@ -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 &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 &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&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 &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><html><head><meta name="qrichtext" content="1" /></head><body style="font-size:12pt;font-family:Arial">
|
||||
<p align="center"><span style="font-weight:600;text-decoration:underline;color:#ff0000">Warning!</span> This function is experimental. Use with caution.</p>
|
||||
<p>The <span style="font-weight:600">On-Access Scanner</span> can scan files and directories as you open them, or even as you create them.</p>
|
||||
<p>This function requires the <span style="font-style:italic">ClamAV Daemon</span> to be already running in the background and requires root permissions to start.</p>
|
||||
</body></html>
|
||||
</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&)</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>
|
@ -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;
|
||||
}
|
Loading…
Reference in new issue