static void test_checksum(const char *filename, lr_ChecksumType ch_type, char *expected) { int fd; char *checksum; fail_if((fd = open(filename, O_RDONLY)) < 0); fail_if((checksum = lr_checksum_fd(ch_type, fd)) == NULL); fail_if(strcmp(checksum, expected), "Checksum is %s instead of %s", checksum, expected); lr_free(checksum); close(fd); }
gboolean lr_checksum_fd_compare(LrChecksumType type, int fd, const char *expected, gboolean caching, gboolean *matches, gchar **calculated, GError **err) { _cleanup_free_ gchar *checksum = NULL; assert(fd >= 0); assert(!err || *err == NULL); *matches = FALSE; if (!expected) { g_set_error(err, LR_CHECKSUM_ERROR, LRE_BADFUNCARG, "No expected checksum passed"); return FALSE; } if (caching) { // Load cached checksum if enabled and used struct stat st; if (fstat(fd, &st) == 0) { ssize_t attr_ret; _cleanup_free_ gchar *key = NULL; char buf[256]; key = g_strdup_printf("user.Zif.MdChecksum[%llu]", (unsigned long long) st.st_mtime); #ifdef __APPLE__ attr_ret = fgetxattr(fd, key, &buf, 256, 0, 0); #else attr_ret = fgetxattr(fd, key, &buf, 256); #endif if (attr_ret != -1) { // Cached checksum found g_debug("%s: Using checksum cached in xattr: [%s] %s", __func__, key, buf); *matches = strcmp(expected, buf) ? FALSE : TRUE; return TRUE; } } } checksum = lr_checksum_fd(type, fd, err); if (!checksum) return FALSE; *matches = (strcmp(expected, checksum)) ? FALSE : TRUE; if (caching && *matches) { // Store checksum as extended file attribute if caching is enabled struct stat st; if (fstat(fd, &st) == 0) { _cleanup_free_ gchar *key = NULL; key = g_strdup_printf("user.Zif.MdChecksum[%llu]", (unsigned long long) st.st_mtime); #ifdef __APPLE__ fsetxattr(fd, key, checksum, strlen(checksum)+1, 0, 0); #else fsetxattr(fd, key, checksum, strlen(checksum)+1, 0); #endif } } if (calculated) *calculated = g_strdup(checksum); return TRUE; }