[ostree] libostree: Move file creation APIs out of core, into checkout.c



commit 36815f52b581d5c2d75cf4206802f734c4fda344
Author: Colin Walters <walters verbum org>
Date:   Wed Sep 4 08:17:42 2013 -0400

    libostree: Move file creation APIs out of core, into checkout.c
    
    Since this was the only user, let's not have generic code to go from
    OSTree representation -> filesystem here.  It should live in checkout.

 doc/ostree-sections.txt              |    2 -
 src/libostree/ostree-core.c          |  208 -------------------------------
 src/libostree/ostree-core.h          |   17 ---
 src/libostree/ostree-repo-checkout.c |  224 ++++++++++++++++++++++++++++++++--
 4 files changed, 216 insertions(+), 235 deletions(-)
---
diff --git a/doc/ostree-sections.txt b/doc/ostree-sections.txt
index 5691f63..8ef9f02 100644
--- a/doc/ostree-sections.txt
+++ b/doc/ostree-sections.txt
@@ -40,8 +40,6 @@ ostree_checksum_file
 ostree_checksum_file_async
 ostree_checksum_file_async_finish
 ostree_create_directory_metadata
-ostree_create_file_from_input
-ostree_create_temp_file_from_input
 ostree_create_temp_dir
 ostree_validate_structureof_objtype
 ostree_validate_structureof_csum_v
diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c
index 381c61f..1ba6646 100644
--- a/src/libostree/ostree-core.c
+++ b/src/libostree/ostree-core.c
@@ -1512,214 +1512,6 @@ zlib_file_header_parse (GVariant         *metadata,
 }
 
 /**
- * ostree_create_file_from_input:
- * @dest_file: Destination; must not exist
- * @finfo: File information
- * @xattrs: (allow-none): Optional extended attributes
- * @input: (allow-none): Optional file content, must be %NULL for symbolic links
- * @cancellable: Cancellable
- * @error: Error
- *
- * Create a directory, regular file, or symbolic link, based on
- * @finfo.  Append extended attributes from @xattrs if provided.  For
- * %G_FILE_TYPE_REGULAR, set content based on @input.
- */
-gboolean
-ostree_create_file_from_input (GFile            *dest_file,
-                               GFileInfo        *finfo,
-                               GVariant         *xattrs,
-                               GInputStream     *input,
-                               GCancellable     *cancellable,
-                               GError          **error)
-{
-  gboolean ret = FALSE;
-  const char *dest_path;
-  guint32 uid, gid, mode;
-  gs_unref_object GOutputStream *out = NULL;
-
-  if (g_cancellable_set_error_if_cancelled (cancellable, error))
-    return FALSE;
-
-  if (finfo != NULL)
-    {
-      mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode");
-    }
-  else
-    {
-      mode = S_IFREG | 0664;
-    }
-  dest_path = gs_file_get_path_cached (dest_file);
-
-  if (S_ISDIR (mode))
-    {
-      if (mkdir (gs_file_get_path_cached (dest_file), mode) < 0)
-        {
-          ot_util_set_error_from_errno (error, errno);
-          goto out;
-        }
-    }
-  else if (S_ISREG (mode))
-    {
-      if (finfo != NULL)
-        {
-          uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
-          gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
-
-          if (!gs_file_create_with_uidgid (dest_file, mode, uid, gid, &out,
-                                           cancellable, error))
-            goto out;
-        }
-      else
-        {
-          if (!gs_file_create (dest_file, mode, &out,
-                               cancellable, error))
-            goto out;
-        }
-
-      if (input)
-        {
-          if (g_output_stream_splice ((GOutputStream*)out, input, 0,
-                                      cancellable, error) < 0)
-            goto out;
-        }
-
-      if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
-        goto out;
-
-      /* Work around libguestfs/FUSE bug */
-      if (mode & (S_ISUID|S_ISGID))
-        {
-          if (chmod (dest_path, mode) == -1)
-            {
-              ot_util_set_error_from_errno (error, errno);
-              goto out;
-            }
-        }
-    }
-  else if (S_ISLNK (mode))
-    {
-      const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target");
-      if (symlink (target, dest_path) < 0)
-        {
-          ot_util_set_error_from_errno (error, errno);
-          goto out;
-        }
-    }
-  else
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Invalid mode %u", mode);
-      goto out;
-    }
-
-  /* We only need to chown for directories and symlinks; we already
-   * did a chown for files above via fchown().
-   */
-  if (finfo != NULL && !S_ISREG (mode))
-    {
-      uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
-      gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
-      
-      if (lchown (dest_path, uid, gid) < 0)
-        {
-          ot_util_set_error_from_errno (error, errno);
-          g_prefix_error (error, "lchown(%u, %u) failed: ", uid, gid);
-          goto out;
-        }
-    }
-
-  if (xattrs != NULL)
-    {
-      if (!ostree_set_xattrs (dest_file, xattrs, cancellable, error))
-        goto out;
-    }
-
-  ret = TRUE;
- out:
-  if (!ret && !S_ISDIR(mode))
-    {
-      (void) unlink (dest_path);
-    }
-  return ret;
-}
-
-/**
- * ostree_create_temp_file_from_input:
- * @dir: Target directory
- * @prefix: Optional prefix
- * @suffix: Optional suffix
- * @finfo: File information
- * @xattrs: (allow-none): Optional extended attributes
- * @input: (allow-none): Optional file content, must be %NULL for symbolic links
- * @out_file: (out): Path for newly created directory, file, or symbolic link
- * @cancellable: Cancellable
- * @error: Error
- *
- * Like ostree_create_file_from_input(), but securely allocates a
- * randomly-named target in @dir.  This is a unified version of
- * mkstemp()/mkdtemp() that also supports symbolic links.
- */
-gboolean
-ostree_create_temp_file_from_input (GFile            *dir,
-                                    const char       *prefix,
-                                    const char       *suffix,
-                                    GFileInfo        *finfo,
-                                    GVariant         *xattrs,
-                                    GInputStream     *input,
-                                    GFile           **out_file,
-                                    GCancellable     *cancellable,
-                                    GError          **error)
-{
-  gboolean ret = FALSE;
-  GError *temp_error = NULL;
-  int i = 0;
-  gs_unref_object GFile *possible_file = NULL;
-
-  /* 128 attempts seems reasonable... */
-  for (i = 0; i < 128; i++)
-    {
-      gs_free char *possible_name = NULL;
-
-      if (g_cancellable_set_error_if_cancelled (cancellable, error))
-        goto out;
-
-      possible_name = gsystem_fileutil_gen_tmp_name (prefix, suffix);
-      g_clear_object (&possible_file);
-      possible_file = g_file_get_child (dir, possible_name);
-      
-      if (!ostree_create_file_from_input (possible_file, finfo, xattrs, input,
-                                          cancellable, &temp_error))
-        {
-          if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
-            {
-              g_clear_error (&temp_error);
-              continue;
-            }
-          else
-            {
-              g_propagate_error (error, temp_error);
-              goto out;
-            }
-        }
-      else
-        {
-          break;
-        }
-    }
-  if (i >= 128)
-    {
-      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Exhausted 128 attempts to create a temporary file");
-      goto out;
-    }
-
-  ret = TRUE;
-  ot_transfer_out_value(out_file, &possible_file);
- out:
-  return ret;
-}
-
-/**
  * ostree_create_temp_dir:
  * @dir: Use this as temporary base
  * @prefix: (allow-none): Optional prefix
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index 5c039c1..789813e 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -228,23 +228,6 @@ gboolean ostree_checksum_file_async_finish (GFile          *f,
 GVariant *ostree_create_directory_metadata (GFileInfo *dir_info,
                                             GVariant  *xattrs);
 
-gboolean ostree_create_file_from_input (GFile          *dest_file,
-                                        GFileInfo      *finfo,
-                                        GVariant       *xattrs,
-                                        GInputStream   *input,
-                                        GCancellable   *cancellable,
-                                        GError        **error);
-
-gboolean ostree_create_temp_file_from_input (GFile            *dir,
-                                             const char       *prefix,
-                                             const char       *suffix,
-                                             GFileInfo        *finfo,
-                                             GVariant         *xattrs,
-                                             GInputStream     *input,
-                                             GFile           **out_file,
-                                             GCancellable     *cancellable,
-                                             GError          **error);
-
 gboolean ostree_create_temp_dir (GFile            *dir,
                                  const char       *prefix,
                                  const char       *suffix,
diff --git a/src/libostree/ostree-repo-checkout.c b/src/libostree/ostree-repo-checkout.c
index 1e50f11..239df4a 100644
--- a/src/libostree/ostree-repo-checkout.c
+++ b/src/libostree/ostree-repo-checkout.c
@@ -28,6 +28,214 @@
 #include "ostree-repo-file.h"
 #include "ostree-repo-private.h"
 
+/*
+ * create_file_from_input:
+ * @dest_file: Destination; must not exist
+ * @finfo: File information
+ * @xattrs: (allow-none): Optional extended attributes
+ * @input: (allow-none): Optional file content, must be %NULL for symbolic links
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Create a directory, regular file, or symbolic link, based on
+ * @finfo.  Append extended attributes from @xattrs if provided.  For
+ * %G_FILE_TYPE_REGULAR, set content based on @input.
+ */
+static gboolean
+create_file_from_input (GFile            *dest_file,
+                        GFileInfo        *finfo,
+                        GVariant         *xattrs,
+                        GInputStream     *input,
+                        GCancellable     *cancellable,
+                        GError          **error)
+{
+  gboolean ret = FALSE;
+  const char *dest_path;
+  guint32 uid, gid, mode;
+  gs_unref_object GOutputStream *out = NULL;
+
+  if (g_cancellable_set_error_if_cancelled (cancellable, error))
+    return FALSE;
+
+  if (finfo != NULL)
+    {
+      mode = g_file_info_get_attribute_uint32 (finfo, "unix::mode");
+    }
+  else
+    {
+      mode = S_IFREG | 0664;
+    }
+  dest_path = gs_file_get_path_cached (dest_file);
+
+  if (S_ISDIR (mode))
+    {
+      if (mkdir (gs_file_get_path_cached (dest_file), mode) < 0)
+        {
+          ot_util_set_error_from_errno (error, errno);
+          goto out;
+        }
+    }
+  else if (S_ISREG (mode))
+    {
+      if (finfo != NULL)
+        {
+          uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
+          gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
+
+          if (!gs_file_create_with_uidgid (dest_file, mode, uid, gid, &out,
+                                           cancellable, error))
+            goto out;
+        }
+      else
+        {
+          if (!gs_file_create (dest_file, mode, &out,
+                               cancellable, error))
+            goto out;
+        }
+
+      if (input)
+        {
+          if (g_output_stream_splice ((GOutputStream*)out, input, 0,
+                                      cancellable, error) < 0)
+            goto out;
+        }
+
+      if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
+        goto out;
+
+      /* Work around libguestfs/FUSE bug */
+      if (mode & (S_ISUID|S_ISGID))
+        {
+          if (chmod (dest_path, mode) == -1)
+            {
+              ot_util_set_error_from_errno (error, errno);
+              goto out;
+            }
+        }
+    }
+  else if (S_ISLNK (mode))
+    {
+      const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target");
+      if (symlink (target, dest_path) < 0)
+        {
+          ot_util_set_error_from_errno (error, errno);
+          goto out;
+        }
+    }
+  else
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Invalid mode %u", mode);
+      goto out;
+    }
+
+  /* We only need to chown for directories and symlinks; we already
+   * did a chown for files above via fchown().
+   */
+  if (finfo != NULL && !S_ISREG (mode))
+    {
+      uid = g_file_info_get_attribute_uint32 (finfo, "unix::uid");
+      gid = g_file_info_get_attribute_uint32 (finfo, "unix::gid");
+      
+      if (lchown (dest_path, uid, gid) < 0)
+        {
+          ot_util_set_error_from_errno (error, errno);
+          g_prefix_error (error, "lchown(%u, %u) failed: ", uid, gid);
+          goto out;
+        }
+    }
+
+  if (xattrs != NULL)
+    {
+      if (!ostree_set_xattrs (dest_file, xattrs, cancellable, error))
+        goto out;
+    }
+
+  ret = TRUE;
+ out:
+  if (!ret && !S_ISDIR(mode))
+    {
+      (void) unlink (dest_path);
+    }
+  return ret;
+}
+
+/*
+ * create_temp_file_from_input:
+ * @dir: Target directory
+ * @prefix: Optional prefix
+ * @suffix: Optional suffix
+ * @finfo: File information
+ * @xattrs: (allow-none): Optional extended attributes
+ * @input: (allow-none): Optional file content, must be %NULL for symbolic links
+ * @out_file: (out): Path for newly created directory, file, or symbolic link
+ * @cancellable: Cancellable
+ * @error: Error
+ *
+ * Like create_file_from_input(), but securely allocates a
+ * randomly-named target in @dir.  This is a unified version of
+ * mkstemp()/mkdtemp() that also supports symbolic links.
+ */
+static gboolean
+create_temp_file_from_input (GFile            *dir,
+                             const char       *prefix,
+                             const char       *suffix,
+                             GFileInfo        *finfo,
+                             GVariant         *xattrs,
+                             GInputStream     *input,
+                             GFile           **out_file,
+                             GCancellable     *cancellable,
+                             GError          **error)
+{
+  gboolean ret = FALSE;
+  GError *temp_error = NULL;
+  int i = 0;
+  gs_unref_object GFile *possible_file = NULL;
+
+  /* 128 attempts seems reasonable... */
+  for (i = 0; i < 128; i++)
+    {
+      gs_free char *possible_name = NULL;
+
+      if (g_cancellable_set_error_if_cancelled (cancellable, error))
+        goto out;
+
+      possible_name = gsystem_fileutil_gen_tmp_name (prefix, suffix);
+      g_clear_object (&possible_file);
+      possible_file = g_file_get_child (dir, possible_name);
+      
+      if (!create_file_from_input (possible_file, finfo, xattrs, input,
+                                   cancellable, &temp_error))
+        {
+          if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+            {
+              g_clear_error (&temp_error);
+              continue;
+            }
+          else
+            {
+              g_propagate_error (error, temp_error);
+              goto out;
+            }
+        }
+      else
+        {
+          break;
+        }
+    }
+  if (i >= 128)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                   "Exhausted 128 attempts to create a temporary file");
+      goto out;
+    }
+
+  ret = TRUE;
+  ot_transfer_out_value(out_file, &possible_file);
+ out:
+  return ret;
+}
+
 static gboolean
 checkout_file_from_input (GFile          *file,
                           OstreeRepoCheckoutMode mode,
@@ -60,9 +268,9 @@ checkout_file_from_input (GFile          *file,
     {
       if (g_file_info_get_file_type (temp_info) == G_FILE_TYPE_DIRECTORY)
         {
-          if (!ostree_create_file_from_input (file, temp_info,
-                                              xattrs, input,
-                                              cancellable, &temp_error))
+          if (!create_file_from_input (file, temp_info,
+                                       xattrs, input,
+                                       cancellable, &temp_error))
             {
               if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
                 {
@@ -78,9 +286,9 @@ checkout_file_from_input (GFile          *file,
       else
         {
           dir = g_file_get_parent (file);
-          if (!ostree_create_temp_file_from_input (dir, NULL, "checkout",
-                                                   temp_info, xattrs, input, &temp_file, 
-                                                   cancellable, error))
+          if (!create_temp_file_from_input (dir, NULL, "checkout",
+                                            temp_info, xattrs, input, &temp_file, 
+                                            cancellable, error))
             goto out;
 
           if (g_file_info_get_file_type (temp_info) == G_FILE_TYPE_REGULAR)
@@ -98,8 +306,8 @@ checkout_file_from_input (GFile          *file,
     }
   else
     {
-      if (!ostree_create_file_from_input (file, temp_info,
-                                          xattrs, input, cancellable, error))
+      if (!create_file_from_input (file, temp_info,
+                                   xattrs, input, cancellable, error))
         goto out;
 
       if (g_file_info_get_file_type (temp_info) == G_FILE_TYPE_REGULAR)


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