static bool rm_directory_equal(RmDirectory *d1, RmDirectory *d2) { /* Will this work with paranoid cfg? Probably, but in a weird way. * Also it might not be very secure when the last block of the file is * compared... * */ if(d1->mergeups != d2->mergeups) { return false; } if(rm_digest_equal(d1->digest, d2->digest) == false) { return false; } if(g_hash_table_size(d1->hash_set) != g_hash_table_size(d2->hash_set)) { return false; } gpointer digest_key; GHashTableIter iter; g_hash_table_iter_init(&iter, d1->hash_set); while(g_hash_table_iter_next(&iter, &digest_key, NULL)) { if(g_hash_table_contains(d2->hash_set, digest_key) == false) { return false; } } return true; }
static bool rm_directory_equal(RmDirectory *d1, RmDirectory *d2) { if(d1->mergeups != d2->mergeups) { return false; } if(rm_digest_equal(d1->digest, d2->digest) == false) { return false; } if(g_hash_table_size(d1->hash_set) != g_hash_table_size(d2->hash_set)) { return false; } gpointer digest_key; GHashTableIter iter; g_hash_table_iter_init(&iter, d1->hash_set); while(g_hash_table_iter_next(&iter, &digest_key, NULL)) { if(g_hash_table_contains(d2->hash_set, digest_key) == false) { return false; } } return true; }
gboolean rm_digest_equal(RmDigest *a, RmDigest *b) { rm_assert_gentle(a && b); if(a->type != b->type) { return false; } if(a->bytes != b->bytes) { return false; } if(a->type == RM_DIGEST_PARANOID) { if(!a->paranoid->buffers) { /* buffers have been freed so we need to rely on shadow hash */ return rm_digest_equal(a->paranoid->shadow_hash, b->paranoid->shadow_hash); } /* check if pre-matched twins */ if(a->paranoid->twin_candidate == b || b->paranoid->twin_candidate == a) { return true; } /* check if already rejected */ if(g_slist_find(a->paranoid->rejects, b) || g_slist_find(b->paranoid->rejects, a)) { return false; } /* all the "easy" ways failed... do manual check of all buffers */ GSList *a_iter = a->paranoid->buffers; GSList *b_iter = b->paranoid->buffers; guint bytes = 0; while(a_iter && b_iter) { if(!rm_buffer_equal(a_iter->data, b_iter->data)) { rm_log_error_line( "Paranoid digest compare found mismatch - must be hash collision in " "shadow hash"); return false; } bytes += ((RmBuffer *)a_iter->data)->len; a_iter = a_iter->next; b_iter = b_iter->next; } return (!a_iter && !b_iter && bytes == a->bytes); } else if(rm_digest_needs_steal(a->type)) { guint8 *buf_a = rm_digest_steal(a); guint8 *buf_b = rm_digest_steal(b); gboolean result; if(a->bytes != b->bytes) { result = false; } else { result = !memcmp(buf_a, buf_b, MIN(a->bytes, b->bytes)); } g_slice_free1(a->bytes, buf_a); g_slice_free1(b->bytes, buf_b); return result; } else { return !memcmp(a->checksum, b->checksum, MIN(a->bytes, b->bytes)); } }