/*
 * Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
 */

#include "klamd.h"
#include "klamav.h"
#include "freshklam.h"
#include "klamavconfig.h"
#include "collectiondb.h"



#include <klocale.h>
#include <kiconloader.h>
#include <kio/netaccess.h>
#include <karrowbutton.h>


#include <kaction.h>

#include <qcheckbox.h>
#include <kbuttonbox.h>
#include <kprocio.h>
#include <kurlrequester.h>
#include <qlayout.h>
#include <kmessagebox.h>
#include <ktempfile.h>
#include <ksystemtray.h>
#include <qtoolbutton.h>
#include <knotifyclient.h>


const char *check_desc1[] = {
    "1",
    "2",
    "3",
    "4",
    "5",
    0
};

const char *check_desc2[] = {
    "On Access",
    "On Execute",
    0
};


Klamd::Klamd(QWidget *_parent, const char *name)
    : QWidget(_parent, name)
{

	parent = _parent;

	klamdAlive = FALSE;
	

	//Data Directory Widget

	//QString dt = QDateTime::currentDateTime().toString();
	//KMessageBox::information (this,dt);

	QVBoxLayout *vbox = new QVBoxLayout(this, KDialog::marginHint(),
			KDialog::spacingHint(), "vbox");

	QGroupBox *group = new QGroupBox(i18n("Include Directories"), this);
	vbox->addWidget(group);

	QGridLayout *layout = new QGridLayout( group, 9, 3, KDialog::spacingHint(),
			KDialog::spacingHint(), "layout");
	layout->addRowSpacing(0, group->fontMetrics().height());
	layout->setColStretch(0, 1);
	layout->setColStretch(1, 1);

	hlp = new QWidget( group );
	layout->addMultiCellWidget(hlp, 1,1, 0,2);
	QHBoxLayout *dir_layout = new QHBoxLayout(hlp, KDialog::spacingHint() );

	KURL root = KURL( "/" );
	m_fileTreeView = new KFileTreeView( hlp );
	m_fileTreeView->addColumn( i18n("Include") );
	treeBranch = m_fileTreeView->addBranch( root, i18n("Root"), SmallIcon("folder_red") );
	m_fileTreeView->setDirOnlyMode( treeBranch, true );
        treeBranch->setShowingDotFiles( true );


	treeBranch->setOpen( true );

	btnup = new KArrowButton(hlp, LeftArrow);
	btnup->setFixedSize(20, 20);
	connect(btnup, SIGNAL( clicked() ), SLOT( slotDelIncludeDir() ));
	
	btndown = new KArrowButton(hlp, RightArrow);
	btndown->setEnabled(true);
	btndown->setFixedSize(20, 20);
	connect(btndown,SIGNAL( clicked() ), SLOT( slotAddIncludeDir()));
	

       sessionslb = new MyListBox(hlp);
       
	config = KGlobal::config();
	config->setGroup("Klamd");
	includePaths = config->readListEntry("IncludePaths");
	if (!(includePaths.isEmpty()))
		btnup->setEnabled(true);

	sessionslb->insertStringList(includePaths);



	dir_layout->addWidget(m_fileTreeView);
	dir_layout->addWidget(btnup);
	dir_layout->addWidget(btndown);
	dir_layout->addWidget(sessionslb);

	QGroupBox *group2 = new QGroupBox(i18n("Exclude Directories"), this);
	vbox->addWidget(group2);

	QGridLayout *layout2 = new QGridLayout( group2, 9, 3, KDialog::spacingHint(),
			KDialog::spacingHint(), "layout2");
	layout2->addRowSpacing(0, group2->fontMetrics().height());
	layout2->setColStretch(0, 1);
	layout2->setColStretch(1, 1);


	hlp2 = new QWidget( group2 );
	layout2->addMultiCellWidget(hlp2, 1,1, 0,2);
	QHBoxLayout *dir_layout2 = new QHBoxLayout(hlp2, KDialog::spacingHint() );

	KURL root2 = KURL( "/" );
	m_fileTreeView2 = new KFileTreeView( hlp2 );
	m_fileTreeView2->addColumn( i18n("Exclude") );
	treeBranch2 = m_fileTreeView2->addBranch( root2, i18n("Root"), SmallIcon("folder_red") );
	m_fileTreeView2->setDirOnlyMode( treeBranch2, true );
        treeBranch2->setShowingDotFiles( true );
	treeBranch2->setOpen( true );

	btnup2 = new KArrowButton(hlp2, LeftArrow);
	btnup2->setFixedSize(20, 20);
	connect(btnup2, SIGNAL( clicked() ), SLOT( slotDelExcludeDir() ));
	
	btndown2 = new KArrowButton(hlp2, RightArrow);
	btndown2->setEnabled(true);
	btndown2->setFixedSize(20, 20);
	connect(btndown2,SIGNAL( clicked() ), SLOT( slotAddExcludeDir()));
	

       sessionslb2 = new MyListBox(hlp2);
       	//config = KGlobal::config();
	config->setGroup("Klamd");
	excludePaths = config->readListEntry("ExcludePaths");
	if (!(excludePaths.isEmpty()))
		btnup2->setEnabled(true);

	sessionslb2->insertStringList(excludePaths);



	dir_layout2->addWidget(m_fileTreeView2);
	dir_layout2->addWidget(btnup2);
	dir_layout2->addWidget(btndown2);
	dir_layout2->addWidget(sessionslb2);

	QGroupBox *group3 = new QGroupBox(i18n("Options"), this);
	vbox->addWidget(group3);

	QGridLayout *layout3 = new QGridLayout( group3, 9, 10, KDialog::spacingHint(),
			KDialog::spacingHint(), "layout3");
	layout3->addRowSpacing(0, group3->fontMetrics().height());
	//layout3->setColStretch(0, 1);
	//layout3->setColStretch(1, 1);


	hlp3 = new QWidget( group3 );
	layout3->addMultiCellWidget(hlp3, 1,1, 0,10);
	QHBoxLayout *dir_layout3 = new QHBoxLayout(hlp3, KDialog::spacingHint() );

	recursive_box = new QCheckBox(i18n("&Quarantine"), hlp3);
	//recursive_box->setMinimumWidth(recursive_box->sizeHint().width());
    	
	if ((config->readEntry("Quarantine")) == "Yes")
		recursive_box->setChecked(true);
	
	connect( recursive_box, SIGNAL(toggled(bool)),
		SLOT(handleChecks()) );
	
	//dir_layout3->addSpacing(10);
	dir_layout3->addWidget(recursive_box);
	
	recursive_box1 = new QCheckBox(i18n("&Display Warnings"), hlp3);
	//recursive_box1->setMinimumWidth(recursive_box1->sizeHint().width());
	
	if ((config->readEntry("Warn")) == "Yes")
		recursive_box1->setChecked(true);

	connect( recursive_box1, SIGNAL(toggled(bool)),
		SLOT(handleChecks()) );
	
	//dir_layout3->addSpacing(10);
	dir_layout3->addWidget(recursive_box1);
	
	recursive_box2 = new QCheckBox(i18n("&Run Docked"), hlp3);
	//recursive_box2->setMinimumWidth(recursive_box2->sizeHint().width());
	
	if ((config->readEntry("Run Docked")) == "Yes")
		recursive_box2->setChecked(true);

	connect( recursive_box2, SIGNAL(toggled(bool)),
		SLOT(handleChecks()) );
	
	dir_layout3->addWidget(recursive_box2);
	dir_layout3->addSpacing(40);

	QLabel *combo_label = new QLabel(i18n("Max File Size (MBs):"), hlp3);
	//combo_label->setFixedSize(combo_label->sizeHint());
	dir_layout3->addWidget(combo_label);
	
	check_combo = new QComboBox(false, hlp3);
	check_combo->insertStrList(check_desc1);
	check_combo->adjustSize();
	//check_combo->setFixedSize(check_combo->size());
	dir_layout3->addWidget(check_combo);

	dir_layout3->addSpacing(20);


 	QToolButton* adv_options = new QToolButton( hlp3,"play" );
 	adv_options->setIconSet( SmallIconSet( "configure" ) );
	adv_options->setTextLabel("Options");
	adv_options->setTextPosition(QToolButton::Right);
	adv_options->setUsesTextLabel(true);
	
//	adv_options = new QPushButton ("Advanced", hlp3);
	dir_layout3->addWidget(adv_options);
	//adv_options->setFixedSize(adv_options->sizeHint());

	connect( adv_options, SIGNAL(clicked()),
		SLOT(slotAdvOptions()) );

/*	QLabel *combo_label2 = new QLabel(i18n("Scan:"), hlp3);
	combo_label2->setFixedSize(combo_label2->sizeHint());
	dir_layout3->addWidget(combo_label2);
	

	check_combo2 = new QComboBox(false, hlp3);
	check_combo2->insertStrList(check_desc2);
	check_combo2->adjustSize();
	check_combo2->setFixedSize(check_combo2->size());
	dir_layout3->addWidget(check_combo2);

	QToolTip::add( check_combo2, "'On Access' scans every file accessed. 'On Execute' only scans files/programs that your system tries to execute." );*/
	
	KButtonBox *actionbox = new KButtonBox(this, Qt::Horizontal);
	vbox->addWidget(actionbox, 2, 0);
	actionbox->addStretch();
	search_button = actionbox->addButton(i18n("&Enable Auto-Scan"));
	search_button->setDefault(true);
	cancel_button = actionbox->addButton(i18n("&Disable Auto-Scan"));
	cancel_button->setEnabled(false);
	actionbox->addStretch();
	actionbox->layout();
	
/*	
	connect( search_button, SIGNAL(clicked()),
		SLOT(startKlamd()) );
	connect( cancel_button, SIGNAL(clicked()),
		SLOT(slotCancel()) );
*/
	if (KApplication::kApplication()->isRestored())
		restoreKlamd();

//	KStdAction::quit(this, SLOT(hide()), actionCollection());

}

Klamd::~Klamd()
{

	if (klamdAlive){
		delete childproc;
		childproc = 0;

	}
	if (!(tempFileName.isEmpty()))
		KIO::NetAccess::del(tempFileName,NULL);

}


void Klamd::processOutput()
{
	item2 = "";
	int pos;
	if ((pos = (childproc->readln(item2))) != -1) {
    	kdDebug() << item2 << endl;
		if ((pos = (item2.find(" FOUND"))) != -1){
			item2 = item2.stripWhiteSpace();
			int fnameStartPoint = (item2.find(":") + 1);
			int fnameEndPoint = item2.findRev(":");
			QString tmpFName = item2.mid(fnameStartPoint,(fnameEndPoint - fnameStartPoint));
			QString tmpVirusName = item2.mid((fnameEndPoint+1),(item2.length() - (fnameEndPoint+1)));
			tmpVirusName.replace("FOUND","");
            CollectionDB::instance()->insertEvent("Virus Found",tmpVirusName,tmpFName);
            if (recursive_box1->isChecked())
                KNotifyClient::event(kmain->_tray->winId(),i18n( "ScanCompleteNoVirus" ), i18n( "Virus %1 Found In %2 by Auto-Scan!" ).arg(tmpVirusName).arg(tmpFName));
			if (recursive_box->isChecked())
				Quarantine(tmpFName.stripWhiteSpace(),tmpVirusName.stripWhiteSpace());
		}
   	}
	childproc->ackRead();

	item2 = "";
	buf = "";


}


bool Klamd::startKlamd()
{

	config = KGlobal::config();
	config->setGroup("Klamd");
	if ((config->readListEntry("IncludePaths")).isEmpty()){
		KMessageBox::information (this,i18n("You haven't specified any paths to scan. Select the directories you want to KlamAV to keep an eye on and try again.")); 
		return FALSE;
	}
		

	if (recursive_box2->isChecked()){
		if (!(this->topLevelWidget()->isHidden()))
			KMessageBox::information (this,i18n("I'm going into the background now. You can restore me by clicking on the icon in the system tray on the bottom right."));
		this->topLevelWidget()->hide();
	}/*else{
		this->topLevelWidget()->show();
	}*/
		
	
	if (runDazuko(true))
		return TRUE;
	else
		return FALSE;
	//this->topLevelWidget()->hide();
}

void Klamd::finish()
{
	search_button->setEnabled(true);
	cancel_button->setEnabled(false);
	//config = KGlobal::config();
	config->setGroup("Klamd");
	config->writeEntry("Enabled", "No");
	
	
	buf += '\n';
	processOutput();
    childproc->closeAll();
    childproc->kill(9);
	delete childproc;
	childproc = 0;
	klamdAlive = FALSE;
	enableInputs();
 	if (!(tempFileName.isEmpty()))
 		KIO::NetAccess::del(tempFileName,NULL);


}


void Klamd::slotCancel()
{
    finish();

    CollectionDB::instance()->insertEvent("Auto-Scan","Scanning Cancelled","");

}


void Klamd::childExited()
{
//    int status = childproc->exitStatus();


    kmain->contextDisable();
    
    KMessageBox::information (this,i18n( "The auto-scan process died unexpectedly!") );

    //if (status != 0)
	      //matches_label->setText("");

}


void Klamd::receivedOutput(KProcIO *)
{
    //buf += QCString(buffer, buflen+1);
    processOutput();
}


void Klamd::slotClear()
{
    finish();

}


void  Klamd::setDirName(QString dir){
//    dir_combo->setEditText(dir);
    dir_combo->setURL(dir);
}

void Klamd::slotAddIncludeDir()
{

	KURL filepattern =  m_fileTreeView->currentURL();
	QString filepa = filepattern.path();
	if(filepa)
		if ((includePaths.contains(filepa) == 0) && (excludePaths.contains(filepa) == 0)){
			sessionslb->insertItem(filepa);
	
			//config = KGlobal::config();
			config->setGroup("Klamd");
			
			if (includePaths.contains(filepa) == 0) {
				includePaths.prepend(filepa);
			}else{
				includePaths.remove(filepa);
				includePaths.prepend(filepa);
			}
			config->writeEntry("IncludePaths", includePaths);
			config->sync();
			
			btnup->setEnabled(true);
		}	
}

void Klamd::slotDelIncludeDir()
{


	while (includePaths.contains(sessionslb->currentText()))
	{
		includePaths.remove(sessionslb->currentText());
	}

	sessionslb->removeItem(sessionslb->currentItem());
	
	//config = KGlobal::config();
	config->setGroup("Klamd");
	config->writeEntry("IncludePaths", includePaths);
	config->sync();

	if ( sessionslb->count() == 0 )
		btnup->setEnabled(false);

	
}


void Klamd::slotAddExcludeDir()
{
//KFileTreeViewItem* treeItem = dynamic_cast<KFileTreeViewItem*>(KFileTreeViewItem::currentKFileTreeViewItem());

	KURL filepattern =  m_fileTreeView2->currentURL();
	QString filepa = filepattern.path();
	if(filepa)
		if ((includePaths.contains(filepa) == 0) && (excludePaths.contains(filepa) == 0)){
			sessionslb2->insertItem(filepa);

			//config = KGlobal::config();
			config->setGroup("Klamd");
			
			if (excludePaths.contains(filepa) == 0) {
				excludePaths.prepend(filepa);
			}else{
				excludePaths.remove(filepa);
				excludePaths.prepend(filepa);
			}
			config->writeEntry("ExcludePaths", excludePaths);
			config->sync();
		
			btnup2->setEnabled(true);
		}
}

void Klamd::slotDelExcludeDir()
{

	while (excludePaths.contains(sessionslb2->currentText()))
	{
		excludePaths.remove(sessionslb2->currentText());
	}
	
	sessionslb2->removeItem(sessionslb2->currentItem());
	
	//config = KGlobal::config();
	config->setGroup("Klamd");
	config->writeEntry("ExcludePaths", excludePaths);
	config->sync();

	if ( sessionslb2->count() == 0 )
		btnup2->setEnabled(false);
	
}


void Klamd::writeConf()
{
     KTempFile tf;
      if ( tf.status() != 0 ) {
	tf.close();
	//delete tf;
	KMessageBox::information (this,"KMFilterActionWithCommand: Could not create temp file!");
	return;
      }


	//config = KGlobal::config();
	config->setGroup("Kuarantine");
	QStringList lastQuarLocations = config->readListEntry("KuarantineLocations");
	QString quarloc;
	for (QStringList::Iterator ita = lastQuarLocations.begin(); ita == lastQuarLocations.begin() ; ita++){
			quarloc = *ita;
	}
	
	QString db = kmain->freshklam->getCurrentDBDir();


      //tf->setAutoDelete(TRUE);

      tempFileName = tf.name();

	QTextStream &ts = *(tf.textStream());

	//ts << "LocalSocket /tmp/klamd " << "\n";
    ts << "TCPSocket 9888 " << "\n";
/*	ts << "MaxDirectoryRecursion 15" << "\n";*/
	ts << "Foreground" << "\n";
	ts << "LogFile /dev/stdout" << "\n";
	ts << "ScanArchive" << "\n";
	//ts << "ClamukoMaxFileSize " << check_combo->currentText() << "M\n";
/*	ts << "ArchiveMaxRecursion 5" << "\n";
	ts << "ArchiveMaxFiles 1000" << "\n";*/
	ts << "FixStaleSocket" << "\n";
	ts << "SelfCheck 1800" << "\n";
	ts << QString("DatabaseDirectory %1").arg(db) << "\n";
	ts << "ClamukoScanOnLine" << "\n";
	


    for ( QListBoxItem *bi = sessionslb->firstItem() ; bi != 0; bi = bi->next() )
       ts << "ClamukoIncludePath " << bi->text() << "\n";

    ts << "ClamukoExcludePath " <<quarloc << "\n";

    for ( QListBoxItem *bi = sessionslb2->firstItem() ; bi != 0; bi = bi->next() )
       ts << "ClamukoExcludePath " << bi->text() << "\n";

	config->setGroup("Klamd");


	if (KlamavConfig::executed())
		ts << "ClamukoScanOnExec" << "\n";

	if (KlamavConfig::created()){
		ts << "ClamukoScanOnCloseModified" << "\n";
		clamdcommand = "klamd";
	}else{
		clamdcommand = "clamd";
		
		if (KlamavConfig::opened())
			ts << "ClamukoScanOnOpen" << "\n";
	
		if (KlamavConfig::closed())
			ts << "ClamukoScanOnClose" << "\n";
	}
/*	if (config->readEntry("ScanArchives") == "Yes"){
		ts << "ClamukoScanArchive" << "\n";
		ts << "ArchiveMaxFileSize " << config->readEntry("MaxSize") << "M\n";
	}*/
//     if (check_combo2->currentItem() == 0)
// 	ts << "ClamukoScanOnOpen" << "\n";
//     else
//     	ts << "ClamukoScanOnExec" << "\n";

//	if (recursive_box1->isChecked())
//		ts << "ClamukoScanOnClose" << "\n";

//	if (recursive_box2->isChecked())
//		ts << "ClamukoScanOnExec" << "\n";

	QString curtex = check_combo->currentText();
	ts << "ClamukoMaxFileSize " << curtex << "M\n";

      tf.close();
}

void  Klamd::Quarantine(QString fname, QString virusname){

	//config = KGlobal::config();
	config->setGroup("Kuarantine");
	//object.replace("Clamuko:","");
	//object = object.stripWhiteSpace();
	////kdDebug() << object << endl;
	//QString QuarLocation = config->readEntry("KuarantineLocations");
	QStringList lastQuarLocations = config->readListEntry("KuarantineLocations");
	
	QString quarloc;
	for (QStringList::Iterator it = lastQuarLocations.begin(); it == lastQuarLocations.begin() ; it++){
			quarloc = *it;
	}

	lastQuarItems = config->readListEntry(QString("Items %1").arg(quarloc));
	
	if (!(fname.isEmpty())){
		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"));

		QString object = fname + ": " + virusname + suffix;
		QStringList tokens = QStringList::split ( "/", fname, FALSE );
		QString qname = tokens.last();
		qname.prepend("/");
		qname.prepend(quarloc);
		qname.append(suffix);
		bufmv = "";
		//kdDebug() << fname << endl;
		//kdDebug() << qname << endl;
		//kdDebug() << object << endl;
		if (rename ((const char *)fname, (const char *)qname) != 0){
			QString suCommand=QString("mv '%1' '%2'").arg(fname).arg(qname);
			//kdDebug() << suCommand << endl;
			proc = new KProcIO();
			proc->setUseShell(TRUE);
			*proc<<suCommand;
			
			
			connect( proc, SIGNAL(readReady(KProcIO *)),
				SLOT(receivedmvOutput(KProcIO *)) );
	
			proc->start(KProcIO::NotifyOnExit,TRUE);
			// ouch
			proc->wait();
			//kdDebug() << "finished " << suCommand << endl;
			if (((bufmv.find("Permission denied"))) != -1){
				KMessageBox::information (this,i18n("<p>Don't have permission to move <b>%1</b> to the quarantine folder.</p>").arg(fname)); 
			}else if (((bufmv.find("No space"))) != -1){
				KMessageBox::information (this,i18n("<p>Don't have enough space to move <b>%1</b> to the quarantine folder.</p>").arg(fname)); 
			
			}else{
				if (recursive_box1->isChecked())
					KMessageBox::queuedMessageBox(0, KMessageBox::Information, i18n("<p>Infected file found: <br><br>Filename: <b>%1</b> <br>Virus found: <b>%2</b> <br><br>I'm going to quarantine this file. You can restore it later if you want.<br></p>").arg(fname).arg(QString(virusname).replace("FOUND","")),
					//i18n( "Infected File Found!" ),
					//i18n( "Quarantine" )
					0);
				
				if (lastQuarItems.contains(object))
					lastQuarItems.remove(object);
				lastQuarItems.prepend(object);
				CollectionDB::instance()->insertEvent("Quarantine",virusname,fname);
			}	
		}else{
			//kdDebug() << "rename worked" << endl;
			if (recursive_box1->isChecked())
				KMessageBox::queuedMessageBox(0, KMessageBox::Information, i18n("<p>Infected file found: <br><br>Filename: <b>%1</b> <br>Virus found: <b>%2</b> <br><br>I'm going to quarantine this file. You can restore it later if you want.<br> If the file already exists in the quarantine directory it will be overwritten.</p>").arg(fname).arg(QString(virusname).replace("FOUND","")),
				//i18n( "Infected File Found!" ),
				//i18n( "Quarantine" )
				0);
			
			if (lastQuarItems.contains(object))
				lastQuarItems.remove(object);
			lastQuarItems.prepend(object);
			CollectionDB::instance()->insertEvent("Quarantine",virusname,fname);
		}
	}
	
	config->writeEntry(QString("Items %1").arg(quarloc), lastQuarItems);
	//config->sync();
	
	//kmain->kuarantine->refresh();
	//kdDebug() << "finished klamd quar" << endl;
}

void Klamd::receivedmvOutput(KProcIO *)
{
    //kdDebug() << "in receivedmvoutput" << endl;

    mvbuffer = "";
    proc->readln(mvbuffer);
    bufmv += QString(mvbuffer);
}



int  Klamd::runDazuko(bool caller){

	
	dazukoLoaded = FALSE;
	QString lsmodCommand="lsmod";
	lsmodproc = new KProcIO();
	QString curpath = (QString) getenv("PATH");
	lsmodproc->setEnvironment("PATH",curpath + ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");


	lsmodproc->setUseShell(TRUE);
	*lsmodproc<<lsmodCommand;

	connect( lsmodproc, SIGNAL(readReady(KProcIO *)),
		SLOT(checkForDazuko()) );
	if (caller){
		connect( lsmodproc, SIGNAL(processExited(KProcess *)),
			SLOT(lsmodOutput()) );
	}else{
		connect( lsmodproc, SIGNAL(processExited(KProcess *)),
			SLOT(lsmodCheck()) );
	}

		
	bool succ = lsmodproc->start(KProcIO::NotifyOnExit,TRUE);

	if (!(succ))
		KMessageBox::information (this,i18n( "There was a problem detecting the loaded status of dazuko.") );
	return 1;
}

void Klamd::lsmodOutput()
{
	if (!(dazukoLoaded)){
		int result;
		result = KMessageBox::warningContinueCancel(this, i18n( "I need to load a module called 'dazuko' first. This module will allow KlamAV to gain real-time access to files. If you don't want this message to appear in future, put the following command in your initialization scripts: 'modprobe dazuko.o'. You will next be asked for the root password."),
		i18n( "Load Module" ),
		i18n( "Load Module" ),
		i18n( "Delete2" ));
		switch (result) {
			case 2 : KMessageBox::information (this,i18n( "Loading of Module Cancelled.") );  break;
			case 5 : loadDazuko();  break;
		}

	}else{
		loadKlamd();
	}
	

}

void Klamd::loadKlamd()
{
	writeConf();

	klamdAlive = TRUE;
	
	//QString suCommand=QString("kdesu -t -c '" +clamdcommand+" -c '%1'").arg(tempFileName)+"'";
    QString suCommand=QString(clamdcommand+" -c '%1'").arg(tempFileName);
	childproc = new KProcIO();
	childproc->setUseShell(TRUE);
	childproc->setUsePty (KProcIO::Stdout,TRUE);
	QString curpath = (QString) getenv("PATH");
	childproc->setEnvironment("PATH",curpath + ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");

	kdDebug() << suCommand << endl;

	*childproc<<suCommand;
	
	connect( childproc, SIGNAL(readReady(KProcIO *)),
		SLOT(receivedOutput(KProcIO *)) );
	childproc->start(KProcIO::NotifyOnExit);
	connect( childproc, SIGNAL(processExited(KProcess *)),
			SLOT(childExited()) );
	
	search_button->setEnabled(false);
	cancel_button->setEnabled(true);
	
	if (kmain->freshklam->isFreshklamAlive())
		kmain->_tray->setPixmap(KSystemTray::loadIcon("klamavdl"));
	else
		kmain->_tray->setPixmap(KSystemTray::loadIcon("klamav"));	
	kmain->EnableKlamd->setEnabled(FALSE);
	kmain->DisableKlamd->setEnabled(TRUE);
	//config = KGlobal::config();
	config->setGroup("Klamd");
	config->writeEntry("Enabled", "Yes");
	config->sync();
	disableInputs();

    CollectionDB::instance()->insertEvent("Auto-Scan","Scanning Started","");

}
void Klamd::loadDazuko()
{

// 	struct utsname info;
// 	
// 	if (uname(&info) == -1)
// 	{
// 		kdError(0) << "uname() failed: errno = " << errno << endl;
// 		return;
// 	}
// 
// 	QString release = QString(info.release);
// 	
// 	//kdDebug() << release << endl;
// 	QString insmodCommand="insmod /lib/modules/" + release + "/dazuko.o";
	QString insmodCommand="modprobe dazuko";
	//QString insmodCommand="insmod /opt/kde/bin/dazuko.o";
	KProcIO *insmodproc = new KProcIO();
	
	QString curpath = (QString) getenv("PATH");
	insmodproc->setEnvironment("PATH",curpath + ":/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin");

	insmodproc->setUseShell(TRUE);
	*insmodproc<<"kdesu -i klamav"<<"-c"<<insmodCommand;
	
	connect( insmodproc, SIGNAL(processExited(KProcess *)),
		SLOT(moduleLoaded()) );

	insmodproc->start(KProcIO::NotifyOnExit);
}

void Klamd::moduleLoaded()
{
	runDazuko(false);
	
}

void Klamd::lsmodCheck()
{
	if (!(dazukoLoaded)){
		KMessageBox::information (this,i18n( "Dazuko was not loaded successfully. Please check your installation." ));
	}else{
		int result;
		result = KMessageBox::warningContinueCancel(this, i18n( "Module has been loaded. Will now continue to start up real-time scanning."),
			i18n( "Continue" ),
			i18n( "Continue" ),
			i18n( "Delete2" ));
		switch (result) {
			case 2 : break;
			case 5 : loadKlamd();break;
		}
	}
	

}

void Klamd::checkForDazuko()
{
	QString item = "";
	int pos;
	pos = lsmodproc->readln(item,TRUE);
	//KMessageBox::information (this,item);
	if (pos != -1) {
		//KMessageBox::information (this,item);
		if ((pos = (item.find("dazuko"))) != -1){
			//KMessageBox::information (this,"found dazuko");
			dazukoLoaded = TRUE;
			lsmodproc->kill();
		}
		lsmodproc->ackRead();
	}
}

void  Klamd::restoreKlamd(){

	config = KGlobal::config();
	config->setGroup("Klamd");
	QString RunKlamd = config->readEntry("Enabled");
	
	if (RunKlamd == "Yes"){
		startKlamd();
	}

}

void  Klamd::handleChecks(){

	//config = KGlobal::config();
	config->setGroup("Klamd");
	if (recursive_box->isChecked())
		config->writeEntry("Quarantine","Yes");
	else
		config->writeEntry("Quarantine","No");
	
	if (recursive_box1->isChecked())
		config->writeEntry("Warn","Yes");
	else
		config->writeEntry("Warn","No");

	if (recursive_box2->isChecked())
		config->writeEntry("Run Docked","Yes");
	else
		config->writeEntry("Run Docked","No");
	
	config->sync();

}

bool  Klamd::isKlamdAlive(){
	if (klamdAlive)
		return true;
	return false;

}

QString  Klamd::getKlamdConfFile(){
	return tempFileName;

}

void  Klamd::slotAdvOptions(){

/*	config = KGlobal::config();
	config->setGroup("Klamd");
	QString RunKlamd = config->readEntry("Enabled");

	KlamdOptions *dialog = new KlamdOptions( this, "settings");
	
//	connect( dialog, SIGNAL(settingsChanged()), SLOT(applySettings()) );

	
	dialog->show();
	dialog->raise();
	dialog->setActiveWindow();*/
	
	kmain->slotConfigKlamav( "Auto-Scan" );	

}

void  Klamd::disableInputs(){

	hlp->setEnabled(false);
	hlp2->setEnabled(false);
	hlp3->setEnabled(false);
}

void  Klamd::enableInputs(){

	hlp->setEnabled(true);
	hlp2->setEnabled(true);
	hlp3->setEnabled(true);

}

#include "klamd.moc"
