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 <klocale.h>
#include <kio/netaccess.h>
#include <kaction.h>
#include <qcheckbox.h>
#include <kbuttonbox.h>
#include <kurlrequester.h>
#include <kurlcompletion.h>
#include <kcombobox.h>
#include <qlayout.h>
#include <kmessagebox.h>
#include <klineedit.h>
#include <ktempfile.h>
#include <ksystemtray.h>
#include <ktar.h>
#include <kprogress.h>
#include <kprocio.h>
#include <knotifyclient.h>
#include <dom/html_misc.h>
#include <kapplication.h>
#include <dcopclient.h>
#include <kuser.h>
#include <qtimer.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
};
QString readymessage = i18n("KlamAV ") + KLAMAV_VERSION + i18n(" - Ready");
Freshklam::Freshklam(QWidget *parent, const char *name)
: QWidget(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) ) );
kmain->firstDownload = false;
checkingDirectly = false;
freshklamAlive = FALSE;
config = KGlobal::config();
config->setGroup("Freshklam");
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
getCurrentVersionOfClamAV( );
if ((lastDownloadPaths.isEmpty()) || (!(KIO::NetAccess::exists(QString((*lastDownloadPaths.begin())),TRUE,NULL)))){
createDBDir();
}
QString proxyIPText = config->readEntry("ProxyIP");
QString proxyPortText = config->readEntry("ProxyPort");
QString proxyUserText = config->readEntry("ProxyUser");
QString proxyPassText = config->readEntry("ProxyPass");
//Data Directory Widget
QVBoxLayout *vbox = new QVBoxLayout(this, KDialog::marginHint(),
KDialog::spacingHint(), "vbox");
//Proxy Widget
QGroupBox *software_group = new QGroupBox(i18n("Software Updates"), this);
vbox->addWidget(software_group);
QGridLayout *software_layout = new QGridLayout( 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
QWidget *dazuko_hlp = new QWidget( software_group );
software_layout->addMultiCellWidget(dazuko_hlp, 1,2, 0,2);
QGridLayout *dazuko_dir_layout = new QGridLayout(dazuko_hlp,2,2, KDialog::spacingHint() );
clamav_box = new QCheckBox(i18n("Update ClamAV Automatically"), dazuko_hlp);
clamav_box->setMinimumWidth(clamav_box->sizeHint().width());
dazuko_dir_layout->addWidget(clamav_box,0,0);
klamav_box = new QCheckBox(i18n("Update KlamAV Automatically"), dazuko_hlp);
klamav_box->setMinimumWidth(klamav_box->sizeHint().width());
dazuko_dir_layout->addWidget(klamav_box,0,1);
clamav_options = new QPushButton (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 QPushButton (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
QGroupBox *group = new QGroupBox(i18n("Virus Database Directory"), this);
vbox->addWidget(group);
QGridLayout *layout = new QGridLayout( group, 9, 2, KDialog::spacingHint(),
KDialog::spacingHint(), "layout");
layout->addRowSpacing(0, group->fontMetrics().height());
layout->setColStretch(0, 1);
layout->setColStretch(1, 1);
QWidget *hlp = new QWidget( group );
layout->addMultiCellWidget(hlp, 1,1, 0,1);
QHBoxLayout *dir_layout = new QHBoxLayout(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 );
QLabel *dir_label = new QLabel(i18n("Directory:"), hlp);
dir_label->setFixedSize(dir_label->sizeHint());
dir_layout->addWidget(dir_label);
dir_layout->addWidget(dir_combo);
//Proxy Widget
QGroupBox *proxy_group = new QGroupBox(i18n("Proxy for Database Updates"), this);
vbox->addWidget(proxy_group);
QGridLayout *proxy_layout = new QGridLayout( 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
QWidget *proxy_hlp = new QWidget( proxy_group );
proxy_layout->addMultiCellWidget(proxy_hlp, 1,2, 0,2);
QGridLayout *proxy_dir_layout = new QGridLayout(proxy_hlp, 2,4,KDialog::spacingHint() );
QLabel *proxy_dir_label = new QLabel(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);
QLabel *proxy_port_label = new QLabel(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);
QLabel *proxy_user_label = new QLabel(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);
QLabel *proxy_pass_label = new QLabel(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
QGroupBox *daemon_group = new QGroupBox(i18n("Database AutoUpdate Settings"), this);
vbox->addWidget(daemon_group);
QGridLayout *daemon_layout = new QGridLayout( 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);
QWidget *daemonhlp = new QWidget( daemon_group );
daemon_layout->addMultiCellWidget(daemonhlp, 1,1, 0,1);
QHBoxLayout *daemon_check_layout = new QHBoxLayout(daemonhlp, KDialog::spacingHint() );
daemon_box = new QCheckBox(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 QComboBox(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);
QLabel *combo_label = new QLabel(i18n("Times a Day"), daemonhlp);
//combo_label->setFixedSize(combo_label->sizeHint());
daemon_check_layout->addWidget(combo_label);
KButtonBox *actionbox = new KButtonBox(this, Qt::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();
QFrame *status_frame = new QFrame(this);
status_frame->setFrameStyle(QFrame::Panel | QFrame::Sunken);
QBoxLayout *status_layout = new QHBoxLayout(status_frame, 2);
status_label = new QLabel(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()))
KIO::NetAccess::del(tempFileName,NULL);
}
void Freshklam::processOutput()
{
int pos;
int pos2;
QString item2;
while (( (pos = buf.find('\n')) != -1) || ( (pos = buf.find(']')) != -1))
{
QString item = buf.left(pos);
QDate today = QDate::currentDate();
QTime now = QTime::currentTime();
QString suffix = QString("%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(kmain->_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(kmain->_tray->winId(),"DatabaseUpToDate", "Virus Database Up To Date.");
updateMailClient();
}
if ((pos = item2.find("Recommended version:")) != -1){
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_update_required"));
pos2 = item2.find('\n',pos);
QString 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(kmain->_tray->winId(),"ClamAVOutDated", QString("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);
QString filepattern = dir_combo->url();
CollectionDB::instance()->insertEvent("Updates","Commencing DB Update", filepattern);
status_label->setText(i18n("Beginning Update..."));
childproc = new KShellProcess();
QString command = "freshclam --stdout ";
QString 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 (!(KApplication::kApplication()->isRestored())){
if (kmain->klamd->isKlamdAlive()){
QString klamdconf = kmain->klamd->getKlamdConfFile();
////kdDebug() << klamdconf << endl;
command += " --daemon-notify=";
command += klamdconf;
}
}
writeConf();
command += " --config-file=";
command += tempFileName;
disableInputs();
*childproc << command;
//kdDebug() << command << endl;
childproc->start(KProcess::NotifyOnExit, KProcess::Stdout);
connect( childproc, SIGNAL(processExited(KProcess *)),
SLOT(childExited()) );
connect( childproc, SIGNAL(receivedStdout(KProcess *, char *, int)),
SLOT(receivedOutput(KProcess *, char *, int)) );
// if (kmain->klamd->isKlamdAlive())
// kmain->_tray->setPixmap(KSystemTray::loadIcon("klamavdl"));
// else
// kmain->_tray->setPixmap(KSystemTray::loadIcon("klamavbwdl"));
kmain->EnableFreshklam->setEnabled(FALSE);
kmain->DisableFreshklam->setEnabled(TRUE);
}
void Freshklam::finish()
{
search_button->setEnabled(true);
cancel_button->setEnabled(false);
enableInputs();
if (kmain->klamd->isKlamdAlive())
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_enabled"));
else
kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav_on_acc_disabled"));
buf += '\n';
processOutput();
delete childproc;
childproc = 0;
freshklamAlive = FALSE;
if (!(tempFileName.isEmpty()))
KIO::NetAccess::del(tempFileName,NULL);
kmain->EnableFreshklam->setEnabled(TRUE);
kmain->DisableFreshklam->setEnabled(FALSE);
//updateMetaDB();
}
void Freshklam::updateMetaDB()
{
QDate latestDate = QDate::fromString(CollectionDB::instance()->latestMetaDBDate(),Qt::ISODate);
QDate today = QDate::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 (KApplication::kApplication()->mainWidget()) {
winid = KApplication::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();
KConfig* mailconfig = new KConfig("kmailrc");
mailconfig->setGroup("General");
QVariant nooffilters = mailconfig->readEntry("filters");
int result;
int numfilters = nooffilters.toInt();
nooffilters = numfilters;
for (int j=0; j != numfilters; j++ ){
QVariant numb = j;
QString filtername=QString("Filter #%1").arg(numb.toString());
mailconfig->setGroup(filtername);
QString binary = mailconfig->readEntry("action-args-0");
if (binary.find("klammail") != -1){
QString pathonly = binary.section(" ",2,2);
if (pathonly == dir_combo->url())
break;
if (binary.find(" " + dir_combo->url() + " ") == -1){
QString 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'. "),QString("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",QString("klammail -d %1").arg(dir_combo->url()));
mailconfig->sync();
break;
}
break;
}
}
}
//KMessageBox::information (this,"Database Update Complete!");
delete mailconfig;
}
void Freshklam::receivedOutput(KProcess */*proc*/, char *buffer, int buflen)
{
//kdDebug() << buffer << endl;
buf += QCString(buffer, buflen+1);
processOutput();
}
void Freshklam::slotClear()
{
finish();
resultbox->clear();
status_label->setText(i18n("Ready"));
matches_label->setText("");
}
void Freshklam::setDirName(QString 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();
QTextStream &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 << QString("HTTPProxyServer %1").arg(proxyIP->text()) << "\n";
if ( proxyPort->hasAcceptableInput() ) {
ts << QString("HTTPProxyPort %1").arg(proxyPort->text()) << "\n";
}
if ( proxyUser->hasAcceptableInput() && ! proxyUser->text().isEmpty() ) {
ts << QString("HTTPProxyUsername %1").arg(proxyUser->text()) << "\n";
if ( proxyPass->hasAcceptableInput() ) {
ts << QString("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 = KGlobal::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(){
QFile inf(pidFileName);
if (!inf.open(IO_ReadOnly))
return false;
QTextStream is(&inf);
QString 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()))
KIO::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);
}
QString Freshklam::getCurrentDBDir(){
unsigned int ret= 0;
unsigned int no = 0;
struct cl_engine *engine = NULL;
QStringList lastDownloadPaths;
QString dbdir;
QString db;
config = KGlobal::config();
config->setGroup("Freshklam");
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
for (QStringList::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(){
QString path = getenv("HOME");
bool ok = true;
// directory exist?
path += "/.klamav";
QDir klamavdir(path);
if (!klamavdir.exists() && !klamavdir.mkdir(path))
ok = false;
path += "/database";
if (ok)
{
QDir klamavqdir(path);
if (!klamavqdir.exists() && !klamavqdir.mkdir(path))
ok = false;
else
chmod((const char *)path,0700);
}
if (ok){
lastDownloadPaths.prepend( QString("%1").arg(path));
config = KGlobal::config();
config->setGroup("Freshklam");
config->writeEntry("lastDownloadPaths", lastDownloadPaths);
config->sync();
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
}
KMessageBox::information (this,QString(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 :
kmain->firstDownload = true;
break;
}
}
}
bool Freshklam::isFreshklamAlive(){
if (freshklamAlive)
return true;
return false;
}
void Freshklam::enableAutoUpdates()
{
config = KGlobal::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;
QString suCommand=QString("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(KProcess *)),
SLOT(versionExited()) );
versionproc->start(KProcIO::NotifyOnExit);
versionproc->closeWhenDone();
}
void Freshklam::versionExited()
{
kdDebug() << "deleting versionproc" << endl;
delete versionproc;
}
void Freshklam::readVersionLine(KProcIO *)
{
QString 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("/");
QString 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"