int cl_cvdverify(const char *file) { FILE *fs; int ret; if((fs = fopen(file, "rb")) == NULL) { cli_errmsg("cl_cvdverify: Can't open file %s\n", file); return CL_EOPEN; } ret = cli_cvdverify(fs, NULL); fclose(fs); return ret; }
int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int dbtype, const char *filename, unsigned int chkonly) { struct cl_cvd cvd, dupcvd; FILE *dupfs; int ret; time_t s_time; int cfd; struct cli_dbio dbio; struct cli_dbinfo *dbinfo = NULL; char *dupname; dbio.hashctx = NULL; cli_dbgmsg("in cli_cvdload()\n"); /* verify */ if((ret = cli_cvdverify(fs, &cvd, dbtype))) return ret; if(dbtype <= 1) { /* check for duplicate db */ dupname = cli_strdup(filename); if(!dupname) return CL_EMEM; dupname[strlen(dupname) - 2] = (dbtype == 1 ? 'v' : 'l'); if(!access(dupname, R_OK) && (dupfs = fopen(dupname, "rb"))) { if((ret = cli_cvdverify(dupfs, &dupcvd, !dbtype))) { fclose(dupfs); free(dupname); return ret; } fclose(dupfs); if(dupcvd.version > cvd.version) { cli_warnmsg("Detected duplicate databases %s and %s. The %s database is older and will not be loaded, you should manually remove it from the database directory.\n", filename, dupname, filename); free(dupname); return CL_SUCCESS; } else if(dupcvd.version == cvd.version && !dbtype) { cli_warnmsg("Detected duplicate databases %s and %s, please manually remove one of them\n", filename, dupname); free(dupname); return CL_SUCCESS; } } free(dupname); } if(strstr(filename, "daily.")) { time(&s_time); if(cvd.stime > s_time) { if(cvd.stime - (unsigned int ) s_time > 3600) { cli_warnmsg("******************************************************\n"); cli_warnmsg("*** Virus database timestamp in the future! ***\n"); cli_warnmsg("*** Please check the timezone and clock settings ***\n"); cli_warnmsg("******************************************************\n"); } } else if((unsigned int) s_time - cvd.stime > 604800) { cli_warnmsg("**************************************************\n"); cli_warnmsg("*** The virus database is older than 7 days! ***\n"); cli_warnmsg("*** Please update it as soon as possible. ***\n"); cli_warnmsg("**************************************************\n"); } engine->dbversion[0] = cvd.version; engine->dbversion[1] = cvd.stime; } if(cvd.fl > cl_retflevel()) { cli_warnmsg("***********************************************************\n"); cli_warnmsg("*** This version of the ClamAV engine is outdated. ***\n"); cli_warnmsg("*** DON'T PANIC! Read http://www.clamav.net/support/faq ***\n"); cli_warnmsg("***********************************************************\n"); } cfd = fileno(fs); dbio.chkonly = 0; if(dbtype == 2) ret = cli_tgzload(cfd, engine, signo, options | CL_DB_UNSIGNED, &dbio, NULL); else ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL); if(ret != CL_SUCCESS) return ret; dbinfo = engine->dbinfo; if(!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) { cli_errmsg("cli_cvdload: Corrupted CVD header\n"); return CL_EMALFDB; } dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL; if(!dbinfo) { cli_errmsg("cli_cvdload: dbinfo error\n"); return CL_EMALFDB; } dbio.chkonly = chkonly; if(dbtype == 2) options |= CL_DB_UNSIGNED; else options |= CL_DB_SIGNED | CL_DB_OFFICIAL; ret = cli_tgzload(cfd, engine, signo, options, &dbio, dbinfo); while(engine->dbinfo) { dbinfo = engine->dbinfo; engine->dbinfo = dbinfo->next; mpool_free(engine->mempool, dbinfo->name); mpool_free(engine->mempool, dbinfo->hash); if(dbinfo->cvd) cl_cvdfree(dbinfo->cvd); mpool_free(engine->mempool, dbinfo); } return ret; }
int cli_cvdload(FILE *fs, struct cl_engine **engine, unsigned int *signo, short warn, unsigned int options) { char *dir; struct cl_cvd cvd; int ret; time_t s_time; int cfd; cli_dbgmsg("in cli_cvdload()\n"); /* verify */ if((ret = cli_cvdverify(fs, &cvd))) return ret; if(cvd.stime && warn) { time(&s_time); if((int) s_time - cvd.stime > 604800) { cli_warnmsg("**************************************************\n"); cli_warnmsg("*** The virus database is older than 7 days! ***\n"); cli_warnmsg("*** Please update it as soon as possible. ***\n"); cli_warnmsg("**************************************************\n"); } } if(cvd.fl > cl_retflevel()) { cli_warnmsg("***********************************************************\n"); cli_warnmsg("*** This version of the ClamAV engine is outdated. ***\n"); cli_warnmsg("*** DON'T PANIC! Read http://www.clamav.net/support/faq ***\n"); cli_warnmsg("***********************************************************\n"); } dir = cli_gentemp(NULL); if(mkdir(dir, 0700)) { cli_errmsg("cli_cvdload(): Can't create temporary directory %s\n", dir); free(dir); return CL_ETMPDIR; } cfd = fileno(fs); /* use only operations on file descriptors, and not on the FILE* from here on * if we seek the FILE*, the underlying descriptor may not seek as expected * (for example on OpenBSD, cygwin, etc.). * So seek the descriptor directly. */ if(lseek(cfd, 512, SEEK_SET) == -1) { cli_errmsg("cli_cvdload(): lseek(fs, 512, SEEK_SET) failed\n"); return CL_EIO; } if(cli_untgz(cfd, dir)) { cli_errmsg("cli_cvdload(): Can't unpack CVD file.\n"); free(dir); return CL_ECVDEXTR; } /* load extracted directory */ ret = cl_load(dir, engine, signo, options); cli_rmdirs(dir); free(dir); return ret; }