[ostree] core: Add API for just effectively stat()ing packed files
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] core: Add API for just effectively stat()ing packed files
- Date: Wed, 9 Nov 2011 11:32:45 +0000 (UTC)
commit 8f0afd1f5443b262f4e469ff26f5dc763f00e473
Author: Colin Walters <walters verbum org>
Date: Tue Nov 8 19:37:41 2011 -0500
core: Add API for just effectively stat()ing packed files
This will allow us to implement more of a VFS-like API on top.
libostree/ostree-core.c | 81 +++++++++++++++++++++++++++++++++-------------
libostree/ostree-core.h | 10 +++++-
2 files changed, 67 insertions(+), 24 deletions(-)
---
diff --git a/libostree/ostree-core.c b/libostree/ostree-core.c
index a54f628..904ce05 100644
--- a/libostree/ostree-core.c
+++ b/libostree/ostree-core.c
@@ -627,29 +627,20 @@ unpack_meta (const char *path,
return ret;
}
-
-static gboolean
-unpack_file (const char *path,
- const char *dest_path,
- GChecksum **out_checksum,
- GError **error)
+gboolean
+ostree_parse_packed_file (GFile *file,
+ GVariant **out_metadata,
+ GInputStream **out_content,
+ GCancellable *cancellable,
+ GError **error)
{
gboolean ret = FALSE;
- GFile *file = NULL;
- GFile *dest_file = NULL;
char *metadata_buf = NULL;
- GVariant *metadata = NULL;
- GVariant *xattrs = NULL;
+ GVariant *ret_metadata = NULL;
GFileInputStream *in = NULL;
- GFileOutputStream *out = NULL;
- GChecksum *ret_checksum = NULL;
guint32 metadata_len;
- guint32 version, uid, gid, mode;
- guint64 content_len;
gsize bytes_read;
- file = ot_util_new_file_for_path (path);
-
in = g_file_read (file, NULL, error);
if (!in)
goto out;
@@ -664,6 +655,13 @@ unpack_file (const char *path,
}
metadata_len = GUINT32_FROM_BE (metadata_len);
+ if (metadata_len > OSTREE_MAX_METADATA_SIZE)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Corrupted packfile; metadata length %u is larger than maximum %u",
+ metadata_len, OSTREE_MAX_METADATA_SIZE);
+ goto out;
+ }
metadata_buf = g_malloc (metadata_len);
if (!g_input_stream_read_all ((GInputStream*)in, metadata_buf, metadata_len, &bytes_read, NULL, error))
@@ -675,9 +673,47 @@ unpack_file (const char *path,
goto out;
}
- metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
- metadata_buf, metadata_len, FALSE, NULL, NULL);
-
+ 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_buf = NULL;
+
+ ret = TRUE;
+ *out_metadata = ret_metadata;
+ ret_metadata = NULL;
+ *out_content = (GInputStream*)in;
+ in = NULL;
+ out:
+ g_clear_object (&in);
+ if (ret_metadata)
+ g_variant_unref (ret_metadata);
+ return ret;
+}
+
+static gboolean
+unpack_file (const char *path,
+ const char *dest_path,
+ GChecksum **out_checksum,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GFile *file = NULL;
+ GFile *dest_file = NULL;
+ GVariant *metadata = NULL;
+ GVariant *xattrs = NULL;
+ GInputStream *in = NULL;
+ GFileOutputStream *out = NULL;
+ GChecksum *ret_checksum = NULL;
+ guint32 version, uid, gid, mode;
+ guint64 content_len;
+ gsize bytes_read;
+
+ file = ot_util_new_file_for_path (path);
+
+ 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);
@@ -697,7 +733,7 @@ unpack_file (const char *path,
if (!out)
goto out;
- if (!splice_and_checksum ((GOutputStream*)out, (GInputStream*)in, ret_checksum, NULL, error))
+ if (!splice_and_checksum ((GOutputStream*)out, in, ret_checksum, NULL, error))
goto out;
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
@@ -707,7 +743,7 @@ unpack_file (const char *path,
{
char target[PATH_MAX+1];
- if (!g_input_stream_read_all ((GInputStream*)in, target, sizeof(target)-1, &bytes_read, NULL, error))
+ if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, NULL, error))
goto out;
target[bytes_read] = '\0';
if (ret_checksum)
@@ -722,7 +758,7 @@ unpack_file (const char *path,
{
guint32 dev;
- if (!g_input_stream_read_all ((GInputStream*)in, &dev, 4, &bytes_read, NULL, error))
+ if (!g_input_stream_read_all (in, &dev, 4, &bytes_read, NULL, error))
goto out;
if (bytes_read != 4)
{
@@ -773,7 +809,6 @@ unpack_file (const char *path,
(void) unlink (dest_path);
if (ret_checksum)
g_checksum_free (ret_checksum);
- g_free (metadata_buf);
g_clear_object (&file);
g_clear_object (&dest_file);
g_clear_object (&in);
diff --git a/libostree/ostree-core.h b/libostree/ostree-core.h
index 959a46b..3dc70b4 100644
--- a/libostree/ostree-core.h
+++ b/libostree/ostree-core.h
@@ -26,6 +26,8 @@
G_BEGIN_DECLS
+#define OSTREE_MAX_METADATA_SIZE (1 << 26)
+
#define OSTREE_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,unix::*"
#define OSTREE_EMPTY_STRING_SHA256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
@@ -128,11 +130,17 @@ gboolean ostree_stat_and_checksum_file (int dirfd, const char *path,
#define OSTREE_PACK_FILE_VARIANT_FORMAT "(uuuua(ayay)t)"
gboolean ostree_pack_object (GOutputStream *output,
- GFile *path,
+ GFile *file,
OstreeObjectType objtype,
GCancellable *cancellable,
GError **error);
+gboolean ostree_parse_packed_file (GFile *file,
+ GVariant **out_metadata,
+ GInputStream **out_content,
+ GCancellable *cancellable,
+ GError **error);
+
gboolean ostree_unpack_object (const char *path,
OstreeObjectType objtype,
const char *dest_path,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]