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:
commit
803f059ab4
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
@ -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
|
||||
|
@ -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");
|
@ -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;
|
@ -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
|
@ -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
3
fdupes-1.6.1.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9d6b6fdb0b8419815b4df3bdfd0aebc135b8276c90bbbe78ebe6af0b88ba49ea
|
||||
size 20869
|
@ -1,7 +1,7 @@
|
||||
Index: Makefile
|
||||
===================================================================
|
||||
--- Makefile.orig
|
||||
+++ Makefile
|
||||
--- Makefile.orig 2016-08-21 06:54:46.000000000 +0200
|
||||
+++ Makefile 2016-11-04 13:46:21.037423459 +0100
|
||||
@@ -11,7 +11,7 @@
|
||||
# determination of the actual installation directories.
|
||||
# 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
|
||||
@@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
46
fdupes.spec
46
fdupes.spec
@ -1,7 +1,7 @@
|
||||
#
|
||||
# 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
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -17,61 +17,25 @@
|
||||
|
||||
|
||||
Name: fdupes
|
||||
Version: 1.51
|
||||
Version: 1.6.1
|
||||
Release: 0
|
||||
Summary: Identifying or deleting duplicate files
|
||||
License: MIT
|
||||
Group: Productivity/Archiving/Compression
|
||||
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
|
||||
#PATCH-FIX-SUSE: fix patch according distro's needs
|
||||
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
|
||||
|
||||
%description
|
||||
FDUPES is a program for identifying or deleting duplicate files
|
||||
residing within specified directories
|
||||
residing within specified directories.
|
||||
|
||||
%prep
|
||||
%setup -q -n %{name}-%{name}-%{version}
|
||||
%setup -q
|
||||
%patch0
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
%patch11 -p1
|
||||
%patch20 -p1
|
||||
|
||||
%build
|
||||
make %{?_smp_mflags} COMPILER_OPTIONS="%{optflags}"
|
||||
|
Loading…
Reference in New Issue
Block a user