Skip to content

Commit

Permalink
Call stat() before deleting any file to ensure it's still the same file.
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianlopezroche committed Aug 16, 2022
1 parent 4b6bcde commit 8568089
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 5 deletions.
4 changes: 4 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ fdupes_SOURCES = fdupes.c\
flags.h\
confirmmatch.c\
confirmmatch.h\
removeifnotchanged.c\
removeifnotchanged.h\
mbstowcs_escape_invalid.c\
mbstowcs_escape_invalid.h\
md5/md5.c\
Expand Down Expand Up @@ -59,6 +61,8 @@ fdupes_SOURCES = fdupes.c\
flags.h\
confirmmatch.c\
confirmmatch.h\
removeifnotchanged.c\
removeifnotchanged.h\
mbstowcs_escape_invalid.c\
mbstowcs_escape_invalid.h\
positive_wcwidth.c\
Expand Down
11 changes: 7 additions & 4 deletions fdupes.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "log.h"
#include "sigint.h"
#include "flags.h"
#include "removeifnotchanged.h"

long long minsize = -1;
long long maxsize = -1;
Expand Down Expand Up @@ -804,6 +805,7 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)
FILE *file1;
FILE *file2;
int ismatch;
char *errorstring;

curfile = files;

Expand Down Expand Up @@ -1005,15 +1007,15 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)
}

if (ismatch) {
if (remove(dupelist[x]->d_name) == 0) {
if (removeifnotchanged(dupelist[x], &errorstring) == 0) {
printf(" [-] %s\n", dupelist[x]->d_name);

if (loginfo)
log_file_deleted(loginfo, dupelist[x]->d_name);
}
else {
printf(" [!] %s ", dupelist[x]->d_name);
printf("-- unable to delete file!\n");
printf("-- unable to delete file: %s!\n", errorstring);

if (loginfo)
log_file_remaining(loginfo, dupelist[x]->d_name);
Expand Down Expand Up @@ -1130,6 +1132,7 @@ void deletesuccessor(file_t **existing, file_t *duplicate, int matchconfirmed,
{
file_t *to_keep;
file_t *to_delete;
char *errorstring;

if (comparef(duplicate, *existing) >= 0)
{
Expand All @@ -1156,14 +1159,14 @@ void deletesuccessor(file_t **existing, file_t *duplicate, int matchconfirmed,

if (matchconfirmed)
{
if (remove(to_delete->d_name) == 0) {
if (removeifnotchanged(to_delete, &errorstring) == 0) {
printf(" [-] %s\n", to_delete->d_name);

if (loginfo)
log_file_deleted(loginfo, to_delete->d_name);
} else {
printf(" [!] %s ", to_delete->d_name);
printf("-- unable to delete file!\n");
printf("-- unable to delete file: %s!\n", errorstring);

if (loginfo)
log_file_remaining(loginfo, to_delete->d_name);
Expand Down
3 changes: 2 additions & 1 deletion ncurses-commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "wcs.h"
#include "mbstowcs_escape_invalid.h"
#include "log.h"
#include "removeifnotchanged.h"
#include <wchar.h>
#include <pcre2.h>

Expand Down Expand Up @@ -780,7 +781,7 @@ int cmd_prune(struct filegroup *groups, int groupcount, wchar_t *commandargument
ismatch = 1;
}

if (ismatch && remove(groups[g].files[f].file->d_name) == 0)
if (ismatch && removeifnotchanged(groups[g].files[f].file, 0) == 0)
{
set_file_action(&groups[g].files[f], FILEACTION_DELIST, deletiontally);

Expand Down
41 changes: 41 additions & 0 deletions removeifnotchanged.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "removeifnotchanged.h"
#include <errno.h>
#include <string.h>
#include <stdio.h>

int removeifnotchanged(const file_t *file, char **errorstring)
{
int result;
struct stat st;

static char *filechanged = "File contents changed during processing";
static char *unknownerror = "Unknown error";

stat(file->d_name, &st);

if (file->device != st.st_dev ||
file->inode != st.st_ino ||
file->ctime != st.st_ctime ||
file->mtime != st.st_mtime ||
file->size != st.st_size)
{
if (errorstring != 0)
*errorstring = filechanged;

return -2;
}
else
{
result = remove(file->d_name);

if (result != 0 && errorstring != 0)
{
*errorstring = strerror(errno);

if (*errorstring == 0)
*errorstring = unknownerror;
}

return result;
}
}
8 changes: 8 additions & 0 deletions removeifnotchanged.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef REMOVEIFNOTCHANGED_H
#define REMOVEIFNOTCHANGED_H

#include "fdupes.h"

int removeifnotchanged(const file_t *file, char **errorstring);

#endif

0 comments on commit 8568089

Please sign in to comment.