82 apr_off_t old_size = -1;
85 apr_uint32_t hash_value;
89 apr_uint32_t chksum_array_sz = 0U;
91 json_t *root_array = json_array();
97 if (file->size == old_size)
99 old_size = file->size;
101 if (NULL != (fsize =
napr_hash_search(conf->sizes, &file->size,
sizeof(apr_off_t), &hash_value))) {
102 chksum_array_sz = FTWIN_MIN(fsize->nb_files, fsize->nb_checksumed);
103 qsort(fsize->chksum_array, chksum_array_sz,
sizeof(ft_chksum_t),
ft_chksum_cmp);
105 for (i = 0; i < fsize->nb_files; i++) {
106 if (NULL == fsize->chksum_array[i].file)
109 json_t *current_set_obj = NULL;
110 json_t *duplicates_array = NULL;
112 for (j = i + 1; j < fsize->nb_files; j++) {
114 memcmp(&fsize->chksum_array[i].hash_value, &fsize->chksum_array[j].hash_value,
sizeof(
ft_hash_t))) {
117 char *fpathi, *fpathj;
118 if (is_option_set(conf->mask, OPTION_UNTAR)) {
119 if (NULL != fsize->chksum_array[i].file->subpath) {
120 fpathi = ft_archive_untar_file(fsize->chksum_array[i].file, conf->pool);
121 if (NULL == fpathi) {
122 DEBUG_ERR(
"error calling ft_archive_untar_file");
127 fpathi = fsize->chksum_array[i].file->path;
129 if (NULL != fsize->chksum_array[j].file->subpath) {
130 fpathj = ft_archive_untar_file(fsize->chksum_array[j].file, conf->pool);
131 if (NULL == fpathj) {
132 DEBUG_ERR(
"error calling ft_archive_untar_file");
137 fpathj = fsize->chksum_array[j].file->path;
141 fpathi = fsize->chksum_array[i].file->path;
142 fpathj = fsize->chksum_array[j].file->path;
144 status =
filecmp(conf->pool, fpathi, fpathj, fsize->val, conf->excess_size, &rv);
146 if (is_option_set(conf->mask, OPTION_UNTAR)) {
147 if (NULL != fsize->chksum_array[i].file->subpath)
148 (void) apr_file_remove(fpathi, conf->pool);
149 if (NULL != fsize->chksum_array[j].file->subpath)
150 (void) apr_file_remove(fpathj, conf->pool);
152 if (APR_SUCCESS != status) {
153 if (is_option_set(conf->mask, OPTION_VERBO))
154 fprintf(stderr,
"\nskipping %s and %s comparison because: %s\n",
155 fsize->chksum_array[i].file->path, fsize->chksum_array[j].file->path,
156 apr_strerror(status, errbuf, 128));
162 if (is_option_set(conf->mask, OPTION_DRY_RUN)) {
163 fprintf(stderr,
"Dry run: would perform action on %s and %s\n",
164 fsize->chksum_array[i].file->path, fsize->chksum_array[j].file->path);
168 if (NULL == current_set_obj) {
169 current_set_obj = json_object();
170 duplicates_array = json_array();
173 json_object_set_new(current_set_obj,
"size_bytes", json_integer(fsize->val));
174 char *hex_hash = ft_hash_to_hex(fsize->chksum_array[i].hash_value, conf->pool);
175 json_object_set_new(current_set_obj,
"hash_xxh128", json_string(hex_hash));
176 json_object_set_new(current_set_obj,
"duplicates", duplicates_array);
179 json_array_append_new(duplicates_array,
180 create_file_json_object(fsize->chksum_array[i].file, conf));
184 json_array_append_new(duplicates_array,
185 create_file_json_object(fsize->chksum_array[j].file, conf));
187 fsize->chksum_array[j].file = NULL;
195 if (NULL != current_set_obj) {
196 json_array_append_new(root_array, current_set_obj);
201 DEBUG_ERR(
"inconsistency error found, no size[%" APR_OFF_T_FMT
"] in hash for file %s", file->size, file->path);
207 json_dumpf(root_array, stdout, JSON_INDENT(2) | JSON_ENSURE_ASCII);
211 json_decref(root_array);