Lot of cosmetics + added the -i option.
[finddup.git] / finddup.c
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);