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.
... | ... |
@@ -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; |