diff --git a/freshclam/freshclam.c b/freshclam/freshclam.c index 50dd91465f..fd614fbee5 100644 --- a/freshclam/freshclam.c +++ b/freshclam/freshclam.c @@ -1432,6 +1432,10 @@ fc_error_t perform_database_update( uint32_t nUpdated = 0; uint32_t nTotalUpdated = 0; + uint32_t i; + char **doNotPruneDatabaseList = NULL; + uint32_t nDoNotPruneDatabases = 0; + STATBUF statbuf; if (NULL == serverList) { @@ -1452,7 +1456,38 @@ fc_error_t perform_database_update( * Prune database directory of official databases * that are no longer available or no longer desired. */ - (void)fc_prune_database_directory(databaseList, nDatabases); + + // include the URL databases in the prune process + doNotPruneDatabaseList = (char **)malloc(sizeof(char *) * (nDatabases + nUrlDatabases)); + if (NULL == doNotPruneDatabaseList) { + logg(LOGG_ERROR, "perform_database_update: Can't allocate memory for doNotPruneDatabaseList\n"); + status = FC_EMEM; + goto done; + } + + for (i = 0; i < nDatabases; i++) { + doNotPruneDatabaseList[i] = strdup(databaseList[i]); + if (doNotPruneDatabaseList[i] == NULL) { + logg(LOGG_ERROR, "perform_database_update: Can't allocate memory for database name in doNotPruneDatabaseList\n"); + status = FC_EMEM; + goto done; + } + } + nDoNotPruneDatabases = nDatabases; + + for (i = 0; i < nUrlDatabases; i++) { + // Only append the URL databases that end with '.cvd' + if (strlen(urlDatabaseList[i]) > 4 && 0 == strcasecmp(urlDatabaseList[i] + strlen(urlDatabaseList[i]) - 4, ".cvd")) { + const char *startOfFilename = strrchr(urlDatabaseList[i], '/') + 1; + if (NULL != startOfFilename) { + // Add the base database name to the do-not-prune list, excluding the '.cvd' extension. + doNotPruneDatabaseList[nDatabases + i] = CLI_STRNDUP(startOfFilename, strlen(startOfFilename) - strlen(".cvd")); + nDoNotPruneDatabases++; + } + } + } + + (void)fc_prune_database_directory(doNotPruneDatabaseList, nDoNotPruneDatabases); } /* @@ -1523,6 +1558,16 @@ fc_error_t perform_database_update( done: + // Free up the database list + if (NULL != doNotPruneDatabaseList) { + for (i = 0; i < nDoNotPruneDatabases; i++) { + free(doNotPruneDatabaseList[i]); + doNotPruneDatabaseList[i] = NULL; + } + free(doNotPruneDatabaseList); + doNotPruneDatabaseList = NULL; + } + if (LSTAT(g_freshclamTempDirectory, &statbuf) != -1) { /* Remove temp directory */ if (*g_freshclamTempDirectory) {