[ostree/wip/objtype: 3/3] wip: It compiles



commit fc08167c749e1437affc5a65209b5b64f607f4b3
Author: Colin Walters <walters verbum org>
Date:   Mon Dec 12 18:38:45 2011 -0500

    wip: It compiles

 src/libostree/ostree-core.c         |   16 +-
 src/libostree/ostree-repo-file.c    |   16 +-
 src/libostree/ostree-repo.c         |  516 ++++++++++++++++++++---------------
 src/libostree/ostree-repo.h         |    3 +-
 src/ostree/ostree-pull.c            |   22 ++-
 src/ostree/ot-builtin-fsck.c        |   26 ++-
 src/ostree/ot-builtin-local-clone.c |   35 ++--
 src/ostree/ot-builtin-log.c         |    1 -
 src/ostree/ot-builtin-show.c        |    2 +-
 9 files changed, 374 insertions(+), 263 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index d37de62..d373ee0 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -499,8 +499,11 @@ ostree_get_relative_object_path (const char *checksum,
     case OSTREE_OBJECT_TYPE_RAW_FILE:
       type_string = ".file";
       break;
-    case OSTREE_OBJECT_TYPE_ARCHIVED_FILE:
-      type_string = ".archive";
+    case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT:
+      type_string = ".archive-content";
+      break;
+    case OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META:
+      type_string = ".archive-meta";
       break;
     case OSTREE_OBJECT_TYPE_DIR_TREE:
       type_string = ".dirtree";
@@ -524,7 +527,6 @@ ostree_create_archive_file_metadata (GFileInfo         *finfo,
                                      const char        *content_checksum)
 {
   guint32 uid, gid, mode, rdev;
-  guint64 object_size;
   GVariantBuilder pack_builder;
 
   uid = g_file_info_get_attribute_uint32 (finfo, G_FILE_ATTRIBUTE_UNIX_UID);
@@ -532,10 +534,10 @@ ostree_create_archive_file_metadata (GFileInfo         *finfo,
   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, G_VARIANT_TYPE (OSTREE_ARCHIVED_FILE_VARIANT_FORMAT));
+  g_variant_builder_init (&pack_builder, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT);
   g_variant_builder_add (&pack_builder, "u", GUINT32_TO_BE (0));   /* Version */ 
   /* If you later add actual metadata here, don't forget to byteswap it to Big Endian if necessary */
-  g_variant_builder_add (&pack_builder, "@a{sv}", g_variant_new_array (G_VARIANT_TYPE ("{sv}", NULL, 0)));
+  g_variant_builder_add (&pack_builder, "@a{sv}", g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0));
   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));
@@ -563,15 +565,13 @@ ostree_parse_archived_file_meta (GVariant         *metadata,
   GFileInfo *ret_file_info = NULL;
   GVariant *metametadata = NULL;
   GVariant *ret_xattrs = NULL;
-  guint32 metadata_len;
   guint32 version, uid, gid, mode, rdev;
-  gsize bytes_read;
   const char *symlink_target;
   char *ret_content_checksum;
 
   g_variant_get (metadata, "(u a{sv}uuuu&s a(ayay)s)",
                  &version, &metametadata, &uid, &gid, &mode, &rdev,
-                 &ret_xattrs, &ret_content_checksum);
+                 &symlink_target, &ret_xattrs, &ret_content_checksum);
   uid = GUINT32_FROM_BE (uid);
   gid = GUINT32_FROM_BE (gid);
   mode = GUINT32_FROM_BE (mode);
diff --git a/src/libostree/ostree-repo-file.c b/src/libostree/ostree-repo-file.c
index 7d11c11..bb5dcbf 100644
--- a/src/libostree/ostree-repo-file.c
+++ b/src/libostree/ostree-repo-file.c
@@ -307,6 +307,7 @@ _ostree_repo_file_get_xattrs (OstreeRepoFile  *self,
 {
   gboolean ret = FALSE;
   GVariant *ret_xattrs = NULL;
+  GVariant *metadata = NULL;
   GFile *local_file = NULL;
 
   if (!_ostree_repo_file_ensure_resolved (self, error))
@@ -317,7 +318,12 @@ _ostree_repo_file_get_xattrs (OstreeRepoFile  *self,
   else if (ostree_repo_get_mode (self->repo) == OSTREE_REPO_MODE_ARCHIVE)
     {
       local_file = _ostree_repo_file_nontree_get_local (self);
-      if (!ostree_parse_archived_file (local_file, NULL, &ret_xattrs, NULL, cancellable, error))
+      
+      if (!ot_util_variant_map (local_file, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT,
+                                &metadata, error))
+        goto out;
+
+      if (!ostree_parse_archived_file_meta (metadata, NULL, &ret_xattrs, NULL, error))
         goto out;
     }
   else
@@ -330,6 +336,7 @@ _ostree_repo_file_get_xattrs (OstreeRepoFile  *self,
   ot_transfer_out_value(out_xattrs, &ret_xattrs);
  out:
   ot_clear_gvariant (&ret_xattrs);
+  ot_clear_gvariant (&metadata);
   g_clear_object (&local_file);
   return ret;
 }
@@ -1002,6 +1009,7 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
   const char *name = NULL;
   gboolean ret = FALSE;
   GFileInfo *ret_info = NULL;
+  GVariant *archive_metadata = NULL;
   GVariant *files_variant = NULL;
   GVariant *dirs_variant = NULL;
   GVariant *tree_child_metadata = NULL;
@@ -1030,7 +1038,10 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
 
       if (ostree_repo_get_mode (self->repo) == OSTREE_REPO_MODE_ARCHIVE)
 	{
-          if (!ostree_parse_archived_file (local_child, &ret_info, NULL, NULL, cancellable, error))
+          if (!ot_util_variant_map (local_child, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT,
+                                    &archive_metadata, error))
+            goto out;
+          if (!ostree_parse_archived_file_meta (archive_metadata, &ret_info, NULL, NULL, error))
             goto out;
 	}
       else
@@ -1086,6 +1097,7 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
   g_clear_object (&local_child);
   if (matcher)
     g_file_attribute_matcher_unref (matcher);
+  ot_clear_gvariant (&archive_metadata);
   ot_clear_gvariant (&tree_child_metadata);
   ot_clear_gvariant (&files_variant);
   ot_clear_gvariant (&dirs_variant);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 81f478e..67f538d 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -658,7 +658,7 @@ 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;
+    return OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META;
   else
     return OSTREE_OBJECT_TYPE_RAW_FILE;
 }
@@ -670,17 +670,6 @@ ostree_repo_get_file_object_path (OstreeRepo   *self,
   return ostree_repo_get_object_path (self, checksum, get_objtype_for_repo_file (self));
 }
 
-static GFile *
-get_pending_or_committed_file_object_path (OstreeRepo   *self,
-                                           const char   *checksum)
-{
-  GFile *ret;
-
-  if (!ret)
-    ret = ostree_repo_get_file_object_path (self, checksum);
-  return ret;
-}
-
 gboolean      
 ostree_repo_has_object (OstreeRepo           *self,
                         OstreeObjectType      objtype,
@@ -690,6 +679,7 @@ ostree_repo_has_object (OstreeRepo           *self,
                         GError             **error)
 {
   gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
   GFile *object_path = NULL;
 
   if (g_hash_table_lookup (priv->pending_transaction_tmpfiles, checksum))
@@ -704,11 +694,22 @@ ostree_repo_has_object (OstreeRepo           *self,
     }
   
   ret = TRUE;
- out:
+  /* out: */
   g_clear_object (&object_path);
   return ret;
 }
 
+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;
+}
+
 static gboolean
 stage_object (OstreeRepo         *self,
               OstreeObjectType    objtype,
@@ -718,22 +719,166 @@ stage_object (OstreeRepo         *self,
               const char         *expected_checksum,
               GChecksum         **out_checksum,
               GCancellable       *cancellable,
-              GError            **error)
+              GError            **error);
+
+static gboolean
+impl_stage_archive_file_object_from_raw (OstreeRepo         *self,
+                                         GFileInfo          *file_info,
+                                         GVariant           *xattrs,
+                                         GInputStream       *input,
+                                         const char         *expected_checksum,
+                                         GChecksum         **out_checksum,
+                                         GCancellable       *cancellable,
+                                         GError            **error)
 {
   gboolean ret = FALSE;
   OstreeRepoPrivate *priv = GET_PRIVATE (self);
-  GOutputStream *temp_out = NULL;
   GChecksum *ret_checksum = NULL;
-  GFile *dest_path = NULL;
+  GVariant *archive_metadata = NULL;
+  GChecksum *content_checksum = NULL;
+  GFileInfo *temp_info = NULL;
+  GFile *temp_file = NULL;
+  GVariant *serialized = NULL;
+  GInputStream *mem = NULL;
+
+  temp_info = dup_file_info_owned_by_me (file_info);
+  if (!ostree_create_temp_file_from_input (priv->tmp_dir,
+                                           "archive-tmp-", NULL,
+                                           temp_info, NULL, input,
+                                           OSTREE_OBJECT_TYPE_RAW_FILE,
+                                           &temp_file,
+                                           &content_checksum,
+                                           cancellable, error))
+    goto out;
+  
+  archive_metadata = ostree_create_archive_file_metadata (file_info, xattrs, 
+                                                          g_checksum_get_string (content_checksum));
+  
+  g_hash_table_insert (priv->pending_transaction_tmpfiles,
+                       g_strdup (g_checksum_get_string (content_checksum)),
+                       g_variant_new ("(us)", OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT,
+                                      ot_gfile_get_basename_cached (temp_file)));
+  
+  serialized = ostree_wrap_metadata_variant (OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META, archive_metadata);
+  mem = g_memory_input_stream_new_from_data (g_variant_get_data (serialized),
+                                             g_variant_get_size (serialized),
+                                             NULL);
+  
+  if (!stage_object (self, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
+                     NULL, NULL, mem,
+                     expected_checksum, out_checksum ? &ret_checksum : NULL, cancellable, error))
+    goto out;
+  
+  ret = TRUE;
+  ot_transfer_out_value (out_checksum, &ret_checksum);
+ out:
+  ot_clear_gvariant (&serialized);
+  ot_clear_gvariant (&archive_metadata);
+  g_clear_object (&mem);
+  g_clear_object (&temp_info);
+  g_clear_object (&temp_file);
+  ot_clear_checksum (&ret_checksum);
+  ot_clear_checksum (&content_checksum);
+  return ret;
+}
+
+static gboolean
+impl_stage_raw_file_object_from_archive (OstreeRepo         *self,
+                                         GFileInfo          *file_info,
+                                         GVariant           *xattrs,
+                                         GInputStream       *input,
+                                         const char         *expected_checksum,
+                                         GChecksum         **out_checksum,
+                                         GCancellable       *cancellable,
+                                         GError            **error)
+{
+  gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
   GFile *temp_file = NULL;
-  GFile *tmpname = NULL;
-  GFile *archive_content = NULL;
+  GChecksum *ret_checksum = NULL;
   GVariant *archive_metadata = NULL;
+  GMemoryOutputStream *tmp_archive_meta = NULL;
   GFileInfo *archived_info = NULL;
-  GInputStream *archived_content_input = NULL;
-  GOutputStream *tmp_archive_meta = NULL;
   GVariant *archived_xattrs = NULL;
   char *archived_content_checksum = NULL;
+  GVariant *archived_content = NULL; /* const */
+  const char *archived_content_path;
+  GFile *archived_content_file = NULL;
+  GInputStream *archived_content_input = NULL;
+
+  tmp_archive_meta = (GMemoryOutputStream*)g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
+
+  if (!g_output_stream_splice ((GOutputStream*)tmp_archive_meta, input, 0, cancellable, error))
+    goto out;
+
+  archive_metadata = g_variant_new_from_data (OSTREE_ARCHIVED_FILE_VARIANT_FORMAT,
+                                              g_memory_output_stream_get_data (tmp_archive_meta),
+                                              g_memory_output_stream_get_size (tmp_archive_meta),
+                                              FALSE, NULL, NULL);
+
+  if (!ostree_parse_archived_file_meta (archive_metadata, &archived_info,
+                                        &archived_xattrs, &archived_content_checksum, error))
+    goto out;
+          
+  archived_content = g_hash_table_lookup (priv->pending_transaction_tmpfiles, archived_content_checksum);
+  if (archived_content == NULL)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Archived file references uncommitted content '%s'",
+                   archived_content_checksum);
+      goto out;
+    }
+
+  g_variant_get (archived_content, "(u&s)", &archived_content_path);
+
+  archived_content_file = g_file_get_child (priv->tmp_dir, archived_content_path);
+  archived_content_input = (GInputStream*)g_file_read (archived_content_file, cancellable, error);
+  if (!archived_content_input)
+    goto out;
+
+  if (!ostree_create_temp_file_from_input (priv->tmp_dir,
+                                           "store-tmp-", NULL,
+                                           archived_info, archived_xattrs,
+                                           archived_content_input,
+                                           OSTREE_OBJECT_TYPE_RAW_FILE,
+                                           &temp_file, &ret_checksum,
+                                           cancellable, error))
+    goto out;
+
+  g_hash_table_insert (priv->pending_transaction_tmpfiles,
+                       g_strdup (g_checksum_get_string (ret_checksum)),
+                       g_variant_new ("(us)", OSTREE_OBJECT_TYPE_RAW_FILE,
+                                      ot_gfile_get_basename_cached (temp_file)));
+
+  ret = TRUE;
+ out:
+  g_clear_object (&temp_file);
+  g_clear_object (&tmp_archive_meta);
+  ot_clear_gvariant (&archive_metadata);
+  g_clear_object (&archived_info);
+  ot_clear_gvariant (&archived_xattrs);
+  g_clear_object (&archived_content_input);
+  g_clear_object (&archived_content_file);
+  g_free (archived_content_checksum);
+  return ret;
+}
+
+static gboolean
+stage_object (OstreeRepo         *self,
+              OstreeObjectType    objtype,
+              GFileInfo          *file_info,
+              GVariant           *xattrs,
+              GInputStream       *input,
+              const char         *expected_checksum,
+              GChecksum         **out_checksum,
+              GCancellable       *cancellable,
+              GError            **error)
+{
+  gboolean ret = FALSE;
+  OstreeRepoPrivate *priv = GET_PRIVATE (self);
+  GChecksum *ret_checksum = NULL;
+  GFileInfo *temp_info = NULL;
+  GFile *temp_file = NULL;
   gboolean already_exists;
   const char *actual_checksum;
   
@@ -754,82 +899,65 @@ stage_object (OstreeRepo         *self,
     {
       if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE && priv->mode == OSTREE_REPO_MODE_ARCHIVE)
         {
-          if (!ostree_create_temp_regular_file (priv->tmp_dir,
-                                                "archive-tmp-", NULL,
-                                                &temp_file, &temp_out,
-                                                cancellable, error))
-            goto out;
-          
-          if (!ostree_archive_file_meta (temp_out, file_info, input, xattrs,
-                                         out_checksum ? &ret_checksum : NULL, cancellable, error))
-            goto out;
-          
-          if (!g_output_stream_close (temp_out, cancellable, error))
+          if (!impl_stage_archive_file_object_from_raw (self, file_info, xattrs, input,
+                                                        expected_checksum,
+                                                        out_checksum ? &ret_checksum : NULL,
+                                                        cancellable, error))
             goto out;
         }
       else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META && priv->mode == OSTREE_REPO_MODE_BARE)
         {
-          tmp_archive_meta = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
-
-          archive_metadata = g_variant_new_from_data (OSTREE_ARCHIVED_FILE_VARIANT_FORMAT,
-                                                      g_memory_output_stream_get_data ((GMemoryOutputStream*) tmp_archive_meta),
-                                                      g_memory_output_stream_get_size ((GMemoryOutputStream*) tmp_archive_meta),
-                                                      FALSE, NULL, NULL);
-
-          if (!g_output_stream_splice (input, tmp_archive_meta, cancellable, error))
-            goto out;
-
-          if (!ostree_parse_archived_file_meta (archive_metadata, &archived_info,
-                                                &archived_xattrs, &archived_content_checksum, error))
-            goto out;
-          
-          archived_content = g_hash_table_lookup (priv->pending_transaction_tmpfiles, checksum);
-          if (archived_content == NULL)
-            {
-              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           "Archived file references uncommitted content '%s'",
-                           archived_content_checksum);
-              goto out;
-            }
-
-          if (!ostree_create_temp_file_from_input (priv->tmp_dir,
-                                                   "store-tmp-", NULL,
-                                                   archived_info, archived_xattrs,
-                                                   archived_content,
-                                                   OSTREE_OBJECT_TYPE_RAW_FILE,
-                                                   &temp_file, out_checksum ? &ret_checksum : NULL,
-                                                   cancellable, error))
+          if (!impl_stage_raw_file_object_from_archive (self, file_info, xattrs, input,
+                                                        expected_checksum,
+                                                        out_checksum ? &ret_checksum : NULL,
+                                                        cancellable, error))
             goto out;
         }
-      else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META && priv->mode == OSTREE_REPO_MODE_ARCHIVE)
+      else 
         {
-          if (!ostree_create_temp_file_from_input (priv->tmp_dir,
-                                                   "store-tmp-", NULL,
-                                                   file_info, xattrs, input,
-                                                   objtype,
-                                                   &temp_file, out_checksum ? &ret_checksum : NULL,
-                                                   cancellable, error))
+          if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT && priv->mode == OSTREE_REPO_MODE_ARCHIVE)
+            {
+              temp_info = dup_file_info_owned_by_me (file_info);
+              if (!ostree_create_temp_file_from_input (priv->tmp_dir,
+                                                       "store-tmp-", NULL,
+                                                       temp_info, NULL, input,
+                                                       objtype,
+                                                       &temp_file,
+                                                       out_checksum ? &ret_checksum : NULL,
+                                                       cancellable, error))
             goto out;
-        }
+            }
+          else
+            {
+              if (!ostree_create_temp_file_from_input (priv->tmp_dir,
+                                                       "store-tmp-", NULL,
+                                                       file_info, xattrs, input,
+                                                       objtype,
+                                                       &temp_file,
+                                                       out_checksum ? &ret_checksum : NULL,
+                                                       cancellable, error))
+                goto out;
+            }
 
-      if (!ret_checksum)
-        actual_checksum = expected_checksum;
-      else
-        {
-          actual_checksum = g_checksum_get_string (ret_checksum);
-          if (strcmp (actual_checksum, expected_checksum) != 0)
+          if (!ret_checksum)
+            actual_checksum = expected_checksum;
+          else
             {
-              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                           "Corrupted object %s (actual checksum is %s)",
-                           expected_checksum, actual_checksum);
-              goto out;
+              actual_checksum = g_checksum_get_string (ret_checksum);
+              if (strcmp (actual_checksum, expected_checksum) != 0)
+                {
+                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "Corrupted object %s (actual checksum is %s)",
+                               expected_checksum, actual_checksum);
+                  goto out;
+                }
             }
+          
+          g_hash_table_insert (priv->pending_transaction_tmpfiles,
+                               g_strdup (actual_checksum),
+                               g_variant_new ("(us)", objtype, ot_gfile_get_basename_cached (temp_file)));
+          g_clear_object (&temp_file);
         }
-      
-      g_hash_table_insert (priv->pending_transaction_tmpfiles,
-                           g_strdup (actual_checksum),
-                           g_variant_new ("(us)", objtype, ot_gfile_get_basename_cached (temp_file)));
-      g_clear_object (&temp_file);
     }
   
   ret = TRUE;
@@ -838,16 +966,7 @@ stage_object (OstreeRepo         *self,
   if (temp_file)
     (void) unlink (ot_gfile_get_path_cached (temp_file));
   g_clear_object (&temp_file);
-  g_clear_object (&dest_path);
-  g_clear_object (&temp_out);
-  g_clear_object (&archived_info);
-  if (archived_content)
-    (void) unlink (ot_gfile_get_path_cached (archived_content));
-  g_clear_object (&archived_content);
-  g_clear_object (&archived_content_input);
-  ot_clear_gvariant (&archived_xattrs);
-  ot_clear_gvariant (&archive_metadata);
-  g_free (archived_content_checksum);
+  g_clear_object (&temp_info);
   ot_clear_checksum (&ret_checksum);
   return ret;
 }
@@ -910,19 +1029,21 @@ ostree_repo_commit_transaction (OstreeRepo     *self,
 {
   gboolean ret = FALSE;
   OstreeRepoPrivate *priv = GET_PRIVATE (self);
-  GSList *iter;
   GFile *f = NULL;
+  GHashTableIter iter;
+  gpointer key, value;
 
   g_return_val_if_fail (priv->in_transaction == TRUE, FALSE);
 
   priv->in_transaction = FALSE;
 
-  for (iter = priv->pending_commit_tmpfiles; iter; iter = iter->next)
+  g_hash_table_iter_init (&iter, priv->pending_transaction_tmpfiles);
+  while (g_hash_table_iter_next (&iter, &key, &value))
     {
-      GVariant *data = iter->data;
+      const char *checksum = key;
+      GVariant *data = value;
       guint32 objtype;
       const char *filename;
-      const char *checksum;
 
       g_variant_get (data, "(u&s&s)", &objtype, &filename, &checksum);
 
@@ -935,96 +1056,11 @@ ostree_repo_commit_transaction (OstreeRepo     *self,
 
   ret = TRUE;
  out:
-  g_ptr_array_set_size (priv->pending_commit_tmpfiles, 0);
+  g_hash_table_remove_all (priv->pending_transaction_tmpfiles);
   g_clear_object (&f);
   return ret;
 }
 
-
-static gboolean
-stage_and_commit_from_input (OstreeRepo        *self,
-                             OstreeObjectType   objtype,
-                             GFileInfo         *file_info,
-                             GVariant          *xattrs,
-                             GInputStream      *input,
-                             const char        *expected_checksum,
-                             GChecksum        **out_checksum,
-                             GCancellable      *cancellable,
-                             GError           **error)
-{
-  gboolean ret = FALSE;
-  GFile *tmp_file = NULL;
-  GChecksum *ret_checksum = NULL;
-  gboolean did_exist;
-
-  if (!ostree_repo_stage_object (self, objtype,
-                                 file_info, xattrs, input,
-                                 expected_checksum,
-                                 &tmp_file, out_checksum ? &ret_checksum : NULL,
-                                 cancellable, error))
-    goto out;
-
-  if (!commit_staged_file (self, tmp_file, g_checksum_get_string (ret_checksum),
-                           objtype, &did_exist, cancellable, error))
-    goto out;
-  g_clear_object (&tmp_file);
-
-  ret = TRUE;
-  ot_transfer_out_value(out_checksum, &ret_checksum);
- out:
-  if (tmp_file)
-    (void) unlink (ot_gfile_get_path_cached (tmp_file));
-  g_clear_object (&tmp_file);
-  ot_clear_checksum (&ret_checksum);
-  return ret;
-}
-
-static gboolean
-commit_raw_file (OstreeRepo      *self,
-                 GFile           *file,
-                 const char      *expected_checksum,
-                 GChecksum      **out_checksum,
-                 GCancellable    *cancellable,
-                 GError         **error)
-{
-  gboolean ret = FALSE;
-  GFileInfo *file_info = NULL;
-  GVariant *xattrs = NULL;
-  GInputStream *input = NULL;
-  GFile *tmp_file = NULL;
-  GChecksum *ret_checksum = NULL;
-  gboolean did_exist;
-  OstreeObjectType objtype;
-
-  objtype = get_objtype_for_repo_file (self);
-
-  if (!stage_and_commit_from_input (self, objtype,
-                                    file_info, xattrs, input,
-                                    &tmp_file, out_checksum ? &ret_checksum : NULL,
-                                    cancellable, error))
-    goto out;
-
-  if (expected_checksum == NULL)
-    expected_checksum = g_checksum_get_string (ret_checksum);
-
-  if (!commit_staged_file (self, tmp_file, expected_checksum, objtype, 
-                           &did_exist, cancellable, error))
-    goto out;
-  g_clear_object (&tmp_file);
-
-  ret = TRUE;
-  ot_transfer_out_value(out_checksum, &ret_checksum);
- out:
-  if (tmp_file)
-    (void) unlink (ot_gfile_get_path_cached (tmp_file));
-  g_clear_object (&tmp_file);
-  g_clear_object (&file_info);
-  ot_clear_gvariant (&xattrs);
-  g_clear_object (&input);
-  ot_clear_checksum (&ret_checksum);
-  return ret;
-}
-
 static gboolean
 stage_gvariant_object (OstreeRepo         *self,
                        OstreeObjectType    type,
@@ -1152,7 +1188,7 @@ ostree_repo_store_object_trusted (OstreeRepo   *self,
 {
   return stage_object (self, objtype,
                        file_info, xattrs, input,
-                       checksum, NULL, cancellable, error));
+                       checksum, NULL, cancellable, error);
 }
 
 gboolean
@@ -1218,16 +1254,17 @@ ostree_repo_write_ref (OstreeRepo  *self,
 }
 
 static gboolean
-do_commit (OstreeRepo *self,
-             const char   *branch,
-             const char   *parent,
-             const char   *subject,
-             const char   *body,
-             GVariant     *metadata,
-             const char   *root_contents_checksum,
-             const char   *root_metadata_checksum,
-             GChecksum   **out_commit,
-             GError      **error)
+do_commit_write_ref (OstreeRepo *self,
+                     const char   *branch,
+                     const char   *parent,
+                     const char   *subject,
+                     const char   *body,
+                     GVariant     *metadata,
+                     const char   *root_contents_checksum,
+                     const char   *root_metadata_checksum,
+                     GChecksum   **out_commit,
+                     GCancellable *cancellable,
+                     GError      **error)
 {
   gboolean ret = FALSE;
   GChecksum *ret_commit = NULL;
@@ -1370,7 +1407,8 @@ stage_directory_recurse (OstreeRepo           *self,
   if (!xattrs)
     goto out;
 
-  if (!import_directory_meta (self, child_info, xattrs, &ret_metadata_checksum, cancellable, error))
+  if (!stage_directory_meta (self, child_info, xattrs, &ret_metadata_checksum,
+                             cancellable, error))
     goto out;
   
   g_clear_object (&child_info);
@@ -1450,9 +1488,9 @@ stage_directory_recurse (OstreeRepo           *self,
                                                      dir_contents_checksums,
                                                      dir_metadata_checksums);
 
-  if (!import_gvariant_object (self, OSTREE_OBJECT_TYPE_DIR_TREE,
-                               serialized_tree, &ret_contents_checksum,
-                               cancellable, error))
+  if (!stage_gvariant_object (self, OSTREE_OBJECT_TYPE_DIR_TREE,
+                              serialized_tree, &ret_contents_checksum,
+                              cancellable, error))
     goto out;
 
   ot_transfer_out_value(out_metadata_checksum, &ret_metadata_checksum);
@@ -1502,19 +1540,22 @@ ostree_repo_commit_directory (OstreeRepo *self,
   g_return_val_if_fail (subject != NULL, FALSE);
   g_return_val_if_fail (metadata == NULL || g_variant_is_of_type (metadata, G_VARIANT_TYPE ("a{sv}")), FALSE);
 
+  if (!ostree_repo_prepare_transaction (self, cancellable, error))
+    goto out;
+
   if (parent == NULL)
     parent = branch;
 
   if (!ostree_repo_resolve_rev (self, parent, TRUE, &current_head, error))
     goto out;
 
-  if (!import_directory_recurse (self, dir, dir, &root_contents_checksum, &root_metadata_checksum, cancellable, error))
+  if (!stage_directory_recurse (self, dir, dir, &root_contents_checksum, &root_metadata_checksum, cancellable, error))
     goto out;
 
-  if (!import_commit (self, branch, current_head, subject, body, metadata,
-                      g_checksum_get_string (root_contents_checksum),
-                      g_checksum_get_string (root_metadata_checksum),
-                      &ret_commit_checksum, error))
+  if (!do_commit_write_ref (self, branch, current_head, subject, body, metadata,
+                            g_checksum_get_string (root_contents_checksum),
+                            g_checksum_get_string (root_metadata_checksum),
+                            &ret_commit_checksum, cancellable, error))
     goto out;
   
   ret = TRUE;
@@ -1588,9 +1629,10 @@ 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_and_commit_from_input (self, get_objtype_for_repo_file (self),
-                                    file_info, NULL, archive_stream,
-                                    &ret_checksum, cancellable, error))
+  if (!stage_object (self, get_objtype_for_repo_file (self),
+                     file_info, NULL, archive_stream,
+                     NULL, &ret_checksum,
+                     cancellable, error))
     goto out;
 
   ret = TRUE;
@@ -1708,9 +1750,9 @@ file_tree_import_recurse (OstreeRepo           *self,
                                                      dir_contents_checksums,
                                                      dir_metadata_checksums);
       
-  if (!import_gvariant_object (self, OSTREE_OBJECT_TYPE_DIR_TREE,
-                               serialized_tree, &ret_contents_checksum_obj,
-                               cancellable, error))
+  if (!stage_gvariant_object (self, OSTREE_OBJECT_TYPE_DIR_TREE,
+                              serialized_tree, &ret_contents_checksum_obj,
+                              cancellable, error))
     goto out;
   ret_contents_checksum = g_strdup (g_checksum_get_string (ret_contents_checksum_obj));
 
@@ -1869,7 +1911,7 @@ import_libarchive (OstreeRepo           *self,
             {
             }
 
-          if (!import_directory_meta (self, file_info, NULL, &tmp_checksum, cancellable, error))
+          if (!stage_directory_meta (self, file_info, NULL, &tmp_checksum, cancellable, error))
             goto out;
 
           if (parent == NULL)
@@ -1976,6 +2018,9 @@ ostree_repo_commit_tarfile (OstreeRepo *self,
   g_return_val_if_fail (subject != NULL, FALSE);
   g_return_val_if_fail (metadata == NULL || g_variant_is_of_type (metadata, G_VARIANT_TYPE ("a{sv}")), FALSE);
 
+  if (!ostree_repo_prepare_transaction (self, cancellable, error))
+    goto out;
+
   if (parent == NULL)
     parent = branch;
 
@@ -1985,8 +2030,9 @@ ostree_repo_commit_tarfile (OstreeRepo *self,
   if (!import_libarchive (self, path, &root_contents_checksum, &root_metadata_checksum, cancellable, error))
     goto out;
 
-  if (!import_commit (self, branch, current_head, subject, body, metadata,
-                      root_contents_checksum, root_metadata_checksum, &ret_commit_checksum, error))
+  if (!do_commit_write_ref (self, branch, current_head, subject, body, metadata,
+                            root_contents_checksum, root_metadata_checksum, &ret_commit_checksum,
+                            cancellable, error))
     goto out;
   
   ret = TRUE;
@@ -2044,8 +2090,10 @@ iter_object_dir (OstreeRepo             *self,
       
       if (g_str_has_suffix (name, ".file"))
         objtype = OSTREE_OBJECT_TYPE_RAW_FILE;
-      else if (g_str_has_suffix (name, ".archive"))
-        objtype = OSTREE_OBJECT_TYPE_ARCHIVED_FILE;
+      else if (g_str_has_suffix (name, ".archive-meta"))
+        objtype = OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT;
+      else if (g_str_has_suffix (name, ".archive-content"))
+        objtype = OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META;
       else if (g_str_has_suffix (name, ".dirtree"))
         objtype = OSTREE_OBJECT_TYPE_DIR_TREE;
       else if (g_str_has_suffix (name, ".dirmeta"))
@@ -2195,13 +2243,16 @@ checkout_tree (OstreeRepo               *self,
   OstreeRepoPrivate *priv = GET_PRIVATE (self);
   gboolean ret = FALSE;
   GError *temp_error = NULL;
+  GVariant *archive_metadata = NULL;
   GFileInfo *file_info = NULL;
-  GInputStream *packed_input = NULL;
+  char *archive_content_checksum = NULL;
   GVariant *xattrs = NULL;
   GFileEnumerator *dir_enum = NULL;
   GFile *src_child = NULL;
   GFile *dest_path = NULL;
   GFile *object_path = NULL;
+  GFile *content_object_path = NULL;
+  GInputStream *content_input = NULL;
 
   if (!_ostree_repo_file_get_xattrs (source, &xattrs, NULL, error))
     goto out;
@@ -2228,7 +2279,10 @@ checkout_tree (OstreeRepo               *self,
       name = g_file_info_get_attribute_byte_string (file_info, "standard::name"); 
       type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
 
+      g_clear_object (&dest_path);
       dest_path = g_file_get_child (destination, name);
+
+      g_clear_object (&src_child);
       src_child = g_file_get_child ((GFile*)source, name);
 
       if (type == G_FILE_TYPE_DIRECTORY)
@@ -2240,16 +2294,30 @@ checkout_tree (OstreeRepo               *self,
         {
           const char *checksum = _ostree_repo_file_get_checksum ((OstreeRepoFile*)src_child);
 
+          g_clear_object (&object_path);
           object_path = ostree_repo_get_object_path (self, checksum, get_objtype_for_repo_file (self));
 
           if (priv->mode == OSTREE_REPO_MODE_ARCHIVE)
             {
-              if (!ostree_parse_archived_file (object_path, NULL, &xattrs, &packed_input,
-                                               cancellable, error))
+              if (!ot_util_variant_map (object_path, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT, &archive_metadata, error))
+                goto out;
+              
+              g_free (archive_content_checksum);
+              archive_content_checksum = NULL;
+              ot_clear_gvariant (&xattrs);
+              if (!ostree_parse_archived_file_meta (archive_metadata, NULL, &xattrs, &archive_content_checksum, error))
+                goto out;
+              
+              g_clear_object (&content_object_path);
+              content_object_path = ostree_repo_get_object_path (self, archive_content_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
+
+              g_clear_object (&content_input);
+              content_input = (GInputStream*)g_file_read (content_object_path, cancellable, error);
+              if (!content_input)
                 goto out;
 
               if (!checkout_file_from_input (dest_path, mode, file_info, xattrs, 
-                                             packed_input, cancellable, error))
+                                             content_input, cancellable, error))
                 goto out;
             }
           else
@@ -2262,12 +2330,7 @@ checkout_tree (OstreeRepo               *self,
             }
         }
 
-      g_clear_object (&object_path);
-      g_clear_object (&dest_path);
       g_clear_object (&file_info);
-      g_clear_object (&src_child);
-      g_clear_object (&packed_input);
-      ot_clear_gvariant (&xattrs);
     }
   if (file_info == NULL && temp_error != NULL)
     {
@@ -2279,11 +2342,14 @@ checkout_tree (OstreeRepo               *self,
  out:
   g_clear_object (&dir_enum);
   g_clear_object (&file_info);
-  g_clear_object (&packed_input);
   ot_clear_gvariant (&xattrs);
+  ot_clear_gvariant (&archive_metadata);
   g_clear_object (&src_child);
   g_clear_object (&object_path);
+  g_clear_object (&content_object_path);
+  g_clear_object (&content_input);
   g_clear_object (&dest_path);
+  g_free (archive_content_checksum);
   g_free (dest_path);
   return ret;
 }
diff --git a/src/libostree/ostree-repo.h b/src/libostree/ostree-repo.h
index 69c1d00..03f687b 100644
--- a/src/libostree/ostree-repo.h
+++ b/src/libostree/ostree-repo.h
@@ -90,6 +90,7 @@ gboolean      ostree_repo_commit_transaction (OstreeRepo     *self,
 gboolean      ostree_repo_has_object (OstreeRepo           *self,
                                       OstreeObjectType      objtype,
                                       const char           *checksum,
+                                      gboolean             *out_have_object,
                                       GCancellable         *cancellable,
                                       GError             **error);
 
@@ -99,7 +100,7 @@ gboolean      ostree_repo_store_object (OstreeRepo       *self,
                                         GFileInfo        *file_info,
                                         GVariant         *xattrs,
                                         GInputStream     *content,
-                                        GCancellable *cancellable,
+                                        GCancellable     *cancellable,
                                         GError          **error);
 
 gboolean      ostree_repo_store_object_trusted (OstreeRepo   *self,
diff --git a/src/ostree/ostree-pull.c b/src/ostree/ostree-pull.c
index 62fae98..38f76d8 100644
--- a/src/ostree/ostree-pull.c
+++ b/src/ostree/ostree-pull.c
@@ -126,6 +126,8 @@ store_object (OstreeRepo  *repo,
   char *objpath = NULL;
   char *relpath = NULL;
   SoupURI *obj_uri = NULL;
+  GFileInfo *file_info = NULL;
+  GInputStream *input = NULL;
   gboolean exists;
 
   g_assert (objtype != OSTREE_OBJECT_TYPE_RAW_FILE);
@@ -143,9 +145,18 @@ store_object (OstreeRepo  *repo,
       if (!fetch_uri (repo, soup, obj_uri, &filename, error))
         goto out;
       
-      ot_gfile_new_for_path (filename);
+      f = ot_gfile_new_for_path (filename);
+
+      file_info = g_file_query_info (f, OSTREE_GIO_FAST_QUERYINFO,
+                                     G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, error);
+      if (!file_info)
+        goto out;
+
+      input = (GInputStream*)g_file_read (f, NULL, error);
+      if (!input)
+        goto out;
   
-      if (!ostree_repo_store_object (repo, objtype, checksum, NULL, error))
+      if (!ostree_repo_store_object (repo, objtype, checksum, file_info, NULL, input, NULL, error))
         goto out;
 
       *did_exist = FALSE;
@@ -160,6 +171,8 @@ store_object (OstreeRepo  *repo,
   if (filename)
     (void) unlink (filename);
   g_clear_object (&f);
+  g_clear_object (&file_info);
+  g_clear_object (&input);
   g_free (filename);
   g_free (objpath);
   g_free (relpath);
@@ -202,7 +215,10 @@ store_tree_recurse (OstreeRepo   *repo,
 
           g_variant_get_child (files_variant, i, "(&s&s)", &filename, &checksum);
 
-          if (!store_object (repo, soup, base_uri, checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE, &did_exist, error))
+          if (!store_object (repo, soup, base_uri, checksum,
+                             OSTREE_OBJECT_TYPE_ARCHIVED_FILE_META,
+                             &did_exist,
+                             error))
             goto out;
         }
       
diff --git a/src/ostree/ot-builtin-fsck.c b/src/ostree/ot-builtin-fsck.c
index 033a8ec..229586c 100644
--- a/src/ostree/ot-builtin-fsck.c
+++ b/src/ostree/ot-builtin-fsck.c
@@ -35,6 +35,7 @@ static GOptionEntry options[] = {
 };
 
 typedef struct {
+  OstreeRepo *repo;
   guint n_objects;
   gboolean had_error;
 } OtFsckData;
@@ -48,13 +49,25 @@ checksum_archived_file (OtFsckData   *data,
   gboolean ret = FALSE;
   GChecksum *ret_checksum = NULL;
   GInputStream *in = NULL;
+  GVariant *archive_metadata = NULL;
   GVariant *xattrs = NULL;
+  char *content_checksum = NULL;
+  GFile *content_path = NULL;
+  GInputStream *content_input = NULL;
   GFileInfo *file_info = NULL;
   char buf[8192];
   gsize bytes_read;
   guint32 mode;
 
-  if (!ostree_parse_archived_file (file, &file_info, &xattrs, &in, NULL, error))
+  if (!ot_util_variant_map (file, OSTREE_ARCHIVED_FILE_VARIANT_FORMAT, &archive_metadata, error))
+    goto out;
+
+  if (!ostree_parse_archived_file_meta (archive_metadata, &file_info, &xattrs, &content_checksum, error))
+    goto out;
+
+  content_path = ostree_repo_get_object_path (data->repo, content_checksum, OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT);
+  content_input = (GInputStream*)g_file_read (content_path, NULL, error);
+  if (!content_input)
     goto out;
 
   ret_checksum = g_checksum_new (G_CHECKSUM_SHA256);
@@ -100,6 +113,10 @@ checksum_archived_file (OtFsckData   *data,
   g_clear_object (&in);
   g_clear_object (&file_info);
   ot_clear_gvariant (&xattrs);
+  ot_clear_gvariant (&archive_metadata);
+  g_free (content_checksum);
+  g_clear_object (&content_path);
+  g_clear_object (&content_input);
   return ret;
 }
 
@@ -173,13 +190,14 @@ ostree_builtin_fsck (int argc, char **argv, const char *repo_path, GError **erro
   if (!g_option_context_parse (context, &argc, &argv, error))
     goto out;
 
-  data.n_objects = 0;
-  data.had_error = FALSE;
-
   repo = ostree_repo_new (repo_path);
   if (!ostree_repo_check (repo, error))
     goto out;
 
+  data.repo = repo;
+  data.n_objects = 0;
+  data.had_error = FALSE;
+
   if (!ostree_repo_iter_objects (repo, object_iter_callback, &data, error))
     goto out;
 
diff --git a/src/ostree/ot-builtin-local-clone.c b/src/ostree/ot-builtin-local-clone.c
index 132821d..b730acf 100644
--- a/src/ostree/ot-builtin-local-clone.c
+++ b/src/ostree/ot-builtin-local-clone.c
@@ -95,29 +95,28 @@ object_iter_callback (OstreeRepo   *repo,
 {
   OtLocalCloneData *data = user_data;
   GError *error = NULL;
-  gboolean did_exist;
+  GVariant *xattrs = NULL;
+  GInputStream *input = NULL;
 
-  if (ostree_repo_get_mode (data->src_repo) == OSTREE_REPO_MODE_ARCHIVE)
-    {
-      if (!ostree_repo_store_archived_file (data->dest_repo, checksum,
-                                            ot_gfile_get_path_cached (objfile),
-                                            objtype,
-                                            &did_exist,
-                                            &error))
-        goto out;
-    }
-  else
+  if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE)
+    xattrs = ostree_get_xattrs_for_file (objfile, &error);
+  
+  if (objtype == OSTREE_OBJECT_TYPE_RAW_FILE
+      || objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE_CONTENT)
     {
-      if (!ostree_repo_store_object_trusted (data->dest_repo,
-                                             objfile, 
-                                             checksum,
-                                             objtype,
-                                             NULL,
-                                             &error))
+      input = (GInputStream*)g_file_read (objfile, NULL, &error);
+      if (!input)
         goto out;
     }
 
+  if (!ostree_repo_store_object_trusted (data->dest_repo, objtype, checksum,
+                                         file_info, xattrs, input,
+                                         NULL, &error))
+    goto out;
+
  out:
+  ot_clear_gvariant (&xattrs);
+  g_clear_object (&input);
   if (error != NULL)
     {
       g_printerr ("%s\n", error->message);
diff --git a/src/ostree/ot-builtin-log.c b/src/ostree/ot-builtin-log.c
index 9fa7b02..9f55fb3 100644
--- a/src/ostree/ot-builtin-log.c
+++ b/src/ostree/ot-builtin-log.c
@@ -69,7 +69,6 @@ ostree_builtin_log (int argc, char **argv, const char *repo_path, GError **error
 
   while (TRUE)
     {
-      OstreeObjectType type;
       char *formatted = NULL;
       guint32 version;
       const char *parent;
diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c
index ab5b5c7..c25dc8c 100644
--- a/src/ostree/ot-builtin-show.c
+++ b/src/ostree/ot-builtin-show.c
@@ -124,7 +124,7 @@ show_repo_meta (OstreeRepo  *repo,
             g_print ("%s", buf);
           } while (bytes_read > 0);
         }
-      else if (objtype == OSTREE_OBJECT_TYPE_ARCHIVED_FILE)
+      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");



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