+ struct file_with_size *node1, *node2;
+ int not_in, found;
+
+ if(dirname2[0] == '^') {
+ not_in = 1;
+ dirname2++;
+ } else {
+ not_in = 0;
+ }
+
+ list1 = scan_directory(0, dirname1);
+ list2 = scan_directory(0, dirname2);
+
+ if(not_in) {
+ for(node1 = list1; node1; node1 = node1->next) {
+ found = 0;
+
+ for(node2 = list2; !found && node2; node2 = node2->next) {
+ if(node1->inode != node2->inode && same_files(node1, node2)) {
+ found = 1;
+ }
+ }
+
+ if(!found) {
+ if(show_realpaths) {
+ printf("%s\n", realpath(node1->filename, 0));
+ } else {
+ printf("%s\n", node1->filename);
+ }
+ }
+ }
+
+ } else {
+
+ for(node1 = list1; node1; node1 = node1->next) {
+ for(node2 = list2; node2; node2 = node2->next) {
+ if(node1->inode != node2->inode && same_files(node1, node2)) {
+ if(show_realpaths) {
+ printf("%s %s\n",
+ realpath(node1->filename, 0),
+ realpath(node2->filename, 0));
+ } else {
+ printf("%s %s\n", node1->filename, node2->filename);
+ }
+ }
+ }
+ }
+ }
+
+ file_list_delete(list1);
+ file_list_delete(list2);
+}
+
+void print_help(FILE *out) {
+ fprintf(out, "Usage: finddup [OPTION]... DIR1 [[^]DIR2]\n");
+ fprintf(out, "Version %s (%s)\n", VERSION_NUMBER, UNAME);
+ fprintf(out, "Without DIR2, lists duplicated files in DIR1. With DIR2, list files common to both directories. With DIR2 starting with a ^, list files found in DIR1 which do not exist in DIR2.\n");
+ fprintf(out, "\n");
+ fprintf(out, " -h show this help.\n");
+ fprintf(out, " -r show the real file paths.\n");
+ fprintf(out, "\n");
+ fprintf(out, "Report bugs and comments to <francois@fleuret.org>\n");