CLAMAPI void Scan_ReloadDatabase(BOOL bLoadMinDefs) { if(InterlockedIncrement(&reload_waiters)==1) { int reload_ok = 0; logg("*Scan_ReloadDatabase: Database reload requested received, waiting for idle state\n"); while(1) { unsigned int i; struct cl_settings *settings; if(WaitForSingleObject(reload_event, INFINITE) == WAIT_FAILED) { logg("!Scan_ReloadDatabase: failed to wait on reload event\n"); continue; } logg("*Scan_ReloadDatabase: Now idle, acquiring engine lock\n"); if(lock_engine()) { logg("!Scan_ReloadDatabase: failed to lock engine\n"); break; } if(!engine) { logg("!Scan_ReloadDatabase: engine is NULL\n"); unlock_engine(); break; } logg("*Scan_ReloadDatabase: Engine locked, acquiring instance lock\n"); if(lock_instances()) { logg("!Scan_ReloadDatabase: failed to lock instances\n"); unlock_engine(); break; } for(i=0; i<ninsts_total; i++) { if(instances[i].inst && instances[i].refcnt) break; } if(i!=ninsts_total) { logg("Scan_ScanObjectByHandle: some instances are still in use\n"); ResetEvent(reload_event); unlock_instances(); unlock_engine(); continue; } settings = cl_engine_settings_copy(engine); if (!settings) { logg("!Scan_ReloadDatabase: Not enough memory for engine settings\n"); unlock_instances(); unlock_engine(); break; } logg("Scan_ReloadDatabase: Destroying old engine\n"); cl_engine_free(engine); minimal_definitions = bLoadMinDefs; logg("Scan_ReloadDatabase: Loading new engine\n"); // NEW STUFF // if(!(engine = cl_engine_new())) { logg("!Scan_ReloadDatabase: Not enough memory for a new engine\n"); unlock_instances(); unlock_engine(); break; } cl_engine_settings_apply(engine, settings); cl_engine_settings_free(settings); load_db(); /* FIXME: FIAL? */ unlock_instances(); unlock_engine(); reload_ok = 1; break; } if(reload_ok) logg("Scan_ReloadDatabase: Database successfully reloaded\n"); else logg("!Scan_ReloadDatabase: Database reload failed\n"); } else logg("*Database reload requested received while reload is pending\n"); InterlockedDecrement(&reload_waiters); }
static struct cl_engine *reload_db(struct cl_engine *engine, unsigned int dboptions, const struct optstruct *opts, int do_check, int *ret) { const char *dbdir; int retval; unsigned int sigs = 0; struct cl_settings *settings = NULL; *ret = 0; if(do_check) { if(!dbstat.entries) { logg("No stats for Database check - forcing reload\n"); return engine; } if(cl_statchkdir(&dbstat) == 1) { logg("SelfCheck: Database modification detected. Forcing reload.\n"); return engine; } else { logg("SelfCheck: Database status OK.\n"); return NULL; } } /* release old structure */ if(engine) { /* copy current settings */ settings = cl_engine_settings_copy(engine); if(!settings) logg("^Can't make a copy of the current engine settings\n"); thrmgr_setactiveengine(NULL); cl_engine_free(engine); } dbdir = optget(opts, "DatabaseDirectory")->strarg; logg("Reading databases from %s\n", dbdir); if(dbstat.entries) cl_statfree(&dbstat); memset(&dbstat, 0, sizeof(struct cl_stat)); if((retval = cl_statinidir(dbdir, &dbstat))) { logg("!cl_statinidir() failed: %s\n", cl_strerror(retval)); *ret = 1; if(settings) cl_engine_settings_free(settings); return NULL; } if(!(engine = cl_engine_new())) { logg("!Can't initialize antivirus engine\n"); *ret = 1; if(settings) cl_engine_settings_free(settings); return NULL; } if(settings) { retval = cl_engine_settings_apply(engine, settings); if(retval != CL_SUCCESS) { logg("^Can't apply previous engine settings: %s\n", cl_strerror(retval)); logg("^Using default engine settings\n"); } cl_engine_settings_free(settings); } if((retval = cl_load(dbdir, engine, &sigs, dboptions))) { logg("!reload db failed: %s\n", cl_strerror(retval)); cl_engine_free(engine); *ret = 1; return NULL; } if((retval = cl_engine_compile(engine)) != 0) { logg("!Database initialization error: can't compile engine: %s\n", cl_strerror(retval)); cl_engine_free(engine); *ret = 1; return NULL; } logg("Database correctly reloaded (%u signatures)\n", sigs); thrmgr_setactiveengine(engine); return engine; }