From 568f9f339201f5ec7e6cf4534d7c66a3a643c47b Mon Sep 17 00:00:00 2001 From: clara-j Date: Fri, 11 Sep 2015 21:37:51 -0400 Subject: [PATCH 1/9] Add b and B option to limit files considered by size --- CHANGES | 3 +++ CONTRIBUTORS | 2 +- README | 2 ++ fdupes.1 | 6 +++++ fdupes.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 83 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index d2bcdfb..9ca417c 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,9 @@ who contributed the patch or idea appears first, followed by those who've otherwise worked on that item. For a list of contributors names and identifiers please see the CONTRIBUTORS file. +Changes from 1.51 to xxx +- Added -b (min) and -B (max) arguments to allow to filter files + based on the given values Changes from 1.50 to 1.51 diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f238f2b..13b3fdf 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -15,4 +15,4 @@ on their contributions. Names are listed in alphabetical order. [LR] Lukas Ruf (lukas@lpr.ch) [PB] Peter Bray (Sydney, Australia) [SSD] Steven S. Dick (ssd@nevets.oau.org) - + [JC] Jason Clara (Toronto, Canada) diff --git a/README b/README index 2882d99..50ced72 100644 --- a/README +++ b/README @@ -20,6 +20,8 @@ Usage: fdupes [options] DIRECTORY... -f --omitfirst omit the first file in each set of matches -1 --sameline list each set of matches on a single line -S --size show size of duplicate files + -b --minfilesize Consider only files larger than N KB + -B --maxfilesize Consider only files smaller than N KB -q --quiet hide progress indicator -d --delete prompt user for files to preserve and delete all others; important: under particular circumstances, diff --git a/fdupes.1 b/fdupes.1 index d8be883..bdbd088 100644 --- a/fdupes.1 +++ b/fdupes.1 @@ -48,6 +48,12 @@ list each set of matches on a single line .B -S --size show size of duplicate files .TP +.B -b --minfilesize +Consider only files larger than N KB +.TP +.B -B --maxfilesize +Consider only files smaller than N KB +.TP .B -m --summarize summarize duplicate files information .TP diff --git a/fdupes.c b/fdupes.c index d33d859..b0e25c7 100644 --- a/fdupes.c +++ b/fdupes.c @@ -54,6 +54,8 @@ #define F_SUMMARIZEMATCHES 0x0800 #define F_EXCLUDEHIDDEN 0x1000 #define F_PERMISSIONS 0x2000 +#define F_MINFILESIZE 0x4000 +#define F_MAXFILESIZE 0x8000 typedef enum { ORDER_TIME = 0, @@ -64,6 +66,9 @@ char *program_name; unsigned long flags = 0; +long min_file_size = 0; +long max_file_size = 0; + #define CHUNK_SIZE 8192 #define INPUT_SIZE 256 @@ -237,6 +242,23 @@ int nonoptafter(char *option, int argc, char **oldargv, return x; } +int skipfile(file_t *file) +{ + if(ISFLAG(flags, F_MINFILESIZE) && filesize(file->d_name) < min_file_size*1024) + { + printf("%s is too small: %ld > %ld\n", file->d_name, min_file_size*1024, filesize(file->d_name)); + return 1; + } + + if(ISFLAG(flags, F_MAXFILESIZE) && filesize(file->d_name) > max_file_size*1024) + { + printf("%s is too big: %ld < %ld\n", file->d_name, max_file_size*1024, filesize(file->d_name)); + return 2; + } + + return 0; +} + int grokdir(char *dir, file_t **filelistp) { DIR *cd; @@ -305,6 +327,13 @@ int grokdir(char *dir, file_t **filelistp) free(fullname); } + if(skipfile(newfile)) + { + free(newfile->d_name); + free(newfile); + continue; + } + if (filesize(newfile->d_name) == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) { free(newfile->d_name); free(newfile); @@ -995,6 +1024,8 @@ void help_text() 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"); + printf(" -b --minfilesize \tConsider only files larger than N KB\n"); + printf(" -B --maxfilesize \tConsider only files smaller than N KB\n"); printf(" -m --summarize \tsummarize dupe information\n"); printf(" -q --quiet \thide progress indicator\n"); printf(" -d --delete \tprompt user for files to preserve and delete all\n"); @@ -1057,6 +1088,8 @@ int main(int argc, char **argv) { { "summary", 0, 0, 'm' }, { "permissions", 0, 0, 'p' }, { "order", 1, 0, 'o' }, + { "minfilesize", 1, 0, 'b' }, + { "maxfilesize", 1, 0, 'B' }, { 0, 0, 0, 0 } }; #define GETOPT getopt_long @@ -1068,7 +1101,7 @@ int main(int argc, char **argv) { oldargv = cloneargs(argc, argv); - while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpo:" + while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpo:b:B:" #ifndef OMIT_GETOPT_LONG , long_options, NULL #endif @@ -1118,6 +1151,43 @@ int main(int argc, char **argv) { break; case 'm': SETFLAG(flags, F_SUMMARIZEMATCHES); + break; + case 'b': + printf("opt: %s\n", optarg); + SETFLAG(flags, F_MINFILESIZE); + if (strlen(optarg) == 0) { + fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider"); + exit(1); + } + char * endPtrb = NULL; + long arg_b = strtol(optarg,&endPtrb,10); + + if ( endPtrb == NULL || arg_b == 0){ + fprintf(stderr, "fdupes -b: provide numeric argument >0 for minimum file size to consider"); + exit(1); + } + min_file_size = arg_b; + break; + case 'B': + SETFLAG(flags, F_MAXFILESIZE); + if (strlen(optarg) == 0) { + fprintf(stderr,"fdupes -B: provide numeric argument >0 for maximum file size to consider"); + exit(1); + } + char * endPtrB = NULL; + long arg_B = strtol(optarg,&endPtrB,10); + + if ( endPtrB == NULL || arg_B == 0){ + fprintf(stderr, "fdupes -B: provide numeric argument >0 for minimum file size to consider"); + exit(1); + } + max_file_size = arg_B; + + if (ISFLAG(flags, F_MAXFILESIZE) && ISFLAG(flags, F_MINFILESIZE) && min_file_size > max_file_size){ + fprintf(stderr, "fdupes -B: min file size (-b) must be smaller then max file size(-B)"); + exit(1); + } + break; case 'p': SETFLAG(flags, F_PERMISSIONS); From a1fe1cd6ae5ef5793cf2b375839c5b5eebd02219 Mon Sep 17 00:00:00 2001 From: clara-j Date: Fri, 11 Sep 2015 22:01:38 -0400 Subject: [PATCH 2/9] Add b and B option to limit files considered by size --- fdupes.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fdupes.c b/fdupes.c index b0e25c7..7aed3e5 100644 --- a/fdupes.c +++ b/fdupes.c @@ -246,13 +246,11 @@ int skipfile(file_t *file) { if(ISFLAG(flags, F_MINFILESIZE) && filesize(file->d_name) < min_file_size*1024) { - printf("%s is too small: %ld > %ld\n", file->d_name, min_file_size*1024, filesize(file->d_name)); return 1; } if(ISFLAG(flags, F_MAXFILESIZE) && filesize(file->d_name) > max_file_size*1024) { - printf("%s is too big: %ld < %ld\n", file->d_name, max_file_size*1024, filesize(file->d_name)); return 2; } @@ -1153,7 +1151,6 @@ int main(int argc, char **argv) { SETFLAG(flags, F_SUMMARIZEMATCHES); break; case 'b': - printf("opt: %s\n", optarg); SETFLAG(flags, F_MINFILESIZE); if (strlen(optarg) == 0) { fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider"); From e1238214000bb9b6f13222750f08ff927f50d15f Mon Sep 17 00:00:00 2001 From: clara-j Date: Sat, 12 Sep 2015 08:18:42 -0400 Subject: [PATCH 3/9] fix bug related to b and B and recursive --- fdupes.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/fdupes.c b/fdupes.c index 7aed3e5..297984b 100644 --- a/fdupes.c +++ b/fdupes.c @@ -242,14 +242,15 @@ int nonoptafter(char *option, int argc, char **oldargv, return x; } -int skipfile(file_t *file) +int skipfile(file_t *file, struct stat info) { - if(ISFLAG(flags, F_MINFILESIZE) && filesize(file->d_name) < min_file_size*1024) + if(ISFLAG(flags, F_MINFILESIZE) && !S_ISDIR(info.st_mode) && filesize(file->d_name) < min_file_size*1024) { + //printf("Small: %s %ld - %ld\n", file->d_name, min_file_size, filesize(file->d_name)); return 1; } - if(ISFLAG(flags, F_MAXFILESIZE) && filesize(file->d_name) > max_file_size*1024) + if(ISFLAG(flags, F_MAXFILESIZE) && !S_ISDIR(info.st_mode) && filesize(file->d_name) > max_file_size*1024) { return 2; } @@ -325,13 +326,6 @@ int grokdir(char *dir, file_t **filelistp) free(fullname); } - if(skipfile(newfile)) - { - free(newfile->d_name); - free(newfile); - continue; - } - if (filesize(newfile->d_name) == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) { free(newfile->d_name); free(newfile); @@ -349,6 +343,13 @@ int grokdir(char *dir, file_t **filelistp) free(newfile); continue; } + + if(skipfile(newfile, info)) + { + free(newfile->d_name); + free(newfile); + continue; + } if (S_ISDIR(info.st_mode)) { if (ISFLAG(flags, F_RECURSE) && (ISFLAG(flags, F_FOLLOWLINKS) || !S_ISLNK(linfo.st_mode))) From 25737caa9853df3df1230cce970ca6c49767f06a Mon Sep 17 00:00:00 2001 From: clara-j Date: Sun, 13 Sep 2015 15:13:38 -0400 Subject: [PATCH 4/9] Add e option to spit byte for byte compare after checksum pass --- Makefile.inc/VERSION | 2 +- fdupes.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Makefile.inc/VERSION b/Makefile.inc/VERSION index 2ec1586..1961d59 100644 --- a/Makefile.inc/VERSION +++ b/Makefile.inc/VERSION @@ -2,4 +2,4 @@ # VERSION determines the program's version number. # -VERSION = 1.51 +VERSION = 1.52-dev diff --git a/fdupes.c b/fdupes.c index 297984b..6998869 100644 --- a/fdupes.c +++ b/fdupes.c @@ -56,6 +56,7 @@ #define F_PERMISSIONS 0x2000 #define F_MINFILESIZE 0x4000 #define F_MAXFILESIZE 0x8000 +#define F_SKIPBYTEVERIFY 0x10000 typedef enum { ORDER_TIME = 0, @@ -1100,7 +1101,7 @@ int main(int argc, char **argv) { oldargv = cloneargs(argc, argv); - while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpo:b:B:" + while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpeo:b:B:" #ifndef OMIT_GETOPT_LONG , long_options, NULL #endif @@ -1151,17 +1152,20 @@ int main(int argc, char **argv) { case 'm': SETFLAG(flags, F_SUMMARIZEMATCHES); break; + case 'e': + SETFLAG(flags, F_SKIPBYTEVERIFY); + break; case 'b': SETFLAG(flags, F_MINFILESIZE); if (strlen(optarg) == 0) { - fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider"); + fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } char * endPtrb = NULL; long arg_b = strtol(optarg,&endPtrb,10); if ( endPtrb == NULL || arg_b == 0){ - fprintf(stderr, "fdupes -b: provide numeric argument >0 for minimum file size to consider"); + fprintf(stderr, "fdupes -b: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } min_file_size = arg_b; @@ -1169,20 +1173,20 @@ int main(int argc, char **argv) { case 'B': SETFLAG(flags, F_MAXFILESIZE); if (strlen(optarg) == 0) { - fprintf(stderr,"fdupes -B: provide numeric argument >0 for maximum file size to consider"); + fprintf(stderr,"fdupes -B: provide numeric argument >0 for maximum file size to consider\n"); exit(1); } char * endPtrB = NULL; long arg_B = strtol(optarg,&endPtrB,10); if ( endPtrB == NULL || arg_B == 0){ - fprintf(stderr, "fdupes -B: provide numeric argument >0 for minimum file size to consider"); + fprintf(stderr, "fdupes -B: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } max_file_size = arg_B; if (ISFLAG(flags, F_MAXFILESIZE) && ISFLAG(flags, F_MINFILESIZE) && min_file_size > max_file_size){ - fprintf(stderr, "fdupes -B: min file size (-b) must be smaller then max file size(-B)"); + fprintf(stderr, "fdupes -B: min file size (-b) must be smaller then max file size(-B)\n"); exit(1); } @@ -1274,7 +1278,7 @@ int main(int argc, char **argv) { continue; } - if (confirmmatch(file1, file2)) { + if (ISFLAG(flags, F_SKIPBYTEVERIFY) || confirmmatch(file1, file2)) { registerpair(match, curfile, (ordertype == ORDER_TIME) ? sort_pairs_by_mtime : sort_pairs_by_filename ); From 7c790773f75a7b53a9705d3f4e23290bd22da8fc Mon Sep 17 00:00:00 2001 From: clara-j Date: Sun, 13 Sep 2015 15:13:38 -0400 Subject: [PATCH 5/9] Add e option to skip byte for byte compare after checksum pass --- Makefile.inc/VERSION | 2 +- fdupes.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/Makefile.inc/VERSION b/Makefile.inc/VERSION index 2ec1586..1961d59 100644 --- a/Makefile.inc/VERSION +++ b/Makefile.inc/VERSION @@ -2,4 +2,4 @@ # VERSION determines the program's version number. # -VERSION = 1.51 +VERSION = 1.52-dev diff --git a/fdupes.c b/fdupes.c index 297984b..6998869 100644 --- a/fdupes.c +++ b/fdupes.c @@ -56,6 +56,7 @@ #define F_PERMISSIONS 0x2000 #define F_MINFILESIZE 0x4000 #define F_MAXFILESIZE 0x8000 +#define F_SKIPBYTEVERIFY 0x10000 typedef enum { ORDER_TIME = 0, @@ -1100,7 +1101,7 @@ int main(int argc, char **argv) { oldargv = cloneargs(argc, argv); - while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpo:b:B:" + while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpeo:b:B:" #ifndef OMIT_GETOPT_LONG , long_options, NULL #endif @@ -1151,17 +1152,20 @@ int main(int argc, char **argv) { case 'm': SETFLAG(flags, F_SUMMARIZEMATCHES); break; + case 'e': + SETFLAG(flags, F_SKIPBYTEVERIFY); + break; case 'b': SETFLAG(flags, F_MINFILESIZE); if (strlen(optarg) == 0) { - fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider"); + fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } char * endPtrb = NULL; long arg_b = strtol(optarg,&endPtrb,10); if ( endPtrb == NULL || arg_b == 0){ - fprintf(stderr, "fdupes -b: provide numeric argument >0 for minimum file size to consider"); + fprintf(stderr, "fdupes -b: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } min_file_size = arg_b; @@ -1169,20 +1173,20 @@ int main(int argc, char **argv) { case 'B': SETFLAG(flags, F_MAXFILESIZE); if (strlen(optarg) == 0) { - fprintf(stderr,"fdupes -B: provide numeric argument >0 for maximum file size to consider"); + fprintf(stderr,"fdupes -B: provide numeric argument >0 for maximum file size to consider\n"); exit(1); } char * endPtrB = NULL; long arg_B = strtol(optarg,&endPtrB,10); if ( endPtrB == NULL || arg_B == 0){ - fprintf(stderr, "fdupes -B: provide numeric argument >0 for minimum file size to consider"); + fprintf(stderr, "fdupes -B: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } max_file_size = arg_B; if (ISFLAG(flags, F_MAXFILESIZE) && ISFLAG(flags, F_MINFILESIZE) && min_file_size > max_file_size){ - fprintf(stderr, "fdupes -B: min file size (-b) must be smaller then max file size(-B)"); + fprintf(stderr, "fdupes -B: min file size (-b) must be smaller then max file size(-B)\n"); exit(1); } @@ -1274,7 +1278,7 @@ int main(int argc, char **argv) { continue; } - if (confirmmatch(file1, file2)) { + if (ISFLAG(flags, F_SKIPBYTEVERIFY) || confirmmatch(file1, file2)) { registerpair(match, curfile, (ordertype == ORDER_TIME) ? sort_pairs_by_mtime : sort_pairs_by_filename ); From d855ecef10fd0fd7a41c9cddf41e295fc3832779 Mon Sep 17 00:00:00 2001 From: clara-j Date: Mon, 14 Sep 2015 12:08:53 -0400 Subject: [PATCH 6/9] make better use of getfilestats --- fdupes.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/fdupes.c b/fdupes.c index 6998869..ac9e491 100644 --- a/fdupes.c +++ b/fdupes.c @@ -245,13 +245,13 @@ int nonoptafter(char *option, int argc, char **oldargv, int skipfile(file_t *file, struct stat info) { - if(ISFLAG(flags, F_MINFILESIZE) && !S_ISDIR(info.st_mode) && filesize(file->d_name) < min_file_size*1024) + if(ISFLAG(flags, F_MINFILESIZE) && !S_ISDIR(info.st_mode) && file->size < min_file_size*1024) { //printf("Small: %s %ld - %ld\n", file->d_name, min_file_size, filesize(file->d_name)); return 1; } - if(ISFLAG(flags, F_MAXFILESIZE) && !S_ISDIR(info.st_mode) && filesize(file->d_name) > max_file_size*1024) + if(ISFLAG(flags, F_MAXFILESIZE) && !S_ISDIR(info.st_mode) && file->size > max_file_size*1024) { return 2; } @@ -259,6 +259,14 @@ int skipfile(file_t *file, struct stat info) return 0; } +void getfilestats(file_t *file) +{ + file->size = filesize(file->d_name); + file->inode = getinode(file->d_name); + file->device = getdevice(file->d_name); + file->mtime = getmtime(file->d_name); +} + int grokdir(char *dir, file_t **filelistp) { DIR *cd; @@ -315,6 +323,8 @@ int grokdir(char *dir, file_t **filelistp) if (lastchar >= 0 && dir[lastchar] != '/') strcat(newfile->d_name, "/"); strcat(newfile->d_name, dirinfo->d_name); + + getfilestats(newfile); if (ISFLAG(flags, F_EXCLUDEHIDDEN)) { fullname = strdup(newfile->d_name); @@ -327,7 +337,7 @@ int grokdir(char *dir, file_t **filelistp) free(fullname); } - if (filesize(newfile->d_name) == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) { + if (newfile->size == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) { free(newfile->d_name); free(newfile); continue; @@ -491,17 +501,10 @@ void purgetree(filetree_t *checktree) free(checktree); } -void getfilestats(file_t *file) -{ - file->size = filesize(file->d_name); - file->inode = getinode(file->d_name); - file->device = getdevice(file->d_name); - file->mtime = getmtime(file->d_name); -} int registerfile(filetree_t **branch, file_t *file) { - getfilestats(file); + //getfilestats(file); *branch = (filetree_t*) malloc(sizeof(filetree_t)); if (*branch == NULL) { @@ -541,11 +544,11 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file) duplicates unless the user specifies otherwise. */ - if (!ISFLAG(flags, F_CONSIDERHARDLINKS) && (getinode(file->d_name) == - checktree->file->inode) && (getdevice(file->d_name) == + if (!ISFLAG(flags, F_CONSIDERHARDLINKS) && (file->inode == + checktree->file->inode) && (file->device == checktree->file->device)) return NULL; - fsize = filesize(file->d_name); + fsize = file->size; if (fsize < checktree->file->size) cmpresult = -1; @@ -639,7 +642,7 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file) } } else { - getfilestats(file); + //getfilestats(file); return &checktree->file; } } From d4201d7b25bacedbaeed942f715ee17af3b9de68 Mon Sep 17 00:00:00 2001 From: clara-j Date: Wed, 16 Sep 2015 08:34:39 -0400 Subject: [PATCH 7/9] Update readme and other documents for new e argument --- CHANGES | 2 ++ README | 2 ++ fdupes.1 | 3 +++ fdupes.c | 2 ++ 4 files changed, 9 insertions(+) diff --git a/CHANGES b/CHANGES index 9ca417c..85f6141 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,8 @@ contributors names and identifiers please see the CONTRIBUTORS file. Changes from 1.51 to xxx - Added -b (min) and -B (max) arguments to allow to filter files based on the given values +- Added -e argument to allow for skipping the byte to byte verification + when the crc matches Changes from 1.50 to 1.51 diff --git a/README b/README index 50ced72..d523216 100644 --- a/README +++ b/README @@ -22,6 +22,8 @@ Usage: fdupes [options] DIRECTORY... -S --size show size of duplicate files -b --minfilesize Consider only files larger than N KB -B --maxfilesize Consider only files smaller than N KB + -e --skipverify Skip final byte to byte verification after + checksum match -q --quiet hide progress indicator -d --delete prompt user for files to preserve and delete all others; important: under particular circumstances, diff --git a/fdupes.1 b/fdupes.1 index bdbd088..c67380d 100644 --- a/fdupes.1 +++ b/fdupes.1 @@ -54,6 +54,9 @@ Consider only files larger than N KB .B -B --maxfilesize Consider only files smaller than N KB .TP +.B -e --skipverify +Skip final byte to byte verification after a checksum match +.TP .B -m --summarize summarize duplicate files information .TP diff --git a/fdupes.c b/fdupes.c index ac9e491..4b3c885 100644 --- a/fdupes.c +++ b/fdupes.c @@ -1029,6 +1029,7 @@ void help_text() printf(" -S --size \tshow size of duplicate files\n"); printf(" -b --minfilesize \tConsider only files larger than N KB\n"); printf(" -B --maxfilesize \tConsider only files smaller than N KB\n"); + printf(" -e --skipverify \tSkip final byte to byte verification after checksum match\n"); printf(" -m --summarize \tsummarize dupe information\n"); printf(" -q --quiet \thide progress indicator\n"); printf(" -d --delete \tprompt user for files to preserve and delete all\n"); @@ -1093,6 +1094,7 @@ int main(int argc, char **argv) { { "order", 1, 0, 'o' }, { "minfilesize", 1, 0, 'b' }, { "maxfilesize", 1, 0, 'B' }, + { "skipverify", 0, 0, 'e' }, { 0, 0, 0, 0 } }; #define GETOPT getopt_long From 107094966c09409d8767590056f96fac01038e2a Mon Sep 17 00:00:00 2001 From: clara-j Date: Fri, 18 Sep 2015 10:37:38 -0400 Subject: [PATCH 8/9] Add x argument to stop going cross device, also add ability to add M, K, or G to size arguments --- CHANGES | 2 ++ README | 2 ++ fdupes.1 | 3 ++ fdupes.c | 98 ++++++++++++++++++++++++++++++++++++++++---------------- 4 files changed, 77 insertions(+), 28 deletions(-) diff --git a/CHANGES b/CHANGES index 85f6141..81db5e8 100644 --- a/CHANGES +++ b/CHANGES @@ -11,6 +11,8 @@ Changes from 1.51 to xxx based on the given values - Added -e argument to allow for skipping the byte to byte verification when the crc matches +- Added -x argument to not cross into another device from the given + arguments starting device Changes from 1.50 to 1.51 diff --git a/README b/README index d523216..56ace1e 100644 --- a/README +++ b/README @@ -24,6 +24,8 @@ Usage: fdupes [options] DIRECTORY... -B --maxfilesize Consider only files smaller than N KB -e --skipverify Skip final byte to byte verification after checksum match + -x --xdevice Do not cross into another device from the given + arguments starting device -q --quiet hide progress indicator -d --delete prompt user for files to preserve and delete all others; important: under particular circumstances, diff --git a/fdupes.1 b/fdupes.1 index c67380d..c70c375 100644 --- a/fdupes.1 +++ b/fdupes.1 @@ -57,6 +57,9 @@ Consider only files smaller than N KB .B -e --skipverify Skip final byte to byte verification after a checksum match .TP +.B -x --xdevice +Do not cross into another device from the given arguments starting device +.TP .B -m --summarize summarize duplicate files information .TP diff --git a/fdupes.c b/fdupes.c index 4b3c885..c010d70 100644 --- a/fdupes.c +++ b/fdupes.c @@ -57,6 +57,7 @@ #define F_MINFILESIZE 0x4000 #define F_MAXFILESIZE 0x8000 #define F_SKIPBYTEVERIFY 0x10000 +#define F_XDEVICE 0x20000 typedef enum { ORDER_TIME = 0, @@ -67,8 +68,9 @@ char *program_name; unsigned long flags = 0; -long min_file_size = 0; -long max_file_size = 0; +unsigned long long int min_file_size = 0; +unsigned long long int max_file_size = 0; +dev_t workingdevice; #define CHUNK_SIZE 8192 @@ -245,13 +247,13 @@ int nonoptafter(char *option, int argc, char **oldargv, int skipfile(file_t *file, struct stat info) { - if(ISFLAG(flags, F_MINFILESIZE) && !S_ISDIR(info.st_mode) && file->size < min_file_size*1024) + if(ISFLAG(flags, F_MINFILESIZE) && !S_ISDIR(info.st_mode) && file->size < min_file_size) { //printf("Small: %s %ld - %ld\n", file->d_name, min_file_size, filesize(file->d_name)); return 1; } - if(ISFLAG(flags, F_MAXFILESIZE) && !S_ISDIR(info.st_mode) && file->size > max_file_size*1024) + if(ISFLAG(flags, F_MAXFILESIZE) && !S_ISDIR(info.st_mode) && file->size > max_file_size) { return 2; } @@ -279,7 +281,11 @@ int grokdir(char *dir, file_t **filelistp) static int progress = 0; static char indicator[] = "-\\|/"; char *fullname, *name; - + + if (ISFLAG(flags, F_XDEVICE) && getdevice(dir) != workingdevice) { + printf("Skipping out of device item: %s\n", dir); + return 0; + } cd = opendir(dir); if (!cd) { @@ -1030,6 +1036,7 @@ void help_text() printf(" -b --minfilesize \tConsider only files larger than N KB\n"); printf(" -B --maxfilesize \tConsider only files smaller than N KB\n"); printf(" -e --skipverify \tSkip final byte to byte verification after checksum match\n"); + printf(" -x --xdevice \tDo not cross into another device from the given arguments starting device\n"); printf(" -m --summarize \tsummarize dupe information\n"); printf(" -q --quiet \thide progress indicator\n"); printf(" -d --delete \tprompt user for files to preserve and delete all\n"); @@ -1053,6 +1060,42 @@ void help_text() #endif } +unsigned long long int parsesizeinput(char* input){ + unsigned long long int inputsize; + char * endptr = NULL; + inputsize = strtoull(input, &endptr,10); + switch(*endptr){ + case '\0': + inputsize = inputsize * 1024; + break; + case 'k': + case 'K': + inputsize = inputsize * 1024; + endptr++; + break; + case 'm': + case 'M': + inputsize = inputsize * 1024*1024; + endptr++; + break; + case 'g': + case 'G': + inputsize = inputsize *1024*1024*1024; + endptr++; + break; + default: + break; + } + printf("Size: %lld - %d\n", inputsize, *endptr); + + if (*endptr != '\0'){ + fprintf(stderr,"fdupes: provide numeric argument >0 for file size to consider\n"); + exit(1); + } + printf("Size: %lld\n", inputsize); + return inputsize; +} + int main(int argc, char **argv) { int x; int opt; @@ -1067,7 +1110,8 @@ int main(int argc, char **argv) { char **oldargv; int firstrecurse; ordertype_t ordertype = ORDER_TIME; - + + #ifndef OMIT_GETOPT_LONG static struct option long_options[] = { @@ -1095,6 +1139,7 @@ int main(int argc, char **argv) { { "minfilesize", 1, 0, 'b' }, { "maxfilesize", 1, 0, 'B' }, { "skipverify", 0, 0, 'e' }, + { "xdevice", 0, 0, 'x' }, { 0, 0, 0, 0 } }; #define GETOPT getopt_long @@ -1106,7 +1151,7 @@ int main(int argc, char **argv) { oldargv = cloneargs(argc, argv); - while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpeo:b:B:" + while ((opt = GETOPT(argc, argv, "frRq1SsHlndvhNmpexo:b:B:" #ifndef OMIT_GETOPT_LONG , long_options, NULL #endif @@ -1160,20 +1205,16 @@ int main(int argc, char **argv) { case 'e': SETFLAG(flags, F_SKIPBYTEVERIFY); break; + case 'x': + SETFLAG(flags, F_XDEVICE); + break; case 'b': SETFLAG(flags, F_MINFILESIZE); if (strlen(optarg) == 0) { fprintf(stderr,"fdupes -b: provide numeric argument >0 for minimum file size to consider\n"); exit(1); } - char * endPtrb = NULL; - long arg_b = strtol(optarg,&endPtrb,10); - - if ( endPtrb == NULL || arg_b == 0){ - fprintf(stderr, "fdupes -b: provide numeric argument >0 for minimum file size to consider\n"); - exit(1); - } - min_file_size = arg_b; + min_file_size = parsesizeinput(optarg); break; case 'B': SETFLAG(flags, F_MAXFILESIZE); @@ -1181,14 +1222,7 @@ int main(int argc, char **argv) { fprintf(stderr,"fdupes -B: provide numeric argument >0 for maximum file size to consider\n"); exit(1); } - char * endPtrB = NULL; - long arg_B = strtol(optarg,&endPtrB,10); - - if ( endPtrB == NULL || arg_B == 0){ - fprintf(stderr, "fdupes -B: provide numeric argument >0 for minimum file size to consider\n"); - exit(1); - } - max_file_size = arg_B; + max_file_size = parsesizeinput(optarg); if (ISFLAG(flags, F_MAXFILESIZE) && ISFLAG(flags, F_MINFILESIZE) && min_file_size > max_file_size){ fprintf(stderr, "fdupes -B: min file size (-b) must be smaller then max file size(-B)\n"); @@ -1244,18 +1278,26 @@ int main(int argc, char **argv) { /* F_RECURSE is not set for directories before --recurse: */ for (x = optind; x < firstrecurse; x++) - filecount += grokdir(argv[x], &files); - + { + workingdevice = getdevice(argv[x]); + filecount += grokdir(argv[x], &files); + } /* Set F_RECURSE for directories after --recurse: */ SETFLAG(flags, F_RECURSE); for (x = firstrecurse; x < argc; x++) - filecount += grokdir(argv[x], &files); + { + workingdevice = getdevice(argv[x]); + filecount += grokdir(argv[x], &files); + } } else { - for (x = optind; x < argc; x++) - filecount += grokdir(argv[x], &files); + for (x = optind; x < argc; x++){ + workingdevice = getdevice(argv[x]); + filecount += grokdir(argv[x], &files); + } } + if (!files) { if (!ISFLAG(flags, F_HIDEPROGRESS)) fprintf(stderr, "\r%40s\r", " "); exit(0); From 512437f3bbc19582d0746d2d8a8e767126bf0c59 Mon Sep 17 00:00:00 2001 From: clara-j Date: Fri, 18 Sep 2015 10:39:14 -0400 Subject: [PATCH 9/9] Remove debug code --- fdupes.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fdupes.c b/fdupes.c index c010d70..921abd1 100644 --- a/fdupes.c +++ b/fdupes.c @@ -1086,13 +1086,10 @@ unsigned long long int parsesizeinput(char* input){ default: break; } - printf("Size: %lld - %d\n", inputsize, *endptr); - if (*endptr != '\0'){ fprintf(stderr,"fdupes: provide numeric argument >0 for file size to consider\n"); exit(1); } - printf("Size: %lld\n", inputsize); return inputsize; }