diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 52b12861..f7b2272a 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -415,8 +415,7 @@ ostree_create_directory_metadata (GFileInfo *dir_info, { GVariant *ret_metadata = NULL; - ret_metadata = g_variant_new ("(uuuu@a(ayay))", - OSTREE_DIR_META_VERSION, + ret_metadata = g_variant_new ("(uuu@a(ayay))", GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::uid")), GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::gid")), GUINT32_TO_BE (g_file_info_get_attribute_uint32 (dir_info, "unix::mode")), @@ -725,7 +724,6 @@ ostree_create_archive_file_metadata (GFileInfo *finfo, rdev = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_RDEV); g_variant_builder_init (&pack_builder, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT); - g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (0)); /* Version */ g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (uid)); g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (gid)); g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (mode)); @@ -750,22 +748,14 @@ ostree_parse_archived_file_meta (GVariant *metadata, GError **error) { gboolean ret = FALSE; - guint32 version, uid, gid, mode, rdev; + guint32 uid, gid, mode, rdev; const char *symlink_target; ot_lobj GFileInfo *ret_file_info = NULL; ot_lvariant GVariant *ret_xattrs = NULL; - g_variant_get (metadata, "(uuuuu&s@a(ayay))", - &version, &uid, &gid, &mode, &rdev, + g_variant_get (metadata, "(uuuu&s@a(ayay))", + &uid, &gid, &mode, &rdev, &symlink_target, &ret_xattrs); - version = GUINT32_FROM_BE (version); - - if (version != 0) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Invalid version %d in archived file metadata", version); - goto out; - } uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); @@ -1400,8 +1390,8 @@ ostree_validate_structureof_objtype (guint32 objtype, } gboolean -ostree_validate_structureof_checksum (GVariant *checksum, - GError **error) +ostree_validate_structureof_csum_v (GVariant *checksum, + GError **error) { gsize n_children = g_variant_n_children (checksum); if (n_children != 32) @@ -1470,27 +1460,28 @@ ostree_validate_structureof_commit (GVariant *commit, GError **error) { gboolean ret = FALSE; - const char *parent; - const char *contents; - const char *metadata; + ot_lvariant GVariant *parent_csum_v = NULL; + ot_lvariant GVariant *content_csum_v = NULL; + ot_lvariant GVariant *metadata_csum_v = NULL; + gsize n_elts; if (!validate_variant (commit, OSTREE_COMMIT_GVARIANT_FORMAT, error)) goto out; - g_variant_get_child (commit, 2, "&s", &parent); - - if (*parent) + g_variant_get_child (commit, 1, "@ay", &parent_csum_v); + (void) g_variant_get_fixed_array (parent_csum_v, &n_elts, 1); + if (n_elts > 0) { - if (!ostree_validate_structureof_checksum_string (parent, error)) + if (!ostree_validate_structureof_csum_v (parent_csum_v, error)) goto out; } - g_variant_get_child (commit, 6, "&s", &contents); - if (!ostree_validate_structureof_checksum_string (contents, error)) + g_variant_get_child (commit, 6, "@ay", &content_csum_v); + if (!ostree_validate_structureof_csum_v (content_csum_v, error)) goto out; - g_variant_get_child (commit, 7, "&s", &metadata); - if (!ostree_validate_structureof_checksum_string (metadata, error)) + g_variant_get_child (commit, 7, "@ay", &metadata_csum_v); + if (!ostree_validate_structureof_csum_v (metadata_csum_v, error)) goto out; ret = TRUE; @@ -1504,37 +1495,40 @@ ostree_validate_structureof_dirtree (GVariant *dirtree, { gboolean ret = FALSE; const char *filename; - const char *meta_checksum; - const char *content_checksum; + ot_lvariant GVariant *content_csum_v = NULL; + ot_lvariant GVariant *meta_csum_v = NULL; GVariantIter *contents_iter = NULL; if (!validate_variant (dirtree, OSTREE_TREE_GVARIANT_FORMAT, error)) goto out; - g_variant_get_child (dirtree, 2, "a(ss)", &contents_iter); + g_variant_get_child (dirtree, 0, "a(say)", &contents_iter); - while (g_variant_iter_loop (contents_iter, "(&s&s)", - &filename, &content_checksum)) + while (g_variant_iter_loop (contents_iter, "(&s@ay)", + &filename, &content_csum_v)) { if (!ot_util_filename_validate (filename, error)) goto out; - if (!ostree_validate_structureof_checksum_string (content_checksum, error)) + if (!ostree_validate_structureof_csum_v (content_csum_v, error)) goto out; } + content_csum_v = NULL; g_variant_iter_free (contents_iter); - g_variant_get_child (dirtree, 3, "a(sss)", &contents_iter); + g_variant_get_child (dirtree, 1, "a(sayay)", &contents_iter); - while (g_variant_iter_loop (contents_iter, "(&s&s&s)", - &filename, &content_checksum, &meta_checksum)) + while (g_variant_iter_loop (contents_iter, "(&s@ay@ay)", + &filename, &content_csum_v, &meta_csum_v)) { if (!ot_util_filename_validate (filename, error)) goto out; - if (!ostree_validate_structureof_checksum_string (content_checksum, error)) + if (!ostree_validate_structureof_csum_v (content_csum_v, error)) goto out; - if (!ostree_validate_structureof_checksum_string (meta_checksum, error)) + if (!ostree_validate_structureof_csum_v (meta_csum_v, error)) goto out; } + content_csum_v = NULL; + meta_csum_v = NULL; ret = TRUE; out: @@ -1597,7 +1591,7 @@ ostree_validate_structureof_dirmeta (GVariant *dirmeta, if (!validate_variant (dirmeta, OSTREE_DIRMETA_GVARIANT_FORMAT, error)) goto out; - g_variant_get_child (dirmeta, 3, "u", &mode); + g_variant_get_child (dirmeta, 2, "u", &mode); mode = GUINT32_FROM_BE (mode); if (!S_ISDIR (mode)) @@ -1623,7 +1617,7 @@ ostree_validate_structureof_pack_index (GVariant *index, const char *header; guint32 objtype; guint64 offset; - ot_lvariant GVariant *csum_bytes = NULL; + ot_lvariant GVariant *csum_v = NULL; GVariantIter *content_iter = NULL; if (!validate_variant (index, OSTREE_PACK_INDEX_VARIANT_FORMAT, error)) @@ -1641,14 +1635,14 @@ ostree_validate_structureof_pack_index (GVariant *index, g_variant_get_child (index, 2, "a(uayt)", &content_iter); while (g_variant_iter_loop (content_iter, "(u@ayt)", - &objtype, &csum_bytes, &offset)) + &objtype, &csum_v, &offset)) { if (!ostree_validate_structureof_objtype (objtype, error)) goto out; - if (!ostree_validate_structureof_checksum (csum_bytes, error)) + if (!ostree_validate_structureof_csum_v (csum_v, error)) goto out; } - csum_bytes = NULL; + csum_v = NULL; ret = TRUE; out: @@ -1663,7 +1657,7 @@ ostree_validate_structureof_pack_superindex (GVariant *superindex, { gboolean ret = FALSE; const char *header; - ot_lvariant GVariant *csum_bytes = NULL; + ot_lvariant GVariant *csum_v = NULL; ot_lvariant GVariant *bloom = NULL; GVariantIter *content_iter = NULL; @@ -1682,12 +1676,12 @@ ostree_validate_structureof_pack_superindex (GVariant *superindex, g_variant_get_child (superindex, 2, "a(ayay)", &content_iter); while (g_variant_iter_loop (content_iter, "(@ay@ay)", - &csum_bytes, &bloom)) + &csum_v, &bloom)) { - if (!ostree_validate_structureof_checksum (csum_bytes, error)) + if (!ostree_validate_structureof_csum_v (csum_v, error)) goto out; } - csum_bytes = NULL; + csum_v = NULL; ret = TRUE; out: diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index 867803e6..2c26334f 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -51,43 +51,36 @@ typedef enum { */ #define OSTREE_XATTR_GVARIANT_FORMAT "a(ayay)" -#define OSTREE_DIR_META_VERSION 0 /* * dirmeta objects: - * u - Version * u - uid * u - gid * u - mode * a(ayay) - xattrs */ -#define OSTREE_DIRMETA_GVARIANT_FORMAT G_VARIANT_TYPE ("(uuuua(ayay))") +#define OSTREE_DIRMETA_GVARIANT_FORMAT G_VARIANT_TYPE ("(uuua(ayay))") -#define OSTREE_TREE_VERSION 0 /* * Tree objects: - * u - Version - * a{sv} - Metadata - * a(ss) - array of (filename, checksum) for files - * a(sss) - array of (dirname, tree_checksum, meta_checksum) for directories + * a(say) - array of (filename, checksum) for files + * a(sayay) - array of (dirname, tree_checksum, meta_checksum) for directories */ -#define OSTREE_TREE_GVARIANT_FORMAT G_VARIANT_TYPE ("(ua{sv}a(ss)a(sss))") +#define OSTREE_TREE_GVARIANT_FORMAT G_VARIANT_TYPE ("(a(say)a(sayay))") -#define OSTREE_COMMIT_VERSION 0 /* * Commit objects: - * u - Version * a{sv} - Metadata - * s - parent checksum (empty string for initial) + * ay - parent checksum (empty string for initial) + * a(say) - Related objects * s - subject * s - body * t - Timestamp in seconds since the epoch (UTC) - * s - Root tree contents - * s - Root tree metadata + * ay - Root tree contents + * ay - Root tree metadata */ -#define OSTREE_COMMIT_GVARIANT_FORMAT G_VARIANT_TYPE ("(ua{sv}ssstss)") +#define OSTREE_COMMIT_GVARIANT_FORMAT G_VARIANT_TYPE ("(a{sv}aya(say)sstayay)") /* Archive file objects: - * u - Version * u - uid * u - gid * u - mode @@ -95,12 +88,12 @@ typedef enum { * s - symlink target * a(ayay) - xattrs */ -#define OSTREE_ARCHIVED_FILE_VARIANT_FORMAT G_VARIANT_TYPE ("(uuuuusa(ayay))") +#define OSTREE_ARCHIVED_FILE_VARIANT_FORMAT G_VARIANT_TYPE ("(uuuusa(ayay))") /* Pack super index * s - OSTv0SUPERPACKINDEX * a{sv} - Metadata - * a(say) - (pack file checksum, bloom filter) + * a(ayay) - (pack file checksum, bloom filter) */ #define OSTREE_PACK_SUPER_INDEX_VARIANT_FORMAT G_VARIANT_TYPE ("(sa{sv}a(ayay))") @@ -290,8 +283,8 @@ gboolean ostree_pack_index_search (GVariant *index, gboolean ostree_validate_structureof_objtype (guint32 objtype, GError **error); -gboolean ostree_validate_structureof_checksum (GVariant *checksum, - GError **error); +gboolean ostree_validate_structureof_csum_v (GVariant *checksum, + GError **error); gboolean ostree_validate_structureof_checksum_string (const char *checksum, GError **error); diff --git a/src/libostree/ostree-repo-file.c b/src/libostree/ostree-repo-file.c index 53d3bc2f..edccb9eb 100644 --- a/src/libostree/ostree-repo-file.c +++ b/src/libostree/ostree-repo-file.c @@ -40,6 +40,8 @@ struct OstreeRepoFile int index; char *name; + char *cached_file_checksum; + char *tree_contents_checksum; GVariant *tree_contents; char *tree_metadata_checksum; @@ -59,6 +61,7 @@ ostree_repo_file_finalize (GObject *object) ot_clear_gvariant (&self->tree_contents); ot_clear_gvariant (&self->tree_metadata); + g_free (self->cached_file_checksum); g_free (self->tree_contents_checksum); g_free (self->tree_metadata_checksum); g_free (self->commit); @@ -146,11 +149,11 @@ do_resolve_commit (OstreeRepoFile *self, GError **error) { gboolean ret = FALSE; - const char *tree_contents_checksum; - const char *tree_meta_checksum; ot_lvariant GVariant *commit = NULL; ot_lvariant GVariant *root_contents = NULL; ot_lvariant GVariant *root_metadata = NULL; + ot_lvariant GVariant *tree_contents_csum_v = NULL; + ot_lvariant GVariant *tree_metadata_csum_v = NULL; g_assert (self->parent == NULL); @@ -159,25 +162,25 @@ do_resolve_commit (OstreeRepoFile *self, goto out; /* PARSE OSTREE_OBJECT_TYPE_COMMIT */ - g_variant_get_child (commit, 6, "&s", &tree_contents_checksum); - g_variant_get_child (commit, 7, "&s", &tree_meta_checksum); + g_variant_get_child (commit, 6, "@ay", &tree_contents_csum_v); + g_variant_get_child (commit, 7, "@ay", &tree_metadata_csum_v); - if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, - tree_contents_checksum, &root_contents, - error)) + if (!ostree_repo_load_variant_c (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, + ostree_checksum_bytes_peek (tree_contents_csum_v), + &root_contents, error)) goto out; - if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META, - tree_meta_checksum, &root_metadata, - error)) + if (!ostree_repo_load_variant_c (self->repo, OSTREE_OBJECT_TYPE_DIR_META, + ostree_checksum_bytes_peek (tree_metadata_csum_v), + &root_metadata, error)) goto out; self->tree_metadata = root_metadata; root_metadata = NULL; self->tree_contents = root_contents; root_contents = NULL; - self->tree_contents_checksum = g_strdup (tree_contents_checksum); - self->tree_metadata_checksum = g_strdup (tree_meta_checksum); + self->tree_contents_checksum = ostree_checksum_from_bytes_v (tree_contents_csum_v); + self->tree_metadata_checksum = ostree_checksum_from_bytes_v (tree_metadata_csum_v); ret = TRUE; out: @@ -194,6 +197,9 @@ do_resolve_nonroot (OstreeRepoFile *self, ot_lvariant GVariant *container = NULL; ot_lvariant GVariant *tree_contents = NULL; ot_lvariant GVariant *tree_metadata = NULL; + ot_lvariant GVariant *content_csum_v = NULL; + ot_lvariant GVariant *metadata_csum_v = NULL; + ot_lfree char *tmp_checksum = NULL; i = ostree_repo_file_tree_find_child (self->parent, self->name, &is_dir, &container); @@ -206,27 +212,26 @@ do_resolve_nonroot (OstreeRepoFile *self, if (is_dir) { const char *name; - const char *content_checksum; - const char *metadata_checksum; GVariant *files_variant; - files_variant = g_variant_get_child_value (self->parent->tree_contents, 2); + files_variant = g_variant_get_child_value (self->parent->tree_contents, 0); self->index = g_variant_n_children (files_variant) + i; ot_clear_gvariant (&files_variant); - g_variant_get_child (container, i, "(&s&s&s)", - &name, &content_checksum, &metadata_checksum); + g_variant_get_child (container, i, "(&s@ay@ay)", + &name, &content_csum_v, &metadata_csum_v); - if (!ot_util_filename_validate (name, error)) - goto out; - + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v); if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_TREE, - content_checksum, &tree_contents, + tmp_checksum, &tree_contents, error)) goto out; + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (metadata_csum_v); if (!ostree_repo_load_variant (self->repo, OSTREE_OBJECT_TYPE_DIR_META, - metadata_checksum, &tree_metadata, + tmp_checksum, &tree_metadata, error)) goto out; @@ -234,8 +239,8 @@ do_resolve_nonroot (OstreeRepoFile *self, tree_contents = NULL; self->tree_metadata = tree_metadata; tree_metadata = NULL; - self->tree_contents_checksum = g_strdup (content_checksum); - self->tree_metadata_checksum = g_strdup (metadata_checksum); + self->tree_contents_checksum = ostree_checksum_from_bytes_v (content_csum_v); + self->tree_metadata_checksum = ostree_checksum_from_bytes_v (metadata_csum_v); } else self->index = i; @@ -296,7 +301,7 @@ ostree_repo_file_get_xattrs (OstreeRepoFile *self, goto out; if (self->tree_metadata) - ret_xattrs = g_variant_get_child_value (self->tree_metadata, 4); + ret_xattrs = g_variant_get_child_value (self->tree_metadata, 3); else if (ostree_repo_get_mode (self->repo) == OSTREE_REPO_MODE_ARCHIVE) { local_file = ostree_repo_file_nontree_get_local (self); @@ -379,31 +384,36 @@ ostree_repo_file_get_checksum (OstreeRepoFile *self) gboolean is_dir; GVariant *files_variant; GVariant *dirs_variant; - const char *checksum; + GVariant *csum_bytes; if (!self->parent) return self->tree_metadata_checksum; + if (self->cached_file_checksum) + return self->cached_file_checksum; + n = ostree_repo_file_tree_find_child (self->parent, self->name, &is_dir, NULL); g_assert (n >= 0); - files_variant = g_variant_get_child_value (self->parent->tree_contents, 2); - dirs_variant = g_variant_get_child_value (self->parent->tree_contents, 3); + files_variant = g_variant_get_child_value (self->parent->tree_contents, 0); + dirs_variant = g_variant_get_child_value (self->parent->tree_contents, 1); if (is_dir) { g_variant_get_child (dirs_variant, n, - "(@s@s&s)", NULL, NULL, &checksum); + "(@s@ay@ay)", NULL, NULL, &csum_bytes); } else { g_variant_get_child (files_variant, n, - "(@s&s)", NULL, &checksum); + "(@s@ay)", NULL, &csum_bytes); } ot_clear_gvariant (&files_variant); ot_clear_gvariant (&dirs_variant); - return checksum; + self->cached_file_checksum = ostree_checksum_from_bytes_v (csum_bytes); + + return self->cached_file_checksum; } static gboolean @@ -661,15 +671,13 @@ static void set_info_from_dirmeta (GFileInfo *info, GVariant *metadata) { - guint32 version, uid, gid, mode; + guint32 uid, gid, mode; g_file_info_set_attribute_uint32 (info, "standard::type", G_FILE_TYPE_DIRECTORY); /* PARSE OSTREE_OBJECT_TYPE_DIR_META */ - g_variant_get (metadata, "(uuuu@a(ayay))", - &version, &uid, &gid, &mode, - NULL); - version = GUINT32_FROM_BE (version); + g_variant_get (metadata, "(uuu@a(ayay))", + &uid, &gid, &mode, NULL); uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); mode = GUINT32_FROM_BE (mode); @@ -706,8 +714,6 @@ query_child_info_dir (OstreeRepo *repo, ret = TRUE; ot_transfer_out_value(out_info, &ret_info); out: - g_clear_object (&ret_info); - ot_clear_gvariant (&metadata); return ret; } @@ -770,8 +776,8 @@ ostree_repo_file_tree_find_child (OstreeRepoFile *self, GVariant *dirs_variant = NULL; GVariant *ret_container = NULL; - files_variant = g_variant_get_child_value (self->tree_contents, 2); - dirs_variant = g_variant_get_child_value (self->tree_contents, 3); + files_variant = g_variant_get_child_value (self->tree_contents, 0); + dirs_variant = g_variant_get_child_value (self->tree_contents, 1); i = -1; if (bsearch_in_file_variant (files_variant, name, &i)) @@ -820,6 +826,9 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self, ot_lvariant GVariant *files_variant = NULL; ot_lvariant GVariant *dirs_variant = NULL; ot_lvariant GVariant *tree_child_metadata = NULL; + ot_lvariant GVariant *content_csum_v = NULL; + ot_lvariant GVariant *meta_csum_v = NULL; + ot_lfree char *tmp_checksum = NULL; GFileAttributeMatcher *matcher = NULL; if (!ostree_repo_file_ensure_resolved (self, error)) @@ -829,35 +838,34 @@ ostree_repo_file_tree_query_child (OstreeRepoFile *self, g_assert (self->tree_contents); - files_variant = g_variant_get_child_value (self->tree_contents, 2); - dirs_variant = g_variant_get_child_value (self->tree_contents, 3); + files_variant = g_variant_get_child_value (self->tree_contents, 0); + dirs_variant = g_variant_get_child_value (self->tree_contents, 1); c = g_variant_n_children (files_variant); if (n < c) { - const char *checksum; + g_variant_get_child (files_variant, n, "(&s@ay)", &name, &content_csum_v); + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v); - g_variant_get_child (files_variant, n, "(&s&s)", &name, &checksum); - - if (!ostree_repo_load_file (self->repo, checksum, NULL, &ret_info, NULL, + if (!ostree_repo_load_file (self->repo, tmp_checksum, NULL, &ret_info, NULL, cancellable, error)) goto out; } else { - const char *tree_checksum; - const char *meta_checksum; - n -= c; c = g_variant_n_children (dirs_variant); if (n < c) { - g_variant_get_child (dirs_variant, n, "(&s&s&s)", - &name, &tree_checksum, &meta_checksum); + g_variant_get_child (dirs_variant, n, "(&s@ay@ay)", + &name, NULL, &meta_csum_v); + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (meta_csum_v); - if (!query_child_info_dir (self->repo, meta_checksum, + if (!query_child_info_dir (self->repo, tmp_checksum, matcher, flags, &ret_info, cancellable, error)) goto out; diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 2034d238..80a65faa 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -341,6 +341,7 @@ ostree_repo_resolve_rev (OstreeRepo *self, ot_lobj GFile *child = NULL; ot_lobj GFile *origindir = NULL; ot_lvariant GVariant *commit = NULL; + ot_lvariant GVariant *parent_csum_v = NULL; g_return_val_if_fail (rev != NULL, FALSE); @@ -363,14 +364,14 @@ ostree_repo_resolve_rev (OstreeRepo *self, if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_COMMIT, tmp2, &commit, error)) goto out; - g_variant_get_child (commit, 2, "s", &ret_rev); - if (strlen (ret_rev) == 0) + g_variant_get_child (commit, 1, "@ay", &parent_csum_v); + if (g_variant_n_children (parent_csum_v) == 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Commit %s has no parent", tmp2); goto out; - } + ret_rev = ostree_checksum_from_bytes_v (parent_csum_v); } else { @@ -1364,14 +1365,15 @@ ostree_repo_stage_commit (OstreeRepo *self, g_return_val_if_fail (root_metadata_checksum != NULL, FALSE); now = g_date_time_new_now_utc (); - commit = g_variant_new ("(u@a{sv}ssstss)", - GUINT32_TO_BE (OSTREE_COMMIT_VERSION), + commit = g_variant_new ("(@a{sv}@ay@a(say)sst@ay@ay)", metadata ? metadata : create_empty_gvariant_dict (), - parent ? parent : "", + parent ? ostree_checksum_to_bytes_v (parent) : ot_gvariant_new_bytearray (NULL, 0), + g_variant_new_array (G_VARIANT_TYPE ("(say)"), + NULL, 0), subject, body ? body : "", GUINT64_TO_BE (g_date_time_to_unix (now)), - root_contents_checksum, - root_metadata_checksum); + ostree_checksum_to_bytes_v (root_contents_checksum), + ostree_checksum_to_bytes_v (root_metadata_checksum)); g_variant_ref_sink (commit); if (!stage_gvariant_object (self, OSTREE_OBJECT_TYPE_COMMIT, commit, &ret_commit_obj, NULL, error)) @@ -2076,8 +2078,8 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, GSList *iter; GVariant *serialized_tree; - g_variant_builder_init (&files_builder, G_VARIANT_TYPE ("a(ss)")); - g_variant_builder_init (&dirs_builder, G_VARIANT_TYPE ("a(sss)")); + g_variant_builder_init (&files_builder, G_VARIANT_TYPE ("a(say)")); + g_variant_builder_init (&dirs_builder, G_VARIANT_TYPE ("a(sayay)")); g_hash_table_iter_init (&hash_iter, file_checksums); while (g_hash_table_iter_next (&hash_iter, &key, &value)) @@ -2094,7 +2096,8 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, const char *value; value = g_hash_table_lookup (file_checksums, name); - g_variant_builder_add (&files_builder, "(ss)", name, value); + g_variant_builder_add (&files_builder, "(s@ay)", name, + ostree_checksum_to_bytes_v (value)); } g_slist_free (sorted_filenames); @@ -2112,19 +2115,22 @@ create_tree_variant_from_hashes (GHashTable *file_checksums, for (iter = sorted_filenames; iter; iter = iter->next) { const char *name = iter->data; + const char *content_checksum; + const char *meta_checksum; - g_variant_builder_add (&dirs_builder, "(sss)", + content_checksum = g_hash_table_lookup (dir_contents_checksums, name); + meta_checksum = g_hash_table_lookup (dir_metadata_checksums, name); + + g_variant_builder_add (&dirs_builder, "(s@ay@ay)", name, - g_hash_table_lookup (dir_contents_checksums, name), - g_hash_table_lookup (dir_metadata_checksums, name)); + ostree_checksum_to_bytes_v (content_checksum), + ostree_checksum_to_bytes_v (meta_checksum)); } g_slist_free (sorted_filenames); sorted_filenames = NULL; - serialized_tree = g_variant_new ("(u@a{sv}@a(ss)@a(sss))", - GUINT32_TO_BE (0), - create_empty_gvariant_dict (), + serialized_tree = g_variant_new ("(@a(say)@a(sayay))", g_variant_builder_end (&files_builder), g_variant_builder_end (&dirs_builder)); g_variant_ref_sink (serialized_tree); @@ -3330,6 +3336,26 @@ out: return ret; } +gboolean +ostree_repo_load_variant_c (OstreeRepo *self, + OstreeObjectType objtype, + const guchar *csum, + GVariant **out_variant, + GError **error) +{ + gboolean ret = FALSE; + ot_lfree char *checksum = NULL; + + checksum = ostree_checksum_from_bytes (csum); + + if (!ostree_repo_load_variant (self, objtype, checksum, out_variant, error)) + goto out; + + ret = TRUE; + out: + return ret; +} + gboolean ostree_repo_load_variant (OstreeRepo *self, OstreeObjectType objtype, diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h index 05a916df..cfb43aaa 100644 --- a/src/libostree/ostree-repo.h +++ b/src/libostree/ostree-repo.h @@ -137,6 +137,12 @@ gboolean ostree_repo_list_all_refs (OstreeRepo *repo, GCancellable *cancellable, GError **error); +gboolean ostree_repo_load_variant_c (OstreeRepo *self, + OstreeObjectType expected_type, + const guchar *csum, + GVariant **out_variant, + GError **error); + gboolean ostree_repo_load_variant (OstreeRepo *self, OstreeObjectType expected_type, const char *sha256, diff --git a/src/libostree/ostree-traverse.c b/src/libostree/ostree-traverse.c index f1f1661a..148372ef 100644 --- a/src/libostree/ostree-traverse.c +++ b/src/libostree/ostree-traverse.c @@ -47,6 +47,10 @@ ostree_traverse_dirtree (OstreeRepo *repo, ot_lvariant GVariant *tree = NULL; ot_lvariant GVariant *files_variant = NULL; ot_lvariant GVariant *dirs_variant = NULL; + ot_lvariant GVariant *csum_v = NULL; + ot_lvariant GVariant *content_csum_v = NULL; + ot_lvariant GVariant *metadata_csum_v = NULL; + ot_lfree char *tmp_checksum = NULL; if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_DIR_TREE, dirtree_checksum, &tree, error)) goto out; @@ -58,46 +62,52 @@ ostree_traverse_dirtree (OstreeRepo *repo, key = NULL; /* PARSE OSTREE_SERIALIZED_TREE_VARIANT */ - files_variant = g_variant_get_child_value (tree, 2); + files_variant = g_variant_get_child_value (tree, 0); n = g_variant_n_children (files_variant); for (i = 0; i < n; i++) { const char *filename; - const char *checksum; - g_variant_get_child (files_variant, i, "(&s&s)", &filename, &checksum); + ot_clear_gvariant (&csum_v); + g_variant_get_child (files_variant, i, "(&s@ay)", &filename, &csum_v); + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (csum_v); if (ostree_repo_get_mode (repo) == OSTREE_REPO_MODE_BARE) { - key = ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_RAW_FILE); + key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_RAW_FILE); g_hash_table_replace (inout_reachable, key, key); key = NULL; } else { - key = ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META); + key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META); g_hash_table_replace (inout_reachable, key, key); - key = ostree_object_name_serialize (checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT); + key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT); g_hash_table_replace (inout_reachable, key, key); key = NULL; } } - dirs_variant = g_variant_get_child_value (tree, 3); + dirs_variant = g_variant_get_child_value (tree, 1); n = g_variant_n_children (dirs_variant); for (i = 0; i < n; i++) { const char *dirname; - const char *tree_checksum; - const char *meta_checksum; - g_variant_get_child (dirs_variant, i, "(&s&s&s)", - &dirname, &tree_checksum, &meta_checksum); + ot_clear_gvariant (&content_csum_v); + ot_clear_gvariant (&metadata_csum_v); + g_variant_get_child (dirs_variant, i, "(&s@ay@ay)", + &dirname, &content_csum_v, &metadata_csum_v); - if (!ostree_traverse_dirtree (repo, tree_checksum, inout_reachable, + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (content_csum_v); + if (!ostree_traverse_dirtree (repo, tmp_checksum, inout_reachable, cancellable, error)) goto out; - key = ostree_object_name_serialize (meta_checksum, OSTREE_OBJECT_TYPE_DIR_META); + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (metadata_csum_v); + key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META); g_hash_table_replace (inout_reachable, key, key); key = NULL; } @@ -117,10 +127,12 @@ ostree_traverse_commit (OstreeRepo *repo, GError **error) { gboolean ret = FALSE; - const char *contents_checksum; - const char *meta_checksum; + ot_lvariant GVariant *parent_csum_bytes = NULL; + ot_lvariant GVariant *meta_csum_bytes = NULL; + ot_lvariant GVariant *content_csum_bytes = NULL; ot_lvariant GVariant *key; ot_lvariant GVariant *commit = NULL; + ot_lfree char*tmp_checksum = NULL; /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ if (!ostree_repo_load_variant (repo, OSTREE_OBJECT_TYPE_COMMIT, commit_checksum, &commit, error)) @@ -130,24 +142,28 @@ ostree_traverse_commit (OstreeRepo *repo, g_hash_table_replace (inout_reachable, key, key); key = NULL; - g_variant_get_child (commit, 7, "&s", &meta_checksum); - key = ostree_object_name_serialize (meta_checksum, OSTREE_OBJECT_TYPE_DIR_META); + g_variant_get_child (commit, 7, "@ay", &meta_csum_bytes); + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (meta_csum_bytes); + key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META); g_hash_table_replace (inout_reachable, key, key); key = NULL; - g_variant_get_child (commit, 6, "&s", &contents_checksum); - if (!ostree_traverse_dirtree (repo, contents_checksum, inout_reachable, cancellable, error)) + g_variant_get_child (commit, 6, "@ay", &content_csum_bytes); + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (content_csum_bytes); + if (!ostree_traverse_dirtree (repo, tmp_checksum, inout_reachable, cancellable, error)) goto out; if (maxdepth == -1 || maxdepth > 0) { - const char *parent_checksum; + g_variant_get_child (commit, 1, "@ay", &parent_csum_bytes); - g_variant_get_child (commit, 2, "&s", &parent_checksum); - - if (parent_checksum[0]) + if (g_variant_n_children (parent_csum_bytes) > 0) { - if (!ostree_traverse_commit (repo, parent_checksum, + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (parent_csum_bytes); + if (!ostree_traverse_commit (repo, tmp_checksum, maxdepth > 0 ? maxdepth - 1 : -1, inout_reachable, cancellable, error)) goto out; diff --git a/src/ostree/ostree-pull.c b/src/ostree/ostree-pull.c index f5c1ab0a..dbf51b14 100644 --- a/src/ostree/ostree-pull.c +++ b/src/ostree/ostree-pull.c @@ -712,24 +712,22 @@ fetch_and_store_tree_metadata_recurse (OtPullData *pull_data, goto out; /* PARSE OSTREE_SERIALIZED_TREE_VARIANT */ - files_variant = g_variant_get_child_value (tree, 2); - dirs_variant = g_variant_get_child_value (tree, 3); + files_variant = g_variant_get_child_value (tree, 0); + dirs_variant = g_variant_get_child_value (tree, 1); n = g_variant_n_children (files_variant); for (i = 0; i < n; i++) { const char *filename; - const char *checksum; + ot_lvariant GVariant *csum = NULL; - g_variant_get_child (files_variant, i, "(&s&s)", &filename, &checksum); + g_variant_get_child (files_variant, i, "(&s@ay)", &filename, &csum); if (!ot_util_filename_validate (filename, error)) goto out; - if (!ostree_validate_checksum_string (checksum, error)) - goto out; { - char *duped_key = g_strdup (checksum); + char *duped_key = ostree_checksum_from_bytes_v (csum); g_hash_table_replace (pull_data->file_checksums_to_fetch, duped_key, duped_key); } @@ -739,24 +737,25 @@ fetch_and_store_tree_metadata_recurse (OtPullData *pull_data, for (i = 0; i < n; i++) { const char *dirname; - const char *tree_checksum; - const char *meta_checksum; + ot_lvariant GVariant *tree_csum = NULL; + ot_lvariant GVariant *meta_csum = NULL; + ot_lfree char *tmp_checksum = NULL; - g_variant_get_child (dirs_variant, i, "(&s&s&s)", - &dirname, &tree_checksum, &meta_checksum); + g_variant_get_child (dirs_variant, i, "(&s@ay@ay)", + &dirname, &tree_csum, &meta_csum); if (!ot_util_filename_validate (dirname, error)) goto out; - if (!ostree_validate_checksum_string (tree_checksum, error)) - goto out; - if (!ostree_validate_checksum_string (meta_checksum, error)) - goto out; - if (!fetch_and_store_object (pull_data, meta_checksum, OSTREE_OBJECT_TYPE_DIR_META, + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (meta_csum); + if (!fetch_and_store_object (pull_data, tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META, cancellable, error)) goto out; - if (!fetch_and_store_tree_metadata_recurse (pull_data, tree_checksum, cancellable, error)) + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (tree_csum); + if (!fetch_and_store_tree_metadata_recurse (pull_data, tmp_checksum, cancellable, error)) goto out; } @@ -773,22 +772,27 @@ fetch_and_store_commit_metadata_recurse (OtPullData *pull_data, { gboolean ret = FALSE; ot_lvariant GVariant *commit = NULL; - const char *tree_contents_checksum; - const char *tree_meta_checksum; + ot_lvariant GVariant *tree_contents_csum = NULL; + ot_lvariant GVariant *tree_meta_csum = NULL; + ot_lfree char *tmp_checksum = NULL; if (!fetch_and_store_metadata (pull_data, rev, OSTREE_OBJECT_TYPE_COMMIT, &commit, cancellable, error)) goto out; /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */ - g_variant_get_child (commit, 6, "&s", &tree_contents_checksum); - g_variant_get_child (commit, 7, "&s", &tree_meta_checksum); - - if (!fetch_and_store_object (pull_data, tree_meta_checksum, OSTREE_OBJECT_TYPE_DIR_META, + g_variant_get_child (commit, 6, "@ay", &tree_contents_csum); + g_variant_get_child (commit, 7, "@ay", &tree_meta_csum); + + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (tree_meta_csum); + if (!fetch_and_store_object (pull_data, tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META, cancellable, error)) goto out; - if (!fetch_and_store_tree_metadata_recurse (pull_data, tree_contents_checksum, + g_free (tmp_checksum); + tmp_checksum = ostree_checksum_from_bytes_v (tree_contents_csum); + if (!fetch_and_store_tree_metadata_recurse (pull_data, tmp_checksum, cancellable, error)) goto out; diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index 317f7742..689c4f68 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -160,6 +160,10 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error) ot_lobj OstreeMutableTree *mtree = NULL; ot_lfree char *tree_type = NULL; ot_lhash GHashTable *mode_adds = NULL; + ot_lvariant GVariant *parent_content_csum_v = NULL; + ot_lvariant GVariant *parent_metadata_csum_v = NULL; + ot_lfree char *parent_content_checksum = NULL; + ot_lfree char *parent_metadata_checksum = NULL; OstreeRepoCommitModifier *modifier = NULL; GMappedFile *metadata_mappedf = NULL; GVariantBuilder metadata_builder; @@ -363,13 +367,13 @@ ostree_builtin_commit (int argc, char **argv, GFile *repo_path, GError **error) if (skip_if_unchanged && parent_commit) { - const char *parent_contents_checksum; - const char *parent_metadata_checksum; + g_variant_get_child (parent_commit, 6, "@ay", &parent_content_csum_v); + g_variant_get_child (parent_commit, 7, "@ay", &parent_metadata_csum_v); - g_variant_get_child (parent_commit, 6, "&s", &parent_contents_checksum); - g_variant_get_child (parent_commit, 7, "&s", &parent_metadata_checksum); + parent_content_checksum = ostree_checksum_from_bytes_v (parent_content_csum_v); + parent_metadata_checksum = ostree_checksum_from_bytes_v (parent_metadata_csum_v); - if (strcmp (contents_checksum, parent_contents_checksum) == 0 + if (strcmp (contents_checksum, parent_content_checksum) == 0 && strcmp (ostree_mutable_tree_get_metadata_checksum (mtree), parent_metadata_checksum) == 0) skip_commit = TRUE; diff --git a/src/ostree/ot-builtin-log.c b/src/ostree/ot-builtin-log.c index cb0b8e9e..b9bfa405 100644 --- a/src/ostree/ot-builtin-log.c +++ b/src/ostree/ot-builtin-log.c @@ -70,13 +70,12 @@ ostree_builtin_log (int argc, char **argv, GFile *repo_path, GError **error) while (TRUE) { char *formatted = NULL; - guint32 version; - const char *parent; + GVariant *parent_csum_v = NULL; const char *subject; const char *body; guint64 timestamp; - const char *contents; - const char *root_metadata; + GVariant *content_csum_v = NULL; + GVariant *metadata_csum_v = NULL; GDateTime *time_obj = NULL; char *formatted_date = NULL; const char *body_newline; @@ -89,10 +88,13 @@ ostree_builtin_log (int argc, char **argv, GFile *repo_path, GError **error) goto out; /* Ignore commit metadata for now */ - g_variant_get (commit, "(u@a{sv}&s&s&st&s&s)", - &version, &commit_metadata, &parent, &subject, &body, - ×tamp, &contents, &root_metadata); - version = GUINT32_FROM_BE (version); + ot_clear_gvariant (&commit_metadata); + ot_clear_gvariant (&parent_csum_v); + ot_clear_gvariant (&content_csum_v); + ot_clear_gvariant (&metadata_csum_v); + g_variant_get (commit, "(@a{sv}@ay@a(say)&s&st@ay@ay)", + &commit_metadata, &parent_csum_v, NULL, &subject, &body, + ×tamp, &content_csum_v, &metadata_csum_v); timestamp = GUINT64_FROM_BE (timestamp); time_obj = g_date_time_new_from_unix_utc (timestamp); formatted_date = g_date_time_format (time_obj, "%a %b %d %H:%M:%S %Y %z"); @@ -130,10 +132,10 @@ ostree_builtin_log (int argc, char **argv, GFile *repo_path, GError **error) body_newline += 1; } while (*body_newline); - if (strcmp (parent, "") == 0) + if (g_variant_n_children (parent_csum_v) == 0) break; g_free (resolved_rev); - resolved_rev = g_strdup (parent); + resolved_rev = ostree_checksum_from_bytes_v (parent_csum_v); } if (!g_output_stream_close (pager, NULL, error))