Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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));
    }
}