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:
Colin Walters committed 2012-04-11 22:27:59 -04:00
1 parent f15c184584
commit 38ef75e6e0
22 files changed
+1062 -805

No files matched your search

+210
View File
@@ -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;
}
+67
View File
@@ -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__ */
+327 -185
View File
@@ -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 if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY)
{
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
{
mode = g_file_info_get_attribute_uint32 (file_info, "unix::mode");
ot_lvariant GVariant *file_header = NULL;
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));
file_header = ostree_file_header_new (file_info, xattrs);
}
else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR)
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,42 +924,11 @@ 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,
GFileInfo **out_file_info,
GVariant **out_xattrs,
GError **error)
ostree_file_header_parse (GVariant *metadata,
GFileInfo **out_file_info,
GVariant **out_xattrs,
GError **error)
{
gboolean ret = FALSE;
guint32 uid, gid, mode, rdev;
@@ -1212,62 +1358,58 @@ ostree_read_pack_entry_raw (guchar *pack_data,
return ret;
}
GInputStream *
ostree_read_pack_entry_as_stream (GVariant *pack_entry)
{
GInputStream *memory_input;
GInputStream *ret_input = NULL;
GVariant *pack_data = NULL;
guchar entry_flags;
gconstpointer data_ptr;
gsize data_len;
g_variant_get_child (pack_entry, 1, "y", &entry_flags);
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 (entry_flags & OSTREE_PACK_FILE_ENTRY_FLAG_GZIP)
{
GConverter *decompressor;
decompressor = (GConverter*)g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP);
ret_input = (GInputStream*)g_object_new (G_TYPE_CONVERTER_INPUT_STREAM,
"converter", decompressor,
"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;
}
return ret_input;
}
gboolean
ostree_read_pack_entry_variant (GVariant *pack_entry,
OstreeObjectType expected_objtype,
gboolean trusted,
GVariant **out_variant,
GCancellable *cancellable,
GError **error)
ostree_parse_file_pack_entry (GVariant *pack_entry,
GInputStream **out_input,
GFileInfo **out_info,
GVariant **out_xattrs,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
ot_lvariant GVariant *ret_variant = NULL;
guchar entry_flags;
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, 2, "v", &ret_variant);
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);
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)
{
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,
"converter", decompressor,
"base-stream", memory_input,
"close-base-stream", TRUE,
NULL);
}
else
{
ret_input = g_object_ref (memory_input);
}
}
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,
+62 -38
View File
@@ -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,14 +300,12 @@ 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,
GCancellable *cancellable,
GError **error);
gboolean ostree_parse_file_pack_entry (GVariant *pack_entry,
GInputStream **out_input,
GFileInfo **out_info,
GVariant **out_xattrs,
GCancellable *cancellable,
GError **error);
gboolean ostree_pack_index_search (GVariant *index,
GVariant *csum_bytes,
+4 -14
View File
@@ -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
+118 -183
View File
@@ -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,72 +784,57 @@ commit_tmpfile_trusted (OstreeRepo *self,
}
static gboolean
impl_stage_archive_file_object_from_raw (OstreeRepo *self,
GFileInfo *file_info,
GVariant *xattrs,
GInputStream *input,
const char *expected_checksum,
guchar **out_csum,
GCancellable *cancellable,
GError **error)
impl_stage_archive_file_object (OstreeRepo *self,
GFileInfo *file_info,
GVariant *xattrs,
GInputStream *input,
const char *expected_checksum,
guchar **out_csum,
GCancellable *cancellable,
GError **error)
{
gboolean ret = FALSE;
OstreeRepoPrivate *priv = GET_PRIVATE (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);
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)
{
checksum = g_checksum_new (G_CHECKSUM_SHA256);
if (input)
checksum_input = ostree_checksum_input_stream_new (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,32 +909,31 @@ 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,
expected_checksum,
out_csum ? &ret_csum : NULL,
cancellable, error))
if (!impl_stage_archive_file_object (self, file_info, xattrs, input,
expected_checksum,
out_csum ? &ret_csum : NULL,
cancellable, error))
goto out;
}
else
else
{
if (out_csum)
{
@@ -981,6 +941,15 @@ stage_object_impl (OstreeRepo *self,
if (input)
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,
@@ -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,103 +3113,83 @@ 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_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 (!ostree_repo_find_object (self, OSTREE_OBJECT_TYPE_FILE,
checksum, &loose_path,
&pack_checksum, &pack_offset,
cancellable, error))
goto out;
if (g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR)
if (loose_path)
{
if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_ARCHIVE)
{
/* 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,
cancellable, error))
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)
}
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;
if (out_xattrs)
{
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)
if (!ostree_get_xattrs_for_file (loose_path, &ret_xattrs,
cancellable, error))
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 =/ */
/* Now, look for the content */
if (out_input)
if (out_input && g_file_info_get_file_type (ret_file_info) == G_FILE_TYPE_REGULAR)
{
if (content_pack_checksum != NULL)
{
if (!ostree_repo_map_pack_file (self, content_pack_checksum, FALSE,
&content_pack_data, &content_pack_len,
cancellable, error))
goto out;
if (!ostree_read_pack_entry_raw (content_pack_data, content_pack_len,
content_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)
goto out;
}
else
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Couldn't find object '%s'", checksum);
goto out;
}
ret_input = (GInputStream*) g_file_read (loose_path, cancellable, error);
if (!ret_input)
goto out;
}
}
}
else
else if (pack_checksum)
{
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)
if (!ostree_repo_map_pack_file (self, pack_checksum, FALSE,
&pack_data, &pack_len,
cancellable, error))
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;
}
if (!ostree_read_pack_entry_raw (pack_data, pack_len,
pack_offset, TRUE, FALSE,
&packed_object, cancellable, error))
goto out;
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
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
"Couldn't find object '%s'", checksum);
goto out;
}
ret = TRUE;
@@ -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)
+3 -14
View File
@@ -72,20 +72,9 @@ 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);
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;
}
key = ostree_object_name_serialize (tmp_checksum, OSTREE_OBJECT_TYPE_FILE);
g_hash_table_replace (inout_reachable, key, key);
key = NULL;
}
dirs_variant = g_variant_get_child_value (tree, 1);
+1
View File
@@ -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>