core: Re-unify on one OSTREE_OBJECT_TYPE_FILE
Having the archived vs not distinction in the object system wasn't useful in light of pack files. In fact, we should probably move towards generating a pack file per commit by default.
This commit is contained in:
parent
f15c184584
commit
38ef75e6e0
|
|
@ -24,6 +24,8 @@ libostree_la_SOURCES = src/libostree/ostree.h \
|
|||
src/libostree/ostree-core.h \
|
||||
src/libostree/ostree-checksum-input-stream.c \
|
||||
src/libostree/ostree-checksum-input-stream.h \
|
||||
src/libostree/ostree-chain-input-stream.c \
|
||||
src/libostree/ostree-chain-input-stream.h \
|
||||
src/libostree/ostree-mutable-tree.c \
|
||||
src/libostree/ostree-mutable-tree.h \
|
||||
src/libostree/ostree-repo.c \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,210 @@
|
|||
/* -*- 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-chain-input-stream.h"
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_STREAMS
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (OstreeChainInputStream, ostree_chain_input_stream, G_TYPE_INPUT_STREAM)
|
||||
|
||||
struct _OstreeChainInputStreamPrivate {
|
||||
GPtrArray *streams;
|
||||
guint index;
|
||||
};
|
||||
|
||||
static void ostree_chain_input_stream_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void ostree_chain_input_stream_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void ostree_chain_input_stream_finalize (GObject *object);
|
||||
static gssize ostree_chain_input_stream_read (GInputStream *stream,
|
||||
void *buffer,
|
||||
gsize count,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
static gboolean ostree_chain_input_stream_close (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
static void
|
||||
ostree_chain_input_stream_class_init (OstreeChainInputStreamClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (OstreeChainInputStreamPrivate));
|
||||
|
||||
gobject_class->get_property = ostree_chain_input_stream_get_property;
|
||||
gobject_class->set_property = ostree_chain_input_stream_set_property;
|
||||
gobject_class->finalize = ostree_chain_input_stream_finalize;
|
||||
|
||||
stream_class->read_fn = ostree_chain_input_stream_read;
|
||||
stream_class->close_fn = ostree_chain_input_stream_close;
|
||||
|
||||
/**
|
||||
* OstreeChainInputStream:streams: (element-type GInputStream)
|
||||
*
|
||||
* Chain of input streams read in order.
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_STREAMS,
|
||||
g_param_spec_pointer ("streams",
|
||||
"", "",
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_chain_input_stream_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
OstreeChainInputStream *self;
|
||||
|
||||
self = OSTREE_CHAIN_INPUT_STREAM (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STREAMS:
|
||||
self->priv->streams = g_ptr_array_ref (g_value_get_pointer (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_chain_input_stream_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
OstreeChainInputStream *self;
|
||||
|
||||
self = OSTREE_CHAIN_INPUT_STREAM (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STREAMS:
|
||||
g_value_set_pointer (value, self->priv->streams);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_chain_input_stream_finalize (GObject *object)
|
||||
{
|
||||
OstreeChainInputStream *stream;
|
||||
|
||||
stream = (OstreeChainInputStream*)(object);
|
||||
|
||||
g_ptr_array_unref (stream->priv->streams);
|
||||
|
||||
G_OBJECT_CLASS (ostree_chain_input_stream_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
ostree_chain_input_stream_init (OstreeChainInputStream *self)
|
||||
{
|
||||
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
||||
OSTREE_TYPE_CHAIN_INPUT_STREAM,
|
||||
OstreeChainInputStreamPrivate);
|
||||
|
||||
}
|
||||
|
||||
OstreeChainInputStream *
|
||||
ostree_chain_input_stream_new (GPtrArray *streams)
|
||||
{
|
||||
OstreeChainInputStream *stream;
|
||||
|
||||
stream = g_object_new (OSTREE_TYPE_CHAIN_INPUT_STREAM,
|
||||
"streams", streams,
|
||||
NULL);
|
||||
|
||||
return (OstreeChainInputStream*) (stream);
|
||||
}
|
||||
|
||||
static gssize
|
||||
ostree_chain_input_stream_read (GInputStream *stream,
|
||||
void *buffer,
|
||||
gsize count,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
OstreeChainInputStream *self = (OstreeChainInputStream*) stream;
|
||||
GInputStream *child;
|
||||
gssize res = -1;
|
||||
|
||||
if (g_cancellable_set_error_if_cancelled (cancellable, error))
|
||||
return -1;
|
||||
|
||||
if (self->priv->index >= self->priv->streams->len)
|
||||
return 0;
|
||||
|
||||
child = self->priv->streams->pdata[self->priv->index];
|
||||
|
||||
res = g_input_stream_read (child,
|
||||
buffer,
|
||||
count,
|
||||
cancellable,
|
||||
error);
|
||||
if (res == 0)
|
||||
self->priv->index++;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ostree_chain_input_stream_close (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
OstreeChainInputStream *self = (gpointer)stream;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->priv->streams->len; i++)
|
||||
{
|
||||
GInputStream *child = self->priv->streams->pdata[i];
|
||||
if (!g_input_stream_close (child, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- 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_CHAIN_INPUT_STREAM_H__
|
||||
#define __OSTREE_CHAIN_INPUT_STREAM_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define OSTREE_TYPE_CHAIN_INPUT_STREAM (ostree_chain_input_stream_get_type ())
|
||||
#define OSTREE_CHAIN_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStream))
|
||||
#define OSTREE_CHAIN_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStreamClass))
|
||||
#define OSTREE_IS_CHAIN_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM))
|
||||
#define OSTREE_IS_CHAIN_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_CHAIN_INPUT_STREAM))
|
||||
#define OSTREE_CHAIN_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_CHAIN_INPUT_STREAM, OstreeChainInputStreamClass))
|
||||
|
||||
typedef struct _OstreeChainInputStream OstreeChainInputStream;
|
||||
typedef struct _OstreeChainInputStreamClass OstreeChainInputStreamClass;
|
||||
typedef struct _OstreeChainInputStreamPrivate OstreeChainInputStreamPrivate;
|
||||
|
||||
struct _OstreeChainInputStream
|
||||
{
|
||||
GInputStream parent_instance;
|
||||
|
||||
/*< private >*/
|
||||
OstreeChainInputStreamPrivate *priv;
|
||||
};
|
||||
|
||||
struct _OstreeChainInputStreamClass
|
||||
{
|
||||
GInputStreamClass 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_chain_input_stream_get_type (void) G_GNUC_CONST;
|
||||
|
||||
OstreeChainInputStream * ostree_chain_input_stream_new (GPtrArray *streams);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __OSTREE_CHAIN_INPUT_STREAM_H__ */
|
||||
|
|
@ -36,8 +36,6 @@ ostree_metadata_variant_type (OstreeObjectType objtype)
|
|||
{
|
||||
switch (objtype)
|
||||
{
|
||||
case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META:
|
||||
return OSTREE_ARCHIVED_FILE_VARIANT_FORMAT;
|
||||
case OSTREE_OBJECT_TYPE_DIR_TREE:
|
||||
return OSTREE_TREE_GVARIANT_FORMAT;
|
||||
case OSTREE_OBJECT_TYPE_DIR_META:
|
||||
|
|
@ -78,66 +76,6 @@ ostree_validate_rev (const char *rev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
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 *
|
||||
canonicalize_xattrs (char *xattr_string, size_t len)
|
||||
{
|
||||
|
|
@ -264,6 +202,265 @@ ostree_get_xattrs_for_file (GFile *f,
|
|||
return ret;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
ostree_file_header_new (GFileInfo *file_info,
|
||||
GVariant *xattrs)
|
||||
{
|
||||
guint32 uid;
|
||||
guint32 gid;
|
||||
guint32 mode;
|
||||
guint32 rdev;
|
||||
const char *symlink_target;
|
||||
GVariant *ret;
|
||||
ot_lvariant GVariant *tmp_xattrs = NULL;
|
||||
|
||||
uid = g_file_info_get_attribute_uint32 (file_info, "unix::uid");
|
||||
gid = g_file_info_get_attribute_uint32 (file_info, "unix::gid");
|
||||
mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
rdev = g_file_info_get_attribute_uint32 (file_info, "unix::rdev");
|
||||
|
||||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_SYMBOLIC_LINK)
|
||||
symlink_target = g_file_info_get_symlink_target (file_info);
|
||||
else
|
||||
symlink_target = "";
|
||||
|
||||
if (xattrs == NULL)
|
||||
tmp_xattrs = g_variant_ref_sink (g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0));
|
||||
|
||||
ret = g_variant_new ("(uuuus@a(ayay))", GUINT32_TO_BE (uid),
|
||||
GUINT32_TO_BE (gid), GUINT32_TO_BE (mode), GUINT32_TO_BE (rdev),
|
||||
symlink_target, xattrs ? xattrs : tmp_xattrs);
|
||||
g_variant_ref_sink (ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_padding (GOutputStream *output,
|
||||
guint alignment,
|
||||
gsize offset,
|
||||
gsize *out_bytes_written,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint bits;
|
||||
guint padding_len;
|
||||
guchar padding_nuls[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
if (alignment == 8)
|
||||
bits = ((offset) & 7);
|
||||
else
|
||||
bits = ((offset) & 3);
|
||||
|
||||
if (bits > 0)
|
||||
{
|
||||
padding_len = alignment - bits;
|
||||
if (!ot_gio_write_update_checksum (output, (guchar*)padding_nuls, padding_len,
|
||||
out_bytes_written, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_write_variant_with_size (GOutputStream *output,
|
||||
GVariant *variant,
|
||||
guint64 alignment_offset,
|
||||
gsize *out_bytes_written,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 variant_size;
|
||||
guint32 variant_size_u32_be;
|
||||
gsize bytes_written;
|
||||
gsize ret_bytes_written = 0;
|
||||
|
||||
/* Write variant size */
|
||||
variant_size = g_variant_get_size (variant);
|
||||
g_assert (variant_size < G_MAXUINT32);
|
||||
variant_size_u32_be = GUINT32_TO_BE((guint32) variant_size);
|
||||
|
||||
bytes_written = 0;
|
||||
if (!ot_gio_write_update_checksum (output, &variant_size_u32_be, 4,
|
||||
&bytes_written, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
ret_bytes_written += bytes_written;
|
||||
alignment_offset += bytes_written;
|
||||
|
||||
bytes_written = 0;
|
||||
/* Pad to offset of 8, write variant */
|
||||
if (!write_padding (output, 8, alignment_offset, &bytes_written, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
ret_bytes_written += bytes_written;
|
||||
|
||||
bytes_written = 0;
|
||||
if (!ot_gio_write_update_checksum (output, g_variant_get_data (variant),
|
||||
variant_size, &bytes_written, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
ret_bytes_written += bytes_written;
|
||||
|
||||
ret = TRUE;
|
||||
if (out_bytes_written)
|
||||
*out_bytes_written = ret_bytes_written;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_write_file_header_update_checksum (GOutputStream *out,
|
||||
GVariant *header,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gsize bytes_written;
|
||||
|
||||
if (!ostree_write_variant_with_size (out, header, 0, &bytes_written, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_raw_file_to_content_stream (GInputStream *input,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GInputStream **out_input,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gpointer header_data;
|
||||
gsize header_size;
|
||||
ot_lobj GInputStream *ret_input = NULL;
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
ot_lptrarray GPtrArray *streams = NULL;
|
||||
ot_lobj GOutputStream *header_out_stream = NULL;
|
||||
ot_lobj GInputStream *header_in_stream = NULL;
|
||||
|
||||
file_header = ostree_file_header_new (file_info, xattrs);
|
||||
|
||||
header_out_stream = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
|
||||
|
||||
if (!ostree_write_variant_with_size (header_out_stream, file_header, 0, NULL, NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
header_size = g_memory_output_stream_get_data_size ((GMemoryOutputStream*) header_out_stream);
|
||||
header_data = g_memory_output_stream_steal_data ((GMemoryOutputStream*) header_out_stream);
|
||||
header_in_stream = g_memory_input_stream_new_from_data (header_data, header_size, g_free);
|
||||
|
||||
streams = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
|
||||
|
||||
g_ptr_array_add (streams, g_object_ref (header_in_stream));
|
||||
g_ptr_array_add (streams, g_object_ref (input));
|
||||
|
||||
ret_input = (GInputStream*)ostree_chain_input_stream_new (streams);
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_input, &ret_input);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_content_file_parse (GFile *content_path,
|
||||
gboolean trusted,
|
||||
GInputStream **out_input,
|
||||
GFileInfo **out_file_info,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 length;
|
||||
guint32 archive_header_size;
|
||||
guchar dummy[4];
|
||||
gsize bytes_read;
|
||||
ot_lobj GInputStream *ret_input = NULL;
|
||||
ot_lobj GFileInfo *content_file_info = NULL;
|
||||
ot_lobj GFileInfo *ret_file_info = NULL;
|
||||
ot_lvariant GVariant *ret_xattrs = NULL;
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
ot_lfree guchar *buf = NULL;
|
||||
|
||||
ret_input = (GInputStream*)g_file_read (content_path, cancellable, error);
|
||||
if (!ret_input)
|
||||
goto out;
|
||||
|
||||
content_file_info = g_file_input_stream_query_info ((GFileInputStream*)ret_input,
|
||||
OSTREE_GIO_FAST_QUERYINFO,
|
||||
cancellable, error);
|
||||
if (!content_file_info)
|
||||
goto out;
|
||||
|
||||
length = g_file_info_get_size (content_file_info);
|
||||
|
||||
if (!g_input_stream_read_all (ret_input,
|
||||
&archive_header_size, 4, &bytes_read,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
archive_header_size = GUINT32_FROM_BE (archive_header_size);
|
||||
if (archive_header_size > length)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
"File header size %u exceeds size %" G_GUINT64_FORMAT,
|
||||
(guint)archive_header_size, length);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Skip over padding */
|
||||
if (!g_input_stream_read_all (ret_input,
|
||||
dummy, 4, &bytes_read,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
buf = g_malloc (archive_header_size);
|
||||
if (!g_input_stream_read_all (ret_input, buf, archive_header_size, &bytes_read,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
file_header = g_variant_new_from_data (OSTREE_FILE_HEADER_GVARIANT_FORMAT,
|
||||
buf, archive_header_size, trusted,
|
||||
g_free, buf);
|
||||
buf = NULL;
|
||||
|
||||
if (!ostree_file_header_parse (file_header,
|
||||
out_file_info ? &ret_file_info : NULL,
|
||||
out_xattrs ? &ret_xattrs : NULL,
|
||||
error))
|
||||
goto out;
|
||||
if (ret_file_info)
|
||||
g_file_info_set_size (ret_file_info, length - archive_header_size - 8);
|
||||
|
||||
if (g_file_info_get_file_type (ret_file_info) != G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
g_clear_object (&ret_input);
|
||||
}
|
||||
|
||||
/* Now give the input stream at its current position as return value */
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_input, &ret_input);
|
||||
ot_transfer_out_value (out_file_info, &ret_file_info);
|
||||
ot_transfer_out_value (out_xattrs, &ret_xattrs);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_checksum_file_from_input (GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
|
|
@ -274,8 +471,6 @@ ostree_checksum_file_from_input (GFileInfo *file_info,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint32 mode;
|
||||
ot_lvariant GVariant *dirmeta = NULL;
|
||||
ot_lfree guchar *ret_csum = NULL;
|
||||
GChecksum *checksum = NULL;
|
||||
|
||||
|
|
@ -286,38 +481,28 @@ ostree_checksum_file_from_input (GFileInfo *file_info,
|
|||
if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
|
||||
{
|
||||
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);
|
||||
ot_lvariant GVariant *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)
|
||||
else
|
||||
{
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
|
||||
file_header = ostree_file_header_new (file_info, xattrs);
|
||||
|
||||
if (!ostree_write_file_header_update_checksum (NULL, file_header, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
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);
|
||||
|
|
@ -358,7 +543,7 @@ ostree_checksum_file (GFile *f,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE)
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
if (!ostree_get_xattrs_for_file (f, &xattrs, cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -509,12 +694,8 @@ ostree_object_type_to_string (OstreeObjectType objtype)
|
|||
{
|
||||
switch (objtype)
|
||||
{
|
||||
case OSTREE_OBJECT_TYPE_RAW_FILE:
|
||||
case OSTREE_OBJECT_TYPE_FILE:
|
||||
return "file";
|
||||
case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT:
|
||||
return "archive-content";
|
||||
case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META:
|
||||
return "archive-meta";
|
||||
case OSTREE_OBJECT_TYPE_DIR_TREE:
|
||||
return "dirtree";
|
||||
case OSTREE_OBJECT_TYPE_DIR_META:
|
||||
|
|
@ -531,11 +712,7 @@ OstreeObjectType
|
|||
ostree_object_type_from_string (const char *str)
|
||||
{
|
||||
if (!strcmp (str, "file"))
|
||||
return OSTREE_OBJECT_TYPE_RAW_FILE;
|
||||
else if (!strcmp (str, "archive-content"))
|
||||
return OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT;
|
||||
else if (!strcmp (str, "archive-meta"))
|
||||
return OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META;
|
||||
return OSTREE_OBJECT_TYPE_FILE;
|
||||
else if (!strcmp (str, "dirtree"))
|
||||
return OSTREE_OBJECT_TYPE_DIR_TREE;
|
||||
else if (!strcmp (str, "dirmeta"))
|
||||
|
|
@ -747,39 +924,8 @@ ostree_get_relative_pack_data_path (gboolean is_meta,
|
|||
return get_pack_name (is_meta, FALSE, "objects/pack/", checksum);
|
||||
}
|
||||
|
||||
GVariant *
|
||||
ostree_create_archive_file_metadata (GFileInfo *finfo,
|
||||
GVariant *xattrs)
|
||||
{
|
||||
guint32 uid, gid, mode, rdev;
|
||||
GVariantBuilder pack_builder;
|
||||
GVariant *ret = NULL;
|
||||
|
||||
uid = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_UID);
|
||||
gid = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_GID);
|
||||
mode = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_MODE);
|
||||
rdev = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_RDEV);
|
||||
|
||||
g_variant_builder_init (&pack_builder, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT);
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (uid));
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (gid));
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (mode));
|
||||
g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (rdev));
|
||||
if (S_ISLNK (mode))
|
||||
g_variant_builder_add (&pack_builder, "s", g_file_info_get_symlink_target (finfo));
|
||||
else
|
||||
g_variant_builder_add (&pack_builder, "s", "");
|
||||
|
||||
g_variant_builder_add (&pack_builder, "@a(ayay)", xattrs ? xattrs : g_variant_new_array (G_VARIANT_TYPE ("(ayay)"), NULL, 0));
|
||||
|
||||
ret = g_variant_builder_end (&pack_builder);
|
||||
g_variant_ref_sink (ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_parse_archived_file_meta (GVariant *metadata,
|
||||
ostree_file_header_parse (GVariant *metadata,
|
||||
GFileInfo **out_file_info,
|
||||
GVariant **out_xattrs,
|
||||
GError **error)
|
||||
|
|
@ -1212,27 +1358,39 @@ ostree_read_pack_entry_raw (guchar *pack_data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
ostree_read_pack_entry_as_stream (GVariant *pack_entry)
|
||||
gboolean
|
||||
ostree_parse_file_pack_entry (GVariant *pack_entry,
|
||||
GInputStream **out_input,
|
||||
GFileInfo **out_info,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GInputStream *memory_input;
|
||||
GInputStream *ret_input = NULL;
|
||||
GVariant *pack_data = NULL;
|
||||
gboolean ret = FALSE;
|
||||
guchar entry_flags;
|
||||
gconstpointer data_ptr;
|
||||
gsize data_len;
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
ot_lvariant GVariant *pack_data = NULL;
|
||||
ot_lobj GInputStream *memory_input = NULL;
|
||||
ot_lobj GInputStream *ret_input = NULL;
|
||||
ot_lobj GFileInfo *ret_info = NULL;
|
||||
ot_lvariant GVariant *ret_xattrs = NULL;
|
||||
|
||||
g_variant_get_child (pack_entry, 1, "y", &entry_flags);
|
||||
g_variant_get_child (pack_entry, 2, "@(uuuusa(ayay))", &file_header);
|
||||
g_variant_get_child (pack_entry, 3, "@ay", &pack_data);
|
||||
|
||||
data_ptr = g_variant_get_fixed_array (pack_data, &data_len, 1);
|
||||
memory_input = g_memory_input_stream_new_from_data (data_ptr, data_len, NULL);
|
||||
g_object_set_data_full ((GObject*)memory_input, "ostree-mem-gvariant",
|
||||
pack_data, (GDestroyNotify) g_variant_unref);
|
||||
if (!ostree_file_header_parse (file_header, &ret_info, &ret_xattrs,
|
||||
error))
|
||||
goto out;
|
||||
g_file_info_set_size (ret_info, g_variant_get_size (pack_data));
|
||||
|
||||
if (g_file_info_get_file_type (ret_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
memory_input = ot_variant_read (pack_data);
|
||||
|
||||
if (entry_flags & OSTREE_PACK_FILE_ENTRY_FLAG_GZIP)
|
||||
{
|
||||
GConverter *decompressor;
|
||||
ot_lobj GConverter *decompressor = NULL;
|
||||
|
||||
decompressor = (GConverter*)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
|
||||
ret_input = (GInputStream*)g_object_new (G_TYPE_CONVERTER_INPUT_STREAM,
|
||||
|
|
@ -1240,34 +1398,18 @@ ostree_read_pack_entry_as_stream (GVariant *pack_entry)
|
|||
"base-stream", memory_input,
|
||||
"close-base-stream", TRUE,
|
||||
NULL);
|
||||
g_object_unref (memory_input);
|
||||
g_object_unref (decompressor);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_input = memory_input;
|
||||
memory_input = NULL;
|
||||
ret_input = g_object_ref (memory_input);
|
||||
}
|
||||
}
|
||||
|
||||
return ret_input;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_read_pack_entry_variant (GVariant *pack_entry,
|
||||
OstreeObjectType expected_objtype,
|
||||
gboolean trusted,
|
||||
GVariant **out_variant,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
ot_lvariant GVariant *ret_variant = NULL;
|
||||
|
||||
g_variant_get_child (pack_entry, 2, "v", &ret_variant);
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_variant, &ret_variant);
|
||||
/* out: */
|
||||
ot_transfer_out_value (out_input, &ret_input);
|
||||
ot_transfer_out_value (out_info, &ret_info);
|
||||
ot_transfer_out_value (out_xattrs, &ret_xattrs);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1346,7 +1488,7 @@ ostree_validate_structureof_objtype (guchar objtype,
|
|||
GError **error)
|
||||
{
|
||||
OstreeObjectType objtype_v = (OstreeObjectType) objtype;
|
||||
if (objtype_v < OSTREE_OBJECT_TYPE_RAW_FILE
|
||||
if (objtype_v < OSTREE_OBJECT_TYPE_FILE
|
||||
|| objtype_v > OSTREE_OBJECT_TYPE_COMMIT)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
|
||||
|
|
|
|||
|
|
@ -32,22 +32,29 @@ G_BEGIN_DECLS
|
|||
#define OSTREE_EMPTY_STRING_SHA256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
||||
|
||||
typedef enum {
|
||||
OSTREE_OBJECT_TYPE_RAW_FILE = 1, /* .raw */
|
||||
OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT = 2, /* .archive-content */
|
||||
OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META = 3, /* .archive-meta */
|
||||
OSTREE_OBJECT_TYPE_DIR_TREE = 4, /* .dirtree */
|
||||
OSTREE_OBJECT_TYPE_DIR_META = 5, /* .dirmeta */
|
||||
OSTREE_OBJECT_TYPE_COMMIT = 6 /* .commit */
|
||||
OSTREE_OBJECT_TYPE_FILE = 1, /* .file */
|
||||
OSTREE_OBJECT_TYPE_DIR_TREE = 2, /* .dirtree */
|
||||
OSTREE_OBJECT_TYPE_DIR_META = 3, /* .dirmeta */
|
||||
OSTREE_OBJECT_TYPE_COMMIT = 4 /* .commit */
|
||||
} OstreeObjectType;
|
||||
|
||||
#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 3 && t <= 6)
|
||||
#define OSTREE_OBJECT_TYPE_IS_META(t) (t >= 2 && t <= 4)
|
||||
#define OSTREE_OBJECT_TYPE_LAST OSTREE_OBJECT_TYPE_COMMIT
|
||||
|
||||
|
||||
/*
|
||||
* xattr objects:
|
||||
* a(ayay) - array of (name, value) pairs, both binary data, though name is a bytestring
|
||||
* file objects:
|
||||
* <BE guint32 containing variant length>
|
||||
* u - uid
|
||||
* u - gid
|
||||
* u - mode
|
||||
* u - rdev
|
||||
* s - symlink target
|
||||
* a(ayay) - xattrs
|
||||
* ---
|
||||
* data
|
||||
*/
|
||||
#define OSTREE_XATTR_GVARIANT_FORMAT "a(ayay)"
|
||||
#define OSTREE_FILE_HEADER_GVARIANT_FORMAT G_VARIANT_TYPE ("(uuuusa(ayay))")
|
||||
|
||||
/*
|
||||
* dirmeta objects:
|
||||
|
|
@ -78,16 +85,6 @@ typedef enum {
|
|||
*/
|
||||
#define OSTREE_COMMIT_GVARIANT_FORMAT G_VARIANT_TYPE ("(a{sv}aya(say)sstayay)")
|
||||
|
||||
/* Archive file objects:
|
||||
* u - uid
|
||||
* u - gid
|
||||
* u - mode
|
||||
* u - rdev
|
||||
* s - symlink target
|
||||
* a(ayay) - xattrs
|
||||
*/
|
||||
#define OSTREE_ARCHIVED_FILE_VARIANT_FORMAT G_VARIANT_TYPE ("(uuuusa(ayay))")
|
||||
|
||||
/* Pack super index
|
||||
* s - OSTv0SUPERPACKINDEX
|
||||
* a{sv} - Metadata
|
||||
|
|
@ -115,9 +112,9 @@ typedef enum {
|
|||
*
|
||||
* Repeating pair of:
|
||||
* <padding to alignment of 8>
|
||||
* ( yyayay ) - objtype, flags, checksum, data
|
||||
* ( ayy(uuuusa(ayay))ay) ) - checksum, flags, file meta, data
|
||||
*/
|
||||
#define OSTREE_PACK_DATA_FILE_VARIANT_FORMAT G_VARIANT_TYPE ("(yyayay)")
|
||||
#define OSTREE_PACK_DATA_FILE_VARIANT_FORMAT G_VARIANT_TYPE ("(ayy(uuuusa(ayay))ay)")
|
||||
|
||||
/* Meta Pack files
|
||||
* s - OSTv0PACKMETAFILE
|
||||
|
|
@ -195,6 +192,43 @@ gboolean ostree_map_metadata_file (GFile *file,
|
|||
GVariant **out_variant,
|
||||
GError **error);
|
||||
|
||||
GVariant *ostree_file_header_new (GFileInfo *file_info,
|
||||
GVariant *xattrs);
|
||||
|
||||
gboolean ostree_write_variant_with_size (GOutputStream *output,
|
||||
GVariant *variant,
|
||||
guint64 alignment_offset,
|
||||
gsize *out_bytes_written,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_file_header_parse (GVariant *data,
|
||||
GFileInfo **out_file_info,
|
||||
GVariant **out_xattrs,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_content_file_parse (GFile *content_path,
|
||||
gboolean trusted,
|
||||
GInputStream **out_input,
|
||||
GFileInfo **out_file_info,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_write_file_header_update_checksum (GOutputStream *out,
|
||||
GVariant *header,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_raw_file_to_content_stream (GInputStream *input,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GInputStream **out_input,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_checksum_file_from_input (GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GInputStream *in,
|
||||
|
|
@ -257,14 +291,6 @@ gboolean ostree_create_temp_hardlink (GFile *dir,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
GVariant *ostree_create_archive_file_metadata (GFileInfo *file_info,
|
||||
GVariant *xattrs);
|
||||
|
||||
gboolean ostree_parse_archived_file_meta (GVariant *data,
|
||||
GFileInfo **out_file_info,
|
||||
GVariant **out_xattrs,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_read_pack_entry_raw (guchar *pack_data,
|
||||
guint64 pack_len,
|
||||
guint64 object_offset,
|
||||
|
|
@ -274,12 +300,10 @@ gboolean ostree_read_pack_entry_raw (guchar *pack_data,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
GInputStream *ostree_read_pack_entry_as_stream (GVariant *pack_entry);
|
||||
|
||||
gboolean ostree_read_pack_entry_variant (GVariant *pack_entry,
|
||||
OstreeObjectType expected_objtype,
|
||||
gboolean trusted,
|
||||
GVariant **out_variant,
|
||||
gboolean ostree_parse_file_pack_entry (GVariant *pack_entry,
|
||||
GInputStream **out_input,
|
||||
GFileInfo **out_info,
|
||||
GVariant **out_xattrs,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
|
|
|||
|
|
@ -943,7 +943,7 @@ ostree_repo_file_read (GFile *file,
|
|||
OstreeRepoFile *self = OSTREE_REPO_FILE (file);
|
||||
const char *checksum;
|
||||
ot_lobj GFile *local_file = NULL;
|
||||
ot_lobj GFileInputStream *ret_stream = NULL;
|
||||
ot_lobj GInputStream *ret_stream = NULL;
|
||||
|
||||
if (!ostree_repo_file_ensure_resolved (self, error))
|
||||
goto out;
|
||||
|
|
@ -958,18 +958,8 @@ ostree_repo_file_read (GFile *file,
|
|||
|
||||
checksum = ostree_repo_file_get_checksum (self);
|
||||
|
||||
if (ostree_repo_get_mode (self->repo) == OSTREE_REPO_MODE_ARCHIVE)
|
||||
{
|
||||
local_file = ostree_repo_get_object_path (self->repo, checksum,
|
||||
OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
local_file = ostree_repo_get_file_object_path (self->repo, checksum);
|
||||
}
|
||||
|
||||
ret_stream = g_file_read (local_file, cancellable, error);
|
||||
if (!ret_stream)
|
||||
if (!ostree_repo_load_file (self->repo, checksum, &ret_stream,
|
||||
NULL, NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
|
|
@ -978,7 +968,7 @@ ostree_repo_file_read (GFile *file,
|
|||
g_clear_object (&ret_stream);
|
||||
else
|
||||
g_object_ref (ret_stream);
|
||||
return ret_stream;
|
||||
return (GFileInputStream*)ret_stream;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -728,32 +728,11 @@ ostree_repo_get_mode (OstreeRepo *self)
|
|||
return priv->mode;
|
||||
}
|
||||
|
||||
static OstreeObjectType
|
||||
get_objtype_for_repo_file (OstreeRepo *self)
|
||||
{
|
||||
OstreeRepoPrivate *priv = GET_PRIVATE (self);
|
||||
if (priv->mode == OSTREE_REPO_MODE_ARCHIVE)
|
||||
return OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META;
|
||||
else
|
||||
return OSTREE_OBJECT_TYPE_RAW_FILE;
|
||||
}
|
||||
|
||||
GFile *
|
||||
ostree_repo_get_file_object_path (OstreeRepo *self,
|
||||
const char *checksum)
|
||||
{
|
||||
return ostree_repo_get_object_path (self, checksum, get_objtype_for_repo_file (self));
|
||||
}
|
||||
|
||||
static GFileInfo *
|
||||
dup_file_info_owned_by_me (GFileInfo *file_info)
|
||||
{
|
||||
GFileInfo *ret = g_file_info_dup (file_info);
|
||||
|
||||
g_file_info_set_attribute_uint32 (ret, "unix::uid", geteuid ());
|
||||
g_file_info_set_attribute_uint32 (ret, "unix::gid", getegid ());
|
||||
|
||||
return ret;
|
||||
return ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_FILE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -805,7 +784,7 @@ commit_tmpfile_trusted (OstreeRepo *self,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
impl_stage_archive_file_object_from_raw (OstreeRepo *self,
|
||||
impl_stage_archive_file_object (OstreeRepo *self,
|
||||
GFileInfo *file_info,
|
||||
GVariant *xattrs,
|
||||
GInputStream *input,
|
||||
|
|
@ -819,58 +798,43 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
|
|||
const char *actual_checksum;
|
||||
ot_lvariant GVariant *archive_metadata = NULL;
|
||||
ot_lobj GFileInfo *temp_info = NULL;
|
||||
ot_lobj GFile *meta_temp_file = NULL;
|
||||
ot_lobj GFile *content_temp_file = NULL;
|
||||
ot_lobj GInputStream *mem = NULL;
|
||||
ot_lobj OstreeChecksumInputStream *checksum_input = NULL;
|
||||
ot_lobj GFile *temp_file = NULL;
|
||||
ot_lobj GOutputStream *out = NULL;
|
||||
ot_lfree guchar *ret_csum = NULL;
|
||||
ot_lvariant GVariant *file_header = 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);
|
||||
|
||||
file_header = ostree_file_header_new (file_info, xattrs);
|
||||
|
||||
if (!ostree_create_temp_regular_file (priv->tmp_dir,
|
||||
"archive-tmp-", NULL,
|
||||
&temp_file, &out,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_write_file_header_update_checksum (out, file_header, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (input && checksum)
|
||||
{
|
||||
if (!ot_gio_splice_update_checksum (out, input, checksum, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
archive_metadata = ostree_create_archive_file_metadata (file_info, xattrs);
|
||||
|
||||
mem = g_memory_input_stream_new_from_data (g_variant_get_data (archive_metadata),
|
||||
g_variant_get_size (archive_metadata),
|
||||
NULL);
|
||||
|
||||
if (!ostree_create_temp_file_from_input (priv->tmp_dir,
|
||||
"archive-tmp-", NULL,
|
||||
NULL, NULL, mem,
|
||||
&meta_temp_file,
|
||||
cancellable, error))
|
||||
if (!g_output_stream_close (out, 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,
|
||||
checksum_input ? (GInputStream*)checksum_input : input,
|
||||
&content_temp_file,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (checksum)
|
||||
ostree_checksum_update_meta (checksum, file_info, xattrs);
|
||||
|
||||
if (expected_checksum && checksum)
|
||||
{
|
||||
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),
|
||||
ostree_object_type_to_string (OSTREE_OBJECT_TYPE_FILE),
|
||||
expected_checksum, g_checksum_get_string (checksum));
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -881,12 +845,8 @@ impl_stage_archive_file_object_from_raw (OstreeRepo *self,
|
|||
else
|
||||
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))
|
||||
goto out;
|
||||
|
||||
if (!commit_tmpfile_trusted (self, actual_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
|
||||
meta_temp_file, cancellable, error))
|
||||
if (!commit_tmpfile_trusted (self, actual_checksum, OSTREE_OBJECT_TYPE_FILE,
|
||||
temp_file, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (checksum)
|
||||
|
|
@ -921,6 +881,7 @@ stage_object_impl (OstreeRepo *self,
|
|||
ot_lfree char *pack_checksum = NULL;
|
||||
ot_lfree guchar *ret_csum = NULL;
|
||||
ot_lobj OstreeChecksumInputStream *checksum_input = NULL;
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
GChecksum *checksum = NULL;
|
||||
|
||||
g_return_val_if_fail (priv->in_transaction, FALSE);
|
||||
|
|
@ -948,26 +909,25 @@ stage_object_impl (OstreeRepo *self,
|
|||
}
|
||||
}
|
||||
|
||||
g_assert (objtype != OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
|
||||
g_assert (objtype != OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META);
|
||||
|
||||
if (stored_path == NULL && pack_checksum == NULL)
|
||||
{
|
||||
if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE)
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
g_assert (file_info != NULL);
|
||||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
|
||||
g_assert (input != NULL);
|
||||
else
|
||||
g_assert (input == NULL);
|
||||
}
|
||||
else if (OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||
else
|
||||
{
|
||||
g_assert (xattrs == NULL);
|
||||
g_assert (input != NULL);
|
||||
}
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE && priv->mode == OSTREE_REPO_MODE_ARCHIVE)
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE && priv->mode == OSTREE_REPO_MODE_ARCHIVE)
|
||||
{
|
||||
if (!impl_stage_archive_file_object_from_raw (self, file_info, xattrs, input,
|
||||
if (!impl_stage_archive_file_object (self, file_info, xattrs, input,
|
||||
expected_checksum,
|
||||
out_csum ? &ret_csum : NULL,
|
||||
cancellable, error))
|
||||
|
|
@ -982,6 +942,15 @@ stage_object_impl (OstreeRepo *self,
|
|||
checksum_input = ostree_checksum_input_stream_new (input, checksum);
|
||||
}
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE && checksum)
|
||||
{
|
||||
file_header = ostree_file_header_new (file_info, xattrs);
|
||||
|
||||
if (!ostree_write_file_header_update_checksum (NULL, file_header, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_create_temp_file_from_input (priv->tmp_dir,
|
||||
ostree_object_type_to_string (objtype), NULL,
|
||||
file_info, xattrs,
|
||||
|
|
@ -990,9 +959,6 @@ stage_object_impl (OstreeRepo *self,
|
|||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (checksum && !OSTREE_OBJECT_TYPE_IS_META (objtype))
|
||||
ostree_checksum_update_meta (checksum, file_info, xattrs);
|
||||
|
||||
if (!checksum)
|
||||
actual_checksum = expected_checksum;
|
||||
else
|
||||
|
|
@ -1961,6 +1927,7 @@ ostree_repo_resync_cached_remote_pack_indexes (OstreeRepo *self,
|
|||
g_hash_table_insert (new_pack_meta_indexes, pack_checksum, pack_checksum);
|
||||
pack_checksum = NULL; /* transfer ownership */
|
||||
}
|
||||
g_variant_iter_free (superindex_contents_iter);
|
||||
|
||||
g_variant_get_child (superindex_variant, 3, "a(ayay)",
|
||||
&superindex_contents_iter);
|
||||
|
|
@ -2009,7 +1976,7 @@ ostree_repo_resync_cached_remote_pack_indexes (OstreeRepo *self,
|
|||
ret = TRUE;
|
||||
ot_transfer_out_value (out_cached_meta_indexes, &ret_cached_meta_indexes);
|
||||
ot_transfer_out_value (out_cached_data_indexes, &ret_cached_data_indexes);
|
||||
ot_transfer_out_value (out_uncached_meta_indexes, &ret_uncached_data_indexes);
|
||||
ot_transfer_out_value (out_uncached_meta_indexes, &ret_uncached_meta_indexes);
|
||||
ot_transfer_out_value (out_uncached_data_indexes, &ret_uncached_data_indexes);
|
||||
out:
|
||||
if (superindex_contents_iter)
|
||||
|
|
@ -2465,7 +2432,7 @@ stage_directory_to_mtree_internal (OstreeRepo *self,
|
|||
|
||||
g_free (child_file_csum);
|
||||
child_file_csum = NULL;
|
||||
if (!stage_object_impl (self, OSTREE_OBJECT_TYPE_RAW_FILE, FALSE,
|
||||
if (!stage_object_impl (self, OSTREE_OBJECT_TYPE_FILE, FALSE,
|
||||
modified_info, xattrs, file_input, NULL,
|
||||
&child_file_csum, cancellable, error))
|
||||
goto out;
|
||||
|
|
@ -2652,7 +2619,7 @@ import_libarchive_entry_file (OstreeRepo *self,
|
|||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
|
||||
archive_stream = ostree_libarchive_input_stream_new (a);
|
||||
|
||||
if (!stage_object_impl (self, OSTREE_OBJECT_TYPE_RAW_FILE, FALSE,
|
||||
if (!stage_object_impl (self, OSTREE_OBJECT_TYPE_FILE, FALSE,
|
||||
file_info, NULL, archive_stream,
|
||||
NULL, out_csum,
|
||||
cancellable, error))
|
||||
|
|
@ -2954,11 +2921,7 @@ list_loose_object_dir (OstreeRepo *self,
|
|||
goto loop_next;
|
||||
|
||||
if (g_str_has_suffix (name, ".file"))
|
||||
objtype = OSTREE_OBJECT_TYPE_RAW_FILE;
|
||||
else if (g_str_has_suffix (name, ".archive-meta"))
|
||||
objtype = OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META;
|
||||
else if (g_str_has_suffix (name, ".archive-content"))
|
||||
objtype = OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT;
|
||||
objtype = OSTREE_OBJECT_TYPE_FILE;
|
||||
else if (g_str_has_suffix (name, ".dirtree"))
|
||||
objtype = OSTREE_OBJECT_TYPE_DIR_TREE;
|
||||
else if (g_str_has_suffix (name, ".dirmeta"))
|
||||
|
|
@ -3140,7 +3103,6 @@ ostree_repo_map_pack_file (OstreeRepo *self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
ostree_repo_load_file (OstreeRepo *self,
|
||||
const char *checksum,
|
||||
|
|
@ -3151,71 +3113,76 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guchar *content_pack_data;
|
||||
guint64 content_pack_len;
|
||||
guint64 content_pack_offset;
|
||||
guchar *pack_data;
|
||||
guint64 pack_len;
|
||||
guint64 pack_offset;
|
||||
ot_lvariant GVariant *packed_object = NULL;
|
||||
ot_lvariant GVariant *archive_meta = NULL;
|
||||
ot_lobj GFile *content_loose_path = NULL;
|
||||
ot_lvariant GVariant *file_data = NULL;
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
ot_lobj GFile *loose_path = NULL;
|
||||
ot_lobj GFileInfo *content_loose_info = NULL;
|
||||
ot_lfree char *content_pack_checksum = NULL;
|
||||
ot_lfree char *pack_checksum = NULL;
|
||||
ot_lobj GInputStream *ret_input = NULL;
|
||||
ot_lobj GFileInfo *ret_file_info = NULL;
|
||||
ot_lvariant GVariant *ret_xattrs = NULL;
|
||||
|
||||
if (!ostree_repo_find_object (self, OSTREE_OBJECT_TYPE_FILE,
|
||||
checksum, &loose_path,
|
||||
&pack_checksum, &pack_offset,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (loose_path)
|
||||
{
|
||||
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_ARCHIVE)
|
||||
{
|
||||
/* First, read the metadata */
|
||||
if (!ostree_repo_load_variant (self, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META, checksum,
|
||||
&archive_meta, error))
|
||||
goto out;
|
||||
if (!ostree_parse_archived_file_meta (archive_meta,
|
||||
&ret_file_info,
|
||||
&ret_xattrs,
|
||||
error))
|
||||
goto out;
|
||||
|
||||
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
/* Blah, right now we need to look up the content too to get the file size */
|
||||
if (!ostree_repo_find_object (self, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT,
|
||||
checksum, &content_loose_path,
|
||||
&content_pack_checksum, &content_pack_offset,
|
||||
if (!ostree_content_file_parse (loose_path, TRUE,
|
||||
out_input ? &ret_input : NULL,
|
||||
&ret_file_info, &ret_xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (content_loose_path)
|
||||
{
|
||||
content_loose_info = g_file_query_info (content_loose_path, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error);
|
||||
if (!content_loose_info)
|
||||
goto out;
|
||||
|
||||
g_file_info_set_attribute_uint64 (ret_file_info,
|
||||
"standard::size",
|
||||
g_file_info_get_attribute_uint64 (content_loose_info, "standard::size"));
|
||||
}
|
||||
/* fixme - don't have file size for packed =/ */
|
||||
else
|
||||
{
|
||||
ret_file_info = g_file_query_info (loose_path, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
|
||||
cancellable, error);
|
||||
if (!ret_file_info)
|
||||
goto out;
|
||||
|
||||
/* Now, look for the content */
|
||||
if (out_input)
|
||||
if (out_xattrs)
|
||||
{
|
||||
if (content_pack_checksum != NULL)
|
||||
{
|
||||
if (!ostree_repo_map_pack_file (self, content_pack_checksum, FALSE,
|
||||
&content_pack_data, &content_pack_len,
|
||||
if (!ostree_get_xattrs_for_file (loose_path, &ret_xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
if (!ostree_read_pack_entry_raw (content_pack_data, content_pack_len,
|
||||
content_pack_offset, TRUE, FALSE,
|
||||
}
|
||||
|
||||
if (out_input && g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
ret_input = (GInputStream*) g_file_read (loose_path, cancellable, error);
|
||||
if (!ret_input)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (pack_checksum)
|
||||
{
|
||||
if (!ostree_repo_map_pack_file (self, pack_checksum, FALSE,
|
||||
&pack_data, &pack_len,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_read_pack_entry_raw (pack_data, pack_len,
|
||||
pack_offset, TRUE, FALSE,
|
||||
&packed_object, cancellable, error))
|
||||
goto out;
|
||||
ret_input = ostree_read_pack_entry_as_stream (packed_object);
|
||||
}
|
||||
else if (content_loose_path != NULL)
|
||||
{
|
||||
ret_input = (GInputStream*)g_file_read (content_loose_path, cancellable, error);
|
||||
if (!ret_input)
|
||||
|
||||
if (!ostree_parse_file_pack_entry (packed_object,
|
||||
out_input ? &ret_input : NULL,
|
||||
out_file_info ? &ret_file_info : NULL,
|
||||
out_xattrs ? &ret_xattrs : NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
|
|
@ -3224,31 +3191,6 @@ ostree_repo_load_file (OstreeRepo *self,
|
|||
"Couldn't find object '%s'", checksum);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
content_loose_path = ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_RAW_FILE);
|
||||
ret_file_info = g_file_query_info (content_loose_path, OSTREE_GIO_FAST_QUERYINFO,
|
||||
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error);
|
||||
if (!ret_file_info)
|
||||
goto out;
|
||||
|
||||
/* Now, look for the content */
|
||||
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR
|
||||
&& out_input)
|
||||
{
|
||||
ret_input = (GInputStream*)g_file_read (content_loose_path, cancellable, error);
|
||||
if (!ret_input)
|
||||
goto out;
|
||||
}
|
||||
if (out_xattrs)
|
||||
{
|
||||
if (!ostree_get_xattrs_for_file (content_loose_path, &ret_xattrs, cancellable,error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_input, &ret_input);
|
||||
|
|
@ -3537,9 +3479,7 @@ ostree_repo_load_variant (OstreeRepo *self,
|
|||
TRUE, TRUE, &packed_object, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_read_pack_entry_variant (packed_object, objtype, TRUE,
|
||||
&ret_variant, cancellable, error))
|
||||
goto out;
|
||||
g_variant_get_child (packed_object, 2, "v", &ret_variant);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3760,14 +3700,9 @@ checkout_one_file (OstreeRepo *self,
|
|||
|
||||
checksum = ostree_repo_file_get_checksum ((OstreeRepoFile*)src);
|
||||
|
||||
/* First check for a loose object */
|
||||
if (priv->mode == OSTREE_REPO_MODE_ARCHIVE && mode == OSTREE_REPO_CHECKOUT_MODE_USER)
|
||||
if (priv->mode == OSTREE_REPO_MODE_BARE && mode == OSTREE_REPO_CHECKOUT_MODE_NONE)
|
||||
{
|
||||
possible_loose_path = ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
|
||||
}
|
||||
else if (priv->mode == OSTREE_REPO_MODE_BARE && mode == OSTREE_REPO_CHECKOUT_MODE_NONE)
|
||||
{
|
||||
possible_loose_path = ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_RAW_FILE);
|
||||
possible_loose_path = ostree_repo_get_object_path (self, checksum, OSTREE_OBJECT_TYPE_FILE);
|
||||
}
|
||||
|
||||
if (possible_loose_path && lstat (ot_gfile_get_path_cached (possible_loose_path), &stbuf) >= 0)
|
||||
|
|
|
|||
|
|
@ -72,21 +72,10 @@ ostree_traverse_dirtree (OstreeRepo *repo,
|
|||
g_variant_get_child (files_variant, i, "(&s@ay)", &filename, &csum_v);
|
||||
g_free (tmp_checksum);
|
||||
tmp_checksum = ostree_checksum_from_bytes_v (csum_v);
|
||||
if (ostree_repo_get_mode (repo) == OSTREE_REPO_MODE_BARE)
|
||||
{
|
||||
key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_RAW_FILE);
|
||||
key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_FILE);
|
||||
g_hash_table_replace (inout_reachable, key, key);
|
||||
key = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META);
|
||||
g_hash_table_replace (inout_reachable, key, key);
|
||||
key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
|
||||
g_hash_table_replace (inout_reachable, key, key);
|
||||
key = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
dirs_variant = g_variant_get_child_value (tree, 1);
|
||||
n = g_variant_n_children (dirs_variant);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#ifndef __OSTREE_H__
|
||||
|
||||
#include <ostree-checksum-input-stream.h>
|
||||
#include <ostree-chain-input-stream.h>
|
||||
#include <ostree-core.h>
|
||||
#include <ostree-repo.h>
|
||||
#include <ostree-mutable-tree.h>
|
||||
|
|
|
|||
|
|
@ -228,6 +228,36 @@ ot_gfile_get_basename_cached (GFile *file)
|
|||
return name;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ot_gio_write_update_checksum (GOutputStream *out,
|
||||
gconstpointer data,
|
||||
gsize len,
|
||||
gsize *out_bytes_written,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
if (out)
|
||||
{
|
||||
if (!g_output_stream_write_all (out, data, len, out_bytes_written,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (out_bytes_written)
|
||||
{
|
||||
*out_bytes_written = len;
|
||||
}
|
||||
|
||||
if (checksum)
|
||||
g_checksum_update (checksum, data, len);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ot_gio_splice_update_checksum (GOutputStream *out,
|
||||
GInputStream *in,
|
||||
|
|
@ -247,13 +277,10 @@ ot_gio_splice_update_checksum (GOutputStream *out,
|
|||
{
|
||||
if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error))
|
||||
goto out;
|
||||
g_checksum_update (checksum, (guint8*)buf, bytes_read);
|
||||
if (out)
|
||||
{
|
||||
if (!g_output_stream_write_all (out, buf, bytes_read, &bytes_written, cancellable, error))
|
||||
if (!ot_gio_write_update_checksum (out, buf, bytes_read, &bytes_written, checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
while (bytes_read > 0);
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -61,6 +61,14 @@ gboolean ot_gfile_load_contents_utf8 (GFile *file,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ot_gio_write_update_checksum (GOutputStream *out,
|
||||
gconstpointer data,
|
||||
gsize len,
|
||||
gsize *out_bytes_written,
|
||||
GChecksum *checksum,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ot_gio_splice_get_checksum (GOutputStream *out,
|
||||
GInputStream *in,
|
||||
guchar **out_csum,
|
||||
|
|
|
|||
|
|
@ -175,3 +175,17 @@ ot_util_variant_from_stream (GInputStream *src,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
GInputStream *
|
||||
ot_variant_read (GVariant *variant)
|
||||
{
|
||||
GMemoryInputStream *ret = NULL;
|
||||
|
||||
ret = (GMemoryInputStream*)g_memory_input_stream_new_from_data (g_variant_get_data (variant),
|
||||
g_variant_get_size (variant),
|
||||
NULL);
|
||||
g_object_set_data_full ((GObject*)ret, "ot-variant-data",
|
||||
g_variant_ref (variant), (GDestroyNotify) g_variant_unref);
|
||||
return (GInputStream*)ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,8 @@ gboolean ot_util_variant_from_stream (GInputStream *src,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
GInputStream *ot_variant_read (GVariant *variant);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,27 +34,6 @@ static GOptionEntry options[] = {
|
|||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
log_verbose (const char *fmt,
|
||||
...) G_GNUC_PRINTF (1, 2);
|
||||
|
||||
static void
|
||||
log_verbose (const char *fmt,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
char *msg;
|
||||
|
||||
if (!verbose)
|
||||
return;
|
||||
|
||||
va_start (args, fmt);
|
||||
|
||||
msg = g_strdup_vprintf (fmt, args);
|
||||
g_print ("%s\n", msg);
|
||||
g_free (msg);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
OstreeRepo *repo;
|
||||
char *remote_name;
|
||||
|
|
@ -122,8 +101,10 @@ static void
|
|||
sync_progress (OtPullData *pull_data)
|
||||
{
|
||||
if (pull_data->stdout_is_tty)
|
||||
{
|
||||
g_print ("%c8%" G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " KiB",
|
||||
0x1b, (pull_data->dl_current_bytes / 1024), (pull_data->dl_total_bytes / 1024));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -193,6 +174,7 @@ fetch_uri (OtPullData *pull_data,
|
|||
|
||||
if (pull_data->stdout_is_tty)
|
||||
{
|
||||
g_print ("%c7", 0x1B);
|
||||
g_print ("0/? KiB");
|
||||
pull_data->dl_current_bytes = 0;
|
||||
pull_data->dl_total_bytes = 0;
|
||||
|
|
@ -221,6 +203,7 @@ fetch_uri (OtPullData *pull_data,
|
|||
if (!g_output_stream_close (output_stream, NULL, error))
|
||||
goto out;
|
||||
|
||||
if (pull_data->stdout_is_tty)
|
||||
g_print ("\n");
|
||||
|
||||
ret = TRUE;
|
||||
|
|
@ -489,43 +472,30 @@ fetch_loose_object (OtPullData *pull_data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
unlink_file_on_unref (GFile *f)
|
||||
{
|
||||
(void) ot_gfile_unlink (f, NULL, NULL);
|
||||
g_object_unref (f);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fetch_object_if_not_stored (OtPullData *pull_data,
|
||||
find_object_ensure_packs (OtPullData *pull_data,
|
||||
const char *checksum,
|
||||
OstreeObjectType objtype,
|
||||
GInputStream **out_input,
|
||||
gboolean *out_is_stored,
|
||||
GFile **out_remote_pack_path,
|
||||
guint64 *out_remote_pack_offset,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 pack_offset = 0;
|
||||
gboolean is_stored;
|
||||
gboolean is_meta;
|
||||
ot_lobj GInputStream *ret_input = NULL;
|
||||
ot_lobj GFile *temp_path = NULL;
|
||||
gboolean ret_is_stored;
|
||||
ot_lobj GFile *stored_path = NULL;
|
||||
ot_lobj GFile *pack_path = NULL;
|
||||
ot_lfree char *local_pack_checksum = NULL;
|
||||
ot_lfree char *remote_pack_checksum = NULL;
|
||||
ot_lvariant GVariant *pack_entry = NULL;
|
||||
GMappedFile *pack_map = NULL;
|
||||
|
||||
is_meta = OSTREE_OBJECT_TYPE_IS_META (objtype);
|
||||
ot_lobj GFile *ret_remote_pack_path = NULL;
|
||||
|
||||
if (!ostree_repo_find_object (pull_data->repo, objtype, checksum,
|
||||
&stored_path, &local_pack_checksum, NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
is_stored = (stored_path != NULL || local_pack_checksum != NULL);
|
||||
if (!is_stored)
|
||||
ret_is_stored = (stored_path != NULL || local_pack_checksum != NULL);
|
||||
if (!ret_is_stored)
|
||||
{
|
||||
if (!pull_data->fetched_packs)
|
||||
{
|
||||
|
|
@ -538,83 +508,23 @@ fetch_object_if_not_stored (OtPullData *pull_data,
|
|||
}
|
||||
|
||||
if (!find_object_in_remote_packs (pull_data, checksum, objtype,
|
||||
&remote_pack_checksum, &pack_offset,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (remote_pack_checksum != NULL)
|
||||
{
|
||||
g_assert (!is_stored);
|
||||
|
||||
if (!fetch_one_pack_file (pull_data, remote_pack_checksum, is_meta,
|
||||
&pack_path, cancellable, error))
|
||||
goto out;
|
||||
|
||||
pack_map = g_mapped_file_new (ot_gfile_get_path_cached (pack_path), FALSE, error);
|
||||
if (!pack_map)
|
||||
goto out;
|
||||
|
||||
if (!ostree_read_pack_entry_raw ((guchar*)g_mapped_file_get_contents (pack_map),
|
||||
g_mapped_file_get_length (pack_map),
|
||||
pack_offset, FALSE, is_meta, &pack_entry,
|
||||
&remote_pack_checksum, out_remote_pack_offset,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* Kind of a hack... */
|
||||
ret_input = ostree_read_pack_entry_as_stream (pack_entry);
|
||||
g_object_set_data_full ((GObject*)ret_input, "ostree-pull-pack-map",
|
||||
pack_map, (GDestroyNotify) g_mapped_file_unref);
|
||||
pack_map = NULL; /* Transfer ownership */
|
||||
}
|
||||
else if (!is_stored)
|
||||
if (remote_pack_checksum)
|
||||
{
|
||||
if (!fetch_loose_object (pull_data, checksum, objtype, &temp_path, cancellable, error))
|
||||
if (!fetch_one_pack_file (pull_data, remote_pack_checksum, OSTREE_OBJECT_TYPE_IS_META (objtype),
|
||||
&ret_remote_pack_path, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret_input = (GInputStream*)g_file_read (temp_path, cancellable, error);
|
||||
if (!ret_input)
|
||||
goto out;
|
||||
g_object_set_data_full ((GObject*)ret_input, "ostree-tmpfile-unlink",
|
||||
g_object_ref (temp_path),
|
||||
(GDestroyNotify)unlink_file_on_unref);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ot_transfer_out_value (out_input, &ret_input);
|
||||
out:
|
||||
if (pack_map)
|
||||
g_mapped_file_unref (pack_map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
fetch_and_store_object (OtPullData *pull_data,
|
||||
const char *checksum,
|
||||
OstreeObjectType objtype,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
ot_lobj GFileInfo *file_info = NULL;
|
||||
ot_lobj GInputStream *input = NULL;
|
||||
|
||||
g_assert (objtype != OSTREE_OBJECT_TYPE_RAW_FILE);
|
||||
|
||||
if (!fetch_object_if_not_stored (pull_data, checksum, objtype, &input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (input)
|
||||
{
|
||||
if (!ostree_repo_stage_object (pull_data->repo, objtype, checksum, NULL, NULL,
|
||||
input, cancellable, error))
|
||||
goto out;
|
||||
|
||||
log_verbose ("Staged object: %s.%s", checksum, ostree_object_type_to_string (objtype));
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
if (out_is_stored)
|
||||
*out_is_stored = ret_is_stored;
|
||||
ot_transfer_out_value (out_remote_pack_path, &ret_remote_pack_path);
|
||||
/* offset set above */
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -628,12 +538,60 @@ fetch_and_store_metadata (OtPullData *pull_data,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 pack_offset = 0;
|
||||
gboolean is_stored;
|
||||
ot_lvariant GVariant *ret_variant = NULL;
|
||||
ot_lobj GFile *remote_pack_path = NULL;
|
||||
ot_lobj GFile *temp_path = NULL;
|
||||
ot_lobj GInputStream *input = NULL;
|
||||
ot_lvariant GVariant *pack_entry = NULL;
|
||||
ot_lvariant GVariant *metadata = NULL;
|
||||
GMappedFile *pack_map = NULL;
|
||||
|
||||
if (!fetch_and_store_object (pull_data, checksum, objtype,
|
||||
g_assert (OSTREE_OBJECT_TYPE_IS_META (objtype));
|
||||
|
||||
if (!find_object_ensure_packs (pull_data, checksum, objtype,
|
||||
&is_stored, &remote_pack_path, &pack_offset,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (remote_pack_path != NULL)
|
||||
{
|
||||
g_assert (!is_stored);
|
||||
|
||||
pack_map = g_mapped_file_new (ot_gfile_get_path_cached (remote_pack_path), FALSE, error);
|
||||
if (!pack_map)
|
||||
goto out;
|
||||
|
||||
if (!ostree_read_pack_entry_raw ((guchar*)g_mapped_file_get_contents (pack_map),
|
||||
g_mapped_file_get_length (pack_map),
|
||||
pack_offset, FALSE, TRUE, &pack_entry,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_variant_get_child (pack_entry, 2, "v", &metadata);
|
||||
|
||||
input = ot_variant_read (metadata);
|
||||
}
|
||||
else if (!is_stored)
|
||||
{
|
||||
if (!fetch_loose_object (pull_data, checksum, objtype, &temp_path, cancellable, error))
|
||||
goto out;
|
||||
|
||||
input = (GInputStream*)g_file_read (temp_path, cancellable, error);
|
||||
if (!input)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (input)
|
||||
{
|
||||
g_assert (remote_pack_path != NULL || !is_stored);
|
||||
if (!ostree_repo_stage_object (pull_data->repo, objtype, checksum,
|
||||
NULL, NULL, input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_load_variant (pull_data->repo, objtype, checksum,
|
||||
&ret_variant, error))
|
||||
goto out;
|
||||
|
|
@ -641,6 +599,10 @@ fetch_and_store_metadata (OtPullData *pull_data,
|
|||
ret = TRUE;
|
||||
ot_transfer_out_value (out_variant, &ret_variant);
|
||||
out:
|
||||
if (temp_path)
|
||||
(void) ot_gfile_unlink (temp_path, NULL, NULL);
|
||||
if (pack_map)
|
||||
g_mapped_file_unref (pack_map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -651,66 +613,66 @@ fetch_and_store_file (OtPullData *pull_data,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gboolean skip_archive_fetch;
|
||||
gboolean is_stored;
|
||||
guint64 pack_offset;
|
||||
ot_lobj GFile *remote_pack_path = NULL;
|
||||
ot_lobj GFile *temp_path = NULL;
|
||||
ot_lvariant GVariant *pack_entry = NULL;
|
||||
ot_lobj GInputStream *input = NULL;
|
||||
ot_lobj GFile *stored_path = NULL;
|
||||
ot_lfree char *pack_checksum = NULL;
|
||||
ot_lvariant GVariant *archive_metadata = NULL;
|
||||
ot_lobj GFileInfo *archive_file_info = NULL;
|
||||
ot_lvariant GVariant *archive_xattrs = NULL;
|
||||
ot_lobj GFileInfo *file_info = NULL;
|
||||
ot_lvariant GVariant *xattrs = NULL;
|
||||
GMappedFile *pack_map = NULL;
|
||||
|
||||
/* If we're fetching from an archive into a bare repository, we need
|
||||
* to explicitly check for raw file types locally.
|
||||
*/
|
||||
if (ostree_repo_get_mode (pull_data->repo) == OSTREE_REPO_MODE_BARE)
|
||||
{
|
||||
if (!ostree_repo_find_object (pull_data->repo, OSTREE_OBJECT_TYPE_RAW_FILE,
|
||||
checksum, &stored_path, &pack_checksum,
|
||||
NULL, cancellable, error))
|
||||
if (!find_object_ensure_packs (pull_data, checksum, OSTREE_OBJECT_TYPE_FILE,
|
||||
&is_stored, &remote_pack_path, &pack_offset,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
skip_archive_fetch = (stored_path || pack_checksum);
|
||||
}
|
||||
else
|
||||
if (remote_pack_path != NULL)
|
||||
{
|
||||
skip_archive_fetch = FALSE;
|
||||
}
|
||||
g_assert (!is_stored);
|
||||
|
||||
if (!skip_archive_fetch)
|
||||
{
|
||||
if (!fetch_object_if_not_stored (pull_data, checksum,
|
||||
OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
|
||||
&input, cancellable, error))
|
||||
pack_map = g_mapped_file_new (ot_gfile_get_path_cached (remote_pack_path), FALSE, error);
|
||||
if (!pack_map)
|
||||
goto out;
|
||||
|
||||
if (input != NULL)
|
||||
{
|
||||
if (!ot_util_variant_from_stream (input, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT,
|
||||
FALSE, &archive_metadata, cancellable, error))
|
||||
if (!ostree_read_pack_entry_raw ((guchar*)g_mapped_file_get_contents (pack_map),
|
||||
g_mapped_file_get_length (pack_map),
|
||||
pack_offset, FALSE, FALSE, &pack_entry,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_parse_archived_file_meta (archive_metadata, &archive_file_info,
|
||||
&archive_xattrs, error))
|
||||
if (!ostree_parse_file_pack_entry (pack_entry, &input, &file_info, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_clear_object (&input);
|
||||
if (g_file_info_get_file_type (archive_file_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
if (!fetch_object_if_not_stored (pull_data, checksum,
|
||||
OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT,
|
||||
&input, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_stage_object (pull_data->repo, OSTREE_OBJECT_TYPE_RAW_FILE, checksum,
|
||||
archive_file_info, archive_xattrs, input,
|
||||
if (!ostree_repo_stage_object (pull_data->repo, OSTREE_OBJECT_TYPE_FILE, checksum,
|
||||
file_info, xattrs, input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (!is_stored)
|
||||
{
|
||||
if (!fetch_loose_object (pull_data, checksum, OSTREE_OBJECT_TYPE_FILE, &temp_path,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_content_file_parse (temp_path, FALSE, &input, &file_info, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_stage_object (pull_data->repo, OSTREE_OBJECT_TYPE_FILE, checksum,
|
||||
file_info, xattrs, input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
if (temp_path)
|
||||
(void) ot_gfile_unlink (temp_path, NULL, NULL);
|
||||
if (pack_map)
|
||||
g_mapped_file_unref (pack_map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -770,8 +732,8 @@ fetch_and_store_tree_metadata_recurse (OtPullData *pull_data,
|
|||
|
||||
g_free (tmp_checksum);
|
||||
tmp_checksum = ostree_checksum_from_bytes_v (meta_csum);
|
||||
if (!fetch_and_store_object (pull_data, tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META,
|
||||
cancellable, error))
|
||||
if (!fetch_and_store_metadata (pull_data, tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META,
|
||||
NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_free (tmp_checksum);
|
||||
|
|
@ -807,8 +769,8 @@ fetch_and_store_commit_metadata_recurse (OtPullData *pull_data,
|
|||
|
||||
g_free (tmp_checksum);
|
||||
tmp_checksum = ostree_checksum_from_bytes_v (tree_meta_csum);
|
||||
if (!fetch_and_store_object (pull_data, tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META,
|
||||
cancellable, error))
|
||||
if (!fetch_and_store_metadata (pull_data, tmp_checksum, OSTREE_OBJECT_TYPE_DIR_META,
|
||||
NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
g_free (tmp_checksum);
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ ostree_builtin_checksum (int argc, char **argv, GFile *repo_path_path, GError **
|
|||
|
||||
data.loop = g_main_loop_new (NULL, FALSE);
|
||||
data.error = error;
|
||||
ostree_checksum_file_async (f, OSTREE_OBJECT_TYPE_RAW_FILE, G_PRIORITY_DEFAULT, NULL, on_checksum_received, &data);
|
||||
ostree_checksum_file_async (f, OSTREE_OBJECT_TYPE_FILE, G_PRIORITY_DEFAULT, NULL, on_checksum_received, &data);
|
||||
|
||||
g_main_loop_run (data.loop);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ get_file_checksum (GFile *f,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_checksum_file (f, OSTREE_OBJECT_TYPE_RAW_FILE,
|
||||
if (!ostree_checksum_file (f, OSTREE_OBJECT_TYPE_FILE,
|
||||
&csum, cancellable, error))
|
||||
goto out;
|
||||
ret_checksum = ostree_checksum_from_bytes (csum);
|
||||
|
|
|
|||
|
|
@ -203,7 +203,6 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
|
|||
GVariant *serialized_key = key;
|
||||
const char *checksum;
|
||||
OstreeObjectType objtype;
|
||||
OstreeObjectType checksum_objtype;
|
||||
|
||||
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
||||
|
||||
|
|
@ -211,8 +210,6 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
|
|||
g_clear_object (&file_info);
|
||||
ot_clear_gvariant (&xattrs);
|
||||
|
||||
checksum_objtype = objtype;
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_COMMIT
|
||||
|| objtype == OSTREE_OBJECT_TYPE_DIR_TREE
|
||||
|| objtype == OSTREE_OBJECT_TYPE_DIR_META)
|
||||
|
|
@ -253,19 +250,12 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
|
|||
g_variant_get_size (metadata),
|
||||
NULL);
|
||||
}
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
|
||||
{
|
||||
/* Handled via ARCHIVED_FILE_META */
|
||||
continue;
|
||||
}
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE
|
||||
|| objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META)
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
guint32 mode;
|
||||
if (!ostree_repo_load_file (data->repo, checksum, &input, &file_info,
|
||||
&xattrs, cancellable, error))
|
||||
goto out;
|
||||
checksum_objtype = OSTREE_OBJECT_TYPE_RAW_FILE; /* Override */
|
||||
|
||||
mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
|
||||
if (!ostree_validate_structureof_file_mode (mode, error))
|
||||
|
|
@ -281,7 +271,7 @@ fsck_reachable_objects_from_commits (OtFsckData *data,
|
|||
|
||||
g_free (computed_csum);
|
||||
if (!ostree_checksum_file_from_input (file_info, xattrs, input,
|
||||
checksum_objtype, &computed_csum,
|
||||
objtype, &computed_csum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ copy_dir_contents_recurse (GFile *src,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
import_loose_object (OtLocalCloneData *data,
|
||||
import_one_object (OtLocalCloneData *data,
|
||||
const char *checksum,
|
||||
OstreeObjectType objtype,
|
||||
GCancellable *cancellable,
|
||||
|
|
@ -105,7 +105,7 @@ import_loose_object (OtLocalCloneData *data,
|
|||
ot_lobj GFileInfo *file_info = NULL;
|
||||
ot_lobj GFile *content_path = NULL;
|
||||
ot_lobj GFileInfo *archive_info = NULL;
|
||||
ot_lvariant GVariant *archive_metadata = NULL;
|
||||
ot_lvariant GVariant *metadata = NULL;
|
||||
ot_lvariant GVariant *xattrs = NULL;
|
||||
ot_lobj GInputStream *input = NULL;
|
||||
|
||||
|
|
@ -116,48 +116,29 @@ import_loose_object (OtLocalCloneData *data,
|
|||
if (file_info == NULL)
|
||||
goto out;
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE)
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
if (!ostree_get_xattrs_for_file (objfile, &xattrs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
|
||||
;
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META)
|
||||
{
|
||||
if (!ostree_repo_load_variant (data->src_repo, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META, checksum, &archive_metadata, error))
|
||||
if (!ostree_repo_load_file (data->src_repo, checksum,
|
||||
&input, &file_info, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_parse_archived_file_meta (archive_metadata, &archive_info, &xattrs, error))
|
||||
goto out;
|
||||
|
||||
content_path = ostree_repo_get_object_path (data->src_repo, checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
|
||||
|
||||
if (g_file_info_get_file_type (archive_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
input = (GInputStream*)g_file_read (content_path, NULL, error);
|
||||
if (!input)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_stage_object_trusted (data->dest_repo, OSTREE_OBJECT_TYPE_RAW_FILE,
|
||||
checksum, FALSE, archive_info, xattrs, input,
|
||||
NULL, error))
|
||||
if (!ostree_repo_stage_object_trusted (data->dest_repo, OSTREE_OBJECT_TYPE_FILE,
|
||||
checksum, FALSE, file_info, xattrs, input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
input = (GInputStream*)g_file_read (objfile, NULL, error);
|
||||
if (!input)
|
||||
if (!ostree_repo_load_variant (data->src_repo, objtype, checksum, &metadata,
|
||||
error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ostree_repo_stage_object_trusted (data->dest_repo, objtype, checksum,
|
||||
FALSE, file_info, xattrs, input,
|
||||
NULL, error))
|
||||
input = ot_variant_read (metadata);
|
||||
|
||||
if (!ostree_repo_stage_object_trusted (data->dest_repo, objtype,
|
||||
checksum, FALSE, NULL, NULL, input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -273,21 +254,14 @@ ostree_builtin_local_clone (int argc, char **argv, GFile *repo_path, GError **er
|
|||
while (g_hash_table_iter_next (&hash_iter, &key, &value))
|
||||
{
|
||||
GVariant *serialized_key = key;
|
||||
GVariant *objdata = value;
|
||||
const char *checksum;
|
||||
OstreeObjectType objtype;
|
||||
gboolean is_loose;
|
||||
|
||||
ostree_object_name_deserialize (serialized_key, &checksum, &objtype);
|
||||
|
||||
g_variant_get_child (objdata, 0, "b", &is_loose);
|
||||
|
||||
if (is_loose)
|
||||
{
|
||||
if (!import_loose_object (&data, checksum, objtype, cancellable, error))
|
||||
if (!import_one_object (&data, checksum, objtype, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ostree_repo_commit_transaction (data.dest_repo, NULL, error))
|
||||
goto out;
|
||||
|
|
|
|||
|
|
@ -151,44 +151,6 @@ write_padding (GOutputStream *output,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_variant_with_size (GOutputStream *output,
|
||||
GVariant *variant,
|
||||
GChecksum *checksum,
|
||||
guint64 *inout_offset,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 variant_size;
|
||||
guint32 variant_size_u32_be;
|
||||
|
||||
g_assert ((*inout_offset & 3) == 0);
|
||||
|
||||
/* Write variant size */
|
||||
variant_size = g_variant_get_size (variant);
|
||||
g_assert (variant_size < G_MAXUINT32);
|
||||
variant_size_u32_be = GUINT32_TO_BE((guint32) variant_size);
|
||||
|
||||
if (!write_bytes_update_checksum (output, (guchar*)&variant_size_u32_be, 4,
|
||||
checksum, inout_offset, cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* Pad to offset of 8, write variant */
|
||||
if (!write_padding (output, 8, checksum, inout_offset, cancellable, error))
|
||||
goto out;
|
||||
g_assert ((*inout_offset & 7) == 0);
|
||||
|
||||
if (!write_bytes_update_checksum (output, g_variant_get_data (variant),
|
||||
variant_size, checksum,
|
||||
inout_offset, cancellable, error))
|
||||
goto out;
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gint
|
||||
compare_index_content (gconstpointer ap,
|
||||
gconstpointer bp)
|
||||
|
|
@ -235,27 +197,6 @@ delete_loose_object (OtRepackData *data,
|
|||
|
||||
object_path = ostree_repo_get_object_path (data->repo, checksum, objtype);
|
||||
|
||||
/* This is gross - we need to specially clean up symbolic link object content */
|
||||
if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META)
|
||||
{
|
||||
if (!ot_util_variant_map (object_path, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT, &archive_meta, error))
|
||||
goto out;
|
||||
if (!ostree_parse_archived_file_meta (archive_meta, &file_info, &xattrs, error))
|
||||
goto out;
|
||||
|
||||
if (g_file_info_get_file_type (file_info) != G_FILE_TYPE_REGULAR)
|
||||
{
|
||||
content_object_path = ostree_repo_get_object_path (data->repo, checksum,
|
||||
OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
|
||||
if (!ot_gfile_unlink (content_object_path, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Failed to delete archived content '%s'",
|
||||
ot_gfile_get_path_cached (content_object_path));
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ot_gfile_unlink (object_path, cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "Failed to delete archived file metadata '%s'",
|
||||
|
|
@ -307,15 +248,16 @@ pack_one_data_object (OtRepackData *data,
|
|||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
guint64 objsize;
|
||||
guchar entry_flags = 0;
|
||||
GInputStream *read_object_in; /* nofree */
|
||||
ot_lobj GFile *object_path = NULL;
|
||||
ot_lobj GFileInputStream *object_input = NULL;
|
||||
ot_lobj GFileInfo *object_file_info = NULL;
|
||||
ot_lobj GInputStream *input = NULL;
|
||||
ot_lobj GFileInfo *file_info = NULL;
|
||||
ot_lvariant GVariant *xattrs = NULL;
|
||||
ot_lobj GMemoryOutputStream *object_data_stream = NULL;
|
||||
ot_lobj GConverter *compressor = NULL;
|
||||
ot_lobj GConverterInputStream *compressed_object_input = NULL;
|
||||
ot_lvariant GVariant *file_header = NULL;
|
||||
ot_lvariant GVariant *ret_packed_object = NULL;
|
||||
|
||||
switch (data->int_compression)
|
||||
|
|
@ -333,45 +275,43 @@ pack_one_data_object (OtRepackData *data,
|
|||
|
||||
object_path = ostree_repo_get_object_path (data->repo, checksum, objtype);
|
||||
|
||||
object_input = g_file_read (object_path, cancellable, error);
|
||||
if (!object_input)
|
||||
if (!ostree_repo_load_file (data->repo, checksum, &input, &file_info, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
object_file_info = g_file_input_stream_query_info (object_input, OSTREE_GIO_FAST_QUERYINFO, cancellable, error);
|
||||
if (!object_file_info)
|
||||
goto out;
|
||||
|
||||
objsize = g_file_info_get_attribute_uint64 (object_file_info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
|
||||
|
||||
g_assert_cmpint (objsize, ==, expected_objsize);
|
||||
file_header = ostree_file_header_new (file_info, xattrs);
|
||||
|
||||
object_data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
|
||||
|
||||
if (input != NULL)
|
||||
{
|
||||
if (entry_flags & OSTREE_PACK_FILE_ENTRY_FLAG_GZIP)
|
||||
{
|
||||
compressor = (GConverter*)g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, OT_GZIP_COMPRESSION_LEVEL);
|
||||
compressed_object_input = (GConverterInputStream*)g_object_new (G_TYPE_CONVERTER_INPUT_STREAM,
|
||||
"converter", compressor,
|
||||
"base-stream", object_input,
|
||||
"base-stream", input,
|
||||
"close-base-stream", TRUE,
|
||||
NULL);
|
||||
read_object_in = (GInputStream*)compressed_object_input;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_object_in = (GInputStream*)object_input;
|
||||
read_object_in = (GInputStream*)input;
|
||||
}
|
||||
|
||||
if (!g_output_stream_splice ((GOutputStream*)object_data_stream, read_object_in,
|
||||
G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
{
|
||||
guchar *data = g_memory_output_stream_get_data (object_data_stream);
|
||||
gsize data_len = g_memory_output_stream_get_data_size (object_data_stream);
|
||||
ret_packed_object = g_variant_new ("(yy@ay@ay)", (guchar)objtype, entry_flags,
|
||||
ret_packed_object = g_variant_new ("(@ayy@(uuuusa(ayay))@ay)",
|
||||
ostree_checksum_to_bytes_v (checksum),
|
||||
entry_flags,
|
||||
file_header,
|
||||
ot_gvariant_new_bytearray (data, data_len));
|
||||
}
|
||||
|
||||
|
|
@ -433,9 +373,10 @@ create_pack_file (OtRepackData *data,
|
|||
g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0),
|
||||
(guint64)objects->len);
|
||||
|
||||
if (!write_variant_with_size (pack_out, pack_header, pack_checksum, &offset,
|
||||
if (!ostree_write_variant_with_size (pack_out, pack_header, offset, &bytes_written, pack_checksum,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
offset += bytes_written;
|
||||
|
||||
for (i = 0; i < objects->len; i++)
|
||||
{
|
||||
|
|
@ -475,9 +416,11 @@ create_pack_file (OtRepackData *data,
|
|||
g_ptr_array_add (index_content_list, g_variant_ref_sink (index_entry));
|
||||
index_entry = NULL;
|
||||
|
||||
if (!write_variant_with_size (pack_out, packed_object, pack_checksum,
|
||||
&offset, cancellable, error))
|
||||
bytes_written = 0;
|
||||
if (!ostree_write_variant_with_size (pack_out, packed_object, offset, &bytes_written,
|
||||
pack_checksum, cancellable, error))
|
||||
goto out;
|
||||
offset += bytes_written;
|
||||
}
|
||||
|
||||
if (!g_output_stream_close (pack_out, cancellable, error))
|
||||
|
|
@ -830,13 +773,11 @@ do_stats_gather_loose (OtRepackData *data,
|
|||
case OSTREE_OBJECT_TYPE_DIR_META:
|
||||
n_dirmeta++;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_RAW_FILE:
|
||||
case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META:
|
||||
case OSTREE_OBJECT_TYPE_FILE:
|
||||
n_files++;
|
||||
break;
|
||||
case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT:
|
||||
/* Counted under files by META */
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ show_repo_meta (OstreeRepo *repo,
|
|||
ot_lobj GFile *object_path = NULL;
|
||||
ot_lobj GInputStream *in = NULL;
|
||||
|
||||
for (objtype = OSTREE_OBJECT_TYPE_RAW_FILE; objtype <= OSTREE_OBJECT_TYPE_COMMIT; objtype++)
|
||||
for (objtype = OSTREE_OBJECT_TYPE_FILE; objtype <= OSTREE_OBJECT_TYPE_COMMIT; objtype++)
|
||||
{
|
||||
g_clear_object (&object_path);
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ show_repo_meta (OstreeRepo *repo,
|
|||
print_variant (variant);
|
||||
break;
|
||||
}
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE)
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
in = (GInputStream*)g_file_read (object_path, NULL, error);
|
||||
if (!in)
|
||||
|
|
@ -121,12 +121,6 @@ show_repo_meta (OstreeRepo *repo,
|
|||
g_print ("%s", buf);
|
||||
} while (bytes_read > 0);
|
||||
}
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Can't show archived files yet");
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,31 +102,24 @@ unpack_one_object (OstreeRepo *repo,
|
|||
ot_lvariant GVariant *xattrs = NULL;
|
||||
ot_lvariant GVariant *meta = NULL;
|
||||
|
||||
g_assert (objtype != OSTREE_OBJECT_TYPE_RAW_FILE);
|
||||
|
||||
if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META)
|
||||
if (objtype == OSTREE_OBJECT_TYPE_FILE)
|
||||
{
|
||||
if (!ostree_repo_load_file (repo, checksum,
|
||||
&input, &file_info, &xattrs,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_stage_object_trusted (repo, OSTREE_OBJECT_TYPE_RAW_FILE,
|
||||
if (!ostree_repo_stage_object_trusted (repo, OSTREE_OBJECT_TYPE_FILE,
|
||||
checksum, TRUE, file_info, xattrs, input,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
|
||||
{
|
||||
/* nothing; handled in META case */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ostree_repo_load_variant (repo, objtype, checksum, &meta, error))
|
||||
goto out;
|
||||
|
||||
input = g_memory_input_stream_new_from_data (g_variant_get_data (meta),
|
||||
g_variant_get_size (meta), NULL);
|
||||
input = ot_variant_read (meta);
|
||||
|
||||
if (!ostree_repo_stage_object_trusted (repo, objtype, checksum, TRUE,
|
||||
NULL, NULL, input, cancellable, error))
|
||||
|
|
|
|||
|
|
@ -19,21 +19,13 @@
|
|||
|
||||
set -e
|
||||
|
||||
echo "1..30"
|
||||
echo "1..29"
|
||||
|
||||
. libtest.sh
|
||||
|
||||
echo hello > afile
|
||||
assert_streq "$(ostree checksum afile)" e56457ac3d60e89083e3492c738588f28311ea44c347f57f12e8b7f35d518fe3
|
||||
|
||||
setup_test_repository "regular"
|
||||
echo "ok setup"
|
||||
|
||||
assert_file_has_content ${test_tmpdir}/repo/objects/3a/9b4a6fb6885c2548e35c9382b316ad073ef7c1872a97cc9661e6403777cbaf.file moo
|
||||
assert_streq "$(readlink ${test_tmpdir}/repo/objects/d4/69b152ab4c8ddcfdfd5b15510560bcb76ae4ffea6eace4074435e5a5d05622.file)" nonexistent
|
||||
|
||||
echo "ok check"
|
||||
|
||||
$OSTREE checkout test2 checkout-test2
|
||||
echo "ok checkout"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue