[ostree: 10/11] core: Re-unify on one OSTREE_OBJECT_TYPE_FILE



commit 38ef75e6e04f7ec19844f9a1c178e6066682d13d
Author: Colin Walters <walters verbum org>
Date:   Wed Apr 11 15:18:34 2012 -0400

    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.

 Makefile-libostree.am                     |    2 +
 src/libostree/ostree-chain-input-stream.c |  210 ++++++++++++
 src/libostree/ostree-chain-input-stream.h |   67 ++++
 src/libostree/ostree-core.c               |  502 ++++++++++++++++++-----------
 src/libostree/ostree-core.h               |  100 ++++---
 src/libostree/ostree-repo-file.c          |   18 +-
 src/libostree/ostree-repo.c               |  297 +++++++-----------
 src/libostree/ostree-traverse.c           |   17 +-
 src/libostree/ostree.h                    |    1 +
 src/libotutil/ot-gio-utils.c              |   39 ++-
 src/libotutil/ot-gio-utils.h              |    8 +
 src/libotutil/ot-variant-utils.c          |   14 +
 src/libotutil/ot-variant-utils.h          |    2 +
 src/ostree/ostree-pull.c                  |  298 ++++++++----------
 src/ostree/ot-builtin-checksum.c          |    2 +-
 src/ostree/ot-builtin-diff.c              |    2 +-
 src/ostree/ot-builtin-fsck.c              |   14 +-
 src/ostree/ot-builtin-local-clone.c       |   72 ++---
 src/ostree/ot-builtin-pack.c              |  141 +++------
 src/ostree/ot-builtin-show.c              |   10 +-
 src/ostree/ot-builtin-unpack.c            |   13 +-
 tests/t0000-basic.sh                      |   10 +-
 22 files changed, 1048 insertions(+), 791 deletions(-)
---
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index bc64cb7..6eb27e0 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -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 \
diff --git a/src/libostree/ostree-chain-input-stream.c b/src/libostree/ostree-chain-input-stream.c
new file mode 100644
index 0000000..b875e07
--- /dev/null
+++ b/src/libostree/ostree-chain-input-stream.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;
+}
diff --git a/src/libostree/ostree-chain-input-stream.h b/src/libostree/ostree-chain-input-stream.h
new file mode 100644
index 0000000..ac9a8ac
--- /dev/null
+++ b/src/libostree/ostree-chain-input-stream.h
@@ -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__ */
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index f87f31c..d649d38 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -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)
+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 (entry_flags & OSTREE_PACK_FILE_ENTRY_FLAG_GZIP)
+  if (g_file_info_get_file_type (ret_info) == G_FILE_TYPE_REGULAR)
     {
-      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)
-{
-  gboolean ret = FALSE;
-  ot_lvariant GVariant *ret_variant = NULL;
+      memory_input = ot_variant_read (pack_data);
 
-  g_variant_get_child (pack_entry, 2, "v", &ret_variant);
+      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,
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 02ccb01..32de905 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -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,
diff --git a/src/libostree/ostree-repo-file.c b/src/libostree/ostree-repo-file.c
index 58477b6..005f59e 100644
--- a/src/libostree/ostree-repo-file.c
+++ b/src/libostree/ostree-repo-file.c
@@ -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
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 64d65db..327f187 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -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,64 +784,49 @@ 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);
-      if (input)
-        checksum_input = ostree_checksum_input_stream_new (input, checksum);
-    }
+    checksum = g_checksum_new (G_CHECKSUM_SHA256);
   
-  archive_metadata = ostree_create_archive_file_metadata (file_info, xattrs);
+  file_header = ostree_file_header_new (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 (!ostree_create_temp_regular_file (priv->tmp_dir,
+                                        "archive-tmp-", NULL,
+                                        &temp_file, &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))
+  if (!ostree_write_file_header_update_checksum (out, file_header, checksum,
+                                                 cancellable, error))
     goto out;
 
-  if (checksum)
-    ostree_checksum_update_meta (checksum, file_info, xattrs);
+  if (input && checksum)
+    {
+      if (!ot_gio_splice_update_checksum (out, input, checksum, cancellable, error))
+        goto out;
+    }
+
+  if (!g_output_stream_close (out, cancellable, error))
+    goto out;
 
   if (expected_checksum && checksum)
     {
@@ -870,7 +834,7 @@ impl_stage_archive_file_object_from_raw (OstreeRepo         *self,
         {
           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)
-    {
-      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)
+  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)
diff --git a/src/libostree/ostree-traverse.c b/src/libostree/ostree-traverse.c
index 148372e..f35c83a 100644
--- a/src/libostree/ostree-traverse.c
+++ b/src/libostree/ostree-traverse.c
@@ -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);
diff --git a/src/libostree/ostree.h b/src/libostree/ostree.h
index a4b7845..9dda6b3 100644
--- a/src/libostree/ostree.h
+++ b/src/libostree/ostree.h
@@ -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>
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index 3cd72ef..72eacf3 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -229,6 +229,36 @@ ot_gfile_get_basename_cached (GFile *file)
 }
 
 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,
                                GChecksum      *checksum,
@@ -247,12 +277,9 @@ 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))
-                goto out;
-            }
+          if (!ot_gio_write_update_checksum (out, buf, bytes_read, &bytes_written, checksum,
+                                             cancellable, error))
+            goto out;
         }
       while (bytes_read > 0);
     }
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 59db714..c98e73a 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -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,
diff --git a/src/libotutil/ot-variant-utils.c b/src/libotutil/ot-variant-utils.c
index 58f3e49..3932386 100644
--- a/src/libotutil/ot-variant-utils.c
+++ b/src/libotutil/ot-variant-utils.c
@@ -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;
+}
+
diff --git a/src/libotutil/ot-variant-utils.h b/src/libotutil/ot-variant-utils.h
index 4988253..95ed2e9 100644
--- a/src/libotutil/ot-variant-utils.h
+++ b/src/libotutil/ot-variant-utils.h
@@ -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
diff --git a/src/ostree/ostree-pull.c b/src/ostree/ostree-pull.c
index 21dae46..7a48b11 100644
--- a/src/ostree/ostree-pull.c
+++ b/src/ostree/ostree-pull.c
@@ -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));
+    {
+      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,7 +203,8 @@ fetch_uri (OtPullData  *pull_data,
   if (!g_output_stream_close (output_stream, NULL, error))
     goto out;
 
-  g_print ("\n");
+  if (pull_data->stdout_is_tty)
+    g_print ("\n");
   
   ret = TRUE;
   ot_transfer_out_value (out_temp_filename, &ret_temp_filename);
@@ -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,
-                            const char           *checksum,
-                            OstreeObjectType      objtype,
-                            GInputStream        **out_input,
-                            GCancellable         *cancellable,
-                            GError              **error)
+find_object_ensure_packs (OtPullData            *pull_data,
+                          const char            *checksum,
+                          OstreeObjectType       objtype,
+                          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,102 +508,90 @@ fetch_object_if_not_stored (OtPullData           *pull_data,
         }
 
       if (!find_object_in_remote_packs (pull_data, checksum, objtype, 
-                                        &remote_pack_checksum, &pack_offset,
+                                        &remote_pack_checksum, out_remote_pack_offset,
                                         cancellable, error))
         goto out;
+
+      if (remote_pack_checksum)
+        {
+          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 = 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;
+}
+
+static gboolean
+fetch_and_store_metadata (OtPullData          *pull_data,
+                          const char          *checksum,
+                          OstreeObjectType     objtype,
+                          GVariant           **out_variant,
+                          GCancellable        *cancellable,
+                          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;
+
+  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_checksum != NULL)
+  if (remote_pack_path != 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);
+      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, is_meta, &pack_entry,
+                                       pack_offset, FALSE, TRUE, &pack_entry,
                                        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 */
+      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;
       
-      ret_input = (GInputStream*)g_file_read (temp_path, cancellable, error);
-      if (!ret_input)
+      input = (GInputStream*)g_file_read (temp_path, cancellable, error);
+      if (!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))
+      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;
-
-      log_verbose ("Staged object: %s.%s", checksum, ostree_object_type_to_string (objtype));
     }
 
-  ret = TRUE;
- out:
-  return ret;
-}
-
-static gboolean
-fetch_and_store_metadata (OtPullData          *pull_data,
-                          const char          *checksum,
-                          OstreeObjectType     objtype,
-                          GVariant           **out_variant,
-                          GCancellable        *cancellable,
-                          GError             **error)
-{
-  gboolean ret = FALSE;
-  ot_lvariant GVariant *ret_variant = NULL;
-
-  if (!fetch_and_store_object (pull_data, checksum, objtype,
-                               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;
-
-  /* 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)
+  ot_lobj GFileInfo *file_info = NULL;
+  ot_lvariant GVariant *xattrs = NULL;
+  GMappedFile *pack_map = NULL;
+
+  if (!find_object_ensure_packs (pull_data, checksum, OSTREE_OBJECT_TYPE_FILE,
+                                 &is_stored, &remote_pack_path, &pack_offset,
+                                 cancellable, error))
+    goto out;
+
+  if (remote_pack_path != NULL)
     {
-      if (!ostree_repo_find_object (pull_data->repo, OSTREE_OBJECT_TYPE_RAW_FILE,
-                                    checksum, &stored_path, &pack_checksum,
-                                    NULL, cancellable, error))
+      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, FALSE, &pack_entry,
+                                       cancellable, error))
+        goto out;
+
+      if (!ostree_parse_file_pack_entry (pack_entry, &input, &file_info, &xattrs,
+                                         cancellable, error))
         goto out;
       
-      skip_archive_fetch = (stored_path || pack_checksum);
-    }
-  else
-    {
-      skip_archive_fetch = FALSE;
+      if (!ostree_repo_stage_object (pull_data->repo, OSTREE_OBJECT_TYPE_FILE, checksum,
+                                     file_info, xattrs, input,
+                                     cancellable, error))
+        goto out;
     }
-
-  if (!skip_archive_fetch)
+  else if (!is_stored)
     {
-      if (!fetch_object_if_not_stored (pull_data, checksum,
-                                       OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
-                                       &input, cancellable, error))
+      if (!fetch_loose_object (pull_data, checksum, OSTREE_OBJECT_TYPE_FILE, &temp_path,
+                               cancellable, error))
         goto out;
 
-      if (input != NULL)
-        {
-          if (!ot_util_variant_from_stream (input, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT,
-                                            FALSE, &archive_metadata, cancellable, error))
-            goto out;
-
-          if (!ostree_parse_archived_file_meta (archive_metadata, &archive_file_info,
-                                                &archive_xattrs, 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_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_RAW_FILE, checksum,
-                                         archive_file_info, archive_xattrs, input,
-                                         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);
diff --git a/src/ostree/ot-builtin-checksum.c b/src/ostree/ot-builtin-checksum.c
index e42454d..3ef3579 100644
--- a/src/ostree/ot-builtin-checksum.c
+++ b/src/ostree/ot-builtin-checksum.c
@@ -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);
 
diff --git a/src/ostree/ot-builtin-diff.c b/src/ostree/ot-builtin-diff.c
index 38a22a3..47ee5af 100644
--- a/src/ostree/ot-builtin-diff.c
+++ b/src/ostree/ot-builtin-diff.c
@@ -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);
diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c
index 6046512..c617ccd 100644
--- a/src/ostree/ot-builtin-fsck.c
+++ b/src/ostree/ot-builtin-fsck.c
@@ -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;
 
diff --git a/src/ostree/ot-builtin-local-clone.c b/src/ostree/ot-builtin-local-clone.c
index 208875f..ee1e66d 100644
--- a/src/ostree/ot-builtin-local-clone.c
+++ b/src/ostree/ot-builtin-local-clone.c
@@ -94,18 +94,18 @@ copy_dir_contents_recurse (GFile  *src,
 }
 
 static gboolean
-import_loose_object (OtLocalCloneData *data,
-                     const char   *checksum,
-                     OstreeObjectType objtype,
-                     GCancellable  *cancellable,
-                     GError        **error)
+import_one_object (OtLocalCloneData *data,
+                   const char   *checksum,
+                   OstreeObjectType objtype,
+                   GCancellable  *cancellable,
+                   GError        **error)
 {
   gboolean ret = FALSE;
   ot_lobj GFile *objfile = NULL;
   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))
-        goto out;
-
-      if (!ostree_parse_archived_file_meta (archive_metadata, &archive_info, &xattrs, error))
+      if (!ostree_repo_load_file (data->src_repo, checksum,
+                                  &input, &file_info, &xattrs,
+                                  cancellable, 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)
-            goto out;
-        }
+      if (!ostree_repo_load_variant (data->src_repo, objtype, checksum, &metadata,
+                                     error))
+        goto out;
+
+      input = ot_variant_read (metadata);
 
-      if (!ostree_repo_stage_object_trusted (data->dest_repo, objtype, checksum,
-                                             FALSE, file_info, xattrs, input,
-                                             NULL, error))
+      if (!ostree_repo_stage_object_trusted (data->dest_repo, objtype,
+                                             checksum, FALSE, NULL, NULL, input,
+                                             cancellable, error))
         goto out;
     }
 
@@ -273,20 +254,13 @@ 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))
-            goto out;
-        }
+      if (!import_one_object (&data, checksum, objtype, cancellable, error))
+        goto out;
     }
 
   if (!ostree_repo_commit_transaction (data.dest_repo, NULL, error))
diff --git a/src/ostree/ot-builtin-pack.c b/src/ostree/ot-builtin-pack.c
index b2f81b6..7ea5dea 100644
--- a/src/ostree/ot-builtin-pack.c
+++ b/src/ostree/ot-builtin-pack.c
@@ -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)
@@ -332,46 +274,44 @@ 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)
-    goto out;
 
-  object_file_info = g_file_input_stream_query_info (object_input, OSTREE_GIO_FAST_QUERYINFO, cancellable, error);
-  if (!object_file_info)
+  if (!ostree_repo_load_file (data->repo, checksum, &input, &file_info, &xattrs,
+                              cancellable, error))
     goto out;
 
-  objsize = g_file_info_get_attribute_uint64 (object_file_info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
-  
-  g_assert_cmpint (objsize, ==, expected_objsize);
-
-  object_data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+  file_header = ostree_file_header_new (file_info, xattrs);
       
-  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,
-                                                                      "close-base-stream", TRUE,
-                                                                      NULL);
-      read_object_in = (GInputStream*)compressed_object_input;
-    }
-  else
+  object_data_stream = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+  if (input != NULL)
     {
-      read_object_in = (GInputStream*)object_input;
-    }
+      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", input,
+                                                                          "close-base-stream", TRUE,
+                                                                          NULL);
+          read_object_in = (GInputStream*)compressed_object_input;
+        }
+      else
+        {
+          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;
+      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,
-                                cancellable, error))
+  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 ();
         }
     }
 
diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c
index 6711981..ea85cc1 100644
--- a/src/ostree/ot-builtin-show.c
+++ b/src/ostree/ot-builtin-show.c
@@ -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 ();
     }
diff --git a/src/ostree/ot-builtin-unpack.c b/src/ostree/ot-builtin-unpack.c
index 1092c70..3f97ca0 100644
--- a/src/ostree/ot-builtin-unpack.c
+++ b/src/ostree/ot-builtin-unpack.c
@@ -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))
diff --git a/tests/t0000-basic.sh b/tests/t0000-basic.sh
index 6cb79ab..dfdb6a1 100755
--- a/tests/t0000-basic.sh
+++ b/tests/t0000-basic.sh
@@ -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"
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]