Next: Database reloading
Up: LibClamAV
Previous: LibClamAV
  Contents
Every program based on libclamav must include the clamav.h header
file:
#include <clamav.h>
A first step is to initialize the scanning engine. There are three
functions available:
int cl_loaddb(const char *filename, struct cl_node **root,
int *virnum);
int cl_loaddbdir(const char *dirname, struct cl_node **root,
int *virnum);
char *cl_retdbdir(void);
cl_loaddb() loads a particular database, cl_loaddbdir()
loads all .cvd (and older .db, .db2) databases from a
directory dirname. cl_retdbdir() returns a hardcoded
database directory path. Initial internal database (Aho-Corasick tree,
trie; see 6.3) will be saved under root and a number of
signatures loaded will be added 7 to virnum. Pointer to the trie
must initially point to NULL. If you don't care about number of signatures
pass NULL as a third argument. cl_loaddb functions return 0 on
success and other value on failure.
struct cl_node *root = NULL;
int ret;
ret = cl_loaddbdir(cl_retdbdir(), &root, NULL);
There's an elegant way to print libclamav's error codes:
char *cl_strerror(int clerror);
cl_strerror() returns a (statically allocated) string describing
a clerror code:
if(ret) {
printf("cl_loaddbdir() error: %s\n", cl_strerror(ret));
exit(1);
}
When database is loaded you must build the final trie with:
void cl_buildtrie(struct cl_node *root);
In our example:
cl_buildtrie(root);
OK, now you can scan a buffer, a descriptor or a file with:
int cl_scanbuff(const char *buffer, unsigned int length,
char **virname, const struct cl_node *root);
int cl_scandesc(int desc, char **virname, unsigned long int
*scanned, const struct cl_node *root, const struct cl_limits
*limits, int options);
int cl_scanfile(const char *filename, char **virname,
unsigned long int *scanned, const struct cl_node *root,
const struct cl_limits *limits, int options);
All the functions save a virus name address under virname pointer.
virname points to a name in the trie structure thus it can't be
released directly. cl_scandesc() and cl_scanfile() can
increase the scanned value in CL_COUNT_PRECISION units, they also
support archive limits:
struct cl_limits {
int maxreclevel;
int maxfiles;
long int maxfilesize;
};
The last argument configures scan engine. Currently it supports
CL_ARCHIVE (enables archive scanning), CL_RAW
(disables archive scanning) and CL_MAIL (enables mbox
and Maildir scanning) and CL_DISABLERAR (disables the built-in
RAR unpacker which leaks like hell). These functions return 0
(CL_CLEAN) when no virus is found, CL_VIRUS when virus
is found and other value on failure.
struct cl_limits limits;
char *virname;
memset(&limits, 0, sizeof(struct cl_limits));
/* maximal number of files in archive */;
limits.maxfiles = 1000
/* maximal archived file size == 10 MB */
limits.maxfilesize = 10 * 1048576;
/* maximal recursion level */
limits.maxreclevel = 5;
if((ret = cl_scanfile("/home/zolw/test", &virname, NULL, root,
&limits, CL_ARCHIVE)) == CL_VIRUS) {
printf("Detected %s virus.\n", virname);
} else {
printf("No virus detected.\n");
if(ret != CL_CLEAN)
printf("Error: %s\n", cl_strerror(ret));
}
Release the trie if you no longer need it:
void cl_freetrie(struct cl_node *root);
You will find an example scanner in clamav sources (/example). Program
based on libclamav must be linked against it:
gcc -Wall ex1.c -o ex1 -lclamav
Enjoy !
Next: Database reloading
Up: LibClamAV
Previous: LibClamAV
  Contents
Tomasz Kojm
2004-02-11