core: Add API for just effectively stat()ing packed files
This will allow us to implement more of a VFS-like API on top.
This commit is contained in:
parent
ed57f1c676
commit
8f0afd1f54
|
|
@ -627,29 +627,20 @@ unpack_meta (const char *path,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
static gboolean
|
ostree_parse_packed_file (GFile *file,
|
||||||
unpack_file (const char *path,
|
GVariant **out_metadata,
|
||||||
const char *dest_path,
|
GInputStream **out_content,
|
||||||
GChecksum **out_checksum,
|
GCancellable *cancellable,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GFile *file = NULL;
|
|
||||||
GFile *dest_file = NULL;
|
|
||||||
char *metadata_buf = NULL;
|
char *metadata_buf = NULL;
|
||||||
GVariant *metadata = NULL;
|
GVariant *ret_metadata = NULL;
|
||||||
GVariant *xattrs = NULL;
|
|
||||||
GFileInputStream *in = NULL;
|
GFileInputStream *in = NULL;
|
||||||
GFileOutputStream *out = NULL;
|
|
||||||
GChecksum *ret_checksum = NULL;
|
|
||||||
guint32 metadata_len;
|
guint32 metadata_len;
|
||||||
guint32 version, uid, gid, mode;
|
|
||||||
guint64 content_len;
|
|
||||||
gsize bytes_read;
|
gsize bytes_read;
|
||||||
|
|
||||||
file = ot_util_new_file_for_path (path);
|
|
||||||
|
|
||||||
in = g_file_read (file, NULL, error);
|
in = g_file_read (file, NULL, error);
|
||||||
if (!in)
|
if (!in)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -664,6 +655,13 @@ unpack_file (const char *path,
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata_len = GUINT32_FROM_BE (metadata_len);
|
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);
|
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 ((GInputStream*)in, metadata_buf, metadata_len, &bytes_read, NULL, error))
|
||||||
|
|
@ -675,8 +673,46 @@ unpack_file (const char *path,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
|
ret_metadata = g_variant_new_from_data (G_VARIANT_TYPE (OSTREE_PACK_FILE_VARIANT_FORMAT),
|
||||||
metadata_buf, metadata_len, FALSE, NULL, NULL);
|
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)",
|
g_variant_get (metadata, "(uuuu@a(ayay)t)",
|
||||||
&version, &uid, &gid, &mode,
|
&version, &uid, &gid, &mode,
|
||||||
|
|
@ -697,7 +733,7 @@ unpack_file (const char *path,
|
||||||
if (!out)
|
if (!out)
|
||||||
goto 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;
|
goto out;
|
||||||
|
|
||||||
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
|
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
|
||||||
|
|
@ -707,7 +743,7 @@ unpack_file (const char *path,
|
||||||
{
|
{
|
||||||
char target[PATH_MAX+1];
|
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;
|
goto out;
|
||||||
target[bytes_read] = '\0';
|
target[bytes_read] = '\0';
|
||||||
if (ret_checksum)
|
if (ret_checksum)
|
||||||
|
|
@ -722,7 +758,7 @@ unpack_file (const char *path,
|
||||||
{
|
{
|
||||||
guint32 dev;
|
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;
|
goto out;
|
||||||
if (bytes_read != 4)
|
if (bytes_read != 4)
|
||||||
{
|
{
|
||||||
|
|
@ -773,7 +809,6 @@ unpack_file (const char *path,
|
||||||
(void) unlink (dest_path);
|
(void) unlink (dest_path);
|
||||||
if (ret_checksum)
|
if (ret_checksum)
|
||||||
g_checksum_free (ret_checksum);
|
g_checksum_free (ret_checksum);
|
||||||
g_free (metadata_buf);
|
|
||||||
g_clear_object (&file);
|
g_clear_object (&file);
|
||||||
g_clear_object (&dest_file);
|
g_clear_object (&dest_file);
|
||||||
g_clear_object (&in);
|
g_clear_object (&in);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
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_GIO_FAST_QUERYINFO "standard::name,standard::type,standard::is-symlink,standard::symlink-target,unix::*"
|
||||||
|
|
||||||
#define OSTREE_EMPTY_STRING_SHA256 "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
#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)"
|
#define OSTREE_PACK_FILE_VARIANT_FORMAT "(uuuua(ayay)t)"
|
||||||
|
|
||||||
gboolean ostree_pack_object (GOutputStream *output,
|
gboolean ostree_pack_object (GOutputStream *output,
|
||||||
GFile *path,
|
GFile *file,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
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,
|
gboolean ostree_unpack_object (const char *path,
|
||||||
OstreeObjectType objtype,
|
OstreeObjectType objtype,
|
||||||
const char *dest_path,
|
const char *dest_path,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue