mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
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.
This commit is contained in:
parent
fa4cbc8b89
commit
f15c184584
@ -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 \
|
||||
|
@ -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 \
|
||||
|
169
src/libostree/ostree-checksum-input-stream.c
Normal file
169
src/libostree/ostree-checksum-input-stream.c
Normal file
@ -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;
|
||||
}
|
68
src/libostree/ostree-checksum-input-stream.h
Normal file
68
src/libostree/ostree-checksum-input-stream.h
Normal file
@ -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__ */
|
@ -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;
|
||||
ot_lfree guchar *ret_csum = NULL;
|
||||
GChecksum *checksum = NULL;
|
||||
|
||||
checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
|
||||
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);
|
||||
|
||||
mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
|
||||
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)
|
||||
{
|
||||
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 (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);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
38
src/libotutil/ot-checksum-utils.c
Normal file
38
src/libotutil/ot-checksum-utils.c
Normal file
@ -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;
|
||||
}
|
34
src/libotutil/ot-checksum-utils.h
Normal file
34
src/libotutil/ot-checksum-utils.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user