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;

Attachment: pgp00000.pgp
Description: PGP signature

Reply via email to