void *safe_malloc(size_t n) {
void *p = malloc(n);
if (!p && n != 0) {
- printf("Can not allocate memory: %s\n", strerror(errno));
+ fprintf(stderr,
+ "finddup: Can not allocate memory: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
return p;
}
} else {
fprintf(stderr,
- "Different read size without error on files of same size.\n");
+ "finddup: Different read size without error on files of same size.\n");
exit(EXIT_FAILURE);
}
}
if(fd1 < 0) {
fprintf(stderr,
- "Can not open \"%s\" error: %s\n",
+ "finddup: Can not open \"%s\" error: %s\n",
f1->name,
strerror(errno));
}
if(fd2 < 0) {
fprintf(stderr,
- "Can not open \"%s\" error: %s\n",
+ "finddup: Can not open \"%s\" error: %s\n",
f2->name,
strerror(errno));
}
/**********************************************************************/
-struct file_node *scan_directory(struct file_node *tail, const char *name) {
+struct file_node *scan_directory_rec(struct file_node *tail, const char *name) {
DIR *dir;
struct dirent *dir_e;
struct stat sb;
char subname[PATH_MAX + 1];
if(lstat(name, &sb) != 0) {
- fprintf(stderr, "Can not stat \"%s\": %s\n", name, strerror(errno));
+ fprintf(stderr, "finddup: Can not stat \"%s\": %s\n", name, strerror(errno));
exit(EXIT_FAILURE);
}
while((dir_e = readdir(dir))) {
if(!ignore_entry(dir_e->d_name)) {
snprintf(subname, PATH_MAX, "%s/%s", name, dir_e->d_name);
- tail = scan_directory(tail, subname);
+ tail = scan_directory_rec(tail, subname);
}
}
closedir(dir);
return tail;
}
+struct file_node *scan_directory(struct file_node *tail, const char *name) {
+ struct file_node *result;
+ int length;
+
+ if(show_progress) {
+ fprintf(stderr, "Scanning '%s' ... ", name);
+ }
+
+ result = scan_directory_rec(tail, name);
+ length = file_list_length(result);
+
+ if(show_progress) {
+ fprintf(stderr, "done (%d file%s).\n",
+ length, (length > 1 ? "s" : ""));
+ }
+
+
+ return result;
+}
+
void print_file(struct file_node *node) {
char tmp[PATH_MAX + 1];
if(show_realpaths) {
printf("%s\n", tmp);
}
} else {
- printf("Can not get the realpath of \"%s\": %s\n",
- node->name,
- strerror(errno));
+ fprintf(stderr,
+ "finddup: Can not get the realpath of \"%s\": %s\n",
+ node->name,
+ strerror(errno));
exit(EXIT_FAILURE);
}
} else {
struct progress_state progress_state;
int not_in, found;
int nb_groups, nb_nodes;
- int list1_length, list2_length, previous_progress;
+ int list1_length, previous_progress;
char *buffer1 = safe_malloc(sizeof(char) * READ_BUFFER_SIZE);
char *buffer2 = safe_malloc(sizeof(char) * READ_BUFFER_SIZE);
not_in = 0;
- if(show_progress) {
- fprintf(stderr, "Scanning '%s' ... ", dirname1);
- }
-
list1 = scan_directory(0, dirname1);
-
list1_length = file_list_length(list1);
- if(show_progress) {
- fprintf(stderr, "done (%d file%s).\n",
- list1_length, (list1_length > 1 ? "s" : ""));
- }
-
if(dirname2) {
if(strncmp(dirname2, "not:", 4) == 0) {
not_in = 1;
} else if(strncmp(dirname2, "and:", 4) == 0) {
dirname2 += 4;
}
- if(show_progress) {
- fprintf(stderr, "Scanning '%s' ... ", dirname2);
- }
list2 = scan_directory(0, dirname2);
- if(show_progress) {
- list2_length = file_list_length(list2);
- fprintf(stderr, "done (%d file%s).\n",
- list2_length, (list2_length > 1 ? "s" : ""));
- }
} else {
list2 = list1;
}
if(show_progress) {
- fprintf(stderr, "Now looking for identical files (this may take a while).\n");
+ fprintf(stderr,
+ "Now looking for identical files (this may take a while).\n");
}
nb_groups = 0;
fprintf(out, "Without DIR2, lists duplicated files found in DIR1, or the current directory if DIR1 is not provided. With DIR2, lists files common to both directories. With the not: prefix, lists files found in DIR1 which do not exist in DIR2. The and: prefix is the default and should be used only if you have a directory starting with 'not:'\n");
fprintf(out, "\n");
/* 01234567890123456789012345678901234567890123456789012345678901234567890123456789*/
+ fprintf(out, " -v, --version prints the version number and exit\n");
fprintf(out, " -h, --help show this help\n");
fprintf(out, " -d, --ignore-dots ignore dot files and directories\n");
fprintf(out, " -0, --ignore-empty ignore empty files\n");
/**********************************************************************/
static struct option long_options[] = {
+ { "version", no_argument, 0, 'v' },
{ "help", no_argument, 0, 'h' },
{ "same-inodes-are-different", no_argument, 0, 'i' },
{ "real-paths", no_argument, 0, 'r' },
setlocale (LC_ALL, "");
- while ((c = getopt_long(argc, argv, "hircgtd0pm",
+ while ((c = getopt_long(argc, argv, "vhircgtd0pm",
long_options, NULL)) != -1) {
switch (c) {
+ case 'v':
+ printf("finddup version %s (%s)\n", VERSION_NUMBER, UNAME);
+ exit(EXIT_SUCCESS);
+ break;
+
case 'h':
usage(stdout);
exit(EXIT_SUCCESS);