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);

	const 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 8 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 an 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:
	const 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:
	int cl_buildtrie(struct cl_node *root);
In our example:
	if((ret = cl_buildtrie(root)))
	    printf("cl_buildtrie() error: %s\n", cl_strerror(ret));
    
Now you can scan a buffer, a descriptor or a file with:
	int cl_scanbuff(const char *buffer, unsigned int length,
	const char **virname, const struct cl_node *root);

	int cl_scandesc(int desc, const char **virname, unsigned
	long int *scanned, const struct cl_node *root, const
	struct cl_limits *limits, int options);

	int cl_scanfile(const char *filename, const 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. It 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; /* maximal recursion level */
	    int maxfiles; /* maximal number of files to be
			   * scanned within an archive
			   */
	    int maxratio; /* maximal compression ratio */
	    short archivememlim; /* limit memory usage for bzip2 (0/1) */
	    long int maxfilesize; /* files in an archive larger than
				   * this value will not be scanned
				   */
	};
The last argument in the cl_scan family configures the scan engine. It supports the following flags: All functions return 0 (CL_CLEAN) if the file is clean, CL_VIRUS when virus is detected and an other value on failure.
	    struct cl_limits limits;
	    const 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;
	/* maximal compression ratio */
	limits.maxratio = 200;
	/* disable memory limit for bzip2 scanner */
	limits.archivememlim = 0;

	if((ret = cl_scanfile("/home/zolw/test", &virname, NULL, root,
	&limits, CL_ARCHIVE | CL_MAIL | CL_OLE2)) == 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). All programs 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-06-14