#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
+#include <sys/wait.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
int sort_by_time = 0; /* 1 means to sort files in each group according
to the modification time */
+char *command_to_exec = 0; /* the name of the command to exec for each
+ group of identical files */
+
/********************************************************************/
/* malloc with error checking. */
}
}
+void exec_command(int nb, struct file_node **nodes) {
+ char **args;
+ int max_group_size = 0, group_size, m, n, status;
+ pid_t pid;
+
+ for(n = 0; n < nb; n++) {
+ if(n == 0 || nodes[n]->group_id != nodes[n-1]->group_id) {
+ group_size = 0;
+ }
+ group_size++;
+ if(group_size > max_group_size) {
+ max_group_size = group_size;
+ }
+ }
+
+ args = safe_malloc((max_group_size + 2) * sizeof(char *));
+ args[0] = command_to_exec;
+
+ n = 0;
+ while(n < nb) {
+ m = n;
+ while(n < nb && nodes[n]->group_id == nodes[m]->group_id) {
+ args[n - m + 1] = nodes[n]->name;
+ n++;
+ }
+ args[n - m + 1] = 0;
+ pid = fork();
+ if(pid < 0) {
+ } else if(pid == 0) {
+ if(execvp(command_to_exec, args) < 0) {
+ perror("execvp");
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ while(wait(&status) != pid);
+ if(status > 0) {
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+
+ free(args);
+}
void print_result(struct file_node *list1, struct file_node *list2) {
struct file_node *node1, *node2;
qsort(nodes, nb, sizeof(struct file_node *), compare_nodes);
- for(n = 0; n < nb; n++) {
- if(!show_groups && n > 0 && nodes[n]->group_id != nodes[n-1]->group_id) {
- printf("\n");
+ if(command_to_exec) {
+ exec_command(nb, nodes);
+ } else {
+ for(n = 0; n < nb; n++) {
+ if(!show_groups && n > 0 && nodes[n]->group_id != nodes[n-1]->group_id) {
+ printf("\n");
+ }
+ print_file(nodes[n]);
}
- print_file(nodes[n]);
}
free(nodes);
fprintf(out, " -r, --real-paths show the real file paths\n");
fprintf(out, " -i, --same-inodes-are-different\n");
fprintf(out, " consider files with same inode as different\n");
+ fprintf(out, " -e <command>, --exec <command>\n");
+ fprintf(out, " execute the provided command for each group of\n");
+ fprintf(out, " identical files, with their names as arguments\n");
fprintf(out, "\n");
fprintf(out, "Report bugs and comments to <francois@fleuret.org>.\n");
}
{ "ignore-dots", no_argument, 0, 'd' },
{ "ignore-empty", no_argument, 0, '0' },
{ "show-progress", no_argument, 0, 'p' },
+ { "exec", 1, 0, 'e' },
{ 0, 0, 0, 0 }
};
setlocale (LC_ALL, "");
- while ((c = getopt_long(argc, argv, "vhircgtd0pm",
+ while ((c = getopt_long(argc, argv, "vhircgtd0pme:",
long_options, NULL)) != -1) {
switch (c) {
show_hits = 0;
break;
+ case 'e':
+ if(command_to_exec != 0) {
+ free(command_to_exec);
+ }
+ command_to_exec = strdup(optarg);
+ break;
+
default:
usage(stderr);
exit(EXIT_FAILURE);