[ostree/wip/archive-v3: 9/10] core: Clean up checksumming
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/archive-v3: 9/10] core: Clean up checksumming
- Date: Thu, 12 Apr 2012 00:44:24 +0000 (UTC)
commit 0d43b60787e03e7e461a418a03f21395e4728ed3
Author: Colin Walters <walters verbum org>
Date: Tue Apr 10 16:40:22 2012 -0400
core: Clean up checksumming
Don't expose GChecksum in APIs. Add a new stream class which allows
us to pass an input stream somewhere, but gather a checksum as it's
read.
Move some bits of the internals towards binary csums.
Makefile-libostree.am | 2 +
Makefile-otutil.am | 2 +
src/libostree/ostree-checksum-input-stream.c | 169 ++++++++++++++++++
src/libostree/ostree-checksum-input-stream.h | 68 ++++++++
src/libostree/ostree-core.c | 235 ++++++++++++--------------
src/libostree/ostree-core.h | 12 +-
src/libostree/ostree-repo.c | 201 ++++++++++++----------
src/libostree/ostree.h | 1 +
src/libotutil/ot-checksum-utils.c | 38 ++++
src/libotutil/ot-checksum-utils.h | 34 ++++
src/libotutil/ot-gio-utils.c | 54 ++++--
src/libotutil/ot-gio-utils.h | 12 +-
src/libotutil/ot-variant-utils.c | 6 +-
src/libotutil/otutil.h | 1 +
src/ostree/ot-builtin-checksum.c | 10 +-
src/ostree/ot-builtin-diff.c | 7 +-
src/ostree/ot-builtin-fsck.c | 27 ++--
17 files changed, 605 insertions(+), 274 deletions(-)
---
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index e244393..bc64cb7 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -22,6 +22,8 @@ privlib_LTLIBRARIES += libostree.la
libostree_la_SOURCES = src/libostree/ostree.h \
src/libostree/ostree-core.c \
src/libostree/ostree-core.h \
+ src/libostree/ostree-checksum-input-stream.c \
+ src/libostree/ostree-checksum-input-stream.h \
src/libostree/ostree-mutable-tree.c \
src/libostree/ostree-mutable-tree.h \
src/libostree/ostree-repo.c \
diff --git a/Makefile-otutil.am b/Makefile-otutil.am
index 4493564..1bf2764 100644
--- a/Makefile-otutil.am
+++ b/Makefile-otutil.am
@@ -20,6 +20,8 @@
noinst_LTLIBRARIES += libotutil.la
libotutil_la_SOURCES = \
+ src/libotutil/ot-checksum-utils.c \
+ src/libotutil/ot-checksum-utils.h \
src/libotutil/ot-local-alloc.c \
src/libotutil/ot-local-alloc.h \
src/libotutil/ot-opt-utils.c \
diff --git a/src/libostree/ostree-checksum-input-stream.c b/src/libostree/ostree-checksum-input-stream.c
new file mode 100644
index 0000000..ef5f0d4
--- /dev/null
+++ b/src/libostree/ostree-checksum-input-stream.c
@@ -0,0 +1,169 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+
+#include <gio/gio.h>
+#include "ostree-checksum-input-stream.h"
+
+enum {
+ PROP_0,
+ PROP_CHECKSUM
+};
+
+G_DEFINE_TYPE (OstreeChecksumInputStream, ostree_checksum_input_stream, G_TYPE_FILTER_INPUT_STREAM)
+
+struct _OstreeChecksumInputStreamPrivate {
+ GChecksum *checksum;
+};
+
+static void ostree_checksum_input_stream_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void ostree_checksum_input_stream_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static gssize ostree_checksum_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error);
+
+static void
+ostree_checksum_input_stream_class_init (OstreeChecksumInputStreamClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (OstreeChecksumInputStreamPrivate));
+
+ gobject_class->get_property = ostree_checksum_input_stream_get_property;
+ gobject_class->set_property = ostree_checksum_input_stream_set_property;
+
+ stream_class->read_fn = ostree_checksum_input_stream_read;
+
+ /**
+ * OstreeChecksumInputStream:checksum:
+ *
+ * The checksum that the stream updates.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CHECKSUM,
+ g_param_spec_pointer ("checksum",
+ "", "",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+}
+
+static void
+ostree_checksum_input_stream_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ OstreeChecksumInputStream *self;
+
+ self = OSTREE_CHECKSUM_INPUT_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_CHECKSUM:
+ self->priv->checksum = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ostree_checksum_input_stream_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ OstreeChecksumInputStream *self;
+
+ self = OSTREE_CHECKSUM_INPUT_STREAM (object);
+
+ switch (prop_id)
+ {
+ case PROP_CHECKSUM:
+ g_value_set_pointer (value, self->priv->checksum);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ostree_checksum_input_stream_init (OstreeChecksumInputStream *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
+ OSTREE_TYPE_CHECKSUM_INPUT_STREAM,
+ OstreeChecksumInputStreamPrivate);
+
+}
+
+OstreeChecksumInputStream *
+ostree_checksum_input_stream_new (GInputStream *base,
+ GChecksum *checksum)
+{
+ OstreeChecksumInputStream *stream;
+
+ g_return_val_if_fail (G_IS_INPUT_STREAM (base), NULL);
+
+ stream = g_object_new (OSTREE_TYPE_CHECKSUM_INPUT_STREAM,
+ "base-stream", base,
+ "checksum", checksum,
+ NULL);
+
+ return (OstreeChecksumInputStream*) (stream);
+}
+
+static gssize
+ostree_checksum_input_stream_read (GInputStream *stream,
+ void *buffer,
+ gsize count,
+ GCancellable *cancellable,
+ GError **error)
+{
+ OstreeChecksumInputStream *self = (OstreeChecksumInputStream*) stream;
+ GFilterInputStream *fself = (GFilterInputStream*) self;
+ gssize res = -1;
+
+ if (g_cancellable_set_error_if_cancelled (cancellable, error))
+ return -1;
+
+ res = g_input_stream_read (fself->base_stream,
+ buffer,
+ count,
+ cancellable,
+ error);
+ if (res > 0)
+ g_checksum_update (self->priv->checksum, buffer, res);
+
+ return res;
+}
diff --git a/src/libostree/ostree-checksum-input-stream.h b/src/libostree/ostree-checksum-input-stream.h
new file mode 100644
index 0000000..32676b0
--- /dev/null
+++ b/src/libostree/ostree-checksum-input-stream.h
@@ -0,0 +1,68 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __OSTREE_CHECKSUM_INPUT_STREAM_H__
+#define __OSTREE_CHECKSUM_INPUT_STREAM_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_CHECKSUM_INPUT_STREAM (ostree_checksum_input_stream_get_type ())
+#define OSTREE_CHECKSUM_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStream))
+#define OSTREE_CHECKSUM_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStreamClass))
+#define OSTREE_IS_CHECKSUM_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM))
+#define OSTREE_IS_CHECKSUM_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_CHECKSUM_INPUT_STREAM))
+#define OSTREE_CHECKSUM_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_CHECKSUM_INPUT_STREAM, OstreeChecksumInputStreamClass))
+
+typedef struct _OstreeChecksumInputStream OstreeChecksumInputStream;
+typedef struct _OstreeChecksumInputStreamClass OstreeChecksumInputStreamClass;
+typedef struct _OstreeChecksumInputStreamPrivate OstreeChecksumInputStreamPrivate;
+
+struct _OstreeChecksumInputStream
+{
+ GFilterInputStream parent_instance;
+
+ /*< private >*/
+ OstreeChecksumInputStreamPrivate *priv;
+};
+
+struct _OstreeChecksumInputStreamClass
+{
+ GFilterInputStreamClass parent_class;
+
+ /*< private >*/
+ /* Padding for future expansion */
+ void (*_g_reserved1) (void);
+ void (*_g_reserved2) (void);
+ void (*_g_reserved3) (void);
+ void (*_g_reserved4) (void);
+ void (*_g_reserved5) (void);
+};
+
+GType ostree_checksum_input_stream_get_type (void) G_GNUC_CONST;
+
+OstreeChecksumInputStream * ostree_checksum_input_stream_new (GInputStream *stream,
+ GChecksum *checksum);
+
+G_END_DECLS
+
+#endif /* __OSTREE_CHECKSUM_INPUT_STREAM_H__ */
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 17f026c..f87f31c 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -79,15 +79,63 @@ ostree_validate_rev (const char *rev,
}
void
-ostree_checksum_update_stat (GChecksum *checksum, guint32 uid, guint32 gid, guint32 mode)
+ostree_checksum_update_meta (GChecksum *checksum,
+ GFileInfo *file_info,
+ GVariant *xattrs)
{
+ guint32 mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
+ guint32 uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid");
+ guint32 gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid");
guint32 perms;
+
+ if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR
+ || g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+ {
+ /* Nothing */
+ }
+ else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
+ {
+ const char *symlink_target = g_file_info_get_symlink_target (file_info);
+
+ g_assert (symlink_target != NULL);
+
+ g_checksum_update (checksum, (guint8*)symlink_target, strlen (symlink_target));
+ }
+ else if (S_ISCHR(mode) || S_ISBLK(mode))
+ {
+ guint32 rdev = g_file_info_get_attribute_uint32 (file_info, "unix::rdev");
+ rdev = GUINT32_TO_BE (rdev);
+ g_checksum_update (checksum, (guint8*)&rdev, 4);
+ }
+ else if (S_ISFIFO(mode))
+ {
+ /* Nothing */
+ }
+ else
+ {
+ g_assert_not_reached ();
+ }
+
perms = GUINT32_TO_BE (mode & ~S_IFMT);
uid = GUINT32_TO_BE (uid);
gid = GUINT32_TO_BE (gid);
g_checksum_update (checksum, (guint8*) &uid, 4);
g_checksum_update (checksum, (guint8*) &gid, 4);
g_checksum_update (checksum, (guint8*) &perms, 4);
+
+ if (xattrs)
+ {
+ g_checksum_update (checksum, (guint8*)g_variant_get_data (xattrs),
+ g_variant_get_size (xattrs));
+ }
+ else
+ {
+ ot_lvariant GVariant *tmp_attrs = g_variant_new_array (G_VARIANT_TYPE ("(ayay)"),
+ NULL, 0);
+ g_variant_ref_sink (tmp_attrs);
+ g_checksum_update (checksum, (guint8*)g_variant_get_data (tmp_attrs),
+ g_variant_get_size (tmp_attrs));
+ }
}
static char *
@@ -220,87 +268,71 @@ gboolean
ostree_checksum_file_from_input (GFileInfo *file_info,
GVariant *xattrs,
GInputStream *in,
- OstreeObjectType objtype,
- GChecksum **out_checksum,
+ OstreeObjectType objtype,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
- guint8 buf[8192];
- gsize bytes_read;
guint32 mode;
ot_lvariant GVariant *dirmeta = NULL;
- GChecksum *ret_checksum = NULL;
-
- if (OSTREE_OBJECT_TYPE_IS_META (objtype))
- return ot_gio_checksum_stream (in, out_checksum, cancellable, error);
-
- ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
+ ot_lfree guchar *ret_csum = NULL;
+ GChecksum *checksum = NULL;
- mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
+ checksum = g_checksum_new (G_CHECKSUM_SHA256);
- if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
- {
- dirmeta = ostree_create_directory_metadata (file_info, xattrs);
- g_checksum_update (ret_checksum, g_variant_get_data (dirmeta),
- g_variant_get_size (dirmeta));
-
- }
- else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
+ if (OSTREE_OBJECT_TYPE_IS_META (objtype))
{
- while ((bytes_read = g_input_stream_read (in, buf, sizeof (buf), cancellable, error)) > 0)
- g_checksum_update (ret_checksum, buf, bytes_read);
- if (bytes_read < 0)
+ if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
goto out;
}
- else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
- {
- const char *symlink_target = g_file_info_get_symlink_target (file_info);
-
- g_assert (symlink_target != NULL);
-
- g_checksum_update (ret_checksum, (guint8*)symlink_target, strlen (symlink_target));
- }
- else if (S_ISCHR(mode) || S_ISBLK(mode))
- {
- guint32 rdev = g_file_info_get_attribute_uint32 (file_info, "unix::rdev");
- rdev = GUINT32_TO_BE (rdev);
- g_checksum_update (ret_checksum, (guint8*)&rdev, 4);
- }
- else if (S_ISFIFO(mode))
- {
- ;
- }
else
{
- g_set_error (error, G_IO_ERROR,
- G_IO_ERROR_FAILED,
- "Unsupported file (must be regular, symbolic link, fifo, or character/block device)");
- goto out;
- }
+ mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
- if (objtype != OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
- {
- ostree_checksum_update_stat (ret_checksum,
- 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"));
- /* FIXME - ensure empty xattrs are the same as NULL xattrs */
- if (xattrs)
- g_checksum_update (ret_checksum, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs));
+ if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
+ {
+ dirmeta = ostree_create_directory_metadata (file_info, xattrs);
+ g_checksum_update (checksum, g_variant_get_data (dirmeta),
+ g_variant_get_size (dirmeta));
+
+ }
+ else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
+ {
+ if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
+ goto out;
+ }
+ else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK
+ || S_ISCHR(mode) || S_ISBLK(mode)
+ || S_ISFIFO(mode))
+ {
+ /* We update the checksum below */
+ }
+ else
+ {
+ g_set_error (error, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Unsupported file (must be regular, symbolic link, fifo, or character/block device)");
+ goto out;
+ }
+
+ if (objtype != OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
+ ostree_checksum_update_meta (checksum, file_info, xattrs);
}
+ ret_csum = ot_csum_from_gchecksum (checksum);
+
ret = TRUE;
- ot_transfer_out_value (out_checksum, &ret_checksum);
+ ot_transfer_out_value (out_csum, &ret_csum);
out:
- ot_clear_checksum (&ret_checksum);
+ ot_clear_checksum (&checksum);
return ret;
}
gboolean
ostree_checksum_file (GFile *f,
- OstreeObjectType objtype,
- GChecksum **out_checksum,
+ OstreeObjectType objtype,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
@@ -308,7 +340,7 @@ ostree_checksum_file (GFile *f,
ot_lobj GFileInfo *file_info = NULL;
ot_lobj GInputStream *in = NULL;
ot_lvariant GVariant *xattrs = NULL;
- GChecksum *ret_checksum = NULL;
+ ot_lfree guchar *ret_csum = NULL;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
@@ -333,20 +365,19 @@ ostree_checksum_file (GFile *f,
}
if (!ostree_checksum_file_from_input (file_info, xattrs, in, objtype,
- &ret_checksum, cancellable, error))
+ &ret_csum, cancellable, error))
goto out;
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
+ ot_transfer_out_value(out_csum, &ret_csum);
out:
- ot_clear_checksum(&ret_checksum);
return ret;
}
typedef struct {
GFile *f;
OstreeObjectType objtype;
- GChecksum *checksum;
+ guchar *csum;
} ChecksumFileAsyncData;
static void
@@ -356,13 +387,13 @@ checksum_file_async_thread (GSimpleAsyncResult *res,
{
GError *error = NULL;
ChecksumFileAsyncData *data;
- GChecksum *checksum = NULL;
+ guchar *csum = NULL;
data = g_simple_async_result_get_op_res_gpointer (res);
- if (!ostree_checksum_file (data->f, data->objtype, &checksum, cancellable, &error))
+ if (!ostree_checksum_file (data->f, data->objtype, &csum, cancellable, &error))
g_simple_async_result_take_error (res, error);
else
- data->checksum = checksum;
+ data->csum = csum;
}
static void
@@ -371,7 +402,7 @@ checksum_file_async_data_free (gpointer datap)
ChecksumFileAsyncData *data = datap;
g_object_unref (data->f);
- ot_clear_checksum (&data->checksum);
+ g_free (data->csum);
g_free (data);
}
@@ -400,7 +431,7 @@ ostree_checksum_file_async (GFile *f,
gboolean
ostree_checksum_file_async_finish (GFile *f,
GAsyncResult *result,
- GChecksum **out_checksum,
+ guchar **out_csum,
GError **error)
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
@@ -413,8 +444,8 @@ ostree_checksum_file_async_finish (GFile *f,
data = g_simple_async_result_get_op_res_gpointer (simple);
/* Transfer ownership */
- *out_checksum = data->checksum;
- data->checksum = NULL;
+ *out_csum = data->csum;
+ data->csum = NULL;
return TRUE;
}
@@ -810,21 +841,13 @@ ostree_create_file_from_input (GFile *dest_file,
GFileInfo *finfo,
GVariant *xattrs,
GInputStream *input,
- OstreeObjectType objtype,
- GChecksum **out_checksum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
const char *dest_path;
guint32 uid, gid, mode;
- gboolean is_meta;
- gboolean is_archived_content;
ot_lobj GFileOutputStream *out = NULL;
- GChecksum *ret_checksum = NULL;
-
- is_meta = OSTREE_OBJECT_TYPE_IS_META (objtype);
- is_archived_content = objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
@@ -832,12 +855,6 @@ ostree_create_file_from_input (GFile *dest_file,
if (finfo != NULL)
{
mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode");
- /* Archived content files should always be readable by all and
- * read/write by owner. If the base file is executable then
- * we're also executable.
- */
- if (is_archived_content)
- mode |= 0644;
}
else
{
@@ -861,9 +878,8 @@ ostree_create_file_from_input (GFile *dest_file,
if (input)
{
- if (!ot_gio_splice_and_checksum ((GOutputStream*)out, input,
- out_checksum ? &ret_checksum : NULL,
- cancellable, error))
+ if (g_output_stream_splice ((GOutputStream*)out, input, 0,
+ cancellable, error) < 0)
goto out;
}
@@ -873,11 +889,6 @@ ostree_create_file_from_input (GFile *dest_file,
else if (S_ISLNK (mode))
{
const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target");
- g_assert (!is_meta);
- if (out_checksum)
- ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
- if (ret_checksum)
- g_checksum_update (ret_checksum, (guint8*)target, strlen (target));
if (symlink (target, dest_path) < 0)
{
ot_util_set_error_from_errno (error, errno);
@@ -887,13 +898,6 @@ ostree_create_file_from_input (GFile *dest_file,
else if (S_ISCHR (mode) || S_ISBLK (mode))
{
guint32 dev = g_file_info_get_attribute_uint32 (finfo, "unix::rdev");
- guint32 dev_be;
- g_assert (!is_meta);
- dev_be = GUINT32_TO_BE (dev);
- if (out_checksum)
- ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
- if (ret_checksum)
- g_checksum_update (ret_checksum, (guint8*)&dev_be, 4);
if (mknod (dest_path, mode, dev) < 0)
{
ot_util_set_error_from_errno (error, errno);
@@ -902,9 +906,6 @@ ostree_create_file_from_input (GFile *dest_file,
}
else if (S_ISFIFO (mode))
{
- g_assert (!is_meta);
- if (out_checksum)
- ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
if (mkfifo (dest_path, mode) < 0)
{
ot_util_set_error_from_errno (error, errno);
@@ -918,7 +919,7 @@ ostree_create_file_from_input (GFile *dest_file,
goto out;
}
- if (finfo != NULL && !is_meta && !is_archived_content)
+ if (finfo != NULL)
{
uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
@@ -941,31 +942,16 @@ ostree_create_file_from_input (GFile *dest_file,
if (xattrs != NULL)
{
- g_assert (!is_meta);
if (!ostree_set_xattrs (dest_file, xattrs, cancellable, error))
goto out;
}
- if (ret_checksum && !is_meta && !is_archived_content)
- {
- g_assert (finfo != NULL);
-
- ostree_checksum_update_stat (ret_checksum,
- g_file_info_get_attribute_uint32 (finfo, "unix::uid"),
- g_file_info_get_attribute_uint32 (finfo, "unix::gid"),
- mode);
- if (xattrs)
- g_checksum_update (ret_checksum, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs));
- }
-
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
out:
if (!ret && !S_ISDIR(mode))
{
(void) unlink (dest_path);
}
- ot_clear_checksum (&ret_checksum);
return ret;
}
@@ -1016,9 +1002,7 @@ ostree_create_temp_file_from_input (GFile *dir,
GFileInfo *finfo,
GVariant *xattrs,
GInputStream *input,
- OstreeObjectType objtype,
GFile **out_file,
- GChecksum **out_checksum,
GCancellable *cancellable,
GError **error)
{
@@ -1027,7 +1011,7 @@ ostree_create_temp_file_from_input (GFile *dir,
int i = 0;
ot_lfree char *possible_name = NULL;
ot_lobj GFile *possible_file = NULL;
- GChecksum *ret_checksum = NULL;
+ ot_lfree guchar *ret_csum = NULL;
GString *tmp_name = NULL;
tmp_name = create_tmp_string (ot_gfile_get_path_cached (dir),
@@ -1045,8 +1029,6 @@ ostree_create_temp_file_from_input (GFile *dir,
possible_file = g_file_get_child (dir, possible_name);
if (!ostree_create_file_from_input (possible_file, finfo, xattrs, input,
- objtype,
- out_checksum ? &ret_checksum : NULL,
cancellable, &temp_error))
{
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
@@ -1073,12 +1055,10 @@ ostree_create_temp_file_from_input (GFile *dir,
}
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
ot_transfer_out_value(out_file, &possible_file);
out:
if (tmp_name)
g_string_free (tmp_name, TRUE);
- ot_clear_checksum (&ret_checksum);
return ret;
}
@@ -1096,8 +1076,7 @@ ostree_create_temp_regular_file (GFile *dir,
ot_lobj GOutputStream *ret_stream = NULL;
if (!ostree_create_temp_file_from_input (dir, prefix, suffix, NULL, NULL, NULL,
- OSTREE_OBJECT_TYPE_RAW_FILE, &ret_file,
- NULL, cancellable, error))
+ &ret_file, cancellable, error))
goto out;
ret_stream = (GOutputStream*)g_file_append_to (ret_file, 0, cancellable, error);
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 936c87e..02ccb01 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -147,7 +147,7 @@ int ostree_cmp_checksum_bytes (const guchar *a, const guchar *b);
gboolean ostree_validate_rev (const char *rev, GError **error);
-void ostree_checksum_update_stat (GChecksum *checksum, guint32 uid, guint32 gid, guint32 mode);
+void ostree_checksum_update_meta (GChecksum *checksum, GFileInfo *file_info, GVariant *xattrs);
const char * ostree_object_type_to_string (OstreeObjectType objtype);
@@ -199,13 +199,13 @@ gboolean ostree_checksum_file_from_input (GFileInfo *file_info,
GVariant *xattrs,
GInputStream *in,
OstreeObjectType objtype,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error);
gboolean ostree_checksum_file (GFile *f,
OstreeObjectType type,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error);
@@ -218,7 +218,7 @@ void ostree_checksum_file_async (GFile *f,
gboolean ostree_checksum_file_async_finish (GFile *f,
GAsyncResult *result,
- GChecksum **out_checksum,
+ guchar **out_csum,
GError **error);
GVariant *ostree_create_directory_metadata (GFileInfo *dir_info,
@@ -228,8 +228,6 @@ gboolean ostree_create_file_from_input (GFile *file,
GFileInfo *finfo,
GVariant *xattrs,
GInputStream *input,
- OstreeObjectType objtype,
- GChecksum **out_checksum,
GCancellable *cancellable,
GError **error);
@@ -239,9 +237,7 @@ gboolean ostree_create_temp_file_from_input (GFile *dir,
GFileInfo *finfo,
GVariant *xattrs,
GInputStream *input,
- OstreeObjectType objtype,
GFile **out_file,
- GChecksum **out_checksum,
GCancellable *cancellable,
GError **error);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index cc92f2f..64d65db 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -764,7 +764,7 @@ stage_object_impl (OstreeRepo *self,
GVariant *xattrs,
GInputStream *input,
const char *expected_checksum,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error);
@@ -810,7 +810,7 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
GVariant *xattrs,
GInputStream *input,
const char *expected_checksum,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
@@ -822,7 +822,16 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
ot_lobj GFile *meta_temp_file = NULL;
ot_lobj GFile *content_temp_file = NULL;
ot_lobj GInputStream *mem = NULL;
- GChecksum *ret_checksum = NULL;
+ ot_lobj OstreeChecksumInputStream *checksum_input = NULL;
+ ot_lfree guchar *ret_csum = NULL;
+ GChecksum *checksum = NULL;
+
+ if (expected_checksum || out_csum)
+ {
+ checksum = g_checksum_new (G_CHECKSUM_SHA256);
+ if (input)
+ checksum_input = ostree_checksum_input_stream_new (input, checksum);
+ }
archive_metadata = ostree_create_archive_file_metadata (file_info, xattrs);
@@ -833,42 +842,36 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
if (!ostree_create_temp_file_from_input (priv->tmp_dir,
"archive-tmp-", NULL,
NULL, NULL, mem,
- OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
&meta_temp_file,
- NULL,
cancellable, error))
goto out;
temp_info = dup_file_info_owned_by_me (file_info);
+ /* Archived content files should always be readable by all and
+ * read/write by owner. If the base file is executable then
+ * we're also executable.
+ */
+ g_file_info_set_attribute_uint32 (temp_info, "unix::mode",
+ g_file_info_get_attribute_uint32 (file_info, "unix::mode") | 0644);
if (!ostree_create_temp_file_from_input (priv->tmp_dir,
"archive-tmp-", NULL,
- temp_info, NULL, input,
- OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT,
+ temp_info, NULL,
+ checksum_input ? (GInputStream*)checksum_input : input,
&content_temp_file,
- out_checksum ? &ret_checksum : NULL,
cancellable, error))
goto out;
- if (out_checksum)
- {
- g_assert (ret_checksum);
- ostree_checksum_update_stat (ret_checksum,
- 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"));
- /* FIXME - ensure empty xattrs are the same as NULL xattrs */
- if (xattrs)
- g_checksum_update (ret_checksum, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs));
- }
+ if (checksum)
+ ostree_checksum_update_meta (checksum, file_info, xattrs);
- if (expected_checksum && ret_checksum)
+ if (expected_checksum && checksum)
{
- if (strcmp (g_checksum_get_string (ret_checksum), expected_checksum) != 0)
+ if (strcmp (g_checksum_get_string (checksum), expected_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Corrupted %s object %s (actual checksum is %s)",
ostree_object_type_to_string (OSTREE_OBJECT_TYPE_RAW_FILE),
- expected_checksum, g_checksum_get_string (ret_checksum));
+ expected_checksum, g_checksum_get_string (checksum));
goto out;
}
actual_checksum = expected_checksum;
@@ -876,7 +879,7 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
else if (expected_checksum)
actual_checksum = expected_checksum;
else
- actual_checksum = g_checksum_get_string (ret_checksum);
+ actual_checksum = g_checksum_get_string (checksum);
if (!commit_tmpfile_trusted (self, actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT,
content_temp_file, cancellable, error))
@@ -886,10 +889,13 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
meta_temp_file, cancellable, error))
goto out;
+ if (checksum)
+ ret_csum = ot_csum_from_gchecksum (checksum);
+
ret = TRUE;
- ot_transfer_out_value (out_checksum, &ret_checksum);
+ ot_transfer_out_value (out_csum, &ret_csum);
out:
- ot_clear_checksum (&ret_checksum);
+ ot_clear_checksum (&checksum);
return ret;
}
@@ -901,7 +907,7 @@ stage_object_impl (OstreeRepo *self,
GVariant *xattrs,
GInputStream *input,
const char *expected_checksum,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
@@ -913,14 +919,16 @@ stage_object_impl (OstreeRepo *self,
ot_lobj GFile *temp_file = NULL;
ot_lobj GFile *stored_path = NULL;
ot_lfree char *pack_checksum = NULL;
- GChecksum *ret_checksum = NULL;
+ ot_lfree guchar *ret_csum = NULL;
+ ot_lobj OstreeChecksumInputStream *checksum_input = NULL;
+ GChecksum *checksum = NULL;
g_return_val_if_fail (priv->in_transaction, FALSE);
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
- g_assert (expected_checksum || out_checksum);
+ g_assert (expected_checksum || out_csum);
if (expected_checksum)
{
@@ -961,26 +969,35 @@ stage_object_impl (OstreeRepo *self,
{
if (!impl_stage_archive_file_object_from_raw (self, file_info, xattrs, input,
expected_checksum,
- out_checksum ? &ret_checksum : NULL,
+ out_csum ? &ret_csum : NULL,
cancellable, error))
goto out;
}
- else
+ else
{
+ if (out_csum)
+ {
+ checksum = g_checksum_new (G_CHECKSUM_SHA256);
+ if (input)
+ checksum_input = ostree_checksum_input_stream_new (input, checksum);
+ }
+
if (!ostree_create_temp_file_from_input (priv->tmp_dir,
ostree_object_type_to_string (objtype), NULL,
- file_info, xattrs, input,
- objtype,
+ file_info, xattrs,
+ checksum_input ? (GInputStream*)checksum_input : input,
&temp_file,
- out_checksum ? &ret_checksum : NULL,
cancellable, error))
goto out;
+
+ if (checksum && !OSTREE_OBJECT_TYPE_IS_META (objtype))
+ ostree_checksum_update_meta (checksum, file_info, xattrs);
- if (!ret_checksum)
+ if (!checksum)
actual_checksum = expected_checksum;
else
{
- actual_checksum = g_checksum_get_string (ret_checksum);
+ actual_checksum = g_checksum_get_string (checksum);
if (expected_checksum && strcmp (actual_checksum, expected_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
@@ -995,6 +1012,9 @@ stage_object_impl (OstreeRepo *self,
temp_file, cancellable, error))
goto out;
g_clear_object (&temp_file);
+
+ if (checksum)
+ ret_csum = ot_csum_from_gchecksum (checksum);
}
}
else
@@ -1004,11 +1024,11 @@ stage_object_impl (OstreeRepo *self,
}
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
+ ot_transfer_out_value(out_csum, &ret_csum);
out:
if (temp_file)
(void) unlink (ot_gfile_get_path_cached (temp_file));
- ot_clear_checksum (&ret_checksum);
+ ot_clear_checksum (&checksum);
return ret;
}
@@ -1064,13 +1084,12 @@ static gboolean
stage_gvariant_object (OstreeRepo *self,
OstreeObjectType type,
GVariant *variant,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
ot_lobj GInputStream *mem = NULL;
- GChecksum *ret_checksum = NULL;
mem = g_memory_input_stream_new_from_data (g_variant_get_data (variant),
g_variant_get_size (variant),
@@ -1078,13 +1097,11 @@ stage_gvariant_object (OstreeRepo *self,
if (!stage_object_impl (self, type, FALSE,
NULL, NULL, mem,
- NULL, &ret_checksum, cancellable, error))
+ NULL, out_csum, cancellable, error))
goto out;
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
out:
- ot_clear_checksum (&ret_checksum);
return ret;
}
@@ -1092,13 +1109,12 @@ static gboolean
stage_directory_meta (OstreeRepo *self,
GFileInfo *file_info,
GVariant *xattrs,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
ot_lvariant GVariant *dirmeta = NULL;
- GChecksum *ret_checksum = NULL;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
@@ -1106,13 +1122,11 @@ stage_directory_meta (OstreeRepo *self,
dirmeta = ostree_create_directory_metadata (file_info, xattrs);
if (!stage_gvariant_object (self, OSTREE_OBJECT_TYPE_DIR_META,
- dirmeta, &ret_checksum, cancellable, error))
+ dirmeta, out_csum, cancellable, error))
goto out;
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
out:
- ot_clear_checksum (&ret_checksum);
return ret;
}
@@ -1159,16 +1173,16 @@ ostree_repo_stage_object (OstreeRepo *self,
GError **error)
{
gboolean ret = FALSE;
- GChecksum *actual_checksum = NULL;
+ ot_lfree guchar *actual_csum = NULL;
if (!stage_object_impl (self, objtype, FALSE,
file_info, xattrs, input,
- expected_checksum, &actual_checksum, cancellable, error))
+ expected_checksum, &actual_csum,
+ cancellable, error))
goto out;
ret = TRUE;
out:
- ot_clear_checksum (&actual_checksum);
return ret;
}
@@ -1352,7 +1366,7 @@ ostree_repo_stage_commit (OstreeRepo *self,
gboolean ret = FALSE;
ot_lfree char *ret_commit = NULL;
ot_lvariant GVariant *commit = NULL;
- GChecksum *ret_commit_obj = NULL;
+ ot_lfree guchar *commit_csum = NULL;
GDateTime *now = NULL;
g_return_val_if_fail (branch != NULL, FALSE);
@@ -1372,15 +1386,14 @@ ostree_repo_stage_commit (OstreeRepo *self,
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))
+ commit, &commit_csum, cancellable, error))
goto out;
- ret_commit = g_strdup (g_checksum_get_string (ret_commit_obj));
+ ret_commit = ostree_checksum_from_bytes (commit_csum);
ret = TRUE;
ot_transfer_out_value(out_commit, &ret_commit);
out:
- ot_clear_checksum (&ret_commit_obj);
if (now)
g_date_time_unref (now);
return ret;
@@ -2344,7 +2357,8 @@ stage_directory_to_mtree_internal (OstreeRepo *self,
ot_lobj GFile *child = NULL;
ot_lvariant GVariant *xattrs = NULL;
ot_lobj GInputStream *file_input = NULL;
- GChecksum *child_file_checksum = NULL;
+ ot_lfree guchar *child_file_csum = NULL;
+ ot_lfree char *tmp_checksum = NULL;
/* We can only reuse checksums directly if there's no modifier */
if (OSTREE_IS_REPO_FILE (dir) && modifier == NULL)
@@ -2380,11 +2394,13 @@ stage_directory_to_mtree_internal (OstreeRepo *self,
goto out;
}
- if (!stage_directory_meta (self, modified_info, xattrs, &child_file_checksum,
+ if (!stage_directory_meta (self, modified_info, xattrs, &child_file_csum,
cancellable, error))
goto out;
- ostree_mutable_tree_set_metadata_checksum (mtree, g_checksum_get_string (child_file_checksum));
+ g_free (tmp_checksum);
+ tmp_checksum = ostree_checksum_from_bytes (child_file_csum);
+ ostree_mutable_tree_set_metadata_checksum (mtree, tmp_checksum);
g_clear_object (&child_info);
g_clear_object (&modified_info);
@@ -2432,10 +2448,7 @@ stage_directory_to_mtree_internal (OstreeRepo *self,
}
else
{
- ot_clear_checksum (&child_file_checksum);
- ot_clear_gvariant (&xattrs);
g_clear_object (&file_input);
-
if (g_file_info_get_file_type (modified_info) == G_FILE_TYPE_REGULAR)
{
file_input = (GInputStream*)g_file_read (child, cancellable, error);
@@ -2445,17 +2458,21 @@ stage_directory_to_mtree_internal (OstreeRepo *self,
if (!(modifier && modifier->skip_xattrs))
{
+ ot_clear_gvariant (&xattrs);
if (!ostree_get_xattrs_for_file (child, &xattrs, cancellable, error))
goto out;
}
+ g_free (child_file_csum);
+ child_file_csum = NULL;
if (!stage_object_impl (self, OSTREE_OBJECT_TYPE_RAW_FILE, FALSE,
modified_info, xattrs, file_input, NULL,
- &child_file_checksum, cancellable, error))
+ &child_file_csum, cancellable, error))
goto out;
- if (!ostree_mutable_tree_replace_file (mtree, name,
- g_checksum_get_string (child_file_checksum),
+ g_free (tmp_checksum);
+ tmp_checksum = ostree_checksum_from_bytes (child_file_csum);
+ if (!ostree_mutable_tree_replace_file (mtree, name, tmp_checksum,
error))
goto out;
}
@@ -2477,7 +2494,6 @@ stage_directory_to_mtree_internal (OstreeRepo *self,
ret = TRUE;
out:
- ot_clear_checksum (&child_file_checksum);
return ret;
}
@@ -2518,7 +2534,7 @@ ostree_repo_stage_mtree (OstreeRepo *self,
ot_lhash GHashTable *dir_metadata_checksums = NULL;
ot_lhash GHashTable *dir_contents_checksums = NULL;
ot_lvariant GVariant *serialized_tree = NULL;
- GChecksum *ret_contents_checksum_obj = NULL;
+ ot_lfree guchar *contents_csum = NULL;
existing_checksum = ostree_mutable_tree_get_contents_checksum (mtree);
if (existing_checksum)
@@ -2558,16 +2574,15 @@ ostree_repo_stage_mtree (OstreeRepo *self,
dir_metadata_checksums);
if (!stage_gvariant_object (self, OSTREE_OBJECT_TYPE_DIR_TREE,
- serialized_tree, &ret_contents_checksum_obj,
+ serialized_tree, &contents_csum,
cancellable, error))
goto out;
- ret_contents_checksum = g_strdup (g_checksum_get_string (ret_contents_checksum_obj));
+ ret_contents_checksum = ostree_checksum_from_bytes (contents_csum);
}
ret = TRUE;
ot_transfer_out_value(out_contents_checksum, &ret_contents_checksum);
out:
- ot_clear_checksum (&ret_contents_checksum_obj);
return ret;
}
@@ -2624,13 +2639,12 @@ import_libarchive_entry_file (OstreeRepo *self,
struct archive *a,
struct archive_entry *entry,
GFileInfo *file_info,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
ot_lobj GInputStream *archive_stream = NULL;
- GChecksum *ret_checksum = NULL;
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
@@ -2640,14 +2654,12 @@ import_libarchive_entry_file (OstreeRepo *self,
if (!stage_object_impl (self, OSTREE_OBJECT_TYPE_RAW_FILE, FALSE,
file_info, NULL, archive_stream,
- NULL, &ret_checksum,
+ NULL, out_csum,
cancellable, error))
goto out;
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
out:
- ot_clear_checksum (&ret_checksum);
return ret;
}
@@ -2657,7 +2669,7 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
struct archive *a,
struct archive_entry *entry,
OstreeRepoCommitModifier *modifier,
- const char *tmp_dir_checksum,
+ const guchar *tmp_dir_csum,
GCancellable *cancellable,
GError **error)
{
@@ -2673,7 +2685,8 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
ot_lobj OstreeMutableTree *hardlink_source_parent = NULL;
ot_lfree char *hardlink_source_checksum = NULL;
ot_lobj OstreeMutableTree *hardlink_source_subdir = NULL;
- GChecksum *tmp_checksum = NULL;
+ ot_lfree guchar *tmp_csum = NULL;
+ ot_lfree char *tmp_checksum = NULL;
pathname = archive_entry_pathname (entry);
@@ -2687,10 +2700,12 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
}
else
{
- if (tmp_dir_checksum)
+ if (tmp_dir_csum)
{
+ g_free (tmp_checksum);
+ tmp_checksum = ostree_checksum_from_bytes (tmp_dir_csum);
if (!ostree_mutable_tree_ensure_parent_dirs (root, split_path,
- tmp_dir_checksum,
+ tmp_checksum,
&parent,
error))
goto out;
@@ -2762,7 +2777,7 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
{
- if (!stage_directory_meta (self, file_info, NULL, &tmp_checksum, cancellable, error))
+ if (!stage_directory_meta (self, file_info, NULL, &tmp_csum, cancellable, error))
goto out;
if (parent == NULL)
@@ -2775,7 +2790,9 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
goto out;
}
- ostree_mutable_tree_set_metadata_checksum (subdir, g_checksum_get_string (tmp_checksum));
+ g_free (tmp_checksum);
+ tmp_checksum = ostree_checksum_from_bytes (tmp_csum);
+ ostree_mutable_tree_set_metadata_checksum (subdir, tmp_checksum);
}
else
{
@@ -2786,11 +2803,13 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
goto out;
}
- if (!import_libarchive_entry_file (self, a, entry, file_info, &tmp_checksum, cancellable, error))
+ if (!import_libarchive_entry_file (self, a, entry, file_info, &tmp_csum, cancellable, error))
goto out;
+ g_free (tmp_checksum);
+ tmp_checksum = ostree_checksum_from_bytes (tmp_csum);
if (!ostree_mutable_tree_replace_file (parent, basename,
- g_checksum_get_string (tmp_checksum),
+ tmp_checksum,
error))
goto out;
}
@@ -2798,7 +2817,6 @@ stage_libarchive_entry_to_mtree (OstreeRepo *self,
ret = TRUE;
out:
- ot_clear_checksum (&tmp_checksum);
return ret;
}
#endif
@@ -2818,7 +2836,7 @@ ostree_repo_stage_archive_to_mtree (OstreeRepo *self,
struct archive_entry *entry;
int r;
ot_lobj GFileInfo *tmp_dir_info = NULL;
- GChecksum *tmp_dir_checksum = NULL;
+ ot_lfree guchar *tmp_csum = NULL;
a = archive_read_new ();
archive_read_support_compression_all (a);
@@ -2840,7 +2858,7 @@ ostree_repo_stage_archive_to_mtree (OstreeRepo *self,
goto out;
}
- if (autocreate_parents && !tmp_dir_checksum)
+ if (autocreate_parents && !tmp_csum)
{
tmp_dir_info = g_file_info_new ();
@@ -2848,13 +2866,13 @@ ostree_repo_stage_archive_to_mtree (OstreeRepo *self,
g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::gid", archive_entry_gid (entry));
g_file_info_set_attribute_uint32 (tmp_dir_info, "unix::mode", 0755 | S_IFDIR);
- if (!stage_directory_meta (self, tmp_dir_info, NULL, &tmp_dir_checksum, cancellable, error))
+ if (!stage_directory_meta (self, tmp_dir_info, NULL, &tmp_csum, cancellable, error))
goto out;
}
if (!stage_libarchive_entry_to_mtree (self, root, a,
entry, modifier,
- autocreate_parents ? g_checksum_get_string (tmp_dir_checksum) : NULL,
+ autocreate_parents ? tmp_csum : NULL,
cancellable, error))
goto out;
}
@@ -2866,7 +2884,6 @@ ostree_repo_stage_archive_to_mtree (OstreeRepo *self,
ret = TRUE;
out:
- ot_clear_checksum (&tmp_dir_checksum);
if (a)
(void)archive_read_close (a);
return ret;
@@ -3626,8 +3643,8 @@ checkout_file_from_input (GFile *file,
if (g_file_info_get_file_type (temp_info ? temp_info : finfo) == G_FILE_TYPE_DIRECTORY)
{
if (!ostree_create_file_from_input (file, temp_info ? temp_info : finfo,
- xattrs, input, OSTREE_OBJECT_TYPE_RAW_FILE,
- NULL, cancellable, &temp_error))
+ xattrs, input,
+ cancellable, &temp_error))
{
if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
{
@@ -3645,8 +3662,7 @@ checkout_file_from_input (GFile *file,
dir = g_file_get_parent (file);
if (!ostree_create_temp_file_from_input (dir, NULL, "checkout",
temp_info ? temp_info : finfo,
- xattrs, input, OSTREE_OBJECT_TYPE_RAW_FILE,
- &temp_file, NULL,
+ xattrs, input, &temp_file,
cancellable, error))
goto out;
@@ -3660,8 +3676,7 @@ checkout_file_from_input (GFile *file,
else
{
if (!ostree_create_file_from_input (file, temp_info ? temp_info : finfo,
- xattrs, input, OSTREE_OBJECT_TYPE_RAW_FILE,
- NULL, cancellable, error))
+ xattrs, input, cancellable, error))
goto out;
}
diff --git a/src/libostree/ostree.h b/src/libostree/ostree.h
index 571aea9..a4b7845 100644
--- a/src/libostree/ostree.h
+++ b/src/libostree/ostree.h
@@ -22,6 +22,7 @@
#ifndef __OSTREE_H__
+#include <ostree-checksum-input-stream.h>
#include <ostree-core.h>
#include <ostree-repo.h>
#include <ostree-mutable-tree.h>
diff --git a/src/libotutil/ot-checksum-utils.c b/src/libotutil/ot-checksum-utils.c
new file mode 100644
index 0000000..7405abf
--- /dev/null
+++ b/src/libotutil/ot-checksum-utils.c
@@ -0,0 +1,38 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters verbum org>
+ */
+
+#include "config.h"
+
+#include "otutil.h"
+
+#include <string.h>
+
+guchar *
+ot_csum_from_gchecksum (GChecksum *checksum)
+{
+ guchar *ret = g_malloc (32);
+ gsize len = 32;
+
+ g_checksum_get_digest (checksum, ret, &len);
+ g_assert (len == 32);
+ return ret;
+}
diff --git a/src/libotutil/ot-checksum-utils.h b/src/libotutil/ot-checksum-utils.h
new file mode 100644
index 0000000..e9de638
--- /dev/null
+++ b/src/libotutil/ot-checksum-utils.h
@@ -0,0 +1,34 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters verbum org>.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters verbum org>
+ */
+
+#ifndef __OSTREE_CHECKSUM_UTILS_H__
+#define __OSTREE_CHECKSUM_UTILS_H__
+
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+guchar *ot_csum_from_gchecksum (GChecksum *checksum);
+
+G_END_DECLS
+
+#endif
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index c93a7bb..3cd72ef 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -229,21 +229,17 @@ ot_gfile_get_basename_cached (GFile *file)
}
gboolean
-ot_gio_splice_and_checksum (GOutputStream *out,
- GInputStream *in,
- GChecksum **out_checksum,
- GCancellable *cancellable,
- GError **error)
+ot_gio_splice_update_checksum (GOutputStream *out,
+ GInputStream *in,
+ GChecksum *checksum,
+ GCancellable *cancellable,
+ GError **error)
{
gboolean ret = FALSE;
- GChecksum *ret_checksum = NULL;
- g_return_val_if_fail (out != NULL || out_checksum != NULL, FALSE);
+ g_return_val_if_fail (out != NULL || checksum != NULL, FALSE);
- if (out_checksum)
- ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
-
- if (ret_checksum != NULL)
+ if (checksum != NULL)
{
gsize bytes_read, bytes_written;
char buf[4096];
@@ -251,8 +247,7 @@ ot_gio_splice_and_checksum (GOutputStream *out,
{
if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error))
goto out;
- if (ret_checksum)
- g_checksum_update (ret_checksum, (guint8*)buf, bytes_read);
+ g_checksum_update (checksum, (guint8*)buf, bytes_read);
if (out)
{
if (!g_output_stream_write_all (out, buf, bytes_read, &bytes_written, cancellable, error))
@@ -268,21 +263,44 @@ ot_gio_splice_and_checksum (GOutputStream *out,
}
ret = TRUE;
- ot_transfer_out_value(out_checksum, &ret_checksum);
out:
- ot_clear_checksum (&ret_checksum);
+ return ret;
+}
+
+gboolean
+ot_gio_splice_get_checksum (GOutputStream *out,
+ GInputStream *in,
+ guchar **out_csum,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GChecksum *checksum = NULL;
+ ot_lfree guchar *ret_csum = NULL;
+
+ checksum = g_checksum_new (G_CHECKSUM_SHA256);
+
+ if (!ot_gio_splice_update_checksum (out, in, checksum, cancellable, error))
+ goto out;
+
+ ret_csum = ot_csum_from_gchecksum (checksum);
+
+ ret = TRUE;
+ ot_transfer_out_value (out_csum, &ret_csum);
+ out:
+ ot_clear_checksum (&checksum);
return ret;
}
gboolean
ot_gio_checksum_stream (GInputStream *in,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
- if (!out_checksum)
+ if (!out_csum)
return TRUE;
- return ot_gio_splice_and_checksum (NULL, in, out_checksum, cancellable, error);
+ return ot_gio_splice_get_checksum (NULL, in, out_csum, cancellable, error);
}
gboolean
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 5fda5da..59db714 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -61,14 +61,20 @@ gboolean ot_gfile_load_contents_utf8 (GFile *file,
GCancellable *cancellable,
GError **error);
-gboolean ot_gio_splice_and_checksum (GOutputStream *out,
+gboolean ot_gio_splice_get_checksum (GOutputStream *out,
GInputStream *in,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error);
+gboolean ot_gio_splice_update_checksum (GOutputStream *out,
+ GInputStream *in,
+ GChecksum *checksum,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ot_gio_checksum_stream (GInputStream *in,
- GChecksum **out_checksum,
+ guchar **out_csum,
GCancellable *cancellable,
GError **error);
diff --git a/src/libotutil/ot-variant-utils.c b/src/libotutil/ot-variant-utils.c
index 3462513..58f3e49 100644
--- a/src/libotutil/ot-variant-utils.c
+++ b/src/libotutil/ot-variant-utils.c
@@ -159,9 +159,9 @@ ot_util_variant_from_stream (GInputStream *src,
data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
- if (!g_output_stream_splice ((GOutputStream*)data_stream, src,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
- cancellable, error))
+ if (g_output_stream_splice ((GOutputStream*)data_stream, src,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+ cancellable, error) < 0)
goto out;
ret_variant = g_variant_new_from_data (type, g_memory_output_stream_get_data (data_stream),
diff --git a/src/libotutil/otutil.h b/src/libotutil/otutil.h
index d6c9fbc..ad276d4 100644
--- a/src/libotutil/otutil.h
+++ b/src/libotutil/otutil.h
@@ -47,5 +47,6 @@
#include <ot-opt-utils.h>
#include <ot-unix-utils.h>
#include <ot-variant-utils.h>
+#include <ot-checksum-utils.h>
#endif
diff --git a/src/ostree/ot-builtin-checksum.c b/src/ostree/ot-builtin-checksum.c
index ad33394..e42454d 100644
--- a/src/ostree/ot-builtin-checksum.c
+++ b/src/ostree/ot-builtin-checksum.c
@@ -41,14 +41,14 @@ on_checksum_received (GObject *obj,
GAsyncResult *result,
gpointer user_data)
{
- GChecksum *checksum = NULL;
+ ot_lfree guchar *csum = NULL;
+ ot_lfree char *checksum = NULL;
AsyncChecksumData *data = user_data;
- if (ostree_checksum_file_async_finish ((GFile*)obj, result, &checksum, data->error))
+ if (ostree_checksum_file_async_finish ((GFile*)obj, result, &csum, data->error))
{
- g_print ("%s\n", g_checksum_get_string (checksum));
-
- ot_clear_checksum (&checksum);
+ checksum = ostree_checksum_from_bytes (csum);
+ g_print ("%s\n", checksum);
}
g_main_loop_quit (data->loop);
diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c
index 6d9b50e..38a22a3 100644
--- a/src/ostree/ot-builtin-diff.c
+++ b/src/ostree/ot-builtin-diff.c
@@ -69,7 +69,7 @@ get_file_checksum (GFile *f,
{
gboolean ret = FALSE;
ot_lfree char *ret_checksum = NULL;
- GChecksum *tmp_checksum = NULL;
+ ot_lfree guchar *csum = NULL;
if (OSTREE_IS_REPO_FILE (f))
{
@@ -78,15 +78,14 @@ get_file_checksum (GFile *f,
else
{
if (!ostree_checksum_file (f, OSTREE_OBJECT_TYPE_RAW_FILE,
- &tmp_checksum, cancellable, error))
+ &csum, cancellable, error))
goto out;
- ret_checksum = g_strdup (g_checksum_get_string (tmp_checksum));
+ ret_checksum = ostree_checksum_from_bytes (csum);
}
ret = TRUE;
ot_transfer_out_value(out_checksum, &ret_checksum);
out:
- ot_clear_checksum (&tmp_checksum);
return ret;
}
diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c
index 45ec228..6046512 100644
--- a/src/ostree/ot-builtin-fsck.c
+++ b/src/ostree/ot-builtin-fsck.c
@@ -59,7 +59,8 @@ fsck_one_pack_file (OtFsckData *data,
ot_lvariant GVariant *index_variant = NULL;
ot_lobj GFile *pack_index_path = NULL;
ot_lobj GFile *pack_data_path = NULL;
- GChecksum *pack_content_checksum = NULL;
+ ot_lfree guchar *pack_content_csum = NULL;
+ ot_lfree char *tmp_checksum = NULL;
GVariantIter *index_content_iter = NULL;
g_free (path);
@@ -88,14 +89,15 @@ fsck_one_pack_file (OtFsckData *data,
goto out;
pack_size = g_file_info_get_attribute_uint64 (pack_info, "standard::size");
- if (!ot_gio_checksum_stream (input, &pack_content_checksum, cancellable, error))
+ if (!ot_gio_checksum_stream (input, &pack_content_csum, cancellable, error))
goto out;
- if (strcmp (g_checksum_get_string (pack_content_checksum), pack_checksum) != 0)
+ tmp_checksum = ostree_checksum_from_bytes (pack_content_csum);
+ if (strcmp (tmp_checksum, pack_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "corrupted pack '%s', expected checksum %s",
- pack_checksum, g_checksum_get_string (pack_content_checksum));
+ "corrupted pack '%s', actual checksum is %s",
+ pack_checksum, tmp_checksum);
goto out;
}
@@ -119,7 +121,6 @@ fsck_one_pack_file (OtFsckData *data,
out:
if (index_content_iter)
g_variant_iter_free (index_content_iter);
- ot_clear_checksum (&pack_content_checksum);
return ret;
}
@@ -175,7 +176,8 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
ot_lobj GFileInfo *file_info = NULL;
ot_lvariant GVariant *xattrs = NULL;
ot_lvariant GVariant *metadata = NULL;
- GChecksum *computed_checksum = NULL;
+ ot_lfree guchar *computed_csum = NULL;
+ ot_lfree char *tmp_checksum = NULL;
reachable_objects = ostree_traverse_new_reachable ();
@@ -277,25 +279,26 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
g_assert_not_reached ();
}
- ot_clear_checksum (&computed_checksum);
+ g_free (computed_csum);
if (!ostree_checksum_file_from_input (file_info, xattrs, input,
- checksum_objtype, &computed_checksum,
+ checksum_objtype, &computed_csum,
cancellable, error))
goto out;
- if (strcmp (checksum, g_checksum_get_string (computed_checksum)) != 0)
+ g_free (tmp_checksum);
+ tmp_checksum = ostree_checksum_from_bytes (computed_csum);
+ if (strcmp (checksum, tmp_checksum) != 0)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"corrupted object %s.%s; actual checksum: %s",
checksum, ostree_object_type_to_string (objtype),
- g_checksum_get_string (computed_checksum));
+ tmp_checksum);
goto out;
}
}
ret = TRUE;
out:
- ot_clear_checksum (&computed_checksum);
return ret;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]