diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 1a1f10b2..35073abb 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -1524,9 +1524,9 @@ ostree_repo_commit_from_filelist_fd (OstreeRepo *self, } static gboolean -iter_object_dir (OstreeRepo *self, - GFile *dir, - OstreeRepoObjectIter callback, +iter_object_dir (OstreeRepo *self, + GFile *dir, + OstreeRepoObjectIter callback, gpointer user_data, GError **error) { @@ -1534,9 +1534,9 @@ iter_object_dir (OstreeRepo *self, GError *temp_error = NULL; GFileEnumerator *enumerator = NULL; GFileInfo *file_info = NULL; - const char *dirpath = NULL; + const char *dirname = NULL; - dirpath = ot_gfile_get_path_cached (dir); + dirname = ot_gfile_get_basename_cached (dir); enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, @@ -1549,31 +1549,44 @@ iter_object_dir (OstreeRepo *self, { const char *name; guint32 type; + char *dot; + GFile *child; + GString *checksum = NULL; + OstreeObjectType objtype; + name = g_file_info_get_attribute_byte_string (file_info, "standard::name"); type = g_file_info_get_attribute_uint32 (file_info, "standard::type"); - - if (type != G_FILE_TYPE_DIRECTORY - && (g_str_has_suffix (name, ".meta") - || g_str_has_suffix (name, ".file") - || g_str_has_suffix (name, ".packfile"))) - { - char *dot; - char *path; - - dot = strrchr (name, '.'); - g_assert (dot); - - if ((dot - name) == 62) - { - path = g_build_filename (dirpath, name, NULL); - callback (self, path, file_info, user_data); - g_free (path); - } - } - g_object_unref (file_info); + if (type == G_FILE_TYPE_DIRECTORY) + goto loop_out; + + if (g_str_has_suffix (name, ".meta")) + objtype = OSTREE_OBJECT_TYPE_META; + else if (g_str_has_suffix (name, ".file") + || g_str_has_suffix (name, ".packfile")) + objtype = OSTREE_OBJECT_TYPE_FILE; + else + goto loop_out; + + dot = strrchr (name, '.'); + g_assert (dot); + + if ((dot - name) != 62) + goto loop_out; + + checksum = g_string_new (dirname); + g_string_append_len (checksum, name, 62); + + child = g_file_get_child (dir, name); + callback (self, checksum->str, objtype, child, file_info, user_data); + + loop_out: + if (checksum) + g_string_free (checksum, TRUE); + g_clear_object (&file_info); + g_clear_object (&child); } - if (file_info == NULL && temp_error != NULL) + if (temp_error != NULL) { g_propagate_error (error, temp_error); goto out; @@ -1583,14 +1596,15 @@ iter_object_dir (OstreeRepo *self, ret = TRUE; out: + g_clear_object (&file_info); return ret; } gboolean ostree_repo_iter_objects (OstreeRepo *self, - OstreeRepoObjectIter callback, - gpointer user_data, - GError **error) + OstreeRepoObjectIter callback, + gpointer user_data, + GError **error) { OstreeRepoPrivate *priv = GET_PRIVATE (self); GFile *objectdir = NULL; diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 7f6e27d8..1b6948da 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -157,13 +157,17 @@ gboolean ostree_repo_diff (OstreeRepo *self, GCancellable *cancellable, GError **error); -typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, const char *path, - GFileInfo *fileinfo, gpointer user_data); +typedef void (*OstreeRepoObjectIter) (OstreeRepo *self, + const char *checksum, + OstreeObjectType type, + GFile *path, + GFileInfo *fileinfo, + gpointer user_data); gboolean ostree_repo_iter_objects (OstreeRepo *self, - OstreeRepoObjectIter callback, - gpointer user_data, - GError **error); + OstreeRepoObjectIter callback, + gpointer user_data, + GError **error); G_END_DECLS diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c index f6f0a113..c9593bb5 100644 --- a/src/ostree/ot-builtin-fsck.c +++ b/src/ostree/ot-builtin-fsck.c @@ -41,13 +41,12 @@ typedef struct { static gboolean checksum_packed_file (OtFsckData *data, - const char *path, + GFile *file, GChecksum **out_checksum, GError **error) { gboolean ret = FALSE; GChecksum *ret_checksum = NULL; - GFile *file = NULL; char *metadata_buf = NULL; GVariant *metadata = NULL; GVariant *xattrs = NULL; @@ -58,8 +57,6 @@ checksum_packed_file (OtFsckData *data, gsize bytes_read; char buf[8192]; - file = ot_gfile_new_for_path (path); - in = g_file_read (file, NULL, error); if (!in) goto out; @@ -105,7 +102,6 @@ checksum_packed_file (OtFsckData *data, if (ret_checksum) g_checksum_free (ret_checksum); g_free (metadata_buf); - g_clear_object (&file); g_clear_object (&in); if (metadata) g_variant_unref (metadata); @@ -115,78 +111,55 @@ checksum_packed_file (OtFsckData *data, } static void -object_iter_callback (OstreeRepo *repo, - const char *path, +object_iter_callback (OstreeRepo *repo, + const char *exp_checksum, + OstreeObjectType objtype, + GFile *objf, GFileInfo *file_info, gpointer user_data) { OtFsckData *data = user_data; - GChecksum *checksum = NULL; + const char *path = NULL; + GChecksum *real_checksum = NULL; GError *error = NULL; - char *dirname = NULL; - char *checksum_prefix = NULL; - char *checksum_string = NULL; - char *filename_checksum = NULL; - gboolean packed = FALSE; - OstreeObjectType objtype; - char *dot; - GFile *f = NULL; - f = ot_gfile_new_for_path (path); + path = ot_gfile_get_path_cached (objf); /* nlinks = g_file_info_get_attribute_uint32 (file_info, "unix::nlink"); if (nlinks < 2 && !quiet) g_printerr ("note: floating object: %s\n", path); */ - if (g_str_has_suffix (path, ".meta")) - objtype = OSTREE_OBJECT_TYPE_META; - else if (g_str_has_suffix (path, ".file")) - objtype = OSTREE_OBJECT_TYPE_FILE; - else if (g_str_has_suffix (path, ".packfile")) + if (ostree_repo_is_archive (repo) + && objtype == OSTREE_OBJECT_TYPE_FILE) { - objtype = OSTREE_OBJECT_TYPE_FILE; - packed = TRUE; - } - else - g_assert_not_reached (); - - if (packed && objtype == OSTREE_OBJECT_TYPE_FILE) - { - if (!checksum_packed_file (data, path, &checksum, &error)) + if (!g_str_has_suffix (path, ".packfile")) + { + g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid unpacked filename '%s'", + path); + goto out; + } + if (!checksum_packed_file (data, objf, &real_checksum, &error)) goto out; } else { - if (!ostree_checksum_file (f, objtype, &checksum, NULL, &error)) + if (!ostree_checksum_file (objf, objtype, &real_checksum, NULL, &error)) goto out; } - filename_checksum = g_strdup (g_file_info_get_name (file_info)); - dot = strrchr (filename_checksum, '.'); - g_assert (dot != NULL); - *dot = '\0'; - - dirname = g_path_get_dirname (path); - checksum_prefix = g_path_get_basename (dirname); - checksum_string = g_strconcat (checksum_prefix, filename_checksum, NULL); - - if (strcmp (checksum_string, g_checksum_get_string (checksum)) != 0) + if (strcmp (exp_checksum, g_checksum_get_string (real_checksum)) != 0) { data->had_error = TRUE; g_printerr ("ERROR: corrupted object '%s' expected checksum: %s\n", - path, g_checksum_get_string (checksum)); + exp_checksum, g_checksum_get_string (real_checksum)); } data->n_objects++; out: - g_clear_object (&f); - if (checksum != NULL) - g_checksum_free (checksum); - g_free (dirname); - g_free (checksum_prefix); - g_free (checksum_string); - g_free (filename_checksum); + if (real_checksum != NULL) + g_checksum_free (real_checksum); if (error != NULL) { g_printerr ("%s\n", error->message);