[ostree] core: Make checksum API also operate on directories
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] core: Make checksum API also operate on directories
- Date: Fri, 18 Nov 2011 14:56:51 +0000 (UTC)
commit 7f64d5cec745fdbc25c4151ef92032cee1587fa4
Author: Colin Walters <walters verbum org>
Date: Fri Nov 18 06:34:54 2011 -0500
core: Make checksum API also operate on directories
src/libostree/ostree-core.c | 118 +++++++++++++++++++++++++++++++------------
src/libostree/ostree-core.h | 4 ++
src/libostree/ostree-repo.c | 47 +++++------------
3 files changed, 104 insertions(+), 65 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 8caff3f..7e47046 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -41,6 +41,12 @@ ostree_validate_checksum_string (const char *sha256,
return TRUE;
}
+GVariant *
+ostree_wrap_metadata_variant (OstreeSerializedVariantType type,
+ GVariant *metadata)
+{
+ return g_variant_new ("(uv)", GUINT32_TO_BE ((guint32)type), metadata);
+}
void
ostree_checksum_update_stat (GChecksum *checksum, guint32 uid, guint32 gid, guint32 mode)
@@ -174,33 +180,59 @@ ostree_get_xattrs_for_file (GFile *f,
return ret;
}
-gboolean
-ostree_checksum_file (GFile *f,
- OstreeObjectType objtype,
- GChecksum **out_checksum,
- GCancellable *cancellable,
- GError **error)
+static gboolean
+checksum_directory (GFile *f,
+ GFileInfo *f_info,
+ GChecksum **out_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GVariant *dirmeta = NULL;
+ GVariant *packed = NULL;
+ GChecksum *ret_checksum = NULL;
+
+ if (!ostree_get_directory_metadata (f, f_info, &dirmeta, cancellable, error))
+ goto out;
+ packed = ostree_wrap_metadata_variant (OSTREE_SERIALIZED_DIRMETA_VARIANT, dirmeta);
+ ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
+ g_checksum_update (ret_checksum, g_variant_get_data (packed),
+ g_variant_get_size (packed));
+
+ ret = TRUE;
+ *out_checksum = ret_checksum;
+ ret_checksum = NULL;
+ out:
+ if (ret_checksum)
+ g_checksum_free (ret_checksum);
+ if (dirmeta)
+ g_variant_unref (dirmeta);
+ if (packed)
+ g_variant_unref (packed);
+ return ret;
+}
+
+static gboolean
+checksum_nondirectory (GFile *f,
+ GFileInfo *file_info,
+ 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;
- gboolean ret = FALSE;
- GFileInfo *file_info = NULL;
GInputStream *input = NULL;
guint32 unix_mode;
path = ot_gfile_get_path_cached (f);
basename = g_path_get_basename (path);
- file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- cancellable, error);
- if (!file_info)
- goto out;
-
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
{
input = (GInputStream*)g_file_read (f, cancellable, error);
@@ -272,7 +304,6 @@ ostree_checksum_file (GFile *f,
ret = TRUE;
out:
g_clear_object (&input);
- g_clear_object (&file_info);
g_free (basename);
if (xattrs)
g_variant_unref (xattrs);
@@ -282,38 +313,61 @@ ostree_checksum_file (GFile *f,
}
gboolean
+ostree_checksum_file (GFile *f,
+ OstreeObjectType objtype,
+ GChecksum **out_checksum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GFileInfo *file_info = NULL;
+ GChecksum *ret_checksum = NULL;
+
+ file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ cancellable, error);
+ if (!file_info)
+ goto out;
+
+ if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+ {
+ if (!checksum_directory (f, file_info, &ret_checksum, cancellable, error))
+ goto out;
+ }
+ else
+ {
+ if (!checksum_nondirectory (f, file_info, objtype, &ret_checksum, cancellable, error))
+ goto out;
+ }
+
+ ret = TRUE;
+ *out_checksum = ret_checksum;
+ ret_checksum = NULL;
+ out:
+ g_clear_object (&file_info);
+ return ret;
+}
+
+gboolean
ostree_get_directory_metadata (GFile *dir,
+ GFileInfo *dir_info,
GVariant **out_metadata,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
- struct stat stbuf;
GVariant *xattrs = NULL;
GVariant *ret_metadata = NULL;
- if (lstat (ot_gfile_get_path_cached (dir), &stbuf) < 0)
- {
- ot_util_set_error_from_errno (error, errno);
- goto out;
- }
-
- if (!S_ISDIR(stbuf.st_mode))
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Not a directory: '%s'", ot_gfile_get_path_cached (dir));
- goto out;
- }
-
xattrs = ostree_get_xattrs_for_file (dir, error);
if (!xattrs)
goto out;
ret_metadata = g_variant_new ("(uuuu a(ayay))",
OSTREE_DIR_META_VERSION,
- GUINT32_TO_BE ((guint32)stbuf.st_uid),
- GUINT32_TO_BE ((guint32)stbuf.st_gid),
- GUINT32_TO_BE ((guint32)stbuf.st_mode),
+ 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")),
xattrs);
g_variant_ref_sink (ret_metadata);
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 38d08ed..3e779e5 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -101,6 +101,9 @@ char *ostree_get_relative_object_path (const char *checksum,
GVariant *ostree_get_xattrs_for_file (GFile *f,
GError **error);
+GVariant *ostree_wrap_metadata_variant (OstreeSerializedVariantType type,
+ GVariant *metadata);
+
gboolean ostree_set_xattrs (GFile *f, GVariant *xattrs,
GCancellable *cancellable, GError **error);
@@ -116,6 +119,7 @@ gboolean ostree_checksum_file (GFile *f,
GError **error);
gboolean ostree_get_directory_metadata (GFile *dir,
+ GFileInfo *dir_info,
GVariant **out_metadata,
GCancellable *cancellable,
GError **error);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 60f38ba..2b28fdc 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -557,13 +557,6 @@ ostree_repo_is_archive (OstreeRepo *self)
return priv->archive;
}
-static GVariant *
-pack_metadata_variant (OstreeSerializedVariantType type,
- GVariant *variant)
-{
- return g_variant_new ("(uv)", GUINT32_TO_BE ((guint32)type), variant);
-}
-
static gboolean
write_gvariant_to_tmp (OstreeRepo *self,
OstreeSerializedVariantType type,
@@ -582,7 +575,7 @@ write_gvariant_to_tmp (OstreeRepo *self,
GUnixOutputStream *stream = NULL;
GChecksum *checksum = NULL;
- serialized = pack_metadata_variant (type, variant);
+ serialized = ostree_wrap_metadata_variant (type, variant);
tmp_name = g_build_filename (ot_gfile_get_path_cached (priv->tmp_dir), "variant-tmp-XXXXXX", NULL);
fd = g_mkstemp (tmp_name);
@@ -709,10 +702,17 @@ import_directory_meta (OstreeRepo *self,
GChecksum *ret_checksum = NULL;
GVariant *dirmeta = NULL;
GFile *f = NULL;
+ GFileInfo *f_info = NULL;
f = ot_util_new_file_for_path (path);
- if (!ostree_get_directory_metadata (f, &dirmeta, NULL, error))
+ f_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL, error);
+ if (!f_info)
+ goto out;
+
+ if (!ostree_get_directory_metadata (f, f_info, &dirmeta, NULL, error))
goto out;
if (!import_gvariant_object (self, OSTREE_SERIALIZED_DIRMETA_VARIANT,
@@ -726,6 +726,7 @@ import_directory_meta (OstreeRepo *self,
ret_checksum = NULL;
out:
g_clear_object (&f);
+ g_clear_object (&f_info);
if (ret_checksum)
g_checksum_free (ret_checksum);
if (dirmeta != NULL)
@@ -1884,8 +1885,6 @@ get_file_checksum (GFile *f,
{
gboolean ret = FALSE;
GChecksum *tmp_checksum = NULL;
- GVariant *dirmeta = NULL;
- GVariant *packed_dirmeta = NULL;
char *ret_checksum = NULL;
if (OSTREE_IS_REPO_FILE (f))
@@ -1894,36 +1893,18 @@ get_file_checksum (GFile *f,
}
else
{
- if (g_file_info_get_file_type (f_info) == G_FILE_TYPE_DIRECTORY)
- {
- tmp_checksum = g_checksum_new (G_CHECKSUM_SHA256);
- if (!ostree_get_directory_metadata (f, &dirmeta, cancellable, error))
- goto out;
- packed_dirmeta = pack_metadata_variant (OSTREE_SERIALIZED_DIRMETA_VARIANT, dirmeta);
- g_checksum_update (tmp_checksum, g_variant_get_data (packed_dirmeta),
- g_variant_get_size (packed_dirmeta));
- ret_checksum = g_strdup (g_checksum_get_string (tmp_checksum));
- }
- else
- {
- if (!ostree_checksum_file (f, OSTREE_OBJECT_TYPE_FILE,
- &tmp_checksum, cancellable, error))
- goto out;
- ret_checksum = g_strdup (g_checksum_get_string (tmp_checksum));
- }
+ if (!ostree_checksum_file (f, OSTREE_OBJECT_TYPE_FILE,
+ &tmp_checksum, cancellable, error))
+ goto out;
+ ret_checksum = g_strdup (g_checksum_get_string (tmp_checksum));
}
ret = TRUE;
*out_checksum = ret_checksum;
ret_checksum = NULL;
out:
- g_free (ret_checksum);
if (tmp_checksum)
g_checksum_free (tmp_checksum);
- if (dirmeta)
- g_variant_unref (dirmeta);
- if (packed_dirmeta)
- g_variant_unref (packed_dirmeta);
return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]