Sorry for rather long response. On [08/21/03 20:46], Tomasz Kojm wrote: > On Wed, 20 Aug 2003 18:10:14 -0400 > No ! : > 1) under BSD the memory usage will be about 50 MB (_now_)
Don't know about BSD -- but on FreeBSD using default 2 levels, my
memory usage was 12MB while using 5 levels it was 48MB -- which is acceptible
to me.
While this memory usage is about 2x of usage on Linux, it's still
acceptible to me.
> 2) under higher level new signatures will cause a _BRUTAL_ memory
> usage because new nodes will be created for most signatures
> (there are only few signatures that have the same first 5
> characters)
I think _BRUTAL_ is pretty rough estimate. I also think if I have lots of
ram, it should be left up to me to decide whether I want to use 500 MB for
my database to gain XXX speed improvement.
The memory usage directly relates to the number of unique prefixes in the
database of length CL_MIN_LENGTH (i.e. the height of the trie).
If you think that the memory usage will increate exponentially, you are mistaken.
It will only increase exponentially in a database that has every possible
prefix exercised (255^(prefixlength))
As you increase the height, the number of unique prefixes does NOT increase
nearly as fast as you would think (this, of course depends on the database).
For example, here is a table with number of unique prefixes as you increase
levels from 1 - 5 (default database):
Level 1: Unique Prefixes: 254
Level 2: Unique Prefixes: 3529
Level 3: Unique Prefixes: 5080
Level 4: Unique Prefixes: 5894
Level 5: Unique Prefixes: 6347
As you can see, the increase is not nearly exponential. As a matter of fact,
as you add more levels, you're increase your memory usage by smaller, and
smaller percentage as compared to previous level increase.
> 3) higher levels brake some polymorphic signatures (eg. W32/Magistr.B,
> W32/Hybris.C), because we don't realize regular expressions in the
> trie
Please elaborate. I think poly viruses (even with short subpatterns) will
be detected just fine.
>
> Please create a _random_ signatures (using /dev/urandom or so) - I
> wonder if your virtual memory will hold a few clamscan process...
>
Now this is where you are not entire correct. Running scanners with
random database is a nice benchmark of WORST case scenario. However,
virus database is all but random -- you do have pattern prefixes
that occur more often the others.
Having said that, I ran my benchmarks with the database generated
from /dev/urandom, containing 100000 simple signatures with length
from 2 - 2048, and with 10000 poly signaturs each containing random
number of subpatterns from 2-10, and each subpattern having length
from 2-2048 bytes. The size of the database was 214 MB. I scanned
a 240 MB file w/out viruses.
Here is a result for default clamav-0.60:
Database | Mem | Real Time | Sys Time | User Time
---------------------------------------------------
Default DB| 6MB | 0m26.537s | 0m26.080s | 0m0.460s
Random DB|275MB| 6m1.162s | 5m54.050s | 0m0.870
To figure out how deep of a tree I want to have for huge database,
I ran dbstats.pl program (attached in earlier email), and got the following results:
Loading virus databes ... done
cl_node_size=1033 totalPatternMemusage=114588591
Level 1:
Unique Prefixes: 256
Avg Linked List Length: 468.75
Avg Linked List Length Descrease: 100.00%
Min Linked List Length: 419.00
Max Linked List Length: 531.00
Memory Usage: 111902.92 KB
Memory Usage Increase: 100.00%
Number of cl_node structures: 257
Level 2:
Unique Prefixes: 54996
Avg Linked List Length: 2.18
Avg Linked List Length Descrease: 99.53%
Min Linked List Length: 1.00
Max Linked List Length: 10.00
Memory Usage: 112162.18 KB
Memory Usage Increase: 0.23%
Number of cl_node structures: 55445
Level 3:
Unique Prefixes: 119561
Avg Linked List Length: 1.00
Avg Linked List Length Descrease: 54.13%
Min Linked List Length: 1.00
Max Linked List Length: 3.00
Memory Usage: 167835.23 KB
Memory Usage Increase: 33.17%
Number of cl_node structures: 175198
This told me, that there was NO need to go beyond level 3 because max linked list
length was 1.00 after 3 levels (optimal). Also notice that the improvement from Level
2,
to Level 3 is not that great in terms of linked list length reduction.
This make perfect sense: since the database was random, and it contained 110000 virus
definitions, the first 2 characters would uniquely identify 65K patterns -- more then
half. So, for this database, I would have configured clamav with 2 levels, but just
for the sake of argument, I ran it with 3 levels:
Here are the results:
Database | Mem | Real Time | Sys Time | User Time
----------------------------------------------------
Default DB|11MB | 0m7.095 | 0m6.430 | 0m0.440
Random DB|275MB| 6m12.710s | 6m10.350s | 0m1.070
So, with 3 levels on random db, clamav performed marginally slower then default
clamav,
which makes sense for the reaons described above -- i.e. there was no need to go
to 3 levels.
I will however generate a much larger database of about 500K virus definitions, and
rerun the stats. I have a feeling that 3 levels will run quite a bit nicer.
BTW, the stats were collected from a server running Linux 2.4.19:
Dual 2.7 GHz Xeon with 2 GB ram.
I'm attaching fixed clamav-0.60 patch if anybody's interested.
--
Eugene Miretskiy <[EMAIL PROTECTED]>
INVISION.COM, INC. (631) 543-1000
www.invision.net / www.longisland.com
diff -ru -x Makefile -x Makefile.in -x configure -x aclocal.m4 -x acinclude.m4
clamav-0.60/configure.in clamav-0.60.new/configure.in
--- clamav-0.60/configure.in Fri Jun 20 23:05:32 2003
+++ clamav-0.60.new/configure.in Fri Aug 22 12:13:45 2003
@@ -176,6 +176,13 @@
AC_SUBST(CFGDIR)
AC_DEFINE_UNQUOTED(CONFDIR,"$cfg_dir",)
+dnl search tree depth
+AC_ARG_WITH(depth,
+[ --with-depth=number number of levels in pattern search tree (default=2).],
+tree_depth=$withval, tree_depth=2)
+
+AC_DEFINE_UNQUOTED(CL_MIN_LENGTH,$tree_depth,)
+
dnl Do not overwrite the current config file
AM_CONDITIONAL(INSTALL_CONF, test ! -r "$cfg_dir/clamav.conf")
diff -ru -x Makefile -x Makefile.in -x configure -x aclocal.m4 -x acinclude.m4
clamav-0.60/libclamav/clamav.h clamav-0.60.new/libclamav/clamav.h
--- clamav-0.60/libclamav/clamav.h Wed Mar 15 20:05:00 2000
+++ clamav-0.60.new/libclamav/clamav.h Fri Aug 22 12:13:50 2003
@@ -30,7 +30,10 @@
#define CL_NUM_CHILDS 256
-#define CL_MIN_LENGTH 2
+
+#ifndef CL_MIN_LENGTH
+ #define CL_MIN_LENGTH 2
+#endif
#define CL_COUNT_PRECISION 4096
@@ -70,15 +73,12 @@
struct patt *next;
};
+extern unsigned int maxpatlen, partsigs, nodes;
+
struct cl_node {
char islast;
struct patt *list;
struct cl_node *trans[CL_NUM_CHILDS], *fail;
-
- /* FIXME: these variables are only used in the root node */
- unsigned int maxpatlen, partsigs;
- unsigned int nodes;
- struct cl_node **nodetable;
};
struct cl_limits {
diff -ru -x Makefile -x Makefile.in -x configure -x aclocal.m4 -x acinclude.m4
clamav-0.60/libclamav/matcher.c clamav-0.60.new/libclamav/matcher.c
--- clamav-0.60/libclamav/matcher.c Sun Jan 9 17:15:00 2000
+++ clamav-0.60.new/libclamav/matcher.c Fri Aug 22 12:13:50 2003
@@ -32,33 +32,30 @@
#include "unrarlib.h"
#include "defaults.h"
+static struct cl_node **nodetable;
int cli_addpatt(struct cl_node *root, struct patt *pattern)
{
struct cl_node *pos, *next;
int i;
- if(pattern->length < CL_MIN_LENGTH) {
- return CL_EPATSHORT;
- }
-
pos = root;
- for(i = 0; i < CL_MIN_LENGTH; i++) {
- next = pos->trans[((unsigned char) pattern->pattern[i]) & 0xff];
+ for(i = 0; i < CL_MIN_LENGTH && i < pattern->length; i++) {
+ next = pos->trans[((unsigned char) pattern->pattern[i]) & 0xff];
- if(!next) {
+ if(!next) {
next = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node));
if(!next)
- return CL_EMEM;
+ return CL_EMEM;
- root->nodes++;
- root->nodetable = (struct cl_node **) realloc(root->nodetable,
(root->nodes) * sizeof(struct cl_node *));
- root->nodetable[root->nodes - 1] = next;
+ nodes++;
+ nodetable = (struct cl_node **) realloc(nodetable, nodes * sizeof(struct
cl_node *));
+ nodetable[nodes - 1] = next;
pos->trans[((unsigned char) pattern->pattern[i]) & 0xff] = next;
- }
-
- pos = next;
+ }
+
+ pos = next;
}
pos->islast = 1;
@@ -117,8 +114,6 @@
cli_enqueue(&bfs, root);
while((node = cli_dequeue(&bfs))) {
- if(node->islast)
- continue;
for(i = 0; i < CL_NUM_CHILDS; i++) {
child = node->trans[i];
@@ -164,12 +159,12 @@
{
int i;
- for(i = 0; i < root->nodes; i++) {
- cli_freepatt(root->nodetable[i]->list);
- free(root->nodetable[i]);
+ for(i = 0; i < nodes; i++) {
+ cli_freepatt(nodetable[i]->list);
+ free(nodetable[i]);
}
- free(root->nodetable);
+ free(nodetable);
free(root);
}
@@ -177,68 +172,64 @@
{
struct cl_node *current;
struct patt *pt;
- int i, position, *partcnt;
+ int i, position, *partcnt;
current = (struct cl_node *) root;
- partcnt = (int *) cli_calloc(root->partsigs + 1, sizeof(int));
+ partcnt = (int *) cli_calloc(partsigs + 1, sizeof(int));
for(i = 0; i < length; i++) {
- current = current->trans[(unsigned char) buffer[i] & 0xff];
+ current = current->trans[(unsigned char) buffer[i] & 0xff];
- if(current->islast) {
+ if(current->islast) {
position = i - CL_MIN_LENGTH + 1;
-
pt = current->list;
+
while(pt) {
- if(cli_findpos(buffer, position, length, pt)) {
- if(pt->sigid) { /* it's a partial signature */
- if(partcnt[pt->sigid] + 1 == pt->partno) {
+ if(pt->length < CL_MIN_LENGTH || cli_findpos(buffer, position, length, pt))
{
+ if(pt->sigid) { /* it's a partial signature */
+ if(partcnt[pt->sigid] + 1 == pt->partno) {
if(++partcnt[pt->sigid] == pt->parts) { /* last */
- if(virname)
+ if(virname)
*virname = pt->virname;
- free(partcnt);
- return CL_VIRUS;
+ free(partcnt);
+ return CL_VIRUS;
}
- }
- } else { /* old type signature */
- if(virname)
+ }
+ } else {
+ if(virname)
*virname = pt->virname;
- free(partcnt);
- return CL_VIRUS;
+ free(partcnt);
+ return CL_VIRUS;
}
- }
+ }
- pt = pt->next;
+ pt = pt->next;
}
current = current->fail;
- }
+ }
}
free(partcnt);
return CL_CLEAN;
}
-int cli_findpos(const char *buffer, int offset, int length, const struct patt
*pattern)
-{
- int bufferpos = offset + CL_MIN_LENGTH;
- int postfixend = offset + length;
- int i;
-
-
- for(i = CL_MIN_LENGTH; i < pattern->length; i++) {
- bufferpos %= length;
- if(bufferpos == postfixend)
- return 0;
+int cli_findpos(const char *buffer, int offset, int length, const struct patt
*pattern)
+{
+ int bufferpos = offset + CL_MIN_LENGTH;
+ int i;
- if(pattern->pattern[i] != CLI_IGN && (char) pattern->pattern[i] !=
buffer[bufferpos])
- return 0;
+ for(i = CL_MIN_LENGTH; i < pattern->length; i++) {
- bufferpos++;
+ if(pattern->pattern[i] != CLI_IGN && (char) pattern->pattern[i] !=
buffer[bufferpos]) {
+ return 0;
}
- return 1;
+ bufferpos++;
+
+ }
+ return 1;
}
diff -ru -x Makefile -x Makefile.in -x configure -x aclocal.m4 -x acinclude.m4
clamav-0.60/libclamav/readdb.c clamav-0.60.new/libclamav/readdb.c
--- clamav-0.60/libclamav/readdb.c Fri Jun 20 13:56:17 2003
+++ clamav-0.60.new/libclamav/readdb.c Fri Aug 22 12:37:00 2003
@@ -34,68 +34,70 @@
#include "str.h"
#include "defaults.h"
+unsigned int maxpatlen=0, partsigs=0, nodes=0;
+
int cli_parse_add(struct cl_node *root, const char *virname, const char *hexstr, int
sigid, int parts, int partno)
{
- struct patt *new;
- const char *pt;
- int ret, virlen;
+ struct patt *new;
+ const char *pt;
+ int ret, virlen;
- /* decode a hexstring and prepare a new entry */
+ /* decode a hexstring and prepare a new entry */
- if((new = (struct patt *) cli_calloc(1, sizeof(struct patt))) == NULL)
+ if((new = (struct patt *) cli_calloc(1, sizeof(struct patt))) == NULL)
return CL_EMEM;
- new->sigid = sigid;
- new->parts = parts;
- new->partno = partno;
+ new->sigid = sigid;
+ new->parts = parts;
+ new->partno = partno;
- new->length = strlen(hexstr) / 2;
+ new->length = strlen(hexstr) / 2;
- if(new->length > root->maxpatlen)
- root->maxpatlen = new->length;
+ if(new->length > maxpatlen)
+ maxpatlen = new->length;
- if((new->pattern = cl_hex2str(hexstr)) == NULL) {
+ if((new->pattern = cl_hex2str(hexstr)) == NULL) {
free(new);
return CL_EMALFDB;
- }
+ }
- if((pt = strstr(virname, "(Clam)")))
+ if((pt = strstr(virname, "(Clam)")))
virlen = strlen(virname) - strlen(pt) - 1;
- else
+ else
virlen = strlen(virname);
- if((new->virname = cli_calloc(virlen + 1, sizeof(char))) == NULL)
+ if((new->virname = cli_calloc(virlen + 1, sizeof(char))) == NULL)
return CL_EMEM;
- strncpy(new->virname, virname, virlen);
+ strncpy(new->virname, virname, virlen);
- if((ret = cli_addpatt(root, new)))
+ if((ret = cli_addpatt(root, new)))
return ret;
- return 0;
+ return 0;
}
/* this functions returns a pointer to the root of trie */
int cl_loaddb(const char *filename, struct cl_node **root, int *virnum)
{
- FILE *fd;
- char buffer[BUFFSIZE], *pt, *start, *pt2;
- int line = 0, ret, parts, i, sigid = 0;
+ FILE *fd;
+ char buffer[BUFFSIZE], *pt, *start, *pt2;
+ int line = 0, ret, parts, i, sigid = 0;
- if((fd = fopen(filename, "rb")) == NULL) {
+ if((fd = fopen(filename, "rb")) == NULL) {
cli_errmsg("cl_loaddb(): Can't open file %s\n", filename);
return CL_EOPEN;
- }
+ }
- cli_dbgmsg("Loading %s\n", filename);
+ cli_dbgmsg("Loading %s\n", filename);
- while(fgets(buffer, BUFFSIZE, fd)) {
+ while(fgets(buffer, BUFFSIZE, fd)) {
/* for forward compatibility */
if(strchr(buffer, '{') || strchr(buffer, '}')) {
- cli_dbgmsg("Not suported signature type detected at line %d. Skipping.\n",
line);
- continue;
+ cli_dbgmsg("Not suported signature type detected at line %d. Skipping.\n",
line);
+ continue;
}
line++;
@@ -103,8 +105,8 @@
pt = strchr(buffer, '=');
if(!pt) {
- cli_errmsg("readdb(): Malformed pattern line %d (file %s).\n", line,
filename);
- return CL_EMALFDB;
+ cli_errmsg("readdb(): Malformed pattern line %d (file %s).\n", line, filename);
+ return CL_EMALFDB;
}
start = buffer;
@@ -113,199 +115,203 @@
if(*pt == '=') continue;
if(!*root) {
- cli_dbgmsg("Initializing trie.\n");
- *root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node));
- if(!*root)
+ cli_dbgmsg("Initializing trie.\n");
+ *root = (struct cl_node *) cli_calloc(1, sizeof(struct cl_node));
+ if(!*root)
return CL_EMEM;
- (*root)->maxpatlen = 0;
+
+ maxpatlen = 0;
+ partsigs = 0;
+ nodes = 0;
}
if(strchr(pt, '*')) { /* new type signature */
- (*root)->partsigs++;
- sigid++;
- parts = 0;
- for(i = 0; i < strlen(pt); i++)
+ partsigs++;
+ sigid++;
+ parts = 0;
+ for(i = 0; i < strlen(pt); i++)
if(pt[i] == '*')
- parts++;
+ parts++;
- if(parts) /* there's always one part more */
+ if(parts) /* there's always one part more */
parts++;
- for(i = 1; i <= parts; i++) {
+ for(i = 1; i <= parts; i++) {
pt2 = cli_tok(pt, i, '*');
if((ret = cli_parse_add(*root, start, pt2, sigid, parts, i))) {
- cli_dbgmsg("parse_add() return code: %d\n", ret);
- cli_errmsg("readdb(): Malformed pattern line %d (file %s).\n",
line, filename);
- return ret;
+ cli_dbgmsg("parse_add() return code: %d\n", ret);
+ cli_errmsg("readdb(): Malformed pattern line %d (file %s).\n", line,
filename);
+ return ret;
}
//cli_dbgmsg("Added part %d of partial signature (id %d)\n", i, sigid);
free(pt2);
- }
+ }
} else { /* old type */
- if((ret = cli_parse_add(*root, start, pt, 0, 0, 0))) {
+ if((ret = cli_parse_add(*root, start, pt, 0, 0, 0))) {
cli_dbgmsg("parse_add() return code: %d\n", ret);
cli_errmsg("readdb(): Malformed pattern line %d (file %s).\n", line,
filename);
return ret;
- }
+ }
}
- }
+ }
- fclose(fd);
- if(virnum != NULL)
+ fclose(fd);
+ if(virnum != NULL)
*virnum += line;
- return 0;
+ return 0;
}
+
char *cl_retdbdir(void)
{
- return DATADIR;
+ return DATADIR;
}
int cl_loaddbdir(const char *dirname, struct cl_node **root, int *virnum)
{
- DIR *dd;
- struct dirent *dent;
- char *dbfile;
- int ret;
+ DIR *dd;
+ struct dirent *dent;
+ char *dbfile;
+ int ret;
- if(virnum != NULL)
+ if(virnum != NULL)
*virnum = 0;
- if((dd = opendir(dirname)) == NULL) {
- cli_errmsg("cl_loaddbdir(): Can't open directory %s\n", dirname);
- return CL_EOPEN;
- }
+ if((dd = opendir(dirname)) == NULL) {
+ cli_errmsg("cl_loaddbdir(): Can't open directory %s\n", dirname);
+ return CL_EOPEN;
+ }
- cli_dbgmsg("Loading databases from %s\n", dirname);
+ cli_dbgmsg("Loading databases from %s\n", dirname);
- while((dent = readdir(dd))) {
+ while((dent = readdir(dd))) {
if(dent->d_ino) {
- if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
+ if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
dbfile = (char *) cli_calloc(strlen(dent->d_name) + strlen(dirname) +
2, sizeof(char));
if(!dbfile) {
- cli_dbgmsg("cl_loaddbdir() -> dbfile == NULL\n");
- closedir(dd);
- return CL_EMEM;
+ cli_dbgmsg("cl_loaddbdir() -> dbfile == NULL\n");
+ closedir(dd);
+ return CL_EMEM;
}
sprintf(dbfile, "%s/%s", dirname, dent->d_name);
if((ret = cl_loaddb(dbfile, root, virnum))) {
- free(dbfile);
- closedir(dd);
- return ret;
+ free(dbfile);
+ closedir(dd);
+ return ret;
}
free(dbfile);
- }
+ }
}
- }
+ }
- closedir(dd);
- return 0;
+ closedir(dd);
+ return 0;
}
int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
{
- DIR *dd;
- struct dirent *dent;
- char *fname;
+ DIR *dd;
+ struct dirent *dent;
+ char *fname;
- if(dbstat) {
+ if(dbstat) {
dbstat->no = 0;
dbstat->stattab = NULL;
dbstat->dir = strdup(dirname);
- } else {
- cli_errmsg("cl_statdbdir(): Null argument passed.\n");
+ } else {
+ cli_errmsg("cl_statdbdir(): Null argument passed.\n");
return CL_ENULLARG;
- }
+ }
- if((dd = opendir(dirname)) == NULL) {
- cli_errmsg("cl_statdbdir(): Can't open directory %s\n", dirname);
- return CL_EOPEN;
- }
+ if((dd = opendir(dirname)) == NULL) {
+ cli_errmsg("cl_statdbdir(): Can't open directory %s\n", dirname);
+ return CL_EOPEN;
+ }
- cli_dbgmsg("Stat()ing files in %s\n", dirname);
+ cli_dbgmsg("Stat()ing files in %s\n", dirname);
- while((dent = readdir(dd))) {
+ while((dent = readdir(dd))) {
if(dent->d_ino) {
- if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
+ if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
dbstat->no++;
dbstat->stattab = (struct stat *) realloc(dbstat->stattab, dbstat->no
* sizeof(struct stat));
- fname = cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2,
sizeof(char));
+ fname = cli_calloc(strlen(dirname) + strlen(dent->d_name) + 2, sizeof(char));
sprintf(fname, "%s/%s", dirname, dent->d_name);
stat(fname, &dbstat->stattab[dbstat->no - 1]);
free(fname);
- }
+ }
}
- }
+ }
- closedir(dd);
- return 0;
+ closedir(dd);
+ return 0;
}
int cl_statchkdir(const struct cl_stat *dbstat)
{
- DIR *dd;
- struct dirent *dent;
- struct stat sb;
- int i, found;
- char *fname;
+ DIR *dd;
+ struct dirent *dent;
+ struct stat sb;
+ int i, found;
+ char *fname;
- if(!dbstat || !dbstat->dir) {
- cli_errmsg("cl_statdbdir(): Null argument passed.\n");
+ if(!dbstat || !dbstat->dir) {
+ cli_errmsg("cl_statdbdir(): Null argument passed.\n");
return CL_ENULLARG;
- }
+ }
- if((dd = opendir(dbstat->dir)) == NULL) {
- cli_errmsg("cl_statdbdir(): Can't open directory %s\n", dbstat->dir);
- return CL_EOPEN;
- }
+ if((dd = opendir(dbstat->dir)) == NULL) {
+ cli_errmsg("cl_statdbdir(): Can't open directory %s\n", dbstat->dir);
+ return CL_EOPEN;
+ }
- cli_dbgmsg("Stat()ing files in %s\n", dbstat->dir);
+ cli_dbgmsg("Stat()ing files in %s\n", dbstat->dir);
- while((dent = readdir(dd))) {
+ while((dent = readdir(dd))) {
if(dent->d_ino) {
- if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
+ if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") &&
(cli_strbcasestr(dent->d_name, ".db") || cli_strbcasestr(dent->d_name, ".db2"))) {
- fname = cli_calloc(strlen(dbstat->dir) + strlen(dent->d_name) + 2,
sizeof(char));
+ fname = cli_calloc(strlen(dbstat->dir) + strlen(dent->d_name) + 2,
sizeof(char));
sprintf(fname, "%s/%s", dbstat->dir, dent->d_name);
stat(fname, &sb);
free(fname);
found = 0;
for(i = 0; i < dbstat->no; i++)
- if(dbstat->stattab[i].st_ino == sb.st_ino) {
+ if(dbstat->stattab[i].st_ino == sb.st_ino) {
found = 1;
if(dbstat->stattab[i].st_mtime != sb.st_mtime)
- return 1;
- }
+ return 1;
+ }
if(!found)
- return 1;
- }
+ return 1;
+ }
}
- }
+ }
- closedir(dd);
- return 0;
+ closedir(dd);
+ return 0;
}
int cl_statfree(struct cl_stat *dbstat)
{
- if(dbstat) {
+ if(dbstat) {
free(dbstat->stattab);
dbstat->stattab = NULL;
dbstat->no = 0;
if(dbstat->dir)
- free(dbstat->dir);
- } else {
- cli_errmsg("cl_statfree(): Null argument passed.\n");
+ free(dbstat->dir);
+ } else {
+ cli_errmsg("cl_statfree(): Null argument passed.\n");
return CL_ENULLARG;
- }
+ }
- return 0;
+ return 0;
}
diff -ru -x Makefile -x Makefile.in -x configure -x aclocal.m4 -x acinclude.m4
clamav-0.60/libclamav/scanners.c clamav-0.60.new/libclamav/scanners.c
--- clamav-0.60/libclamav/scanners.c Thu Jun 19 21:37:31 2003
+++ clamav-0.60.new/libclamav/scanners.c Fri Aug 22 12:13:51 2003
@@ -67,14 +67,14 @@
/* prepare the buffer */
- buffsize = root->maxpatlen + BUFFSIZE;
+ buffsize = maxpatlen + BUFFSIZE;
if(!(buffer = (char *) cli_calloc(buffsize, sizeof(char))))
return CL_EMEM;
buff = buffer;
- buff += root->maxpatlen; /* pointer to read data block */
- endbl = buff + BUFFSIZE - root->maxpatlen; /* pointer to the last block
- * length of root->maxpatlen
+ buff += maxpatlen; /* pointer to read data block */
+ endbl = buff + BUFFSIZE - maxpatlen; /* pointer to the last block
+ * length of maxpatlen
*/
pt= buff;
@@ -94,7 +94,7 @@
}
if(bytes == BUFFSIZE)
- memmove(buffer, endbl, root->maxpatlen);
+ memmove(buffer, endbl, maxpatlen);
pt = buffer;
length=buffsize;
pgp00000.pgp
Description: PGP signature
