You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
klamav/src/freshklam.cpp

1041 lines
31 KiB

/*
* Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
*/
#include "freshklam.h"
#include "klamav.h"
#include "klamd.h"
#include "collectiondb.h"
/*#include "gmanedb.h"*/
#include "klamavconfig.h"
#include "config.h"
#include "../config.h"
#include <tdelocale.h>
#include <tdeio/netaccess.h>
#include <tdeaction.h>
#include <tqcheckbox.h>
#include <kbuttonbox.h>
#include <kurlrequester.h>
#include <kurlcompletion.h>
#include <kcombobox.h>
#include <tqlayout.h>
#include <tdemessagebox.h>
#include <klineedit.h>
#include <tdetempfile.h>
#include <ksystemtray.h>
#include <ktar.h>
#include <kprogress.h>
#include <kprocio.h>
#include <knotifyclient.h>
#include <dom/html_misc.h>
#include <tdeapplication.h>
#include <dcopclient.h>
#include <kuser.h>
#include <tqtimer.h>
#include <clamav.h>
#include "version.h"
#include <stdlib.h>
const char *check_desc[] = {
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12",
"13",
"14",
"15",
"16",
"17",
"18",
"19",
"20",
"21",
"22",
"23",
"24",
"48",
0
};
TQString readymessage = i18n("KlamAV ") + KLAMAV_VERSION + i18n(" - Ready");
Freshklam::Freshklam(TQWidget *parent, const char *name)
: TQWidget(parent, name)
{
// MetaDB* updater = new MetaDB();
// updater->update();
updater = new KlamavUpdate(this);
connect( updater, SIGNAL( getCurrentVersionOfClamAV() ), SLOT( getCurrentVersionOfClamAV() ) );
connect( updater, SIGNAL( toggleUpgradeButtons(bool) ), SLOT( toggleUpgradeButtons(bool) ) );
tdemain->firstDownload = false;
checkingDirectly = false;
freshklamAlive = FALSE;
config = TDEGlobal::config();
config->setGroup("Freshklam");
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
getCurrentVersionOfClamAV( );
if ((lastDownloadPaths.isEmpty()) || (!(TDEIO::NetAccess::exists(TQString((*lastDownloadPaths.begin())),TRUE,NULL)))){
createDBDir();
}
TQString proxyIPText = config->readEntry("ProxyIP");
TQString proxyPortText = config->readEntry("ProxyPort");
TQString proxyUserText = config->readEntry("ProxyUser");
TQString proxyPassText = config->readEntry("ProxyPass");
//Data Directory Widget
TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialog::marginHint(),
KDialog::spacingHint(), "vbox");
//Proxy Widget
TQGroupBox *software_group = new TQGroupBox(i18n("Software Updates"), this);
vbox->addWidget(software_group);
TQGridLayout *software_layout = new TQGridLayout( software_group, 5, 2, KDialog::spacingHint(),
KDialog::spacingHint(), "software_layout");
software_layout->addRowSpacing(0, software_group->fontMetrics().height());
software_layout->setColStretch(0, 1);
software_layout->setColStretch(1, 1);
//Dazuko
TQWidget *dazuko_hlp = new TQWidget( software_group );
software_layout->addMultiCellWidget(dazuko_hlp, 1,2, 0,2);
TQGridLayout *dazuko_dir_layout = new TQGridLayout(dazuko_hlp,2,2, KDialog::spacingHint() );
clamav_box = new TQCheckBox(i18n("Update ClamAV Automatically"), dazuko_hlp);
clamav_box->setMinimumWidth(clamav_box->sizeHint().width());
dazuko_dir_layout->addWidget(clamav_box,0,0);
klamav_box = new TQCheckBox(i18n("Update KlamAV Automatically"), dazuko_hlp);
klamav_box->setMinimumWidth(klamav_box->sizeHint().width());
dazuko_dir_layout->addWidget(klamav_box,0,1);
clamav_options = new TQPushButton (i18n( "Upgrade ClamAV Now" ), dazuko_hlp);
dazuko_dir_layout->addWidget(clamav_options,1,0);
clamav_options->setFixedSize(clamav_options->sizeHint());
connect( clamav_options, SIGNAL( clicked() ), this,
SLOT( checkForNewClamAVNow() ) );
klamav_options = new TQPushButton (i18n( "Upgrade KlamAV Now" ), dazuko_hlp);
dazuko_dir_layout->addWidget(klamav_options,1,1);
klamav_options->setFixedSize(klamav_options->sizeHint());
connect( klamav_options, SIGNAL( clicked() ), this,
SLOT( checkForNewKlamAVNow() ) );
#ifdef DISABLE_UPDATES
clamav_box->setEnabled(false);
klamav_box->setEnabled(false);
clamav_options->setEnabled(false);
klamav_options->setEnabled(false);
#endif
//Virus Database Directory
TQGroupBox *group = new TQGroupBox(i18n("Virus Database Directory"), this);
vbox->addWidget(group);
TQGridLayout *layout = new TQGridLayout( group, 9, 2, KDialog::spacingHint(),
KDialog::spacingHint(), "layout");
layout->addRowSpacing(0, group->fontMetrics().height());
layout->setColStretch(0, 1);
layout->setColStretch(1, 1);
TQWidget *hlp = new TQWidget( group );
layout->addMultiCellWidget(hlp, 1,1, 0,1);
TQHBoxLayout *dir_layout = new TQHBoxLayout(hlp,KDialog::spacingHint() );
dir_combo = new KURLRequester( new KComboBox(true, this), hlp, "dir combo" );
dir_combo->completionObject()->setMode(KURLCompletion::DirCompletion);
dir_combo->comboBox()->insertStringList(lastDownloadPaths);
dir_combo->setMode( KFile::Directory|KFile::LocalOnly );
TQLabel *dir_label = new TQLabel(i18n("Directory:"), hlp);
dir_label->setFixedSize(dir_label->sizeHint());
dir_layout->addWidget(dir_label);
dir_layout->addWidget(dir_combo);
//Proxy Widget
TQGroupBox *proxy_group = new TQGroupBox(i18n("Proxy for Database Updates"), this);
vbox->addWidget(proxy_group);
TQGridLayout *proxy_layout = new TQGridLayout( proxy_group, 2, 5, KDialog::spacingHint(),
KDialog::spacingHint(), "proxy_layout");
proxy_layout->addRowSpacing(0, proxy_group->fontMetrics().height());
proxy_layout->setColStretch(0, 1);
proxy_layout->setColStretch(1, 1);
//IP Address & Port
TQWidget *proxy_hlp = new TQWidget( proxy_group );
proxy_layout->addMultiCellWidget(proxy_hlp, 1,2, 0,2);
TQGridLayout *proxy_dir_layout = new TQGridLayout(proxy_hlp, 2,4,KDialog::spacingHint() );
TQLabel *proxy_dir_label = new TQLabel(i18n("IP Address:"), proxy_hlp);
//proxy_dir_label->setFixedSize(proxy_dir_label->sizeHint());
proxy_dir_layout->addWidget(proxy_dir_label,0,0);
proxyIP = new KLineEdit(proxy_hlp);
proxy_dir_layout->addWidget(proxyIP,0,1);
proxyIP->setText(proxyIPText);
TQLabel *proxy_port_label = new TQLabel(i18n("Port:"), proxy_hlp);
//proxy_port_label->setFixedSize(proxy_port_label->sizeHint());
proxy_dir_layout->addWidget(proxy_port_label,0,3);
proxyPort = new KLineEdit(proxy_hlp);
proxy_dir_layout->addWidget(proxyPort,0,4);
proxyPort->setText(proxyPortText);
TQLabel *proxy_user_label = new TQLabel(i18n("User:"), proxy_hlp);
//proxy_user_label->setFixedSize(proxy_user_label->sizeHint());
proxy_dir_layout->addWidget(proxy_user_label,1,0);
proxyUser = new KLineEdit(proxy_hlp);
proxy_dir_layout->addWidget(proxyUser,1,1);
proxyUser->setText(proxyUserText);
TQLabel *proxy_pass_label = new TQLabel(i18n("Password:"), proxy_hlp);
//proxy_pass_label->setFixedSize(proxy_pass_label->sizeHint());
proxy_dir_layout->addWidget(proxy_pass_label,1,3);
proxyPass = new KLineEdit(proxy_hlp);
proxy_dir_layout->addWidget(proxyPass,1,4);
proxyPass->setText(proxyPassText);
//Daemon Widget
TQGroupBox *daemon_group = new TQGroupBox(i18n("Database AutoUpdate Settings"), this);
vbox->addWidget(daemon_group);
TQGridLayout *daemon_layout = new TQGridLayout( daemon_group, 5, 4, KDialog::spacingHint(),
KDialog::spacingHint(), "daemon_layout");
daemon_layout->addRowSpacing(0, daemon_group->fontMetrics().height());
daemon_layout->addRowSpacing(1, daemon_group->fontMetrics().height());
//daemon_layout->setColStretch(0, 1);
//daemon_layout->setColStretch(1, 1);
TQWidget *daemonhlp = new TQWidget( daemon_group );
daemon_layout->addMultiCellWidget(daemonhlp, 1,1, 0,1);
TQHBoxLayout *daemon_check_layout = new TQHBoxLayout(daemonhlp, KDialog::spacingHint() );
daemon_box = new TQCheckBox(i18n("Update Virus Database Automatically"), daemonhlp);
daemon_box->setMinimumWidth(daemon_box->sizeHint().width());
daemon_check_layout->addSpacing(10);
daemon_check_layout->addWidget(daemon_box);
check_combo = new TQComboBox(false, daemonhlp);
check_combo->insertStrList(check_desc);
if (!(config->readEntry("NoOfUpdates").isEmpty()))
check_combo->setCurrentText(config->readEntry("NoOfUpdates"));
check_combo->adjustSize();
//check_combo->setFixedSize(check_combo->size());
daemon_check_layout->addWidget(check_combo);
TQLabel *combo_label = new TQLabel(i18n("Times a Day"), daemonhlp);
//combo_label->setFixedSize(combo_label->sizeHint());
daemon_check_layout->addWidget(combo_label);
KButtonBox *actionbox = new KButtonBox(this, TQt::Horizontal);
vbox->addWidget(actionbox, 2, 0);
actionbox->addStretch();
search_button = actionbox->addButton(i18n("&Update Now"));
search_button->setDefault(true);
cancel_button = actionbox->addButton(i18n("Cancel"));
cancel_button->setEnabled(false);
actionbox->addStretch();
actionbox->layout();
TQFrame *status_frame = new TQFrame(this);
status_frame->setFrameStyle(TQFrame::Panel | TQFrame::Sunken);
TQBoxLayout *status_layout = new TQHBoxLayout(status_frame, 2);
status_label = new TQLabel(readymessage, status_frame);
status_layout->addWidget(status_label, 10);
status_layout->activate();
status_frame->adjustSize();
status_frame->setMinimumSize(status_frame->size());
vbox->addWidget(status_frame);
initCheckBoxes();
checkInternet();
}
Freshklam::~Freshklam()
{
if (daemon_box->isChecked()){
killPID();
}
if (!(tempFileName.isEmpty()))
TDEIO::NetAccess::del(tempFileName,NULL);
}
void Freshklam::processOutput()
{
int pos;
int pos2;
TQString item2;
while (( (pos = buf.find('\n')) != -1) || ( (pos = buf.find(']')) != -1))
{
TQString item = buf.left(pos);
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 ap : "));
if (!item.isEmpty()){
if ( (pos2 = buf.find('[')) != -1)
item +=']';
status_label->setText(suffix + item);
item2 += item;
item2 += '\n';
}
buf = buf.right(buf.length()-pos-1);
}
if ((pos = item2.find("ERROR")) != -1){
pos2 = item2.find('\n',pos);
errorMessage = item2.mid(pos,pos2);
}
if ((pos = item2.find("Database updated")) != -1){
CollectionDB::instance()->insertEvent("Updates","Database Updated",dir_combo->url());
KNotifyClient::event(tdemain->_tray->winId(),"UpdatedDatabase", "Virus Database Updated.");
updateMailClient();
}
if ((pos = item2.find("daily.cvd is up to date")) != -1){
CollectionDB::instance()->insertEvent("Updates","Database Already Up To Date",dir_combo->url());
KNotifyClient::event(tdemain->_tray->winId(),"DatabaseUpToDate", "Virus Database Up To Date.");
updateMailClient();
}
if ((pos = item2.find("Recommended version:")) != -1){
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_update_required"));
pos2 = item2.find('\n',pos);
TQString version = item2.mid((pos+20),pos2 - (pos+20)).stripWhiteSpace();
if ((clamav_box->isChecked())){
int result = KMessageBox::warningContinueCancel(this, i18n( "It looks like your version of the ClamAV engine is out of date! ClamAV-%1 is the most recent version of ClamAV available. Would you like to KlamAV to download and compile it for you?").arg(version),i18n( "Download and Install ClamAV-%1" ).arg(version),i18n( "Download and Install ClamAV-%1" ).arg(version));
switch (result) {
case 2 :
break;
case 5 :
updater->downloadComponent("clamav",version,"tar.gz");
}
}else if (!(clamav_box->isChecked()))
KNotifyClient::event(tdemain->_tray->winId(),"ClamAVOutDated", TQString("Your copy of ClamAV is out of date! Please Upgrade to ClamAV %1!").arg(version));
}
}
void Freshklam::slotSearch()
{
search_button->setEnabled(false);
cancel_button->setEnabled(true);
TQString filepattern = dir_combo->url();
CollectionDB::instance()->insertEvent("Updates","Commencing DB Update", filepattern);
status_label->setText(i18n("Beginning Update..."));
childproc = new KShellProcess();
TQString command = "freshclam --stdout ";
TQString user = KUser().loginName();
command += " --user=" + user + " ";
if (!(filepattern.isEmpty())){
command += " --datadir=";
command += filepattern;
}
if (daemon_box->isChecked()){
command += " -d -c ";
command += check_combo->currentText();
KTempFile tf;
if ( tf.status() != 0 ) {
tf.close();
//delete tf;
KMessageBox::information (this,i18n( "There was an error creating a temp file!") );
return;
}
pidFileName = tf.name();
command += " -p ";
command += pidFileName;
freshklamAlive = TRUE;
}
if (!(TDEApplication::kApplication()->isRestored())){
if (tdemain->klamd->isKlamdAlive()){
TQString klamdconf = tdemain->klamd->getKlamdConfFile();
////kdDebug() << klamdconf << endl;
command += " --daemon-notify=";
command += klamdconf;
}
}
writeConf();
command += " --config-file=";
command += tempFileName;
disableInputs();
*childproc << command;
//kdDebug() << command << endl;
childproc->start(TDEProcess::NotifyOnExit, TDEProcess::Stdout);
connect( childproc, SIGNAL(processExited(TDEProcess *)),
SLOT(childExited()) );
connect( childproc, SIGNAL(receivedStdout(TDEProcess *, char *, int)),
SLOT(receivedOutput(TDEProcess *, char *, int)) );
// if (tdemain->klamd->isKlamdAlive())
// tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamavdl"));
// else
// tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamavbwdl"));
tdemain->EnableFreshklam->setEnabled(FALSE);
tdemain->DisableFreshklam->setEnabled(TRUE);
}
void Freshklam::finish()
{
search_button->setEnabled(true);
cancel_button->setEnabled(false);
enableInputs();
if (tdemain->klamd->isKlamdAlive())
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_enabled"));
else
tdemain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled"));
buf += '\n';
processOutput();
delete childproc;
childproc = 0;
freshklamAlive = FALSE;
if (!(tempFileName.isEmpty()))
TDEIO::NetAccess::del(tempFileName,NULL);
tdemain->EnableFreshklam->setEnabled(TRUE);
tdemain->DisableFreshklam->setEnabled(FALSE);
//updateMetaDB();
}
void Freshklam::updateMetaDB()
{
TQDate latestDate = TQDate::fromString(CollectionDB::instance()->latestMetaDBDate(),TQt::ISODate);
TQDate today = TQDate::currentDate();
kdDebug() << latestDate << " " << today << endl;
if (latestDate.daysTo(today) > 31){
/* MetaDB* updater = new MetaDB();
updater->update();*/
}
}
void Freshklam::slotCancel()
{
finish();
if (daemon_box->isChecked()){
if (!(killPID()))
KMessageBox::information (this,i18n( "There was a problem killing the update process!") );
}
status_label->setText(i18n("Canceled"));
CollectionDB::instance()->insertEvent("Updates","Database Update Cancelled", dir_combo->url());
}
void Freshklam::processDied()
{
KMessageBox::information (this,i18n( "Update Process died unexpectedly! Did you kill it manually?" ));
status_label->setText(i18n("Update Process Died Unexpectedly!"));
CollectionDB::instance()->insertEvent("Updates","Database Update Process Died Unexpectedly",dir_combo->url());
}
void Freshklam::childExited()
{
int status = childproc->exitStatus();
/* int winid = 0;
if (TDEApplication::kApplication()->mainWidget()) {
winid = TDEApplication::kApplication()->mainWidget()->winId();
}*/
finish();
if (daemon_box->isChecked()){
//KMessageBox::information (this,"Update Running in Background!", "Auto-Update","Don't Show Again");
processDied();
return;
}
if (status == 0){
//updateMailClient();
}else if (status == 1){
//KMessageBox::information (this,"No Update Required - Database already up to date!");
//updateMailClient();
}else if (status == 40)
KMessageBox::information (this, i18n("Unknown option passed."));
else if (status == 50)
KMessageBox::information (this, i18n("Can't change directory."));
else if (status == 51)
KMessageBox::information (this, i18n("Can't check MD5 sum."));
else if (status == 52)
KMessageBox::information (this, i18n("Connection (network) problem."));
else if (status == 53)
KMessageBox::information (this, i18n("Can't unlink a file."));
else if (status == 54)
KMessageBox::information (this, i18n("MD5 or digital signature verification error."));
else if (status == 55)
KMessageBox::information (this, i18n("Error reading file."));
else if (status == 56)
KMessageBox::information (this, i18n("Config file error."));
else if (status == 57)
KMessageBox::information (this, i18n("Can't create a new file."));
else if (status == 58)
KMessageBox::information (this, i18n("Can't read database from remote server."));
else if (status == 59)
KMessageBox::information (this, i18n("Mirrors are not fully synchronized (try again later)."));
else if (status == 60)
KMessageBox::information (this, i18n("Can't get information about clamav user from /etc/passwd."));
else if (status == 61)
KMessageBox::information (this, i18n("Can't drop privileges."));
else
KMessageBox::information (this, i18n("Warning - Unknown Error!"));
if (errorMessage != "")
KMessageBox::information (this,errorMessage);
errorMessage = "";
status_label->setText( readymessage );
//if (status != 0)
//matches_label->setText("");
}
void Freshklam::updateMailClient()
{
config->setGroup("Freshklam");
if (lastDownloadPaths.contains(dir_combo->/*currentText*/url()) == 0) {
dir_combo->comboBox()->insertItem(dir_combo->/*currentText*/url(), 0);
lastDownloadPaths.prepend(dir_combo->/*currentText*/url());
if (lastDownloadPaths.count() > 10) {
lastDownloadPaths.remove(lastDownloadPaths.fromLast());
dir_combo->comboBox()->removeItem(dir_combo->comboBox()->count() - 1);
}
}else{
lastDownloadPaths.remove(dir_combo->url());
lastDownloadPaths.prepend(dir_combo->url());
}
config->writeEntry("lastDownloadPaths", lastDownloadPaths);
config->writeEntry("ProxyIP", proxyIP->text());
config->writeEntry("ProxyPort", proxyPort->text());
config->writeEntry("ProxyUser", proxyUser->text());
config->writeEntry("ProxyPass", proxyPass->text());
//KMessageBox::information (this,proxyIP->text());
config->sync();
TDEConfig* mailconfig = new TDEConfig("kmailrc");
mailconfig->setGroup("General");
TQVariant nooffilters = mailconfig->readEntry("filters");
int result;
int numfilters = nooffilters.toInt();
nooffilters = numfilters;
for (int j=0; j != numfilters; j++ ){
TQVariant numb = j;
TQString filtername=TQString("Filter #%1").arg(numb.toString());
mailconfig->setGroup(filtername);
TQString binary = mailconfig->readEntry("action-args-0");
if (binary.find("klammail") != -1){
TQString pathonly = binary.section(" ",2,2);
if (pathonly == dir_combo->url())
break;
if (binary.find(" " + dir_combo->url() + " ") == -1){
TQString path = getenv("HOME");
result = KMessageBox::warningContinueCancelList(this, i18n( "Since you have changed the database location, KlamAV needs to change the parameters used for mail scanning in KMail. The change is displayed below. If you have KMail open you will need to close it now so that the change can take effect. If you want to make the change manually just click 'Cancel'. "),TQString("New filter command: klammail -d %1").arg(dir_combo->url()),i18n( "Update KMail Filters" ),i18n( "Update" ));
switch (result) {
case 2 : KMessageBox::information (this,"KMail has not been updated with the new database location."); break;
case 5 :
mailconfig->writeEntry("action-args-0",TQString("klammail -d %1").arg(dir_combo->url()));
mailconfig->sync();
break;
}
break;
}
}
}
//KMessageBox::information (this,"Database Update Complete!");
delete mailconfig;
}
void Freshklam::receivedOutput(TDEProcess */*proc*/, char *buffer, int buflen)
{
//kdDebug() << buffer << endl;
buf += TQCString(buffer, buflen+1);
processOutput();
}
void Freshklam::slotClear()
{
finish();
resultbox->clear();
status_label->setText(i18n("Ready"));
matches_label->setText("");
}
void Freshklam::setDirName(TQString dir){
// dir_combo->setEditText(dir);
dir_combo->setURL(dir);
}
void Freshklam::writeConf()
{
KTempFile tf;
if ( tf.status() != 0 ) {
tf.close();
//delete tf;
KMessageBox::information (this,i18n( "KMFilterActionWithCommand: Could not create temp file!" ));
return;
}
//tf->setAutoDelete(TRUE);
tempFileName = tf.name();
TQTextStream &ts = *(tf.textStream());
ts << "DatabaseMirror database.clamav.net" << "\n";
ts << "DNSDatabaseInfo current.cvd.clamav.net" << "\n";
ts << "Foreground True" << "\n";
if ( (proxyIP->hasAcceptableInput()) && (!(proxyIP->text().isEmpty()))) {
ts << TQString("HTTPProxyServer %1").arg(proxyIP->text()) << "\n";
if ( proxyPort->hasAcceptableInput() ) {
ts << TQString("HTTPProxyPort %1").arg(proxyPort->text()) << "\n";
}
if ( proxyUser->hasAcceptableInput() && ! proxyUser->text().isEmpty() ) {
ts << TQString("HTTPProxyUsername %1").arg(proxyUser->text()) << "\n";
if ( proxyPass->hasAcceptableInput() ) {
ts << TQString("HTTPProxyPassword %1").arg(proxyPass->text()) << "\n";
}
}
}
else
return;
}
void Freshklam::initCheckBoxes(){
if ((config->readEntry("AutoUpdate")) == "Yes"){
daemon_box->setChecked(true);
check_combo->setEnabled(true);
}else{
daemon_box->setChecked(false);
check_combo->setEnabled(false);
}
if ((config->readEntry("AutoUpdateClamAV")) == "Yes"){
clamav_box->setChecked(true);
}else{
clamav_box->setChecked(false);
}
if ((config->readEntry("AutoUpdateKlamAV")) == "Yes"){
klamav_box->setChecked(true);
}else{
klamav_box->setChecked(false);
}
connect( clamav_box, SIGNAL(toggled(bool)), SLOT(handleChecks()) );
connect( klamav_box, SIGNAL(toggled(bool)), SLOT(handleChecks()) );
connect( daemon_box, SIGNAL(toggled(bool)), SLOT(handleChecks()) );
connect( check_combo, SIGNAL(activated(int)), SLOT(handleChecks()) );
if (daemon_box->isChecked())
slotSearch();
}
void Freshklam::handleChecks(){
config = TDEGlobal::config();
config->setGroup("Freshklam");
if (daemon_box->isChecked()){
config->writeEntry("AutoUpdate","Yes");
check_combo->setEnabled(true);
}else{
config->writeEntry("AutoUpdate","No");
check_combo->setEnabled(false);
}
config->writeEntry("NoOfUpdates", check_combo->currentText());
if (clamav_box->isChecked()){
config->writeEntry("AutoUpdateClamAV","Yes");
}else{
config->writeEntry("AutoUpdateClamAV","No");
}
if (klamav_box->isChecked()){
config->writeEntry("AutoUpdateKlamAV","Yes");
}else{
config->writeEntry("AutoUpdateKlamAV","No");
}
config->sync();
}
bool Freshklam::killPID(){
TQFile inf(pidFileName);
if (!inf.open(IO_ReadOnly))
return false;
TQTextStream is(&inf);
TQString line;
while (!is.eof())
line = is.readLine();
inf.close();
////kdDebug() << line << endl;
if (!(line.isEmpty()))
kill(line.toInt(), SIGKILL);
else
return false;
if (!(pidFileName.isEmpty()))
TDEIO::NetAccess::del(pidFileName,NULL);
return true;
}
void Freshklam::disableInputs(){
dir_combo->setEnabled(false);
daemon_box->setEnabled(false);
check_combo->setEnabled(false);
proxyIP->setEnabled(false);
proxyUser->setEnabled(false);
proxyPort->setEnabled(false);
proxyPass->setEnabled(false);
}
void Freshklam::enableInputs(){
dir_combo->setEnabled(true);
daemon_box->setEnabled(true);
if (daemon_box->isChecked())
check_combo->setEnabled(true);
else
check_combo->setEnabled(false);
proxyIP->setEnabled(true);
proxyUser->setEnabled(true);
proxyPort->setEnabled(true);
proxyPass->setEnabled(true);
}
TQString Freshklam::getCurrentDBDir(){
unsigned int ret= 0;
unsigned int no = 0;
struct cl_engine *engine = NULL;
TQStringList lastDownloadPaths;
TQString dbdir;
TQString db;
config = TDEGlobal::config();
config->setGroup("Freshklam");
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
for (TQStringList::Iterator ita = lastDownloadPaths.begin(); ita == lastDownloadPaths.begin() ; ita++){
dbdir = *ita;
}
if (dbdir != dir_combo->url()){
/* load all available databases from default directory */
#ifdef SUPPORT_CLAMAV_V095
ret = cl_load((const char *)dir_combo->url(), engine, &no, CL_DB_STDOPT);
#else
ret = cl_load((const char *)dir_combo->url(), &engine, &no, CL_DB_STDOPT);
#endif
//ret = cl_loaddbdir((const char *)dir_combo->url(), &root, &no);
////kdDebug() << "ret " << ret << endl;
if (no == 0){
db = dbdir;
}else{
db = dir_combo->url();
lastDownloadPaths.prepend(dir_combo->url());
config->writeEntry("lastDownloadPaths", lastDownloadPaths);
config->sync();
}
}else
db = dbdir;
return db;
}
void Freshklam::createDBDir(){
TQString path = getenv("HOME");
bool ok = true;
// directory exist?
path += "/.klamav";
TQDir klamavdir(path);
if (!klamavdir.exists() && !klamavdir.mkdir(path))
ok = false;
path += "/database";
if (ok)
{
TQDir klamavqdir(path);
if (!klamavqdir.exists() && !klamavqdir.mkdir(path))
ok = false;
else
chmod((const char *)path,0700);
}
if (ok){
lastDownloadPaths.prepend( TQString("%1").arg(path));
config = TDEGlobal::config();
config->setGroup("Freshklam");
config->writeEntry("lastDownloadPaths", lastDownloadPaths);
config->sync();
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
}
KMessageBox::information (this,TQString(ok ? i18n( "Your Virus Database location has been set up as '%1'. You can change this to something else if you want to." ) : i18n( "I cannot create the directory '%1' for you. Something is wrong with your HOME or klamav directory. You have to adjust your Virus Database directory by your self." )).arg(path));
if (ok){
int result = KMessageBox::warningContinueCancel(this, i18n( "Would you like to download the latest Virus Database to your new database location now? (You can do this later manually if you want.)"),i18n( "Download Virus Database" ),i18n( "Download" ));
switch (result) {
case 2 : KMessageBox::information (this,i18n( "You should update the database manually at your earliest convenience.") ); break;
case 5 :
tdemain->firstDownload = true;
break;
}
}
}
bool Freshklam::isFreshklamAlive(){
if (freshklamAlive)
return true;
return false;
}
void Freshklam::enableAutoUpdates()
{
config = TDEGlobal::config();
config->writeEntry("AutoUpdate","Yes");
config->sync();
daemon_box->setChecked(true);
check_combo->setEnabled(true);
slotSearch();
}
void Freshklam::checkForNewClamAVNow()
{
updater->checkForNewClamAVDirectly();
}
void Freshklam::checkForNewKlamAVNow()
{
updater->checkForNewKlamAVDirectly();
}
void
Freshklam::checkInternet() //SLOT
{
m_url.setHost( "prdownloads.sourceforge.net" );
if ( !m_url.port() ) m_url.setPort( 80 );
connect( &m_resolver, SIGNAL( finished( KResolverResults ) ), SLOT( resolved( KResolverResults ) ) );
connectToHost();
}
void
Freshklam::connectToHost() //SLOT
{
////kdDebug() << m_url.host() << endl;
m_resolver.setNodeName( m_url.host() );
m_resolver.setFamily( KResolver::InetFamily );
m_resolver.start();
}
void
Freshklam::resolved( KResolverResults result) // SLOT
{
if ((!( result.error() != KResolver::NoError || result.isEmpty() ))
&& klamav_box->isChecked()){
updater->checkForNewKlamAV();
}else
kdDebug() << "network error or not set to check for new klamav" << endl;
}
void
Freshklam::getCurrentVersionOfClamAV( )
{
////kdDebug() << "version clamav" << endl;
TQString suCommand=TQString("clamscan -V");
versionproc = new KProcIO();
versionproc->setUseShell(TRUE);
versionproc->setUsePty (KProcIO::Stdout,TRUE);
*versionproc<<suCommand;
connect( versionproc, SIGNAL(readReady(KProcIO *)),
SLOT(readVersionLine(KProcIO *)) );
connect( versionproc, SIGNAL(processExited(TDEProcess *)),
SLOT(versionExited()) );
versionproc->start(KProcIO::NotifyOnExit);
versionproc->closeWhenDone();
}
void Freshklam::versionExited()
{
kdDebug() << "deleting versionproc" << endl;
delete versionproc;
}
void Freshklam::readVersionLine(KProcIO *)
{
TQString lineout = "";
int pos;
if ((pos = (versionproc->readln(lineout))) != -1) {
if ((pos = (lineout.find("ClamAV"))) != -1){
lineout = lineout.stripWhiteSpace();
int StartPoint = (lineout.find("ClamAV") + 6);
int EndPoint = lineout.find("/");
TQString currentClamAVVersion = lineout.mid(StartPoint,(EndPoint - StartPoint));
currentClamAVVersion = currentClamAVVersion.stripWhiteSpace();
KlamavConfig::setClamAVVersion(currentClamAVVersion);
KlamavConfig::writeConfig();
////kdDebug() << currentClamAVVersion << endl;
}
}
versionproc->ackRead();
lineout = "";
}
void Freshklam::toggleUpgradeButtons(bool state)
{
klamav_options->setEnabled(state);
clamav_options->setEnabled(state);
}
#include "freshklam.moc"