BOOL WINAPI cw_stop_ctrl_handler(DWORD CtrlType) { double mb; if (CtrlType == CTRL_C_EVENT) { SetConsoleCtrlHandler(cw_stop_ctrl_handler, FALSE); logg("\nScanning aborted...\n"); logg("\n----------- SCAN SUMMARY -----------\n"); logg("Known viruses: %u\n", info.sigs); logg("Engine version: %s\n", cl_retver()); logg("Scanned directories: %u\n", info.dirs); logg("Scanned files: %u\n", info.files); logg("Infected files: %u\n", info.ifiles); if(info.errors) logg("Total errors: %u\n", info.errors); if(notremoved) logg("Not removed: %u\n", notremoved); if(notmoved) logg("Not moved: %u\n", notmoved); mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0; logg("Data scanned: %2.2lf MB\n", mb); exit(1); } return TRUE; }
END_TEST #ifndef REPO_VERSION #define REPO_VERSION VERSION #endif /* extern const char *cl_retver(void); */ START_TEST (test_cl_retver) { const char *ver = cl_retver(); fail_unless(!strcmp(REPO_VERSION""VERSION_SUFFIX, ver),"cl_retver"); fail_unless(strcspn(ver,"012345789") < strlen(ver), "cl_retver must have a number"); }
static void print_commands(int desc, char term, const struct cl_engine *engine) { unsigned i, n; const char *engine_ver = cl_retver(); const char *clamd_ver = get_version(); if (strcmp(engine_ver, clamd_ver)) { mdprintf(desc, "ENGINE VERSION MISMATCH: %s != %s. ERROR%c", engine_ver, clamd_ver, term); return; } print_ver(desc, '|', engine); mdprintf(desc, " COMMANDS:"); n = sizeof(commands)/sizeof(commands[0]); for (i=0;i<n;i++) { mdprintf(desc, " %s", commands[i].cmd); } mdprintf(desc, "%c", term); }
/* Display summary on Ctrl+C, --no-summary is not honored here :( */ void clamscan_ctrl_handler(DWORD ctrl_type) { double mb; logg("\nScanning aborted...\n"); logg("\n----------- SCAN SUMMARY -----------\n"); logg("Known viruses: %u\n", info.sigs); logg("Engine version: %s\n", cl_retver()); logg("Scanned directories: %u\n", info.dirs); logg("Scanned files: %u\n", info.files); logg("Infected files: %u\n", info.ifiles); if(info.notremoved) logg("Not removed: %u\n", info.notremoved); if(info.notmoved) logg("Not moved: %u\n", info.notmoved); mb = info.blocks * (CL_COUNT_PRECISION / 1024) / 1024.0; logg("Data scanned: %2.2lf MB\n", mb); exit(1); }
int init_virusdb() { int ret; unsigned int no = 0; virusdb = malloc(sizeof(struct virus_db)); memset(virusdb, 0, sizeof(struct virus_db)); if (!virusdb) return 0; #ifdef HAVE_LIBCLAMAV_095 if((ret = cl_init(CL_INIT_DEFAULT))) { ci_debug_printf(1, "!Can't initialize libclamav: %s\n", cl_strerror(ret)); return 0; } if(!(virusdb->db = cl_engine_new())) { ci_debug_printf(1, "Clamav DB load: Cannot create new clamav engine\n"); return 0; } if ((ret = cl_load(cl_retdbdir(), virusdb->db, &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB load: cl_load failed: %s\n", cl_strerror(ret)); #elif defined(HAVE_LIBCLAMAV_09X) if ((ret = cl_load(cl_retdbdir(), &(virusdb->db), &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB load: cl_load failed: %s\n", cl_strerror(ret)); #else if ((ret = cl_loaddbdir(cl_retdbdir(), &(virusdb->db), &no))) { ci_debug_printf(1, "cl_loaddbdir: %s\n", cl_perror(ret)); #endif return 0; } #ifdef HAVE_LIBCLAMAV_095 if ((ret = cl_engine_compile(virusdb->db))) { #else if ((ret = cl_build(virusdb->db))) { #endif ci_debug_printf(1, "Database initialization error: %s\n", cl_strerror(ret)); #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(virusdb->db); #else cl_free(virusdb->db); #endif free(virusdb); virusdb = NULL; return 0; } ci_thread_mutex_init(&db_mutex); virusdb->refcount = 1; old_virusdb = NULL; return 1; } /* Instead of using struct virus_db and refcount's someone can use the cl_dup function of clamav library, but it is undocumented so I did not use it. The following implementation we are starting to reload clamav db while threads are scanning for virus but we are not allow any child to start a new scan until we are loading DB. */ /*#define DB_NO_FULL_LOCK 1*/ #undef DB_NO_FULL_LOCK int reload_virusdb() { struct virus_db *vdb = NULL; int ret; unsigned int no = 0; ci_thread_mutex_lock(&db_mutex); if (old_virusdb) { ci_debug_printf(1, "Clamav DB reload pending, cancelling.\n"); ci_thread_mutex_unlock(&db_mutex); return 0; } #ifdef DB_NO_FULL_LOCK ci_thread_mutex_unlock(&db_mutex); #endif vdb = malloc(sizeof(struct virus_db)); if (!vdb) return 0; memset(vdb, 0, sizeof(struct virus_db)); ci_debug_printf(9, "db_reload going to load db\n"); #ifdef HAVE_LIBCLAMAV_095 if(!(vdb->db = cl_engine_new())) { ci_debug_printf(1, "Clamav DB load: Cannot create new clamav engine\n"); return 0; } if ((ret = cl_load(cl_retdbdir(), vdb->db, &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB reload: cl_load failed: %s\n", cl_strerror(ret)); #elif defined(HAVE_LIBCLAMAV_09X) if ((ret = cl_load(cl_retdbdir(), &(vdb->db), &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB reload: cl_load failed: %s\n", cl_strerror(ret)); #else if ((ret = cl_loaddbdir(cl_retdbdir(), &(vdb->db), &no))) { ci_debug_printf(1, "Clamav DB reload: cl_loaddbdir failed: %s\n", cl_perror(ret)); #endif return 0; } ci_debug_printf(9, "loaded. Going to build\n"); #ifdef HAVE_LIBCLAMAV_095 if ((ret = cl_engine_compile(vdb->db))) { #else if ((ret = cl_build(vdb->db))) { #endif ci_debug_printf(1, "Clamav DB reload: Database initialization error: %s\n", cl_strerror(ret)); #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(vdb->db); #else cl_free(vdb->db); #endif free(vdb); vdb = NULL; #ifdef DB_NO_FULL_LOCK /*no lock needed */ #else ci_thread_mutex_unlock(&db_mutex); #endif return 0; } ci_debug_printf(9, "Done releasing.....\n"); #ifdef DB_NO_FULL_LOCK ci_thread_mutex_lock(&db_mutex); #endif old_virusdb = virusdb; old_virusdb->refcount--; ci_debug_printf(9, "Old VirusDB refcount:%d\n", old_virusdb->refcount); if (old_virusdb->refcount <= 0) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } virusdb = vdb; virusdb->refcount = 1; ci_thread_mutex_unlock(&db_mutex); return 1; } CL_ENGINE *get_virusdb() { struct virus_db *vdb; ci_thread_mutex_lock(&db_mutex); vdb = virusdb; vdb->refcount++; ci_thread_mutex_unlock(&db_mutex); return vdb->db; } void release_virusdb(CL_ENGINE * db) { ci_thread_mutex_lock(&db_mutex); if (virusdb && db == virusdb->db) virusdb->refcount--; else if (old_virusdb && (db == old_virusdb->db)) { old_virusdb->refcount--; ci_debug_printf(9, "Old VirusDB refcount: %d\n", old_virusdb->refcount); if (old_virusdb->refcount <= 0) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } } else { ci_debug_printf(1, "BUG in srv_clamav service! please contact the author\n"); } ci_thread_mutex_unlock(&db_mutex); } void destroy_virusdb() { if (virusdb) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(virusdb->db); #else cl_free(virusdb->db); #endif free(virusdb); virusdb = NULL; } if (old_virusdb) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } } void set_istag(ci_service_xdata_t * srv_xdata) { char istag[SERVICE_ISTAG_SIZE + 1]; char str_version[64]; char *daily_path; char *s1, *s2; struct cl_cvd *d1; int version = 0, cfg_version = 0; struct stat daily_stat; /*instead of 128 should be strlen("/daily.inc/daily.info")+1*/ daily_path = malloc(strlen(cl_retdbdir()) + 128); if (!daily_path) /*???????? */ return; sprintf(daily_path, "%s/daily.cvd", cl_retdbdir()); if(stat(daily_path,&daily_stat) != 0){ /* if the clamav_lib_path/daily.cvd does not exists */ sprintf(daily_path, "%s/daily.cld", cl_retdbdir()); if(stat(daily_path,&daily_stat) != 0){ /* else try to use the clamav_lib_path/daily.inc/daly.info file instead" */ sprintf(daily_path, "%s/daily.inc/daily.info", cl_retdbdir()); } } if ((d1 = cl_cvdhead(daily_path))) { version = d1->version; free(d1); } free(daily_path); s1 = (char *) cl_retver(); s2 = str_version; while (*s1 != '\0' && s2 - str_version < 64) { if (*s1 != '.') { *s2 = *s1; s2++; } s1++; } *s2 = '\0'; /*cfg_version maybe must set by user when he is changing the srv_clamav configuration.... */ snprintf(istag, SERVICE_ISTAG_SIZE, "-%.3d-%s-%d%d", cfg_version, str_version, cl_retflevel(), version); istag[SERVICE_ISTAG_SIZE] = '\0'; ci_service_set_istag(srv_xdata, istag); }
BOOL init() { char whereami[PATH_MAX], *slash; int ret; ret = GetModuleFileName((HINSTANCE)&__ImageBase, whereami, sizeof(whereami) -1); if(!ret || ret == sizeof(whereami) -1) { printf("ERROR: GetModuleFileName failed\n"); return FALSE; } whereami[sizeof(whereami)-1] = '\0'; slash = strrchr(whereami, '\\'); if(!slash) { printf("ERROR: No slash found in path %s\n", whereami); return FALSE; } slash++; *slash='\0'; SetDllDirectory(whereami); __try { cl_set_clcb_msg(msg_callback); ret = cl_init(CL_INIT_DEFAULT); } __except(EXCEPTION_EXECUTE_HANDLER) { ret = -1; } SetDllDirectory(NULL); if(ret) { printf("ERROR: Failed cl_init() returned %d\n", ret); return FALSE; } strncpy(slash, "clamav_log_verbose", sizeof(whereami) - (slash - whereami)); whereami[sizeof(whereami)-1] = '\0'; logg_verbose = access(whereami, 0) == -1 ? 0 : 1; strncpy(slash, "clamav.log", sizeof(whereami) - (slash - whereami)); whereami[sizeof(whereami)-1] = '\0'; logg_nowarn = 0; logg_lock = 0; logg_time = 1; // bb #5659: force log rotation at 100 MB logg_size = 104857600; logg_rotate = 1; logg_file = strdup(whereami); if(!logg_file) { printf("ERROR: failed to duplicate log filename\n"); return FALSE; } strncpy(slash, "clamav.old.log", sizeof(whereami) - (slash - whereami)); whereami[sizeof(whereami)-1] = '\0'; if(!MoveFileEx(logg_file, whereami, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) DeleteFile(logg_file); logg_noflush = 1;/* only flush on errors and warnings */ if(logg("ClamAV core initialized (version %s, flevel %d)\n", cl_retver(), cl_retflevel())<0) { printf("ERROR: logg failed\n"); return FALSE; } if(init_errors()) { logg("!Failed to initialize errors\n"); return FALSE; } ret = interface_setup(); logg("ClamAV module initialization %s\n", ret == TRUE ? "succeeded" : "failed! Aborting..."); return ret; }