From 9d39517554050f70ef72bf42dd32f101c37b7606 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Mon, 5 Dec 2011 10:28:42 -0500 Subject: [PATCH] core: Add _from_input variant of checksum API --- src/libostree/ostree-core.c | 85 +++++++++++++++++++------------------ src/libostree/ostree-core.h | 8 ++++ 2 files changed, 52 insertions(+), 41 deletions(-) diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 196dec85..97c67ebf 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -181,8 +181,8 @@ ostree_get_xattrs_for_file (GFile *f, } static gboolean -checksum_directory (GFile *f, - GFileInfo *f_info, +checksum_directory (GFileInfo *f_info, + GVariant *xattrs, GChecksum **out_checksum, GCancellable *cancellable, GError **error) @@ -190,13 +190,8 @@ checksum_directory (GFile *f, gboolean ret = FALSE; GVariant *dirmeta = NULL; GVariant *packed = NULL; - GVariant *xattrs = NULL; GChecksum *ret_checksum = NULL; - xattrs = ostree_get_xattrs_for_file (f, error); - if (!xattrs) - goto out; - dirmeta = ostree_create_directory_metadata (f_info, xattrs); packed = ostree_wrap_metadata_variant (OSTREE_SERIALIZED_DIRMETA_VARIANT, dirmeta); ret_checksum = g_checksum_new (G_CHECKSUM_SHA256); @@ -205,7 +200,6 @@ checksum_directory (GFile *f, ret = TRUE; ot_transfer_out_value(out_checksum, ret_checksum); - out: ot_clear_checksum (&ret_checksum); ot_clear_gvariant (&dirmeta); ot_clear_gvariant (&packed); @@ -214,40 +208,20 @@ checksum_directory (GFile *f, } static gboolean -checksum_nondirectory (GFile *f, - GFileInfo *file_info, +checksum_nondirectory (GFileInfo *file_info, + GVariant *xattrs, + GInputStream *input, OstreeObjectType objtype, GChecksum **out_checksum, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; - const char *path = NULL; GChecksum *content_sha256 = NULL; GChecksum *content_and_meta_sha256 = NULL; ssize_t bytes_read; - GVariant *xattrs = NULL; - char *basename = NULL; - GInputStream *input = NULL; guint32 unix_mode; - path = ot_gfile_get_path_cached (f); - basename = g_path_get_basename (path); - - if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) - { - input = (GInputStream*)g_file_read (f, cancellable, error); - if (!input) - goto out; - } - - if (objtype == OSTREE_OBJECT_TYPE_FILE) - { - xattrs = ostree_get_xattrs_for_file (f, error); - if (!xattrs) - goto out; - } - content_sha256 = g_checksum_new (G_CHECKSUM_SHA256); unix_mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode"); @@ -285,8 +259,7 @@ checksum_nondirectory (GFile *f, { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, - "Unsupported file '%s' (must be regular, symbolic link, fifo, or character/block device)", - path); + "Unsupported file (must be regular, symbolic link, fifo, or character/block device)"); goto out; } @@ -298,20 +271,39 @@ checksum_nondirectory (GFile *f, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), g_file_info_get_attribute_uint32 (file_info, "unix::gid"), g_file_info_get_attribute_uint32 (file_info, "unix::mode")); - g_checksum_update (content_and_meta_sha256, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs)); + /* FIXME - ensure empty xattrs are the same as NULL xattrs */ + if (xattrs) + g_checksum_update (content_and_meta_sha256, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs)); } ot_transfer_out_value(out_checksum, content_and_meta_sha256); ret = TRUE; out: - g_clear_object (&input); - g_free (basename); - ot_clear_gvariant (&xattrs); ot_clear_checksum (&content_sha256); ot_clear_checksum (&content_and_meta_sha256); return ret; } +gboolean +ostree_checksum_file_from_input (GFileInfo *file_info, + GVariant *xattrs, + GInputStream *in, + OstreeObjectType objtype, + GChecksum **out_checksum, + GCancellable *cancellable, + GError **error) +{ + if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) + { + return checksum_directory (file_info, xattrs, out_checksum, cancellable, error); + } + else + { + return checksum_nondirectory (file_info, xattrs, in, objtype, + out_checksum, cancellable, error); + } +} + gboolean ostree_checksum_file (GFile *f, OstreeObjectType objtype, @@ -322,6 +314,8 @@ ostree_checksum_file (GFile *f, gboolean ret = FALSE; GFileInfo *file_info = NULL; GChecksum *ret_checksum = NULL; + GInputStream *in = NULL; + GVariant *xattrs = NULL; if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; @@ -332,22 +326,31 @@ ostree_checksum_file (GFile *f, if (!file_info) goto out; - if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) + if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { - if (!checksum_directory (f, file_info, &ret_checksum, cancellable, error)) + in = (GInputStream*)g_file_read (f, cancellable, error); + if (!in) goto out; } - else + + if (objtype == OSTREE_OBJECT_TYPE_FILE) { - if (!checksum_nondirectory (f, file_info, objtype, &ret_checksum, cancellable, error)) + xattrs = ostree_get_xattrs_for_file (f, error); + if (!xattrs) goto out; } + if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype, + &ret_checksum, cancellable, error)) + goto out; + ret = TRUE; ot_transfer_out_value(out_checksum, ret_checksum); out: g_clear_object (&file_info); + g_clear_object (&in); ot_clear_checksum(&ret_checksum); + ot_clear_gvariant(&xattrs); return ret; } diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index 454889fc..d87a0041 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -110,6 +110,14 @@ gboolean ostree_parse_metadata_file (GFile *file, GVariant **out_variant, GError **error); +gboolean ostree_checksum_file_from_input (GFileInfo *file_info, + GVariant *xattrs, + GInputStream *in, + OstreeObjectType objtype, + GChecksum **out_checksum, + GCancellable *cancellable, + GError **error); + gboolean ostree_checksum_file (GFile *f, OstreeObjectType type, GChecksum **out_checksum,