From f6ec479f173cbaba757ddeea519904156b755af9 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 18 Nov 2011 15:21:32 -0500 Subject: [PATCH] core: Rework object iteration API to be GFile based and pass more data It makes more sense to have e.g. the details of .packfile naming inside the repo, and pass the expected checksum and type. --- src/libostree/ostree-repo.c | 72 +++++++++++++++++++++-------------- src/libostree/ostree-repo.h | 14 ++++--- src/ostree/ot-builtin-fsck.c | 73 ++++++++++++------------------------ 3 files changed, 75 insertions(+), 84 deletions(-) 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);