next up previous contents
Next: Database reloading Up: LibClamAV Previous: LibClamAV   Contents

General API

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 up previous contents
Next: Database reloading Up: LibClamAV Previous: LibClamAV   Contents
Tomasz Kojm 2004-02-11