Lot of cosmetics + added the -i option.
authorFrancois Fleuret <francois@fleuret.org>
Wed, 10 Mar 2010 07:09:37 +0000 (08:09 +0100)
committerFrancois Fleuret <francois@fleuret.org>
Wed, 10 Mar 2010 07:09:37 +0000 (08:09 +0100)
finddup.1
finddup.c

index 4ba1807..71e0e57 100644 (file)
--- a/finddup.1
+++ b/finddup.1
@@ -22,10 +22,13 @@ present in DIR1 and not in DIR2.
 It compares files by first comparing their sizes, hence goes
 reasonably fast.
 
-When looking for identical files,
-.B finddup
-by default associates a group ID to every content, and prints it along
-the file names.
+When looking for identical files, \fBfinddup\fP associates by default
+a group ID to every content, and prints it along the file names.
+
+Note that
+.B finddup DIR
+is the same as
+.B finddup -i DIR DIR
 
 .SH "OPTIONS"
 .TP
@@ -37,6 +40,8 @@ ignore files and directories starting with a dot
 .TP
 \fB-c\fR
 do not show which files from DIR2 corresponds to files from DIR1
+(hence, show only the files from DIR1 which have an identical twin in
+DIR2)
 .TP
 \fB-g\fR
 do not show the file group IDs
@@ -46,6 +51,9 @@ show progress information in stderr
 .TP
 \fB-r\fR
 show the real path of the files
+.TP
+\fB-i\fR
+files with same inode are considered as different
 
 .SH "BUGS"
 
@@ -56,40 +64,32 @@ None known, probably many. Valgrind does not complain though.
 The format of the output should definitely be improved. Not clear how.
 
 The comparison algorithm could definitely use some MD5 kind of
-signature. I doubt it would really speed up a lot.
+signature. However, I doubt it would improve speed much.
 
-Their should be some fancy option to run two instances of the command
-on different machines so that comparison could be done without disk
-access where the disk are physically.
+Their should be some fancy option to link two instances of the command
+running on different machines to reduce network disk accesses.
 
 .SH "EXAMPLES"
 
 .B finddup -cg blah something
 
 .fi
-List files found in
-.B ./blah/
-which have a matching file with same content in
-.B ./something/
-without the group IDs
+List files found in \fB./blah/\fR which have a matching file with same
+content in \fB./something/\fR. Do not display the group IDs.
 
 .P
 .B finddup sources not:/mnt/backup
 
 .fi
-List all files found in
-.B ./sources/
-which do not have content-matching equivalent in
-.B /mnt/backup
+List all files found in \fB./sources/\fR which do not have
+content-matching equivalent in \fB/mnt/backup\fR.
 
 .P
 .B finddup tralala cuicui
 
 .fi
 List groups of files with same content which exist both in
-.B ./tralala/
-and
-.B ./cuicui/
+\fB./tralala/\fR and \fB./cuicui/\fR.
 
 .SH "AUTHOR"
 
index e36c229..adf138e 100644 (file)
--- a/finddup.c
+++ b/finddup.c
@@ -62,6 +62,9 @@ int show_hits = 1; /* 1 means to show the files from dir2
 int show_groups = 1; /* 1 means to show the group IDs when printing
                         file names */
 
+int ignore_same_inode = 0; /* 1 means that comparison between two file
+                              with same inode will always be false */
+
 /********************************************************************/
 
 /* malloc with error checking.  */
@@ -186,6 +189,9 @@ int same_content(struct file_with_size *f1, struct file_with_size *f2) {
 }
 
 int same_files(struct file_with_size *f1, struct file_with_size *f2) {
+  if(ignore_same_inode && f1->inode == f2->inode) {
+    return 0;
+  }
   return f1->size == f2->size && same_content(f1, f2);
 }
 
@@ -313,28 +319,10 @@ void print_result(struct file_with_size *list1, struct file_with_size *list2) {
 void start(const char *dirname1, const char *dirname2) {
   struct file_with_size *list1, *list2;
   struct file_with_size *node1, *node2;
-  struct stat sb1, sb2;
-  int not_in, found, same_dir;
+  int not_in, found;
   int k, p, pp, l1, n;
 
-  if(strncmp(dirname2, "not:", 4) == 0) {
-    not_in = 1;
-    dirname2 += 4;
-  } else {
-    not_in = 0;
-  }
-
-  if(lstat(dirname1, &sb1) != 0) {
-    fprintf(stderr, "Can not stat \"%s\": %s\n", dirname1, strerror(errno));
-    exit(EXIT_FAILURE);
-  }
-
-  if(lstat(dirname2, &sb2) != 0) {
-    fprintf(stderr, "Can not stat \"%s\": %s\n", dirname2, strerror(errno));
-    exit(EXIT_FAILURE);
-  }
-
-  same_dir = (sb1.st_ino == sb2.st_ino);
+  not_in = 0;
 
   if(show_progress) {
     fprintf(stderr, "Scanning %s ... ", dirname1);
@@ -342,13 +330,17 @@ void start(const char *dirname1, const char *dirname2) {
 
   list1 = scan_directory(0, dirname1);
 
-  if(same_dir) {
-    list2 = list1;
-  } else {
+  if(dirname2) {
+    if(strncmp(dirname2, "not:", 4) == 0) {
+      not_in = 1;
+      dirname2 += 4;
+    }
     if(show_progress) {
       fprintf(stderr, "%s ... ", dirname2);
     }
     list2 = scan_directory(0, dirname2);
+  } else {
+    list2 = list1;
   }
 
   if(show_progress) {
@@ -374,7 +366,7 @@ void start(const char *dirname1, const char *dirname2) {
       found = 0;
 
       for(node2 = list2; !found && node2; node2 = node2->next) {
-        if(node1->inode != node2->inode && same_files(node1, node2)) {
+        if(same_files(node1, node2)) {
           found = 1;
         }
       }
@@ -400,7 +392,7 @@ void start(const char *dirname1, const char *dirname2) {
       }
 
       for(node2 = list2; node2; node2 = node2->next) {
-        if(node1->inode != node2->inode && same_files(node1, node2)) {
+        if(same_files(node1, node2)) {
           if(node1->group_id < 0) {
             if(node2->group_id >= 0) {
               node1->group_id = node2->group_id;
@@ -420,7 +412,7 @@ void start(const char *dirname1, const char *dirname2) {
   print_result(list1, list2);
 
   file_list_delete(list1);
-  if(!same_dir) {
+  if(dirname2) {
     file_list_delete(list2);
   }
 }
@@ -436,6 +428,7 @@ void print_help(FILE *out) {
   fprintf(out, "   -g   do not show the file groups\n");
   fprintf(out, "   -p   show progress\n");
   fprintf(out, "   -r   show the real file paths\n");
+  fprintf(out, "   -i   consider files with same inode as different\n");
   fprintf(out, "\n");
   fprintf(out, "Report bugs and comments to <francois@fleuret.org>\n");
 }
@@ -471,6 +464,10 @@ int main(int argc, char **argv) {
       show_realpaths = 1;
       break;
 
+    case 'i':
+      ignore_same_inode = 1;
+      break;
+
     case 'g':
       show_groups = 0;
       break;
@@ -488,10 +485,11 @@ int main(int argc, char **argv) {
     }
   }
 
-  if(optind + 1 < argc) {
+  if(optind + 2 == argc) {
     start(argv[optind], argv[optind + 1]);
-  } else if(optind < argc) {
-    start(argv[optind], argv[optind]);
+  } else if(optind + 1 == argc) {
+    ignore_same_inode = 1;
+    start(argv[optind], 0);
   } else {
     print_help(stderr);
     exit(EXIT_FAILURE);