SHA256
3
0
forked from pool/fdupes

Accepting request 438720 from utilities

1

OBS-URL: https://build.opensuse.org/request/show/438720
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/fdupes?expand=0&rev=26
This commit is contained in:
Dominique Leuenberger 2016-11-07 11:21:17 +00:00 committed by Git OBS Bridge
commit 803f059ab4
16 changed files with 35 additions and 894 deletions

View File

@ -1,73 +0,0 @@
From 1e8e84ee52397881558e083bcae4d243d319e811 Mon Sep 17 00:00:00 2001
From: Sandro Tosi <matrixhasu@gmail.com>
Date: Fri, 12 Oct 2012 14:54:42 +0200
Subject: [PATCH 01/10] restore pristine code
speedup the file compare by reading larger buffers, comparing the
results of fread and so
---
fdupes.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/fdupes.c b/fdupes.c
index 4b870b2..f16e4e0 100644
--- a/fdupes.c
+++ b/fdupes.c
@@ -492,7 +492,10 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
else {
if (checktree->file->crcpartial == NULL) {
crcsignature = getcrcpartialsignature(checktree->file->d_name);
- if (crcsignature == NULL) return NULL;
+ if (crcsignature == NULL) {
+ errormsg ("cannot read file %s\n", checktree->file->d_name);
+ return NULL;
+ }
checktree->file->crcpartial = (char*) malloc(strlen(crcsignature)+1);
if (checktree->file->crcpartial == NULL) {
@@ -504,7 +507,10 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
if (file->crcpartial == NULL) {
crcsignature = getcrcpartialsignature(file->d_name);
- if (crcsignature == NULL) return NULL;
+ if (crcsignature == NULL) {
+ errormsg ("cannot read file %s\n", file->d_name);
+ return NULL;
+ }
file->crcpartial = (char*) malloc(strlen(crcsignature)+1);
if (file->crcpartial == NULL) {
@@ -577,8 +583,8 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
int confirmmatch(FILE *file1, FILE *file2)
{
- unsigned char c1 = 0;
- unsigned char c2 = 0;
+ unsigned char c1[CHUNK_SIZE];
+ unsigned char c2[CHUNK_SIZE];
size_t r1;
size_t r2;
@@ -586,14 +592,13 @@ int confirmmatch(FILE *file1, FILE *file2)
fseek(file2, 0, SEEK_SET);
do {
- r1 = fread(&c1, sizeof(c1), 1, file1);
- r2 = fread(&c2, sizeof(c2), 1, file2);
+ r1 = fread(c1, 1, sizeof(c1), file1);
+ r2 = fread(c2, 1, sizeof(c2), file2);
- if (c1 != c2) return 0; /* file contents are different */
- } while (r1 && r2);
+ if (r1 != r2) return 0; /* file lengths are different */
+ if (memcmp (c1, c2, r1)) return 0; /* file contents are different */
+ } while (r2);
- if (r1 != r2) return 0; /* file lengths are different */
-
return 1;
}
--
1.7.11.5

View File

@ -1,26 +0,0 @@
From 05157cf087829d18092c6906ac9a61b93f390059 Mon Sep 17 00:00:00 2001
From: Sandro Tosi <matrixhasu@gmail.com>
Date: Fri, 12 Oct 2012 14:57:06 +0200
Subject: [PATCH 02/10] Added to escape minus signs in manpage (lintian
warning)
---
fdupes.1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fdupes.1 b/fdupes.1
index 2102344..c0a02f0 100644
--- a/fdupes.1
+++ b/fdupes.1
@@ -53,7 +53,7 @@ prompt user for files to preserve, deleting all others (see
below)
.TP
.B -N --noprompt
-when used together with --delete, preserve the first file in each
+when used together with \-\-delete, preserve the first file in each
set of duplicates and delete the others without prompting the user
.TP
.B -v --version
--
1.7.11.5

View File

@ -1,25 +0,0 @@
From 445205969c23e8c51e19456b3fcd1571b44c6e5c Mon Sep 17 00:00:00 2001
From: A Costa <agcosta@gis.net>
Date: Fri, 12 Oct 2012 14:58:00 +0200
Subject: [PATCH 03/10] Fix a typo in a manpage (bts353789)
---
fdupes.1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fdupes.1 b/fdupes.1
index c0a02f0..71da2c4 100644
--- a/fdupes.1
+++ b/fdupes.1
@@ -84,7 +84,7 @@ If fdupes returns with an error message such as
.B fdupes: error invoking md5sum
it means the program has been compiled to use an external
program to calculate MD5 signatures (otherwise, fdupes uses
-interal routines for this purpose), and an error has occurred
+internal routines for this purpose), and an error has occurred
while attempting to execute it. If this is the case, the
specified program should be properly installed prior
to running fdupes.
--
1.7.11.5

View File

@ -1,26 +0,0 @@
From 9b6800eb5bdcea2ceb0a2e44c4ea744c77656213 Mon Sep 17 00:00:00 2001
From: Sandro Tosi <matrixhasu@gmail.com>
Date: Fri, 12 Oct 2012 15:01:35 +0200
Subject: [PATCH 05/10] add --summarize to manpage (bts481809)
---
fdupes.1 | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fdupes.1 b/fdupes.1
index 71da2c4..f12945b 100644
--- a/fdupes.1
+++ b/fdupes.1
@@ -44,6 +44,9 @@ list each set of matches on a single line
.B -S --size
show size of duplicate files
.TP
+.B -m --summarize
+summarize duplicate files information
+.TP
.B -q --quiet
hide progress indicator
.TP
--
1.7.11.5

View File

@ -1,108 +0,0 @@
From 1e15ced9c10a04b6f4ae816ced687fd982760dbc Mon Sep 17 00:00:00 2001
From: maxy <maxy@debian.org>
Date: Fri, 12 Oct 2012 15:02:49 +0200
Subject: [PATCH 06/10] add --nohidden support (bts511702)
---
fdupes.1 | 3 +++
fdupes.c | 21 ++++++++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/fdupes.1 b/fdupes.1
index f12945b..5f7c526 100644
--- a/fdupes.1
+++ b/fdupes.1
@@ -38,6 +38,9 @@ exclude zero-length files from consideration
.B -f --omitfirst
omit the first file in each set of matches
.TP
+.B -A --nohidden
+exclude hidden files from consideration
+.TP
.B -1 --sameline
list each set of matches on a single line
.TP
diff --git a/fdupes.c b/fdupes.c
index 4ecf51b..fe540e6 100644
--- a/fdupes.c
+++ b/fdupes.c
@@ -31,6 +31,7 @@
#endif
#include <string.h>
#include <errno.h>
+#include <libgen.h>
#ifndef EXTERNAL_MD5
#include "md5/md5.h"
@@ -51,6 +52,7 @@
#define F_RECURSEAFTER 0x0200
#define F_NOPROMPT 0x0400
#define F_SUMMARIZEMATCHES 0x0800
+#define F_EXCLUDEHIDDEN 0x1000
char *program_name;
@@ -240,6 +242,7 @@ int grokdir(char *dir, file_t **filelistp)
struct stat linfo;
static int progress = 0;
static char indicator[] = "-\\|/";
+ char *fullname, *name;
cd = opendir(dir);
@@ -285,6 +288,17 @@ int grokdir(char *dir, file_t **filelistp)
strcat(newfile->d_name, "/");
strcat(newfile->d_name, dirinfo->d_name);
+ if (ISFLAG(flags, F_EXCLUDEHIDDEN)) {
+ fullname = strdup(newfile->d_name);
+ name = basename(fullname);
+ if (name[0] == '.' && strcmp(name, ".") && strcmp(name, "..") ) {
+ free(newfile->d_name);
+ free(newfile);
+ continue;
+ }
+ free(fullname);
+ }
+
if (filesize(newfile->d_name) == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) {
free(newfile->d_name);
free(newfile);
@@ -945,6 +959,7 @@ void help_text()
printf(" \tdisk area they are treated as non-duplicates; this\n");
printf(" \toption will change this behavior\n");
printf(" -n --noempty \texclude zero-length files from consideration\n");
+ printf(" -A --nohidden \texclude hidden files from consideration\n");
printf(" -f --omitfirst \tomit the first file in each set of matches\n");
printf(" -1 --sameline \tlist each set of matches on a single line\n");
printf(" -S --size \tshow size of duplicate files\n");
@@ -996,6 +1011,7 @@ int main(int argc, char **argv) {
{ "hardlinks", 0, 0, 'H' },
{ "relink", 0, 0, 'l' },
{ "noempty", 0, 0, 'n' },
+ { "nohidden", 0, 0, 'A' },
{ "delete", 0, 0, 'd' },
{ "version", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
@@ -1013,7 +1029,7 @@ int main(int argc, char **argv) {
oldargv = cloneargs(argc, argv);
- while ((opt = GETOPT(argc, argv, "frRq1Ss::HlndvhNm"
+ while ((opt = GETOPT(argc, argv, "frRq1Ss::HlnAdvhNm"
#ifndef OMIT_GETOPT_LONG
, long_options, NULL
#endif
@@ -1046,6 +1062,9 @@ int main(int argc, char **argv) {
case 'n':
SETFLAG(flags, F_EXCLUDEEMPTY);
break;
+ case 'A':
+ SETFLAG(flags, F_EXCLUDEHIDDEN);
+ break;
case 'd':
SETFLAG(flags, F_DELETEFILES);
break;
--
1.7.11.5

View File

@ -1,58 +0,0 @@
From 299e999ba8ac1916797e4956ee774a46ef11851b Mon Sep 17 00:00:00 2001
From: Sandro Tosi <morph@debian.org>
Date: Fri, 12 Oct 2012 15:06:16 +0200
Subject: [PATCH 07/10] Disambiguate the options '--recurse' and '--recurse:'
(bts537138)
---
fdupes.1 | 12 +++++++++++-
fdupes.c | 3 ++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/fdupes.1 b/fdupes.1
index 5f7c526..9263adc 100644
--- a/fdupes.1
+++ b/fdupes.1
@@ -23,7 +23,8 @@ for every directory given follow subdirectories encountered within
.TP
.B -R --recurse:
for each directory given after this option follow subdirectories
-encountered within
+encountered within (note the ':' at the end of option; see the
+Examples section below for further explanation)
.TP
.B -s --symlinks
follow symlinked directories
@@ -85,6 +86,15 @@ or
.B --sameline
is specified, spaces and backslash characters (\fB\e\fP) appearing
in a filename are preceded by a backslash character.
+
+.SH EXAMPLES
+.TP
+.B fdupes a --recurse: b
+will follow subdirectories under b, but not those under a.
+.TP
+.B fdupes a --recurse b
+will follow subdirectories under both a and b.
+
.SH CAVEATS
If fdupes returns with an error message such as
.B fdupes: error invoking md5sum
diff --git a/fdupes.c b/fdupes.c
index fe540e6..1e9e620 100644
--- a/fdupes.c
+++ b/fdupes.c
@@ -953,7 +953,8 @@ void help_text()
printf(" -r --recurse \tfor every directory given follow subdirectories\n");
printf(" \tencountered within\n");
printf(" -R --recurse: \tfor each directory given after this option follow\n");
- printf(" \tsubdirectories encountered within\n");
+ printf(" \tsubdirectories encountered within (note the ':' at\n");
+ printf(" \tthe end of the option, manpage for more details)\n");
printf(" -s --symlinks \tfollow symlinks\n");
printf(" -H --hardlinks \tnormally, when two or more files point to the same\n");
printf(" \tdisk area they are treated as non-duplicates; this\n");
--
1.7.11.5

View File

@ -1,36 +0,0 @@
From c2bd76bb103b3a5b873bee72fbacce6bbe58bbe2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
Date: Fri, 12 Oct 2012 15:20:53 +0200
Subject: [PATCH 08/10] speedup the file compare
Use aligned reads for md5 computation, saves another memcpy.
https://bugzilla.novell.com/show_bug.cgi?id=406825
---
fdupes.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
Index: fdupes-fdupes-1.51/fdupes.c
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.c
+++ fdupes-fdupes-1.51/fdupes.c
@@ -370,7 +370,7 @@ char *getcrcsignatureuntil(char *filenam
}
while (fsize > 0) {
- toread = (fsize % CHUNK_SIZE) ? (fsize % CHUNK_SIZE) : CHUNK_SIZE;
+ toread = (fsize >= CHUNK_SIZE) ? CHUNK_SIZE : fsize;
if (fread(chunk, toread, 1, file) != 1) {
errormsg("error reading from file %s\n", filename);
fclose(file);
@@ -606,8 +606,8 @@ int confirmmatch(FILE *file1, FILE *file
fseek(file2, 0, SEEK_SET);
do {
- r1 = fread(c1, 1, sizeof(c1), file1);
- r2 = fread(c2, 1, sizeof(c2), file2);
+ r1 = fread(c1, sizeof(unsigned char), sizeof(c1), file1);
+ r2 = fread(c2, sizeof(unsigned char), sizeof(c2), file2);
if (r1 != r2) return 0; /* file lengths are different */
if (memcmp (c1, c2, r1)) return 0; /* file contents are different */

View File

@ -1,33 +0,0 @@
From 6b0f55c489ff78bd29d6d881fddf7abeabbed12f Mon Sep 17 00:00:00 2001
From: Michal Vyskocil <mvyskocil@suse.cz>
Date: Fri, 12 Oct 2012 15:21:49 +0200
Subject: [PATCH 09/10] glibc endianness check in md5
https://bugzilla.novell.com/show_bug.cgi?id=406825
---
md5/md5.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/md5/md5.c b/md5/md5.c
index 233ee2d..3ad899b 100644
--- a/md5/md5.c
+++ b/md5/md5.c
@@ -45,6 +45,15 @@
#include "md5.h"
#include <string.h>
+/* endianness check using glibc endian.h */
+#include <endian.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define ARCH_IS_BIG_ENDIAN 1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define ARCH_IS_BIG_ENDIAN 0
+#endif
+
#ifdef TEST
/*
* Compile with -DTEST to create a self-contained executable test program.
--
1.7.11.5

View File

@ -1,107 +0,0 @@
From 0cf7f38569e1c0ff65803342f63244f864d87141 Mon Sep 17 00:00:00 2001
From: Michal Vyskocil <mvyskocil@suse.cz>
Date: Fri, 12 Oct 2012 15:24:16 +0200
Subject: [PATCH 10/10] add --permissions mode
With -p/--permissions mode enabled fdupes checks if the
uid/gid/secure-bits are same or not. In later case, files are not
considered as duplicates.
Requested-in: https://bugzilla.novell.com/show_bug.cgi?id=784670
---
fdupes.1 | 3 +++
fdupes.c | 25 ++++++++++++++++++++++++-
2 files changed, 27 insertions(+), 1 deletion(-)
Index: fdupes-fdupes-1.51/fdupes.1
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.1
+++ fdupes-fdupes-1.51/fdupes.1
@@ -63,6 +63,9 @@ below)
when used together with \-\-delete, preserve the first file in each
set of duplicates and delete the others without prompting the user
.TP
+.B -p --permissions
+don't consider files with different owner/group or permission bits as duplicates
+.TP
.B -v --version
display fdupes version
.TP
Index: fdupes-fdupes-1.51/fdupes.c
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.c
+++ fdupes-fdupes-1.51/fdupes.c
@@ -53,6 +53,7 @@
#define F_NOPROMPT 0x0400
#define F_SUMMARIZEMATCHES 0x0800
#define F_EXCLUDEHIDDEN 0x1000
+#define F_PERMISSIONS 0x2000
char *program_name;
@@ -481,6 +482,19 @@ int registerfile(filetree_t **branch, fi
return 1;
}
+int same_permissions(char* name1, char* name2)
+{
+ struct stat s1, s2;
+
+ if (stat(name1, &s1) != 0) return -1;
+ if (stat(name2, &s2) != 0) return -1;
+
+ return (s1.st_mode == s2.st_mode &&
+ s1.st_uid == s2.st_uid &&
+ s1.st_gid == s2.st_gid);
+}
+
+
file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
{
int cmpresult;
@@ -503,6 +517,10 @@ file_t **checkmatch(filetree_t **root, f
cmpresult = -1;
else
if (fsize > checktree->file->size) cmpresult = 1;
+ else
+ if (ISFLAG(flags, F_PERMISSIONS) &&
+ !same_permissions(file->d_name, checktree->file->d_name))
+ cmpresult = -1;
else {
if (checktree->file->crcpartial == NULL) {
crcsignature = getcrcpartialsignature(checktree->file->d_name);
@@ -979,6 +997,7 @@ void help_text()
printf(" -N --noprompt \ttogether with --delete, preserve the first file in\n");
printf(" \teach set of duplicates and delete the rest without\n");
printf(" \tprompting the user\n");
+ printf(" -p --permissions \tdon't consider files with different owner/group or permission bits as duplicates\n");
printf(" -v --version \tdisplay fdupes version\n");
printf(" -h --help \tdisplay this help message\n\n");
#ifdef OMIT_GETOPT_LONG
@@ -1022,6 +1041,7 @@ int main(int argc, char **argv) {
{ "noprompt", 0, 0, 'N' },
{ "summarize", 0, 0, 'm'},
{ "summary", 0, 0, 'm' },
+ { "permissions", 0, 0, 'p' },
{ 0, 0, 0, 0 }
};
#define GETOPT getopt_long
@@ -1033,7 +1053,7 @@ int main(int argc, char **argv) {
oldargv = cloneargs(argc, argv);
- while ((opt = GETOPT(argc, argv, "frRq1Ss::HlnAdvhNm"
+ while ((opt = GETOPT(argc, argv, "frRq1Ss::HlnAdvhNmp"
#ifndef OMIT_GETOPT_LONG
, long_options, NULL
#endif
@@ -1084,6 +1104,9 @@ int main(int argc, char **argv) {
case 'm':
SETFLAG(flags, F_SUMMARIZEMATCHES);
break;
+ case 'p':
+ SETFLAG(flags, F_PERMISSIONS);
+ break;
default:
fprintf(stderr, "Try `fdupes --help' for more information.\n");

View File

@ -1,119 +0,0 @@
From a0b7fb219b8e5203ae9884871c61b7f064e45797 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Br=C3=BCns?= <stefan.bruens@rwth-aachen.de>
Date: Tue, 29 Apr 2014 19:12:48 +0200
Subject: [PATCH] add an option to sort duplicate files by name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de>
---
fdupes.1 | 4 ++++
fdupes.c | 30 ++++++++++++++++++++++++++++--
2 files changed, 32 insertions(+), 2 deletions(-)
Index: fdupes-fdupes-1.51/fdupes.1
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.1
+++ fdupes-fdupes-1.51/fdupes.1
@@ -66,6 +66,10 @@ set of duplicates and delete the others
.B -p --permissions
don't consider files with different owner/group or permission bits as duplicates
.TP
+.B -o --order\fR=\fIWORD\fR
+order files according to WORD:
+time - sort by mtime, name - sort by filename
+.TP
.B -v --version
display fdupes version
.TP
Index: fdupes-fdupes-1.51/fdupes.c
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.c
+++ fdupes-fdupes-1.51/fdupes.c
@@ -55,6 +55,11 @@
#define F_EXCLUDEHIDDEN 0x1000
#define F_PERMISSIONS 0x2000
+typedef enum {
+ ORDER_TIME = 0,
+ ORDER_NAME
+} ordertype_t;
+
char *program_name;
unsigned long flags = 0;
@@ -921,6 +926,11 @@ int sort_pairs_by_mtime(file_t *f1, file
return 0;
}
+int sort_pairs_by_filename(file_t *f1, file_t *f2)
+{
+ return strcmp(f1->d_name, f2->d_name);
+}
+
void registerpair(file_t **matchlist, file_t *newmatch,
int (*comparef)(file_t *f1, file_t *f2))
{
@@ -998,6 +1008,9 @@ void help_text()
printf(" \teach set of duplicates and delete the rest without\n");
printf(" \tprompting the user\n");
printf(" -p --permissions \tdon't consider files with different owner/group or permission bits as duplicates\n");
+ printf(" -o --order \tselect sort order for output, linking and deleting. One of:\n");
+ printf(" time \torder by mtime (default)\n");
+ printf(" name \torder by filename\n");
printf(" -v --version \tdisplay fdupes version\n");
printf(" -h --help \tdisplay this help message\n\n");
#ifdef OMIT_GETOPT_LONG
@@ -1018,6 +1031,7 @@ int main(int argc, char **argv) {
int progress = 0;
char **oldargv;
int firstrecurse;
+ ordertype_t ordertype = ORDER_TIME;
#ifndef OMIT_GETOPT_LONG
static struct option long_options[] =
@@ -1042,6 +1056,7 @@ int main(int argc, char **argv) {
{ "summarize", 0, 0, 'm'},
{ "summary", 0, 0, 'm' },
{ "permissions", 0, 0, 'p' },
+ { "order", 1, 0, 'o' },
{ 0, 0, 0, 0 }
};
#define GETOPT getopt_long
@@ -1053,7 +1068,7 @@ int main(int argc, char **argv) {
oldargv = cloneargs(argc, argv);
- while ((opt = GETOPT(argc, argv, "frRq1Ss::HlnAdvhNmp"
+ while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpo:"
#ifndef OMIT_GETOPT_LONG
, long_options, NULL
#endif
@@ -1107,6 +1122,16 @@ int main(int argc, char **argv) {
case 'p':
SETFLAG(flags, F_PERMISSIONS);
break;
+ case 'o':
+ if (!strcasecmp("name", optarg)) {
+ ordertype = ORDER_NAME;
+ } else if (!strcasecmp("time", optarg)) {
+ ordertype = ORDER_TIME;
+ } else {
+ errormsg("invalid value for --order: '%s'\n", optarg);
+ exit(1);
+ }
+ break;
default:
fprintf(stderr, "Try `fdupes --help' for more information.\n");
@@ -1182,7 +1207,8 @@ int main(int argc, char **argv) {
}
if (confirmmatch(file1, file2)) {
- registerpair(match, curfile, sort_pairs_by_mtime);
+ registerpair(match, curfile,
+ (ordertype == ORDER_TIME) ? sort_pairs_by_mtime : sort_pairs_by_filename );
/*match->hasdupes = 1;
curfile->duplicates = match->duplicates;

View File

@ -1,228 +0,0 @@
#! /bin/sh /usr/share/dpatch/dpatch-run
## 50_bts284274_hardlinkreplace.dpatch by <jfs@debian.org>
##
## All lines beginning with `## DP:' are a description of the patch.
## DP: Replace duplicate files with hardlinks
@DPATCH@
Index: fdupes-fdupes-1.51/fdupes.c
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.c
+++ fdupes-fdupes-1.51/fdupes.c
@@ -54,6 +54,8 @@
#define F_SUMMARIZEMATCHES 0x0800
#define F_EXCLUDEHIDDEN 0x1000
#define F_PERMISSIONS 0x2000
+#define F_HARDLINKFILES 0x4000
+#define F_DEBUGINFO 0x8000
typedef enum {
ORDER_TIME = 0,
@@ -908,6 +910,88 @@ void deletefiles(file_t *files, int prom
free(preservestr);
}
+void hardlinkfiles(file_t *files, int debug)
+{
+ int counter;
+ int groups = 0;
+ int curgroup = 0;
+ file_t *tmpfile;
+ file_t *curfile;
+ file_t **dupelist;
+ int max = 0;
+ int x = 0;
+
+ curfile = files;
+
+ while (curfile) {
+ if (curfile->hasdupes) {
+ counter = 1;
+ groups++;
+
+ tmpfile = curfile->duplicates;
+ while (tmpfile) {
+ counter++;
+ tmpfile = tmpfile->duplicates;
+ }
+
+ if (counter > max) max = counter;
+ }
+
+ curfile = curfile->next;
+ }
+
+ max++;
+
+ dupelist = (file_t**) malloc(sizeof(file_t*) * max);
+
+ if (!dupelist) {
+ errormsg("out of memory\n");
+ exit(1);
+ }
+
+ while (files) {
+ if (files->hasdupes) {
+ curgroup++;
+ counter = 1;
+ dupelist[counter] = files;
+
+ if (debug) printf("[%d] %s\n", counter, files->d_name);
+
+ tmpfile = files->duplicates;
+
+ while (tmpfile) {
+ dupelist[++counter] = tmpfile;
+ if (debug) printf("[%d] %s\n", counter, tmpfile->d_name);
+ tmpfile = tmpfile->duplicates;
+ }
+
+ if (debug) printf("\n");
+
+ /* preserve only the first file */
+
+ printf(" [+] %s\n", dupelist[1]->d_name);
+ for (x = 2; x <= counter; x++) {
+ if (unlink(dupelist[x]->d_name) == 0) {
+ if ( link(dupelist[1]->d_name, dupelist[x]->d_name) == 0 ) {
+ printf(" [h] %s\n", dupelist[x]->d_name);
+ } else {
+ printf("-- unable to create a hardlink for the file: %s\n", strerror(errno));
+ printf(" [!] %s ", dupelist[x]->d_name);
+ }
+ } else {
+ printf(" [!] %s ", dupelist[x]->d_name);
+ printf("-- unable to delete the file!\n");
+ }
+ }
+ printf("\n");
+ }
+
+ files = files->next;
+ }
+
+ free(dupelist);
+}
+
int sort_pairs_by_arrival(file_t *f1, file_t *f2)
{
if (f2->duplicates != 0)
@@ -1003,10 +1087,12 @@ void help_text()
printf(" \twith -s or --symlinks, or when specifying a\n");
printf(" \tparticular directory more than once; refer to the\n");
printf(" \tfdupes documentation for additional information\n");
- /*printf(" -l --relink \t(description)\n");*/
+ printf(" -L --linkhard \thardlink duplicate files to the first file in\n");
+ printf(" \teach set of duplicates without prompting the user\n");
printf(" -N --noprompt \ttogether with --delete, preserve the first file in\n");
printf(" \teach set of duplicates and delete the rest without\n");
printf(" \tprompting the user\n");
+ printf(" -D --debug \tenable debugging information\n");
printf(" -p --permissions \tdon't consider files with different owner/group or permission bits as duplicates\n");
printf(" -o --order \tselect sort order for output, linking and deleting. One of:\n");
printf(" time \torder by mtime (default)\n");
@@ -1047,12 +1133,14 @@ int main(int argc, char **argv) {
{ "symlinks", 0, 0, 's' },
{ "hardlinks", 0, 0, 'H' },
{ "relink", 0, 0, 'l' },
+ { "linkhard", 0, 0, 'L' },
{ "noempty", 0, 0, 'n' },
{ "nohidden", 0, 0, 'A' },
{ "delete", 0, 0, 'd' },
{ "version", 0, 0, 'v' },
{ "help", 0, 0, 'h' },
{ "noprompt", 0, 0, 'N' },
+ { "debug", 0, 0, 'D' },
{ "summarize", 0, 0, 'm'},
{ "summary", 0, 0, 'm' },
{ "permissions", 0, 0, 'p' },
@@ -1068,7 +1156,7 @@ int main(int argc, char **argv) {
oldargv = cloneargs(argc, argv);
- while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpo:"
+ while ((opt = GETOPT(argc, argv, "frRq1SsHlLndDvhNmpo:"
#ifndef OMIT_GETOPT_LONG
, long_options, NULL
#endif
@@ -1107,6 +1195,12 @@ int main(int argc, char **argv) {
case 'd':
SETFLAG(flags, F_DELETEFILES);
break;
+ case 'L':
+ SETFLAG(flags, F_HARDLINKFILES);
+ break;
+ case 'D':
+ SETFLAG(flags, F_DEBUGINFO);
+ break;
case 'v':
printf("fdupes %s\n", VERSION);
exit(0);
@@ -1154,6 +1248,16 @@ int main(int argc, char **argv) {
exit(1);
}
+ if (ISFLAG(flags, F_HARDLINKFILES) && ISFLAG(flags, F_DELETEFILES)) {
+ errormsg("options --linkhard and --delete are not compatible\n");
+ exit(1);
+ }
+
+ if (ISFLAG(flags, F_HARDLINKFILES) && ISFLAG(flags, F_CONSIDERHARDLINKS)) {
+ errormsg("options --linkhard and --hardlinks are not compatible\n");
+ exit(1);
+ }
+
if (ISFLAG(flags, F_RECURSEAFTER)) {
firstrecurse = nonoptafter("--recurse:", argc, oldargv, argv, optind);
@@ -1245,12 +1349,23 @@ int main(int argc, char **argv) {
else
- if (ISFLAG(flags, F_SUMMARIZEMATCHES))
- summarizematches(files);
-
- else
+ if (ISFLAG(flags, F_HARDLINKFILES))
+
+ if (ISFLAG(flags, F_DEBUGINFO))
+ hardlinkfiles(files, 1);
+ else
+ hardlinkfiles(files, 0);
- printmatches(files);
+ else {
+
+ if (ISFLAG(flags, F_SUMMARIZEMATCHES))
+ summarizematches(files);
+
+ else
+
+ printmatches(files);
+
+ }
while (files) {
curfile = files->next;
Index: fdupes-fdupes-1.51/fdupes.1
===================================================================
--- fdupes-fdupes-1.51.orig/fdupes.1
+++ fdupes-fdupes-1.51/fdupes.1
@@ -59,10 +59,17 @@ prompt user for files to preserve, delet
.B CAVEATS
below)
.TP
+.B -L --hardlink
+replace all duplicate files with hardlinks to the
+first file in each set of duplicates
+.TP
.B -N --noprompt
when used together with \-\-delete, preserve the first file in each
set of duplicates and delete the others without prompting the user
.TP
+.B -D --debug
+provide debugging information
+.TP
.B -p --permissions
don't consider files with different owner/group or permission bits as duplicates
.TP

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:761e16d4ecfef7302c62fe7ef1e181cd34f5c6ce5377dcad96e3ed44fb364986
size 18930

3
fdupes-1.6.1.tar.gz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9d6b6fdb0b8419815b4df3bdfd0aebc135b8276c90bbbe78ebe6af0b88ba49ea
size 20869

View File

@ -1,7 +1,7 @@
Index: Makefile Index: Makefile
=================================================================== ===================================================================
--- Makefile.orig --- Makefile.orig 2016-08-21 06:54:46.000000000 +0200
+++ Makefile +++ Makefile 2016-11-04 13:46:21.037423459 +0100
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
# determination of the actual installation directories. # determination of the actual installation directories.
# Suggested values are "/usr/local", "/usr", "/pkgs/fdupes-$(VERSION)" # Suggested values are "/usr/local", "/usr", "/pkgs/fdupes-$(VERSION)"
@ -11,12 +11,3 @@ Index: Makefile
# #
# When compiling for 32-bit systems, FILEOFFSET_64BIT must be enabled # When compiling for 32-bit systems, FILEOFFSET_64BIT must be enabled
@@ -56,7 +56,7 @@ BIN_DIR = $(PREFIX)/bin
# MAN_DIR indicates directory where the fdupes man page is to be
# installed. Suggested value is "$(PREFIX)/man/man1"
#
-MAN_BASE_DIR = $(PREFIX)/man
+MAN_BASE_DIR = $(PREFIX)/share/man
MAN_DIR = $(MAN_BASE_DIR)/man1
MAN_EXT = 1

View File

@ -1,3 +1,28 @@
-------------------------------------------------------------------
Fri Nov 4 14:33:59 UTC 2016 - psimons@suse.com
- Drop 50_bts284274_hardlinkreplace.dpatch. The --linkhard option
added by this patch has an implementation bug that can cause data
loss. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=677419
has more details.
-------------------------------------------------------------------
Fri Nov 4 13:47:27 UTC 2016 - psimons@suse.com
- Update to version 1.6.1. The following patches have been applied
upstream and were dropped:
* 0001-restore-pristine-code.patch
* 0002-Added-to-escape-minus-signs-in-manpage-lintian-warni.patch
* 0003-Fix-a-typo-in-a-manpage-bts353789.patch
* 0005-add-summarize-to-manpage-bts481809.patch
* 0006-add-nohidden-support-bts511702.patch
* 0007-Disambiguate-the-options-recurse-and-recurse-bts5371.patch
* 0008-speedup-the-file-compare.patch
* 0009-glibc-endianness-check-in-md5.patch
* 0010-add-permissions-mode.patch
* 0011-add-an-option-to-sort-duplicate-files-by-name.patch
- 50_bts284274_hardlinkreplace.dpatch had to be refreshed.
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Aug 4 13:01:47 UTC 2015 - tchvatal@suse.com Tue Aug 4 13:01:47 UTC 2015 - tchvatal@suse.com

View File

@ -1,7 +1,7 @@
# #
# spec file for package fdupes # spec file for package fdupes
# #
# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
# #
# All modifications and additions to the file contributed by third parties # All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed # remain the property of their copyright owners, unless otherwise agreed
@ -17,61 +17,25 @@
Name: fdupes Name: fdupes
Version: 1.51 Version: 1.6.1
Release: 0 Release: 0
Summary: Identifying or deleting duplicate files Summary: Identifying or deleting duplicate files
License: MIT License: MIT
Group: Productivity/Archiving/Compression Group: Productivity/Archiving/Compression
Url: https://github.com/adrianlopezroche/fdupes Url: https://github.com/adrianlopezroche/fdupes
Source0: https://github.com/adrianlopezroche/%{name}/archive/%{name}-%{version}.tar.gz Source0: https://github.com/adrianlopezroche/fdupes/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
Source1: macros.fdupes Source1: macros.fdupes
#PATCH-FIX-SUSE: fix patch according distro's needs #PATCH-FIX-SUSE: fix patch according distro's needs
Patch0: fdupes-makefile.patch Patch0: fdupes-makefile.patch
# I'v imported all patches from Debian (Fedora and Gentoo has the subset only)
# to git and added there as individual patches
# TODO: export the git repo or upstream it
#PATCH-FIX-DEBIAN: obsoletes partly the speedup patch
Patch1: 0001-restore-pristine-code.patch
#PATCH-FIX-DEBIAN: minor typo in man page
Patch2: 0002-Added-to-escape-minus-signs-in-manpage-lintian-warni.patch
#PATCH-FIX-DEBIAN: dtto
Patch3: 0003-Fix-a-typo-in-a-manpage-bts353789.patch
#PATCH-FIX-DEBIAN: manpage fix
Patch5: 0005-add-summarize-to-manpage-bts481809.patch
#PATCH-FIX-DEBIAN: dtto
Patch6: 0006-add-nohidden-support-bts511702.patch
#PATCH-FIX-DEBIAN: manpage fix
Patch7: 0007-Disambiguate-the-options-recurse-and-recurse-bts5371.patch
#PATCH-FIX-OPENSUSE: speedup the compare
Patch8: 0008-speedup-the-file-compare.patch
#PATCH-FIX-OPENSUSE: endianness check in md5.h
Patch9: 0009-glibc-endianness-check-in-md5.patch
#PATCH-FIX-OPENSUSE: -p/--permissions mode
Patch10: 0010-add-permissions-mode.patch
#PATCH-FIX-OPENSUSE: -o/--order mode
Patch11: 0011-add-an-option-to-sort-duplicate-files-by-name.patch
#PATCH-FIX-DEBIAN: add -L/--linkhard
Patch20: 50_bts284274_hardlinkreplace.dpatch
BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build
%description %description
FDUPES is a program for identifying or deleting duplicate files FDUPES is a program for identifying or deleting duplicate files
residing within specified directories residing within specified directories.
%prep %prep
%setup -q -n %{name}-%{name}-%{version} %setup -q
%patch0 %patch0
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch11 -p1
%patch20 -p1
%build %build
make %{?_smp_mflags} COMPILER_OPTIONS="%{optflags}" make %{?_smp_mflags} COMPILER_OPTIONS="%{optflags}"