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.
This commit is contained in:
parent
f98e2a2ddb
commit
7fc625c967
|
|
@ -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,79 +784,44 @@ 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;
|
||||
|
||||
ret = TRUE;
|
||||
*out_metadata = ret_metadata;
|
||||
ret_metadata = NULL;
|
||||
*out_content = (GInputStream*)in;
|
||||
in = NULL;
|
||||
out:
|
||||
g_clear_object (&in);
|
||||
ot_clear_gvariant (&ret_metadata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
unpack_file (GFile *file,
|
||||
GFile *dest_file,
|
||||
GChecksum **out_checksum,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
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;
|
||||
const char *dest_path;
|
||||
|
||||
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);
|
||||
&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))
|
||||
{
|
||||
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))
|
||||
goto out;
|
||||
|
||||
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
|
||||
goto out;
|
||||
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, NULL, error))
|
||||
if (!g_input_stream_read_all (in, target, sizeof(target)-1, &bytes_read, cancellable, error))
|
||||
goto out;
|
||||
target[bytes_read] = '\0';
|
||||
if (ret_checksum)
|
||||
g_checksum_update (ret_checksum, (guint8*)target, bytes_read);
|
||||
if (symlink (target, dest_path) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
|
@ -866,6 +836,94 @@ unpack_file (GFile *file,
|
|||
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;
|
||||
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 (&metadata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
GFileOutputStream *out = NULL;
|
||||
guint32 uid, gid, mode;
|
||||
GChecksum *ret_checksum = NULL;
|
||||
|
||||
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 (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, input,
|
||||
out_checksum ? &ret_checksum : NULL,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!g_output_stream_close ((GOutputStream*)out, NULL, error))
|
||||
goto out;
|
||||
}
|
||||
else if (S_ISLNK (mode))
|
||||
{
|
||||
const char *target = g_file_info_get_attribute_byte_string (finfo, "standard::symlink-target");
|
||||
if (ret_checksum)
|
||||
g_checksum_update (ret_checksum, (guint8*)target, strlen (target));
|
||||
if (symlink (target, dest_path) < 0)
|
||||
{
|
||||
ot_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (S_ISCHR (mode) || S_ISBLK (mode))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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_info = g_file_info_new ();
|
||||
|
||||
if (g_file_attribute_matcher_matches (matcher, "unix::mode"))
|
||||
{
|
||||
ret = TRUE;
|
||||
goto out;
|
||||
if (!ostree_repo_load_variant_checked (repo, OSTREE_SERIALIZED_DIRMETA_VARIANT,
|
||||
metadata_checksum, &metadata, error))
|
||||
goto out;
|
||||
|
||||
set_info_from_dirmeta (ret_info, metadata);
|
||||
}
|
||||
|
||||
if (!ostree_repo_load_variant_checked (repo, OSTREE_SERIALIZED_DIRMETA_VARIANT,
|
||||
metadata_checksum, &metadata, error))
|
||||
goto out;
|
||||
|
||||
set_info_from_dirmeta (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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
@ -103,31 +101,6 @@ show_repo_meta (OstreeRepo *repo,
|
|||
return ret;
|
||||
}
|
||||
|
||||
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,
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue