Browse code

Allow manual freshclam when daemon is running

Freshclam creates a tmp directory in the database directory used to
store downloaded patches or databases before they replace current
databases. The tmp directory previously was created at when freshclam
was initialized and deleted when freshclam exited. This was problematic
if freshclam was run in daemon mode and then run manually while the
daemon was already running.

This commit alters the behavior to create tmp directory with a random
suffix before the update begins and remove this directory when the
update ends, allowing freshclam to be run manually without causing the
freshclam daemon to fail later.

Micah Snyder authored on 2019/12/24 07:31:18
Showing 2 changed files
... ...
@@ -750,11 +750,8 @@ static fc_error_t initialize(struct optstruct *opts)
750 750
     cl_error_t cl_init_retcode;
751 751
     fc_config fcConfig;
752 752
     char *tempDirectory = NULL;
753
-    size_t tempDirectoryLen;
754 753
     const struct optstruct *logFileOpt = NULL;
755 754
 
756
-    STATBUF statbuf;
757
-
758 755
     memset(&fcConfig, 0, sizeof(fc_config));
759 756
 
760 757
     if (NULL == opts) {
... ...
@@ -862,25 +859,9 @@ static fc_error_t initialize(struct optstruct *opts)
862 862
     fcConfig.databaseDirectory = optget(opts, "DatabaseDirectory")->strarg;
863 863
 
864 864
     /* Select a path for the temp directory:  databaseDirectory/tmp */
865
-    tempDirectoryLen = strlen(fcConfig.databaseDirectory) + strlen(PATHSEP) + strlen("tmp") + 1; /* mdir/fname\0 */
866
-    tempDirectory    = (char *)cli_calloc(tempDirectoryLen, sizeof(char));
867
-    if (!tempDirectory) {
868
-        mprintf("!initialize: out of memory\n");
869
-        status = FC_EMEM;
870
-        goto done;
871
-    }
872
-    snprintf(tempDirectory, tempDirectoryLen, "%s" PATHSEP "tmp", fcConfig.databaseDirectory);
865
+    tempDirectory = cli_gentemp_with_prefix(fcConfig.databaseDirectory, "tmp");
873 866
     fcConfig.tempDirectory = tempDirectory;
874 867
 
875
-    if (LSTAT(tempDirectory, &statbuf) == -1) {
876
-        if (0 != mkdir(tempDirectory, 0755)) {
877
-            logg("!Can't create temporary directory %s\n", tempDirectory);
878
-            logg("Hint: The database directory must be writable for UID %d or GID %d\n", getuid(), getgid());
879
-            status = FC_EDBDIRACCESS;
880
-            goto done;
881
-        }
882
-    }
883
-
884 868
     /* Store the path of the temp directory so we can delete it later. */
885 869
     strncpy(g_freshclamTempDirectory, fcConfig.tempDirectory, sizeof(g_freshclamTempDirectory));
886 870
     g_freshclamTempDirectory[sizeof(g_freshclamTempDirectory) - 1] = '\0';
... ...
@@ -1411,6 +1392,8 @@ fc_error_t perform_database_update(
1411 1411
     uint32_t nUpdated      = 0;
1412 1412
     uint32_t nTotalUpdated = 0;
1413 1413
 
1414
+    STATBUF statbuf;
1415
+
1414 1416
     if (NULL == serverList) {
1415 1417
         mprintf("!perform_database_update: Invalid arguments.\n");
1416 1418
         goto done;
... ...
@@ -1437,6 +1420,18 @@ fc_error_t perform_database_update(
1437 1437
      */
1438 1438
     (void)fc_dns_query_update_info(dnsUpdateInfoServer, &dnsUpdateInfo, &newVersion);
1439 1439
 
1440
+    /*
1441
+     * Create a temp directory to use for the update process.
1442
+     */
1443
+    if (LSTAT(g_freshclamTempDirectory, &statbuf) == -1) {
1444
+        if (0 != mkdir(g_freshclamTempDirectory, 0755)) {
1445
+            logg("!Can't create temporary directory %s\n", g_freshclamTempDirectory);
1446
+            logg("Hint: The database directory must be writable for UID %d or GID %d\n", getuid(), getgid());
1447
+            status = FC_EDBDIRACCESS;
1448
+            goto done;
1449
+        }
1450
+    }
1451
+
1440 1452
     if ((NULL != databaseList) && (0 < nDatabases)) {
1441 1453
         /*
1442 1454
         * Download/update the desired official databases.
... ...
@@ -1497,6 +1492,12 @@ fc_error_t perform_database_update(
1497 1497
 
1498 1498
 done:
1499 1499
 
1500
+    if (LSTAT(g_freshclamTempDirectory, &statbuf) != -1) {
1501
+        /* Remove temp directory */
1502
+        if (*g_freshclamTempDirectory) {
1503
+            cli_rmdirs(g_freshclamTempDirectory);
1504
+        }
1505
+    }
1500 1506
     if (NULL != dnsUpdateInfo) {
1501 1507
         free(dnsUpdateInfo);
1502 1508
     }
... ...
@@ -235,17 +235,6 @@ fc_error_t fc_initialize(fc_config *fcConfig)
235 235
         goto done;
236 236
     }
237 237
 
238
-    /* Validate that the temp directory exists, and store it. */
239
-    if (LSTAT(fcConfig->tempDirectory, &statbuf) == -1) {
240
-        logg("!Temp directory does not exist: %s\n", fcConfig->tempDirectory);
241
-        status = FC_EDIRECTORY;
242
-        goto done;
243
-    }
244
-    if (!S_ISDIR(statbuf.st_mode)) {
245
-        logg("!Temp directory is not a directory: %s\n", fcConfig->tempDirectory);
246
-        status = FC_EDIRECTORY;
247
-        goto done;
248
-    }
249 238
     g_tempDirectory = cli_strdup(fcConfig->tempDirectory);
250 239
 
251 240
     g_maxAttempts    = fcConfig->maxAttempts;