[ostree] core: Move pack file parsing into core, add ostree_create_file_from_input() API



commit 7fc625c967ddbbe35a10da358a57a925b975c989
Author: Colin Walters <walters verbum org>
Date:   Fri Dec 2 10:11:09 2011 -0500

    core: Move pack file parsing into core, add ostree_create_file_from_input() API
    
    This moves us closer to consistently passing around a triple of:
      (GFileInfo *info, GVariant *xattrs, GInputStream *content)
    Which will help the libarchive work.

 src/libostree/ostree-core.c      |  227 ++++++++++++++++++++++++++-----------
 src/libostree/ostree-core.h      |   17 ++-
 src/libostree/ostree-repo-file.c |  230 ++++++--------------------------------
 src/libotutil/ot-gio-utils.c     |   13 ++
 src/libotutil/ot-gio-utils.h     |    2 +
 src/ostree/ot-builtin-show.c     |   34 +------
 6 files changed, 221 insertions(+), 302 deletions(-)
---
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 91cf299..da84fec 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -673,7 +673,7 @@ ostree_pack_file (GOutputStream     *output,
   if (!finfo)
     goto out;
 
-  if (S_ISREG (g_file_info_get_attribute_uint32 (finfo, "unix::mode")))
+  if (g_file_info_get_file_type (finfo) == G_FILE_TYPE_REGULAR)
     {
       instream = (GInputStream*)g_file_read (file, cancellable, error);
       if (!instream)
@@ -735,23 +735,28 @@ unpack_meta (GFile        *file,
 
 gboolean
 ostree_parse_packed_file (GFile            *file,
-                          GVariant    **out_metadata,
-                          GInputStream **out_content,
-                          GCancellable *cancellable,
-                          GError      **error)
+                          GFileInfo       **out_file_info,
+                          GVariant        **out_xattrs,
+                          GInputStream    **out_content,
+                          GCancellable     *cancellable,
+                          GError          **error)
 {
   gboolean ret = FALSE;
   char *metadata_buf = NULL;
-  GVariant *ret_metadata = NULL;
-  GFileInputStream *in = NULL;
+  GVariant *metadata = NULL;
+  GFileInfo *ret_file_info = NULL;
+  GVariant *ret_xattrs = NULL;
+  GInputStream *in = NULL;
   guint32 metadata_len;
+  guint32 version, uid, gid, mode;
+  guint64 content_len;
   gsize bytes_read;
 
-  in = g_file_read (file, NULL, error);
+  in = (GInputStream*)g_file_read (file, NULL, error);
   if (!in)
     goto out;
       
-  if (!g_input_stream_read_all ((GInputStream*)in, &metadata_len, 4, &bytes_read, NULL, error))
+  if (!g_input_stream_read_all (in, &metadata_len, 4, &bytes_read, NULL, error))
     goto out;
   if (bytes_read != 4)
     {
@@ -770,7 +775,7 @@ ostree_parse_packed_file (GFile            *file,
     }
   metadata_buf = g_malloc (metadata_len);
 
-  if (!g_input_stream_read_all ((GInputStream*)in, metadata_buf, metadata_len, &bytes_read, NULL, error))
+  if (!g_input_stream_read_all (in, metadata_buf, metadata_len, &bytes_read, NULL, error))
     goto out;
   if (bytes_read != metadata_len)
     {
@@ -779,60 +784,127 @@ ostree_parse_packed_file (GFile            *file,
       goto out;
     }
 
-  ret_metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
-                                          metadata_buf, metadata_len, FALSE,
-                                          (GDestroyNotify)g_free,
-                                          metadata_buf);
+  metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
+                                      metadata_buf, metadata_len, FALSE,
+                                      (GDestroyNotify)g_free,
+                                      metadata_buf);
   metadata_buf = NULL;
 
+  g_variant_get (metadata, "(uuuu a(ayay)t)",
+                 &version, &uid, &gid, &mode,
+                 &ret_xattrs, &content_len);
+  uid = GUINT32_FROM_BE (uid);
+  gid = GUINT32_FROM_BE (gid);
+  mode = GUINT32_FROM_BE (mode);
+  content_len = GUINT64_FROM_BE (content_len);
+
+  ret_file_info = g_file_info_new ();
+  g_file_info_set_attribute_uint32 (ret_file_info, "standard::type", ot_gfile_type_for_mode (mode));
+  g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", S_ISLNK (mode));
+  g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", uid);
+  g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", gid);
+  g_file_info_set_attribute_uint32 (ret_file_info, "unix::mode", mode);
+  g_file_info_set_attribute_uint64 (ret_file_info, "standard::size", content_len);
+
+  if (S_ISREG (mode))
+    {
+      g_file_info_set_attribute_uint64 (ret_file_info, "standard::size", content_len);
+    }
+  else if (S_ISLNK (mode))
+    {
+      char target[PATH_MAX+1];
+      if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, cancellable, error))
+        goto out;
+      target[bytes_read] = '\0';
+
+      g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", TRUE);
+      g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", target);
+
+      g_input_stream_close (in, cancellable, error);
+      g_clear_object (&in);
+    }
+  else if (S_ISCHR (mode) || S_ISBLK (mode))
+    {
+      guint32 dev;
+
+      if (!g_input_stream_read_all (in, &dev, 4, &bytes_read, NULL, error))
+        goto out;
+      if (bytes_read != 4)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                       "Corrupted packfile; too short while reading device id");
+          goto out;
+        }
+      dev = GUINT32_FROM_BE (dev);
+      g_file_info_set_attribute_uint32 (ret_file_info, "unix::rdev", dev);
+      g_input_stream_close (in, cancellable, error);
+      g_clear_object (&in);
+    }
+  else if (S_ISFIFO (mode))
+    {
+      g_input_stream_close (in, cancellable, error);
+      g_clear_object (&in);
+    }
+  else
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Corrupted packfile; invalid mode %u", mode);
+      goto out;
+    }
+
   ret = TRUE;
-  *out_metadata = ret_metadata;
-  ret_metadata = NULL;
-  *out_content = (GInputStream*)in;
-  in = NULL;
+  if (out_file_info)
+    {
+      *out_file_info = ret_file_info;
+      ret_file_info = NULL;
+    }
+  if (out_xattrs)
+    {
+      *out_xattrs = ret_xattrs;
+      ret_xattrs = NULL;
+    }
+  if (out_content)
+    {
+      *out_content = (GInputStream*)in;
+      in = NULL;
+    }
  out:
+  g_clear_object (&ret_file_info);
+  ot_clear_gvariant (&ret_xattrs);
   g_clear_object (&in);
-  ot_clear_gvariant (&ret_metadata);
+  ot_clear_gvariant (&metadata);
   return ret;
 }
 
-static gboolean
-unpack_file (GFile        *file,
-             GFile        *dest_file,    
-             GChecksum   **out_checksum,
-             GError      **error)
+gboolean
+ostree_create_file_from_input (GFile            *dest_file,
+                               GFileInfo        *finfo,
+                               GVariant         *xattrs,
+                               GInputStream     *input,
+                               GChecksum       **out_checksum,
+                               GCancellable     *cancellable,
+                               GError          **error)
 {
+  const char *dest_path;
   gboolean ret = FALSE;
-  GVariant *metadata = NULL;
-  GVariant *xattrs = NULL;
-  GInputStream *in = NULL;
   GFileOutputStream *out = NULL;
+  guint32 uid, gid, mode;
   GChecksum *ret_checksum = NULL;
-  guint32 version, uid, gid, mode;
-  guint64 content_len;
-  gsize bytes_read;
-  const char *dest_path;
 
+  uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
+  gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
+  mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode");
   dest_path = ot_gfile_get_path_cached (dest_file);
 
-  if (!ostree_parse_packed_file (file, &metadata, &in, NULL, error))
-    goto out;
-
-  g_variant_get (metadata, "(uuuu a(ayay)t)",
-                 &version, &uid, &gid, &mode,
-                 &xattrs, &content_len);
-  uid = GUINT32_FROM_BE (uid);
-  gid = GUINT32_FROM_BE (gid);
-  mode = GUINT32_FROM_BE (mode);
-  content_len = GUINT64_FROM_BE (content_len);
-
   if (S_ISREG (mode))
     {
       out = g_file_replace (dest_file, NULL, FALSE, 0, NULL, error);
       if (!out)
         goto out;
 
-      if (!ot_gio_splice_and_checksum ((GOutputStream*)out, in, out_checksum ? &ret_checksum : NULL, NULL, error))
+      if (!ot_gio_splice_and_checksum ((GOutputStream*)out, input,
+                                       out_checksum ? &ret_checksum : NULL,
+                                       cancellable, error))
         goto out;
 
       if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
@@ -840,13 +912,9 @@ unpack_file (GFile        *file,
     }
   else if (S_ISLNK (mode))
     {
-      char target[PATH_MAX+1];
-
-      if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, NULL, error))
-        goto out;
-      target[bytes_read] = '\0';
+      const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target");
       if (ret_checksum)
-        g_checksum_update (ret_checksum, (guint8*)target, bytes_read);
+        g_checksum_update (ret_checksum, (guint8*)target, strlen (target));
       if (symlink (target, dest_path) < 0)
         {
           ot_util_set_error_from_errno (error, errno);
@@ -855,17 +923,7 @@ unpack_file (GFile        *file,
     }
   else if (S_ISCHR (mode) || S_ISBLK (mode))
     {
-      guint32 dev;
-
-      if (!g_input_stream_read_all (in, &dev, 4, &bytes_read, NULL, error))
-        goto out;
-      if (bytes_read != 4)
-        {
-          g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                       "Corrupted packfile; too short while reading device id");
-          goto out;
-        }
-      dev = GUINT32_FROM_BE (dev);
+      guint32 dev = g_file_info_get_attribute_uint32 (finfo, "unix::rdev");
       if (ret_checksum)
         g_checksum_update (ret_checksum, (guint8*)&dev, 4);
       if (mknod (dest_path, mode, dev) < 0)
@@ -885,7 +943,7 @@ unpack_file (GFile        *file,
   else
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Corrupted packfile; invalid mode %u", mode);
+                   "Invalid mode %u", mode);
       goto out;
     }
 
@@ -904,7 +962,7 @@ unpack_file (GFile        *file,
         }
     }
 
-  if (!ostree_set_xattrs (dest_file, xattrs, NULL, error))
+  if (!ostree_set_xattrs (dest_file, xattrs, cancellable, error))
     goto out;
 
   if (ret_checksum)
@@ -915,16 +973,51 @@ unpack_file (GFile        *file,
 
   ret = TRUE;
   if (out_checksum)
-    *out_checksum = ret_checksum;
-  ret_checksum = NULL;
+    {
+      *out_checksum = ret_checksum;
+      ret_checksum = NULL;
+    }
  out:
   if (!ret)
     (void) unlink (dest_path);
   ot_clear_checksum (&ret_checksum);
-  g_clear_object (&in);
   g_clear_object (&out);
-  ot_clear_gvariant (&metadata);
+  return ret;
+}
+
+static gboolean
+unpack_file (GFile        *file,
+             GFile        *dest_file,    
+             GChecksum   **out_checksum,
+             GCancellable *cancellable,
+             GError      **error)
+{
+  gboolean ret = FALSE;
+  GFileInfo *finfo;
+  GVariant *metadata = NULL;
+  GVariant *xattrs = NULL;
+  GInputStream *in = NULL;
+  GChecksum *ret_checksum = NULL;
+
+  if (!ostree_parse_packed_file (file, &finfo, &xattrs, &in, cancellable, error))
+    goto out;
+
+  if (!ostree_create_file_from_input (dest_file, finfo, xattrs, in,
+                                      out_checksum ? &ret_checksum : NULL,
+                                      cancellable, error))
+    goto out;
+
+  ret = TRUE;
+  if (out_checksum)
+    {
+      *out_checksum = ret_checksum;
+      ret_checksum = NULL;
+    }
+ out:
+  g_clear_object (&finfo);
   ot_clear_gvariant (&xattrs);
+  ot_clear_gvariant (&metadata);
+  ot_clear_checksum (&ret_checksum);
   return ret;
 }
 
@@ -938,5 +1031,5 @@ ostree_unpack_object (GFile            *file,
   if (objtype == OSTREE_OBJECT_TYPE_META)
     return unpack_meta (file, dest, out_checksum, error);
   else
-    return unpack_file (file, dest, out_checksum, error);
+    return unpack_file (file, dest, out_checksum, NULL, error);
 }
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 5318deb..64bfca7 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -162,11 +162,20 @@ gboolean  ostree_pack_file_for_input (GOutputStream     *output,
                                       GCancellable     *cancellable,
                                       GError          **error);
 
+gboolean ostree_create_file_from_input (GFile          *file,
+                                        GFileInfo      *finfo,
+                                        GVariant       *xattrs,
+                                        GInputStream   *input,
+                                        GChecksum     **out_checksum,
+                                        GCancellable   *cancellable,
+                                        GError        **error);
+
 gboolean ostree_parse_packed_file (GFile            *file,
-                                   GVariant    **out_metadata,
-                                   GInputStream **out_content,
-                                   GCancellable *cancellable,
-                                   GError      **error);
+                                   GFileInfo       **out_file_info,
+                                   GVariant        **out_xattrs,
+                                   GInputStream    **out_content,
+                                   GCancellable     *cancellable,
+                                   GError          **error);
 
 gboolean ostree_unpack_object (GFile             *file,
                                OstreeObjectType  objtype,
diff --git a/src/libostree/ostree-repo-file.c b/src/libostree/ostree-repo-file.c
index 11887f0..97996ac 100644
--- a/src/libostree/ostree-repo-file.c
+++ b/src/libostree/ostree-repo-file.c
@@ -307,8 +307,6 @@ _ostree_repo_file_get_xattrs (OstreeRepoFile  *self,
 {
   gboolean ret = FALSE;
   GVariant *ret_xattrs = NULL;
-  GVariant *metadata = NULL;
-  GInputStream *input = NULL;
   GFile *local_file = NULL;
 
   if (!_ostree_repo_file_ensure_resolved (self, error))
@@ -319,9 +317,8 @@ _ostree_repo_file_get_xattrs (OstreeRepoFile  *self,
   else if (ostree_repo_is_archive (self->repo))
     {
       local_file = _ostree_repo_file_nontree_get_local (self);
-      if (!ostree_parse_packed_file (local_file, &metadata, &input, cancellable, error))
+      if (!ostree_parse_packed_file (local_file, NULL, &ret_xattrs, NULL, cancellable, error))
         goto out;
-      ret_xattrs = g_variant_get_child_value (metadata, 4);
     }
   else
     {
@@ -334,8 +331,6 @@ _ostree_repo_file_get_xattrs (OstreeRepoFile  *self,
   ret_xattrs = NULL;
  out:
   ot_clear_gvariant (&ret_xattrs);
-  ot_clear_gvariant (&metadata);
-  g_clear_object (&input);
   g_clear_object (&local_file);
   return ret;
 }
@@ -698,173 +693,6 @@ get_child_local_file (OstreeRepo   *repo,
   return ostree_repo_get_object_path (repo, checksum, OSTREE_OBJECT_TYPE_FILE);
 }
 
-static gboolean
-query_child_info_file_nonarchive (OstreeRepo       *repo,
-                                  const char       *checksum,
-                                  GFileAttributeMatcher *matcher,
-                                  GFileInfo        *info,
-                                  GCancellable     *cancellable,
-                                  GError          **error)
-{
-  gboolean ret = FALSE;
-  GFileInfo *local_info = NULL;
-  GFile *local_file = NULL;
-  int i ;
-  const char *mapped_boolean[] = {
-    "standard::is-symlink"
-  };
-  const char *mapped_string[] = {
-  };
-  const char *mapped_byte_string[] = {
-    "standard::symlink-target"
-  };
-  const char *mapped_uint32[] = {
-    "standard::type",
-    "unix::device",
-    "unix::mode",
-    "unix::nlink",
-    "unix::uid",
-    "unix::gid",
-    "unix::rdev"
-  };
-  const char *mapped_uint64[] = {
-    "standard::size",
-    "standard::allocated-size",
-    "unix::inode"
-  };
-
-  if (!(g_file_attribute_matcher_matches (matcher, "unix::mode")
-        || g_file_attribute_matcher_matches (matcher, "standard::type")))
-    {
-      ret = TRUE;
-      goto out;
-    }
-
-  local_file = get_child_local_file (repo, checksum);
-  local_info = g_file_query_info (local_file,
-				  OSTREE_GIO_FAST_QUERYINFO,
-				  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-				  cancellable,
-				  error);
-  if (!local_info)
-    goto out;
-
-  for (i = 0; i < G_N_ELEMENTS (mapped_boolean); i++)
-    g_file_info_set_attribute_boolean (info, mapped_boolean[i], g_file_info_get_attribute_boolean (local_info, mapped_boolean[i]));
-
-  for (i = 0; i < G_N_ELEMENTS (mapped_string); i++)
-    {
-      const char *string = g_file_info_get_attribute_string (local_info, mapped_string[i]);
-      if (string)
-        g_file_info_set_attribute_string (info, mapped_string[i], string);
-    }
-
-  for (i = 0; i < G_N_ELEMENTS (mapped_byte_string); i++)
-    {
-      const char *byte_string = g_file_info_get_attribute_byte_string (local_info, mapped_byte_string[i]);
-      if (byte_string)
-        g_file_info_set_attribute_byte_string (info, mapped_byte_string[i], byte_string);
-    }
-
-  for (i = 0; i < G_N_ELEMENTS (mapped_uint32); i++)
-    g_file_info_set_attribute_uint32 (info, mapped_uint32[i], g_file_info_get_attribute_uint32 (local_info, mapped_uint32[i]));
-
-  for (i = 0; i < G_N_ELEMENTS (mapped_uint64); i++)
-    g_file_info_set_attribute_uint64 (info, mapped_uint64[i], g_file_info_get_attribute_uint64 (local_info, mapped_uint64[i]));
-  
-  ret = TRUE;
- out:
-  g_clear_object (&local_info);
-  g_clear_object (&local_file);
-  return ret;
-}
-
-static gboolean
-query_child_info_file_archive (OstreeRepo       *repo,
-                               const char       *checksum,
-                               GFileAttributeMatcher *matcher,
-                               GFileInfo        *info,
-                               GCancellable     *cancellable,
-                               GError          **error)
-{
-  gboolean ret = FALSE;
-  GFile *local_file = NULL;
-  GVariant *metadata = NULL;
-  GInputStream *input = NULL;
-  guint32 version, uid, gid, mode;
-  guint64 content_len;
-  guint32 file_type;
-  gsize bytes_read;
-  char *buf = NULL;
-
-  local_file = get_child_local_file (repo, checksum);
-
-  if (!ostree_parse_packed_file (local_file, &metadata, &input, cancellable, error))
-    goto out;
-
-  g_variant_get (metadata, "(uuuu a(ayay)t)",
-                 &version, &uid, &gid, &mode,
-                 NULL, &content_len);
-  uid = GUINT32_FROM_BE (uid);
-  gid = GUINT32_FROM_BE (gid);
-  mode = GUINT32_FROM_BE (mode);
-  content_len = GUINT64_FROM_BE (content_len);
-
-  g_file_info_set_attribute_boolean (info, "standard::is-symlink",
-                                     S_ISLNK (mode));
-  if (S_ISLNK (mode))
-    file_type = G_FILE_TYPE_SYMBOLIC_LINK;
-  else if (S_ISREG (mode))
-    file_type = G_FILE_TYPE_REGULAR;
-  else if (S_ISBLK (mode) || S_ISCHR(mode) || S_ISFIFO(mode))
-    file_type = G_FILE_TYPE_SPECIAL;
-  else
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Corrupted packfile %s: Invalid mode", checksum);
-      goto out;
-    }
-  g_file_info_set_attribute_uint32 (info, "standard::type", file_type);
-
-  g_file_info_set_attribute_uint32 (info, "unix::uid", uid);
-  g_file_info_set_attribute_uint32 (info, "unix::gid", gid);
-  g_file_info_set_attribute_uint32 (info, "unix::mode", mode);
-
-  if (file_type == G_FILE_TYPE_REGULAR)
-    {
-      g_file_info_set_attribute_uint64 (info, "standard::size", content_len);
-    }
-  else if (file_type == G_FILE_TYPE_SYMBOLIC_LINK)
-    {
-      gsize len = MIN (PATH_MAX, content_len) + 1;
-      buf = g_malloc (len);
-
-      if (!g_input_stream_read_all (input, buf, len, &bytes_read, cancellable, error))
-        goto out;
-      buf[bytes_read] = '\0';
-
-      g_file_info_set_attribute_byte_string (info, "standard::symlink-target", buf);
-    }
-  else if (file_type == G_FILE_TYPE_SPECIAL)
-    {
-      guint32 device;
-
-      if (!g_input_stream_read_all (input, &device, 4, &bytes_read, cancellable, error))
-        goto out;
-
-      device = GUINT32_FROM_BE (device);
-      g_file_info_set_attribute_uint32 (info, "unix::device", device);
-    }
-
-  ret = TRUE;
- out:
-  g_free (buf);
-  ot_clear_gvariant (&metadata);
-  g_clear_object (&local_file);
-  g_clear_object (&input);
-  return ret;
-}
-
 static void
 set_info_from_dirmeta (GFileInfo  *info,
                        GVariant   *metadata)
@@ -888,31 +716,34 @@ set_info_from_dirmeta (GFileInfo  *info,
 }
 
 static gboolean
-query_child_info_dir (OstreeRepo         *repo,
-                      const char         *metadata_checksum,
-                      GFileAttributeMatcher *matcher,
-                      GFileQueryInfoFlags flags,
-                      GFileInfo        *info,
-                      GCancellable    *cancellable,
-                      GError         **error)
+query_child_info_dir (OstreeRepo               *repo,
+                      const char               *metadata_checksum,
+                      GFileAttributeMatcher    *matcher,
+                      GFileQueryInfoFlags       flags,
+                      GFileInfo               **out_info,
+                      GCancellable             *cancellable,
+                      GError                  **error)
 {
   gboolean ret = FALSE;
+  GFileInfo *ret_info = NULL;
   GVariant *metadata = NULL;
 
-  if (!g_file_attribute_matcher_matches (matcher, "unix::mode"))
-    {
-      ret = TRUE;
-      goto out;
-    }
+  ret_info = g_file_info_new ();
 
-  if (!ostree_repo_load_variant_checked (repo, OSTREE_SERIALIZED_DIRMETA_VARIANT,
-                                         metadata_checksum, &metadata, error))
-    goto out;
+  if (g_file_attribute_matcher_matches (matcher, "unix::mode"))
+    {
+      if (!ostree_repo_load_variant_checked (repo, OSTREE_SERIALIZED_DIRMETA_VARIANT,
+                                             metadata_checksum, &metadata, error))
+        goto out;
 
-  set_info_from_dirmeta (info, metadata);
+      set_info_from_dirmeta (ret_info, metadata);
+    }
   
   ret = TRUE;
+  *out_info = ret_info;
+  ret_info = NULL;
  out:
+  g_clear_object (&ret_info);
   ot_clear_gvariant (&metadata);
   return ret;
 }
@@ -1183,6 +1014,7 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
   GVariant *files_variant = NULL;
   GVariant *dirs_variant = NULL;
   GVariant *tree_child_metadata = NULL;
+  GFile *local_child = NULL;
   GFileAttributeMatcher *matcher = NULL;
   int c;
 
@@ -1191,8 +1023,6 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
 
   matcher = g_file_attribute_matcher_new (attributes);
 
-  ret_info = g_file_info_new ();
-
   g_assert (self->tree_contents);
 
   files_variant = g_variant_get_child_value (self->tree_contents, 2);
@@ -1205,17 +1035,20 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
 
       g_variant_get_child (files_variant, n, "(&s&s)", &name, &checksum);
 
+      local_child = get_child_local_file (self->repo, checksum);
+
       if (ostree_repo_is_archive (self->repo))
 	{
-	  if (!query_child_info_file_archive (self->repo, checksum, matcher, ret_info,
-                                              cancellable, error))
-	    goto out;
+          if (!ostree_parse_packed_file (local_child, &ret_info, NULL, NULL, cancellable, error))
+            goto out;
 	}
       else
 	{
-	  if (!query_child_info_file_nonarchive (self->repo, checksum, matcher, ret_info,
-                                                 cancellable, error))
-	    goto out;
+          ret_info = g_file_query_info (local_child,
+                                        OSTREE_GIO_FAST_QUERYINFO,
+                                        G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+                                        cancellable,
+                                        error);
 	}
     }
   else
@@ -1233,7 +1066,7 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
                                &name, &tree_checksum, &meta_checksum);
 
           if (!query_child_info_dir (self->repo, meta_checksum,
-                                     matcher, flags, ret_info,
+                                     matcher, flags, &ret_info,
                                      cancellable, error))
             goto out;
         }
@@ -1260,6 +1093,7 @@ _ostree_repo_file_tree_query_child (OstreeRepoFile  *self,
   ret_info = NULL;
  out:
   g_clear_object (&ret_info);
+  g_clear_object (&local_child);
   if (matcher)
     g_file_attribute_matcher_unref (matcher);
   ot_clear_gvariant (&tree_child_metadata);
diff --git a/src/libotutil/ot-gio-utils.c b/src/libotutil/ot-gio-utils.c
index da43161..0e8f4c2 100644
--- a/src/libotutil/ot-gio-utils.c
+++ b/src/libotutil/ot-gio-utils.c
@@ -34,6 +34,19 @@
 #define O_BINARY 0
 #endif
 
+GFileType
+ot_gfile_type_for_mode (guint32 mode)
+{
+  if (S_ISREG (mode))
+    return G_FILE_TYPE_REGULAR;
+  else if (S_ISLNK (mode))
+    return G_FILE_TYPE_SYMBOLIC_LINK;
+  else if (S_ISBLK (mode) || S_ISCHR(mode) || S_ISFIFO(mode))
+    return G_FILE_TYPE_SPECIAL;
+  else
+    return G_FILE_TYPE_UNKNOWN;
+}
+
 gboolean
 ot_gfile_ensure_directory (GFile     *dir,
                            gboolean   with_parents, 
diff --git a/src/libotutil/ot-gio-utils.h b/src/libotutil/ot-gio-utils.h
index 98a3616..de131df 100644
--- a/src/libotutil/ot-gio-utils.h
+++ b/src/libotutil/ot-gio-utils.h
@@ -29,6 +29,8 @@ G_BEGIN_DECLS
 
 #define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,standard::is-hidden,unix::*"
 
+GFileType ot_gfile_type_for_mode (guint32 mode);
+
 GFile *ot_gfile_new_for_path (const char *path);
 
 const char *ot_gfile_get_path_cached (GFile *file);
diff --git a/src/ostree/ot-builtin-show.c b/src/ostree/ot-builtin-show.c
index 30b1e39..45ef2ae 100644
--- a/src/ostree/ot-builtin-show.c
+++ b/src/ostree/ot-builtin-show.c
@@ -27,12 +27,10 @@
 
 #include <glib/gi18n.h>
 
-static gboolean print_packfile;
 static gboolean print_compose;
 static char* print_variant_type;
 
 static GOptionEntry options[] = {
-  { "print-packfile", 0, 0, G_OPTION_ARG_NONE, &print_packfile, "If given, argument given is a packfile", NULL },
   { "print-compose", 0, 0, G_OPTION_ARG_NONE, &print_compose, "If given, show the branches which make up the given compose commit", NULL },
   { "print-variant-type", 0, 0, G_OPTION_ARG_STRING, &print_variant_type, "If given, argument should be a filename and it will be interpreted as this type", NULL },
   { NULL }
@@ -104,31 +102,6 @@ show_repo_meta (OstreeRepo  *repo,
 }
 
 static gboolean
-do_print_packfile (OstreeRepo  *repo,
-                   const char *checksum,
-                   GError **error)
-{
-  gboolean ret = FALSE;
-  GVariant *variant = NULL;
-  GInputStream *content = NULL;
-  GFile *file = NULL;
-
-  file = ostree_repo_get_object_path (repo, checksum, OSTREE_OBJECT_TYPE_FILE);
-
-  if (!ostree_parse_packed_file (file, &variant, &content, NULL, error))
-    goto out;
-  
-  print_variant (variant);
-
-  ret = TRUE;
- out:
-  g_clear_object (&file);
-  g_clear_object (&content);
-  ot_clear_gvariant (&variant);
-  return ret;
-}
-
-static gboolean
 do_print_compose (OstreeRepo  *repo,
                   const char *rev,
                   const char *resolved_rev,
@@ -202,12 +175,7 @@ ostree_builtin_show (int argc, char **argv, const char *repo_path, GError **erro
     }
   rev = argv[1];
 
-  if (print_packfile)
-    {
-      if (!do_print_packfile (repo, rev, error))
-        goto out;
-    }
-  else if (print_compose)
+  if (print_compose)
     {
       if (!ostree_repo_resolve_rev (repo, rev, FALSE, &resolved_rev, error))
         goto out;



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