|
|
|
/*
|
|
|
|
* Copyright (C) 2004 Robert Hogan <robert at roberthogan dot net>
|
|
|
|
*
|
|
|
|
* ClamAV DB code:
|
|
|
|
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "dbviewer.h"
|
|
|
|
#include "klamav.h"
|
|
|
|
#include <clamav.h>
|
|
|
|
#include "pageviewer.h"
|
|
|
|
#include "tabwidget.h"
|
|
|
|
#include "freshklam.h"
|
|
|
|
#include "../config.h"
|
|
|
|
|
|
|
|
#include <tqheader.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqpopupmenu.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
|
|
|
|
#include <tdetoolbarbutton.h> //ctor
|
|
|
|
#include <tdetempfile.h>
|
|
|
|
#include <ktempdir.h>
|
|
|
|
#include <tdelistviewsearchline.h>
|
|
|
|
#include <tdelistview.h>
|
|
|
|
#include <kprogress.h>
|
|
|
|
|
|
|
|
#include <dirent.h>
|
|
|
|
#include <zlib.h>
|
|
|
|
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
|
|
|
|
#include <kurl.h>
|
|
|
|
|
|
|
|
#define TAR_BLOCKSIZE 512
|
|
|
|
#define FILEBUFF 8192
|
|
|
|
|
|
|
|
int cli_untgz(int fd, const char *destdir);
|
|
|
|
int cli_rmdirs(const char *dirname);
|
|
|
|
int cli_strbcasestr(const char *haystack, const char *needle);
|
|
|
|
int cli_chomp(char *string);
|
|
|
|
char *cli_strtok(const char *line, int field, const char *delim);
|
|
|
|
|
|
|
|
using namespace KlamAV;
|
|
|
|
/*
|
|
|
|
* Constructs a KlamDB as a child of 'parent', with the
|
|
|
|
* name 'name' and widget flags set to 'f'.
|
|
|
|
*
|
|
|
|
* The dialog will by default be modeless, unless you set 'modal' to
|
|
|
|
* TRUE to construct a modal dialog.
|
|
|
|
*/
|
|
|
|
KlamDB::KlamDB( TQWidget* parent, const char* name, bool modal, WFlags fl )
|
|
|
|
: TQDialog( parent, name, modal, fl )
|
|
|
|
{
|
|
|
|
if ( !name )
|
|
|
|
setName( "KlamDB" );
|
|
|
|
|
|
|
|
loadinprogress = false;
|
|
|
|
TQVBoxLayout *vbox = new TQVBoxLayout(this, KDialog::marginHint(),
|
|
|
|
KDialog::spacingHint(), "vbox");
|
|
|
|
|
|
|
|
TQWidget* privateLayoutWidget = new TQWidget( this, "dblayout" );
|
|
|
|
vbox->addWidget(privateLayoutWidget);
|
|
|
|
|
|
|
|
dblayout = new TQGridLayout( privateLayoutWidget, 1, 1, 2, 2, "dblayout");
|
|
|
|
dblayout->setColStretch(1, 1);
|
|
|
|
|
|
|
|
tabBrowser = new TabWidget(privateLayoutWidget, "KlamDB", TQStringList("Home"));
|
|
|
|
|
|
|
|
|
|
|
|
dblayout->addMultiCellWidget( tabBrowser, 0, 1, 1, 1 );
|
|
|
|
|
|
|
|
TDEToolBarButton *button;
|
|
|
|
TDEToolBar* searchToolBar = new TDEToolBar( privateLayoutWidget );
|
|
|
|
searchToolBar->setMovingEnabled(false);
|
|
|
|
searchToolBar->setFlat(true);
|
|
|
|
searchToolBar->setIconSize( 16 );
|
|
|
|
searchToolBar->setEnableContextMenu( false );
|
|
|
|
|
|
|
|
button = new TDEToolBarButton( "locationbar_erase", 0, searchToolBar );
|
|
|
|
|
|
|
|
VirusList = new TDEListView( privateLayoutWidget, "VirusList" );
|
|
|
|
VirusList->addColumn( i18n( "All Known Viruses" ),150 );
|
|
|
|
connect(VirusList, SIGNAL( doubleClicked( TQListViewItem * , const TQPoint &, int ) ),
|
|
|
|
this, SLOT(slotOpenTab(TQListViewItem * , const TQPoint &, int )) );
|
|
|
|
|
|
|
|
menu = new TQPopupMenu( VirusList );
|
|
|
|
|
|
|
|
TQPixmap gicon;
|
|
|
|
TQPixmap ticon;
|
|
|
|
|
|
|
|
TQString iconPath = locate("cache", KMimeType::favIconForURL("http://www.google.com")+".png");
|
|
|
|
if ( iconPath.isEmpty() )
|
|
|
|
gicon = SmallIcon("edit-find");
|
|
|
|
else
|
|
|
|
gicon = TQPixmap( iconPath );
|
|
|
|
|
|
|
|
iconPath = locate("cache", KMimeType::favIconForURL("http://www.trendmicro.com")+".png");
|
|
|
|
if ( iconPath.isEmpty() )
|
|
|
|
ticon = SmallIcon("edit-find");
|
|
|
|
else
|
|
|
|
ticon = TQPixmap( iconPath );
|
|
|
|
|
|
|
|
menu->insertItem(ticon, i18n("Search with Trend Micro"), this,SLOT(slotTrendMicro()) );
|
|
|
|
menu->insertItem(gicon, i18n("Search with Google"), this,SLOT(slotGoogle()) );
|
|
|
|
|
|
|
|
googlePrefix = TQString::fromAscii("http://www.google.com/search?ie=ISO-8859-1&q=");
|
|
|
|
tMicroPrefix = TQString::fromAscii("https://www.trendmicro.com/vinfo/us/threat-encyclopedia/search/");
|
|
|
|
|
|
|
|
connect(VirusList, SIGNAL( contextMenuRequested( TQListViewItem *, const TQPoint& , int ) ),
|
|
|
|
this, SLOT( slotRMB( TQListViewItem *, const TQPoint &, int ) ) );
|
|
|
|
|
|
|
|
kLineEdit1 = new TDEListViewSearchLine( (TQWidget *)searchToolBar, VirusList,"klinedit1");
|
|
|
|
TQValueList<int> columns;
|
|
|
|
columns.append(0);
|
|
|
|
kLineEdit1->setSearchColumns(columns);
|
|
|
|
kLineEdit1->setMaxLength(2);
|
|
|
|
connect(button, SIGNAL( clicked() ),
|
|
|
|
kLineEdit1, SLOT(clear()) );
|
|
|
|
|
|
|
|
dblayout->addWidget( searchToolBar, 0, 0 );
|
|
|
|
|
|
|
|
dblayout->addWidget( VirusList, 1, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
languageChange();
|
|
|
|
clearWState( WState_Polished );
|
|
|
|
|
|
|
|
slotOpenHome();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Destroys the object and frees any allocated resources
|
|
|
|
*/
|
|
|
|
KlamDB::~KlamDB()
|
|
|
|
{
|
|
|
|
// no need to delete child widgets, TQt does it all for us
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Sets the strings of the subwidgets using the current
|
|
|
|
* language.
|
|
|
|
*/
|
|
|
|
void KlamDB::languageChange()
|
|
|
|
{
|
|
|
|
setCaption( i18n( "Form1" ) );
|
|
|
|
tabBrowser->changeTab( tab, i18n( "Info" ) );
|
|
|
|
VirusList->header()->setLabel( 0, i18n( "All Known Viruses" ) );
|
|
|
|
VirusList->clear();
|
|
|
|
/*TDEListViewItem * item =*/ new TDEListViewItem( VirusList, 0 );
|
|
|
|
//item->setText( 0, tr( "New Item" ) );
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int KlamDB::listdb(const char *filename)
|
|
|
|
{
|
|
|
|
FILE *fd, *tmpd;
|
|
|
|
// char *buffer, *pt, *start, *dir, *tmp;
|
|
|
|
char *buffer, *pt, *start;
|
|
|
|
int line = 0, bytes;
|
|
|
|
const char *tmpdir;
|
|
|
|
|
|
|
|
if(cli_strbcasestr(filename, ".inc")) { /* incremental directory */
|
|
|
|
if(listdir(filename) == -1) {
|
|
|
|
printf("!listdb: Can't list incremental directory %s\n", filename);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((fd = fopen(filename, "rb")) == NULL) {
|
|
|
|
printf("!listdb(): Can't open file %s\n", filename);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(buffer = (char *) malloc(FILEBUFF))) {
|
|
|
|
printf("!listdb(): Can't allocate memory.\n");
|
|
|
|
fclose(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(buffer, 0, FILEBUFF);
|
|
|
|
/* check for CVD file */
|
|
|
|
fgets(buffer, 12, fd);
|
|
|
|
rewind(fd);
|
|
|
|
|
|
|
|
if(!strncmp(buffer, "ClamAV-VDB:", 11)) {
|
|
|
|
|
|
|
|
fseek(fd, 512, SEEK_SET);
|
|
|
|
|
|
|
|
tmpdir = getenv("TMPDIR");
|
|
|
|
if(tmpdir == NULL)
|
|
|
|
#ifdef P_tmpdir
|
|
|
|
tmpdir = P_tmpdir;
|
|
|
|
#else
|
|
|
|
tmpdir = "/tmp";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
KTempDir* tf = new KTempDir();
|
|
|
|
if ( tf->status() != 0 ) {
|
|
|
|
delete tf;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FIXME: it seems there is some problem with current position indicator
|
|
|
|
* after gzdopen() call in cli_untgz(). Temporarily we need this wrapper:
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* start */
|
|
|
|
|
|
|
|
KTempFile* tn = new KTempFile(tf->name());
|
|
|
|
|
|
|
|
if((tmpd = fopen(tn->name(), "wb+")) == NULL) {
|
|
|
|
printf("!listdb(): Can't create temporary file \n");
|
|
|
|
delete tf;
|
|
|
|
delete tn;
|
|
|
|
free(buffer);
|
|
|
|
fclose(fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while((bytes = fread(buffer, 1, FILEBUFF, fd)) > 0)
|
|
|
|
fwrite(buffer, 1, bytes, tmpd);
|
|
|
|
|
|
|
|
free(buffer);
|
|
|
|
fclose(fd);
|
|
|
|
|
|
|
|
fflush(tmpd);
|
|
|
|
fseek(tmpd, 0L, SEEK_SET);
|
|
|
|
|
|
|
|
if(cli_untgz(fileno(tmpd), tf->name())) {
|
|
|
|
printf("!listdb(): Can't unpack CVD file.\n");
|
|
|
|
cli_rmdirs(tf->name());
|
|
|
|
delete tf;
|
|
|
|
delete tn;
|
|
|
|
fclose(tmpd);
|
|
|
|
free(buffer);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(tmpd);
|
|
|
|
delete tn;
|
|
|
|
/* wrapper end */
|
|
|
|
|
|
|
|
/* list extracted directory */
|
|
|
|
listdir(tf->name());
|
|
|
|
|
|
|
|
cli_rmdirs(tf->name());
|
|
|
|
delete tf;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(cli_strbcasestr(filename, ".db") || cli_strbcasestr(filename, ".db2")) {
|
|
|
|
/* old style database */
|
|
|
|
|
|
|
|
while(fgets(buffer, FILEBUFF, fd)) {
|
|
|
|
line++;
|
|
|
|
pt = strchr(buffer, '=');
|
|
|
|
if(!pt) {
|
|
|
|
printf("!listdb(): Malformed pattern line %d (file %s).\n", line, filename);
|
|
|
|
fclose(fd);
|
|
|
|
free(buffer);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
start = buffer;
|
|
|
|
*pt = 0;
|
|
|
|
|
|
|
|
if((pt = strstr(start, " (Clam)")))
|
|
|
|
*pt = 0;
|
|
|
|
|
|
|
|
//printf("%s\n", start);
|
|
|
|
addVirusName(start);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if(cli_strbcasestr(filename, ".hdb")) {
|
|
|
|
|
|
|
|
while(fgets(buffer, FILEBUFF, fd)) {
|
|
|
|
line++;
|
|
|
|
cli_chomp(buffer);
|
|
|
|
start = cli_strtok(buffer, 2, ":");
|
|
|
|
|
|
|
|
if(!start) {
|
|
|
|
printf("!listdb(): Malformed pattern line %d (file %s).\n", line, filename);
|
|
|
|
fclose(fd);
|
|
|
|
free(buffer);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((pt = strstr(start, " (Clam)")))
|
|
|
|
*pt = 0;
|
|
|
|
|
|
|
|
//printf("%s\n", start);
|
|
|
|
addVirusName(start);
|
|
|
|
free(start);
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if(cli_strbcasestr(filename, ".ndb")) {
|
|
|
|
|
|
|
|
while(fgets(buffer, FILEBUFF, fd)) {
|
|
|
|
line++;
|
|
|
|
cli_chomp(buffer);
|
|
|
|
start = cli_strtok(buffer, 0, ":");
|
|
|
|
|
|
|
|
if(!start) {
|
|
|
|
printf("!listdb(): Malformed pattern line %d (file %s).\n", line, filename);
|
|
|
|
fclose(fd);
|
|
|
|
free(buffer);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((pt = strstr(start, " (Clam)")))
|
|
|
|
*pt = 0;
|
|
|
|
|
|
|
|
//printf("%s\n", start);
|
|
|
|
addVirusName(start);
|
|
|
|
|
|
|
|
free(start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(fd);
|
|
|
|
free(buffer);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int KlamDB::listdir(const char *dirname)
|
|
|
|
{
|
|
|
|
DIR *dd;
|
|
|
|
struct dirent *dent;
|
|
|
|
char *dbfile;
|
|
|
|
|
|
|
|
|
|
|
|
if((dd = opendir(dirname)) == NULL) {
|
|
|
|
printf("!Can't open directory %s\n", dirname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
while((dent = readdir(dd))) {
|
|
|
|
#ifndef C_INTERIX
|
|
|
|
if(dent->d_ino)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
|
|
|
|
(cli_strbcasestr(dent->d_name, ".db") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".hdb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".mdb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".ndb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".sdb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".zmd") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".rmd") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".inc") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".cvd"))) {
|
|
|
|
|
|
|
|
dbfile = (char *) calloc(strlen(dent->d_name) + strlen(dirname) + 2, sizeof(char));
|
|
|
|
|
|
|
|
if(!dbfile) {
|
|
|
|
printf("!listdir(): Can't allocate memory.\n");
|
|
|
|
closedir(dd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
sprintf(dbfile, "%s/%s", dirname, dent->d_name);
|
|
|
|
|
|
|
|
if(listdb(dbfile)) {
|
|
|
|
printf("!listdb(): error listing database %s\n", dbfile);
|
|
|
|
free(dbfile);
|
|
|
|
closedir(dd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
free(dbfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int KlamDB::checkdir(const char *dirname)
|
|
|
|
{
|
|
|
|
DIR *dd;
|
|
|
|
struct dirent *dent;
|
|
|
|
|
|
|
|
|
|
|
|
if((dd = opendir(dirname)) == NULL) {
|
|
|
|
printf("!Can't open directory %s\n", dirname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int found = 0;
|
|
|
|
while((dent = readdir(dd))) {
|
|
|
|
#ifndef C_INTERIX
|
|
|
|
if(dent->d_ino)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
|
|
|
|
(cli_strbcasestr(dent->d_name, ".db") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".hdb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".mdb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".ndb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".sdb") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".zmd") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".rmd") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".inc") ||
|
|
|
|
cli_strbcasestr(dent->d_name, ".cvd"))) {
|
|
|
|
found = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dd);
|
|
|
|
|
|
|
|
if (!(found))
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cli_untgz(int fd, const char *destdir)
|
|
|
|
{
|
|
|
|
char *fullname, osize[13], name[101], type;
|
|
|
|
char block[TAR_BLOCKSIZE];
|
|
|
|
int nbytes, nread, nwritten, in_block = 0;
|
|
|
|
unsigned int size;
|
|
|
|
FILE *outfile = NULL;
|
|
|
|
gzFile infile;
|
|
|
|
|
|
|
|
printf("in cli_untgz()\n");
|
|
|
|
|
|
|
|
if((infile = gzdopen(fd, "rb")) == NULL) {
|
|
|
|
printf("Can't gzdopen() descriptor %d\n", fd);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fullname = (char *) calloc(sizeof(char), strlen(destdir) + 100 + 5);
|
|
|
|
|
|
|
|
while(1) {
|
|
|
|
|
|
|
|
nread = gzread(infile, block, TAR_BLOCKSIZE);
|
|
|
|
|
|
|
|
if(!in_block && nread == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if(nread != TAR_BLOCKSIZE) {
|
|
|
|
printf("Incomplete block read.\n");
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!in_block) {
|
|
|
|
if (block[0] == '\0') /* We're done */
|
|
|
|
break;
|
|
|
|
|
|
|
|
strncpy(name, block, 100);
|
|
|
|
name[100] = '\0';
|
|
|
|
strcpy(fullname, destdir);
|
|
|
|
strcat(fullname, "/");
|
|
|
|
strcat(fullname, name);
|
|
|
|
printf("Unpacking %s\n",fullname);
|
|
|
|
type = block[156];
|
|
|
|
|
|
|
|
switch(type) {
|
|
|
|
case '0':
|
|
|
|
case '\0':
|
|
|
|
break;
|
|
|
|
case '5':
|
|
|
|
printf("Directories in CVD are not supported.\n");
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
return -1;
|
|
|
|
default:
|
|
|
|
printf("Unknown type flag %c.\n",type);
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
in_block = 1;
|
|
|
|
|
|
|
|
if(outfile) {
|
|
|
|
if(fclose(outfile)) {
|
|
|
|
printf("Cannot close file %s.\n", fullname);
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
outfile = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!(outfile = fopen(fullname, "wb"))) {
|
|
|
|
printf("Cannot create file %s.\n", fullname);
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(osize, block + 124, 12);
|
|
|
|
osize[12] = '\0';
|
|
|
|
|
|
|
|
if((sscanf(osize, "%o", &size)) == 0) {
|
|
|
|
printf("Invalid size in header.\n");
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
fclose(outfile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
} else { /* write or continue writing file contents */
|
|
|
|
nbytes = size > TAR_BLOCKSIZE ? TAR_BLOCKSIZE : size;
|
|
|
|
nwritten = fwrite(block, 1, nbytes, outfile);
|
|
|
|
|
|
|
|
if(nwritten != nbytes) {
|
|
|
|
printf("Wrote %d instead of %d (%s).\n", nwritten, nbytes, fullname);
|
|
|
|
free(fullname);
|
|
|
|
gzclose(infile);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
size -= nbytes;
|
|
|
|
if(size == 0)
|
|
|
|
in_block = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(outfile)
|
|
|
|
fclose(outfile);
|
|
|
|
|
|
|
|
gzclose(infile);
|
|
|
|
free(fullname);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cli_rmdirs(const char *dirname)
|
|
|
|
{
|
|
|
|
DIR *dd;
|
|
|
|
struct dirent *dent;
|
|
|
|
#if defined(HAVE_READDIR_R_3) || defined(HAVE_READDIR_R_2)
|
|
|
|
union {
|
|
|
|
struct dirent d;
|
|
|
|
char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
|
|
|
|
} result;
|
|
|
|
#endif
|
|
|
|
struct stat maind, statbuf;
|
|
|
|
char *fname;
|
|
|
|
|
|
|
|
|
|
|
|
chmod(dirname, 0700);
|
|
|
|
if((dd = opendir(dirname)) != NULL) {
|
|
|
|
while(stat(dirname, &maind) != -1) {
|
|
|
|
if(!rmdir(dirname)) break;
|
|
|
|
|
|
|
|
#ifdef HAVE_READDIR_R_3
|
|
|
|
while(!readdir_r(dd, &result.d, &dent) && dent) {
|
|
|
|
#elif defined(HAVE_READDIR_R_2)
|
|
|
|
while((dent = (struct dirent *) readdir_r(dd, &result.d))) {
|
|
|
|
#else
|
|
|
|
while((dent = readdir(dd))) {
|
|
|
|
#endif
|
|
|
|
#ifndef C_INTERIX
|
|
|
|
if(dent->d_ino)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
|
|
|
|
fname = (char *)calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
|
|
|
|
sprintf(fname, "%s/%s", dirname, dent->d_name);
|
|
|
|
|
|
|
|
/* stat the file */
|
|
|
|
if(lstat(fname, &statbuf) != -1) {
|
|
|
|
if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
|
|
|
|
if(rmdir(fname) == -1) { /* can't be deleted */
|
|
|
|
if(errno == EACCES) {
|
|
|
|
printf("Can't remove some temporary directories due to access problem.\n");
|
|
|
|
closedir(dd);
|
|
|
|
free(fname);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
cli_rmdirs(fname);
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
unlink(fname);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(fname);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rewinddir(dd);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
return 53;
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dd);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int cli_strbcasestr(const char *haystack, const char *needle)
|
|
|
|
{
|
|
|
|
char *pt = (char *) haystack;
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
i = strlen(haystack);
|
|
|
|
j = strlen(needle);
|
|
|
|
|
|
|
|
if(i < j)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
pt += i - j;
|
|
|
|
|
|
|
|
return !strcasecmp(pt, needle);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove trailing NL and CR characters from the end of the given string.
|
|
|
|
* Return the new length of the string (ala strlen)
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
cli_chomp(char *string)
|
|
|
|
{
|
|
|
|
int l;
|
|
|
|
|
|
|
|
if(string == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
l = strlen(string);
|
|
|
|
|
|
|
|
if(l == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
--l;
|
|
|
|
|
|
|
|
while((l >= 0) && ((string[l] == '\n') || (string[l] == '\r')))
|
|
|
|
string[l--] = '\0';
|
|
|
|
|
|
|
|
return l + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* char *cli_strok(const char *line, int fieldno, char *delim)
|
|
|
|
* Return a copy of field <fieldno> from the string <line>, where
|
|
|
|
* fields are delimited by any char from <delim>, or NULL if <line>
|
|
|
|
* doesn't have <fieldno> fields or not enough memory is available.
|
|
|
|
* The caller has to free() the result afterwards.
|
|
|
|
*/
|
|
|
|
char *cli_strtok(const char *line, int fieldno, const char *delim)
|
|
|
|
{
|
|
|
|
int counter = 0, i, j;
|
|
|
|
char *buffer = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/* step to arg # <fieldno> */
|
|
|
|
for (i=0; line[i] && counter != fieldno; i++) {
|
|
|
|
if (strchr(delim, line[i])) {
|
|
|
|
counter++;
|
|
|
|
while(line[i+1] && strchr(delim, line[i+1])) {
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!line[i]) {
|
|
|
|
/* end of buffer before field reached */
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (j=i; line[j]; j++) {
|
|
|
|
if (strchr(delim, line[j])) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i == j) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
buffer = (char *)malloc(j-i+1);
|
|
|
|
if(!buffer)
|
|
|
|
return NULL;
|
|
|
|
strncpy(buffer, line+i, j-i);
|
|
|
|
buffer[j-i] = '\0';
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::shouldIShow(TQWidget * current)
|
|
|
|
{
|
|
|
|
|
|
|
|
static struct cl_stat *dbstat=NULL;
|
|
|
|
TQString location;
|
|
|
|
|
|
|
|
if ((current == this) && (!(loadinprogress))){
|
|
|
|
TQString db = tdemain->freshklam->getCurrentDBDir();
|
|
|
|
|
|
|
|
if (checkdir((const char *)db) == -1){
|
|
|
|
kdDebug() << "returned -1" << endl;
|
|
|
|
location = locate("data", "klamav/about/nodb.html");
|
|
|
|
homepage->openURL(location);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ( ((cl_statchkdir(dbstat) == 1) || (dbstat == NULL))) {
|
|
|
|
location = locate("data", "klamav/about/wait.html");
|
|
|
|
homepage->openURL(location);
|
|
|
|
|
|
|
|
loadinprogress = true;
|
|
|
|
sigs = ( int )getSigNos();
|
|
|
|
progress = new KProgressDialog (this, "progress", i18n( "Loading .." ), i18n( "Loading..." ), true);
|
|
|
|
progress->setAllowCancel(false);
|
|
|
|
prog = progress->progressBar();
|
|
|
|
progress->setLabel(i18n( "Loading lots and lots and lots of virus information" ));
|
|
|
|
|
|
|
|
|
|
|
|
prog->setTotalSteps(sigs);
|
|
|
|
|
|
|
|
//kdDebug() << prog->totalSteps() << endl;
|
|
|
|
|
|
|
|
VirusList->hide();
|
|
|
|
if (VirusList->childCount() > 0)
|
|
|
|
VirusList->clear();
|
|
|
|
count = 0;
|
|
|
|
prog->setProgress (count);
|
|
|
|
kapp->processEvents();
|
|
|
|
|
|
|
|
// TQString db = tdemain->freshklam->getCurrentDBDir();
|
|
|
|
|
|
|
|
listdir((const char *)db);
|
|
|
|
|
|
|
|
|
|
|
|
prog->setProgress (sigs);
|
|
|
|
|
|
|
|
VirusList->show();
|
|
|
|
|
|
|
|
if(dbstat == NULL) {
|
|
|
|
dbstat = (struct cl_stat *) malloc(sizeof(struct cl_stat));
|
|
|
|
} else {
|
|
|
|
cl_statfree(dbstat);
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(dbstat, 0, sizeof(struct cl_stat));
|
|
|
|
|
|
|
|
cl_statinidir((const char *)db, dbstat);
|
|
|
|
|
|
|
|
|
|
|
|
loadinprogress = false;
|
|
|
|
// Default english
|
|
|
|
TQString location = locate( "data", "klamav/about/main-" + TDEGlobal::locale()->language() + ".html" );
|
|
|
|
if( location != TQString::null )
|
|
|
|
homepage->openURL( location );
|
|
|
|
else
|
|
|
|
homepage->openURL( locate("data", "klamav/about/main.html") );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::addVirusName(char *start)
|
|
|
|
{
|
|
|
|
|
|
|
|
count++;
|
|
|
|
|
|
|
|
kapp->processEvents();
|
|
|
|
if ((count % 500) == 0){
|
|
|
|
//progress->setLabel("Loading " + TQString(start));
|
|
|
|
progress->setLabel( i18n( "Loading ClamAV's Database of Virus Signatures") );
|
|
|
|
prog->setProgress (count);
|
|
|
|
kapp->processEvents();
|
|
|
|
}
|
|
|
|
new TDEListViewItem( VirusList, TQString(start));
|
|
|
|
kapp->processEvents();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int KlamDB::getSigNos()
|
|
|
|
{
|
|
|
|
|
|
|
|
unsigned int ret= 0;
|
|
|
|
unsigned int no = 0;
|
|
|
|
struct cl_engine *engine = NULL;
|
|
|
|
TQStringList lastDownloadPaths;
|
|
|
|
TQString dbdir;
|
|
|
|
TQString db;
|
|
|
|
|
|
|
|
TDEConfig* config = TDEGlobal::config();
|
|
|
|
config->setGroup("Freshklam");
|
|
|
|
lastDownloadPaths = config->readListEntry("lastDownloadPaths");
|
|
|
|
dbdir = lastDownloadPaths.first();
|
|
|
|
|
|
|
|
#ifdef SUPPORT_CLAMAV_V095
|
|
|
|
if((engine = cl_engine_new()) == NULL) {
|
|
|
|
printf("Database initialization error: %s\n", cl_strerror(ret));;
|
|
|
|
cl_engine_free(engine);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef SUPPORT_CLAMAV_V095
|
|
|
|
ret = cl_load((const char *)dbdir, engine, &no, CL_DB_STDOPT);
|
|
|
|
cl_engine_free(engine);
|
|
|
|
#else
|
|
|
|
ret = cl_load((const char *)dbdir, &engine, &no, CL_DB_STDOPT);
|
|
|
|
cl_free(engine);
|
|
|
|
#endif
|
|
|
|
kdDebug() << "no of sigs" << no << endl;
|
|
|
|
return no;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotOpenTab(TQListViewItem * item, const TQPoint& , int )
|
|
|
|
{
|
|
|
|
PageViewer* page = new PageViewer(this, "page");
|
|
|
|
//connect( m_part, SIGNAL(signalSettingsChanged()), page, SLOT(slotPaletteOrFontChanged()));
|
|
|
|
|
|
|
|
//connect( page, SIGNAL(setTabIcon(const TQPixmap&)),
|
|
|
|
// this, SLOT(setTabIcon(const TQPixmap&)));
|
|
|
|
//connect( page, SIGNAL(setWindowCaption (const TQString &)),
|
|
|
|
// this, SLOT(slotTabCaption (const TQString &)) );
|
|
|
|
connect( page, SIGNAL(urlClicked(const KURL &,bool)),
|
|
|
|
this, SLOT(slotOpenTabPlain(const KURL &,bool)) );
|
|
|
|
|
|
|
|
TQString url = item->text(0);
|
|
|
|
|
|
|
|
Frame *frame=new Frame(this, page, page->widget(), "VirusList : "+item->text(0));
|
|
|
|
//connectFrame(frame);
|
|
|
|
tabBrowser->addFrame(frame);
|
|
|
|
|
|
|
|
// if(!background)
|
|
|
|
tabBrowser->showPage(page->widget());
|
|
|
|
// else
|
|
|
|
setFocus();
|
|
|
|
|
|
|
|
//if (m_tabs->count() > 1 && m_tabs->currentPageIndex() != 0)
|
|
|
|
// m_tabsClose->setEnabled(true);
|
|
|
|
page->openURL("http://www.viruslist.com/en/find?search_mode=virus&words="+url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotOpenTabPlain(const KURL& url, bool background)
|
|
|
|
{
|
|
|
|
PageViewer* page = new PageViewer(this, "page");
|
|
|
|
//connect( m_part, SIGNAL(signalSettingsChanged()), page, SLOT(slotPaletteOrFontChanged()));
|
|
|
|
|
|
|
|
/* connect( page, SIGNAL(setTabIcon(const TQPixmap&)),
|
|
|
|
this, SLOT(setTabIcon(const TQPixmap&)));*/
|
|
|
|
connect( page, SIGNAL(setWindowCaption (const TQString &)),
|
|
|
|
this, SLOT(slotTabCaption (const TQString &)) );
|
|
|
|
connect( page, SIGNAL(urlClicked(const KURL &,bool)),
|
|
|
|
this, SLOT(slotOpenTabPlain(const KURL &,bool)) );
|
|
|
|
|
|
|
|
Frame *frame=new Frame(this, page, page->widget(), i18n("Untitled"));
|
|
|
|
//connectFrame(frame);
|
|
|
|
tabBrowser->addFrame(frame);
|
|
|
|
|
|
|
|
if(!background)
|
|
|
|
tabBrowser->showPage(page->widget());
|
|
|
|
else
|
|
|
|
setFocus();
|
|
|
|
|
|
|
|
//if (m_tabs->count() > 1 && m_tabs->currentPageIndex() != 0)
|
|
|
|
// m_tabsClose->setEnabled(true);
|
|
|
|
|
|
|
|
//kdDebug() << url << endl;
|
|
|
|
page->openURL(url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotTabCaption(const TQString &caption)
|
|
|
|
{
|
|
|
|
if (!caption.isEmpty())
|
|
|
|
{
|
|
|
|
PageViewer *pv=(PageViewer *)sender();
|
|
|
|
tabBrowser->setTitle(caption, pv->widget());
|
|
|
|
pv->slotSetCaption(caption);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotOpenHome()
|
|
|
|
{
|
|
|
|
homepage = new PageViewer(this, "page");
|
|
|
|
|
|
|
|
Frame *frame=new Frame(this, homepage, homepage->widget(), "Home");
|
|
|
|
//connectFrame(frame);
|
|
|
|
tabBrowser->addFrame(frame);
|
|
|
|
|
|
|
|
// if(!background)
|
|
|
|
tabBrowser->showPage(homepage->widget());
|
|
|
|
// else
|
|
|
|
setFocus();
|
|
|
|
|
|
|
|
TQString location = locate( "data", "klamav/about/wait-" + TDEGlobal::locale()->language() + ".html" );
|
|
|
|
if( location != TQString::null )
|
|
|
|
homepage->openURL( location );
|
|
|
|
else
|
|
|
|
homepage->openURL( locate("data", "klamav/about/wait.html") );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotRMB( TQListViewItem* Item, const TQPoint & point, int )
|
|
|
|
{
|
|
|
|
if( Item )
|
|
|
|
menu->popup( point );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotOpenPrefix(TQString prefix, TQString title,TQString url)
|
|
|
|
{
|
|
|
|
|
|
|
|
PageViewer* page = new PageViewer(this, "page");
|
|
|
|
|
|
|
|
|
|
|
|
Frame *frame=new Frame(this, page, page->widget(), title+" : "+url);
|
|
|
|
tabBrowser->addFrame(frame);
|
|
|
|
|
|
|
|
tabBrowser->showPage(page->widget());
|
|
|
|
setFocus();
|
|
|
|
|
|
|
|
page->openURL(prefix+url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotGoogle()
|
|
|
|
{
|
|
|
|
TQString url = KURL::encode_string( VirusList->selectedItem()->text(0) );
|
|
|
|
slotOpenPrefix(googlePrefix,"Google",url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotTrendMicro()
|
|
|
|
{
|
|
|
|
|
|
|
|
TQString url = KURL::encode_string( VirusList->selectedItem()->text(0) );
|
|
|
|
slotOpenPrefix(tMicroPrefix,"TrendMicro",url);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KlamDB::slotExternal(TQString name,TQString service)
|
|
|
|
{
|
|
|
|
tdemain->showVirusBrowser();
|
|
|
|
shouldIShow(this);
|
|
|
|
TQString prefix;
|
|
|
|
if (service == "Google")
|
|
|
|
prefix = googlePrefix;
|
|
|
|
else
|
|
|
|
prefix = tMicroPrefix;
|
|
|
|
slotOpenPrefix(prefix,service,name);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "dbviewer.moc"
|