Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to ignore inode changes in removeifnotchanged #192

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Usage: fdupes [options] DIRECTORY...
change time (BY='ctime'), or filename (BY='name')
-i --reverse reverse order while sorting
-l --log=LOGFILE log file deletion choices to LOGFILE
-e --noinodes don't use inodes to test for changed file contents
-v --version display fdupes version
-h --help display this help message

Expand All @@ -84,6 +85,13 @@ once. All files within that directory will be listed as their own
duplicates, leading to data loss should a user preserve a file
without its "duplicate" (the file itself!).

Some remote-mounted filesystems (e.g. gvfs-smb) generate inodes in
the client instead of sending server inode values. With a large
number of files or client cache activity, inodes can change even
though the file has not changed or moved. Using -e or --noinodes
allows fdupes to delete files where the device, creation and
modification times, and size has not changed during processing,
ignoring any inode change.

Contact Information for Adrian Lopez
--------------------------------------------------------------------
Expand Down
10 changes: 10 additions & 0 deletions fdupes.1
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ Reverse order while sorting.
.B -l --log\fR=\fILOGFILE\fR
Log file deletion choices to LOGFILE.
.TP
.B -e --noinodes
Don't use inodes to test for changed file contents.
.TP
.B -v --version
Display fdupes version.
.TP
Expand All @@ -148,6 +151,13 @@ or
is specified, spaces and backslash characters (\fB\e\fP) appearing
in a filename are preceded by a backslash character.

When
.B -e
or
.B --noinodes
is specified, file inode will not be used to test for file content
changes before deletion.

.SH EXAMPLES
.TP
.B fdupes a --recurse: b
Expand Down
13 changes: 10 additions & 3 deletions fdupes.c
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,7 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)
int ismatch;
char *deletepath;
char *errorstring;
int checkinode = !ISFLAG(flags, F_NOINODES);

curfile = files;

Expand Down Expand Up @@ -1125,7 +1126,7 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)
}

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

#ifndef NO_SQLITE
Expand Down Expand Up @@ -1286,6 +1287,7 @@ void deletesuccessor(file_t **existing, file_t *duplicate, int matchconfirmed,
file_t *to_delete;
char *deletepath;
char *errorstring;
int checkinode = !ISFLAG(flags, F_NOINODES);

if (comparef(duplicate, *existing) >= 0)
{
Expand All @@ -1312,7 +1314,7 @@ void deletesuccessor(file_t **existing, file_t *duplicate, int matchconfirmed,

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

#ifndef NO_SQLITE
Expand Down Expand Up @@ -1419,6 +1421,7 @@ void help_text()
printf(" change time (BY='ctime'), or filename (BY='name')\n");
printf(" -i --reverse reverse order while sorting\n");
printf(" -l --log=LOGFILE log file deletion choices to LOGFILE\n");
printf(" -e --noinodes don't use inodes to test for changed file contents\n");
printf(" -v --version display fdupes version\n");
printf(" -h --help display this help message\n\n");
#ifndef HAVE_GETOPT_H
Expand Down Expand Up @@ -1503,6 +1506,7 @@ int main(int argc, char **argv) {
{ "log", 1, 0, 'l' },
{ "deferconfirmation", 0, 0, 'D' },
{ "cache", 0, 0, 'c' },
{ "noinodes", 0, 0, 'e'},
{ 0, 0, 0, 0 }
};
#define GETOPT getopt_long
Expand All @@ -1516,7 +1520,7 @@ int main(int argc, char **argv) {

oldargv = cloneargs(argc, argv);

while ((opt = GETOPT(argc, argv, "frRq1StsHG:L:nAdPvhNImpo:il:Dcx:"
while ((opt = GETOPT(argc, argv, "frRq1StsHG:L:nAdPvhNImpo:il:Dcex:"
#ifdef HAVE_GETOPT_H
, long_options, NULL
#endif
Expand Down Expand Up @@ -1619,6 +1623,9 @@ int main(int argc, char **argv) {
case 'c':
SETFLAG(flags, F_CACHESIGNATURES);
break;
case 'e':
SETFLAG(flags, F_NOINODES);
break;
case 'x':
if (strcmp("cache.readonly", optarg) == 0)
SETFLAG(flags, F_READONLYCACHE);
Expand Down
1 change: 1 addition & 0 deletions flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#define F_PRUNECACHE 0x200000
#define F_READONLYCACHE 0x400000
#define F_VACUUMCACHE 0x800000
#define F_NOINODES 0x1000000

extern unsigned long flags;

Expand Down
3 changes: 2 additions & 1 deletion ncurses-commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ int cmd_prune(struct filegroup *groups, int groupcount, wchar_t *commandargument
wchar_t *statuscopy;
struct groupfile *firstnotdeleted;
char *deletepath;
int checkinode = !ISFLAG(flags, F_NOINODES);

if (logfile != 0)
loginfo = log_open(logfile, 0);
Expand Down Expand Up @@ -808,7 +809,7 @@ int cmd_prune(struct filegroup *groups, int groupcount, wchar_t *commandargument
}
#endif

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

Expand Down
4 changes: 2 additions & 2 deletions removeifnotchanged.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <string.h>
#include <stdio.h>

int removeifnotchanged(const file_t *file, char **errorstring)
int removeifnotchanged(const file_t *file, char **errorstring, int checkinode)
{
int result;
struct stat st;
Expand All @@ -36,7 +36,7 @@ int removeifnotchanged(const file_t *file, char **errorstring)
stat(file->d_name, &st);

if (file->device != st.st_dev ||
file->inode != st.st_ino ||
(checkinode && (file->inode != st.st_ino)) ||
file->ctime != st.st_ctime ||
file->mtime != st.st_mtime ||
#ifdef HAVE_NSEC_TIMES
Expand Down
2 changes: 1 addition & 1 deletion removeifnotchanged.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@

#include "fdupes.h"

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

#endif