lib: Add a helper to convert struct stat → GFileInfo

It's more natural for a few calling places. Prep for patches to go the other
way, which in turn are prep for adding a commit filter v2 that takes `struct
stat`.

`ot_gfile_type_for_mode()` was only used in this function, so inline it here.

Closes: #974
Approved by: jlebon
This commit is contained in:
Colin Walters 2017-06-28 16:09:37 -04:00 committed by Atomic Bot
parent 1a9a473580
commit d57410a7e6
8 changed files with 58 additions and 72 deletions

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include "ostree-core.h" #include "ostree-core.h"
#include <sys/stat.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -88,7 +89,8 @@ _ostree_make_temporary_symlink_at (int tmp_dirfd,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
GFileInfo * _ostree_header_gfile_info_new (mode_t mode, uid_t uid, gid_t gid); GFileInfo * _ostree_stbuf_to_gfileinfo (const struct stat *stbuf);
GFileInfo * _ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid);
static inline void static inline void
_ostree_checksum_inplace_from_bytes_v (GVariant *csum_v, char *buf) _ostree_checksum_inplace_from_bytes_v (GVariant *csum_v, char *buf)

View File

@ -1493,7 +1493,7 @@ _ostree_loose_path (char *buf,
} }
/** /**
* _ostree_header_gfile_info_new: * _ostree_stbuf_to_gfileinfo:
* @mode: File mode * @mode: File mode
* @uid: File uid * @uid: File uid
* @gid: File gid * @gid: File gid
@ -1506,17 +1506,42 @@ _ostree_loose_path (char *buf,
* Returns: (transfer full): A new #GFileInfo mapping a subset of @stbuf. * Returns: (transfer full): A new #GFileInfo mapping a subset of @stbuf.
*/ */
GFileInfo * GFileInfo *
_ostree_header_gfile_info_new (mode_t mode, uid_t uid, gid_t gid) _ostree_stbuf_to_gfileinfo (const struct stat *stbuf)
{ {
GFileInfo *ret = g_file_info_new (); GFileInfo *ret = g_file_info_new ();
g_file_info_set_attribute_uint32 (ret, "standard::type", ot_gfile_type_for_mode (mode)); GFileType ftype;
const mode_t mode = stbuf->st_mode;
if (S_ISDIR (mode))
ftype = G_FILE_TYPE_DIRECTORY;
else if (S_ISREG (mode))
ftype = G_FILE_TYPE_REGULAR;
else if (S_ISLNK (mode))
ftype = G_FILE_TYPE_SYMBOLIC_LINK;
else if (S_ISBLK (mode) || S_ISCHR(mode) || S_ISFIFO(mode))
ftype = G_FILE_TYPE_SPECIAL;
else
ftype = G_FILE_TYPE_UNKNOWN;
g_file_info_set_attribute_uint32 (ret, "standard::type", ftype);
g_file_info_set_attribute_boolean (ret, "standard::is-symlink", S_ISLNK (mode)); g_file_info_set_attribute_boolean (ret, "standard::is-symlink", S_ISLNK (mode));
g_file_info_set_attribute_uint32 (ret, "unix::uid", uid); g_file_info_set_attribute_uint32 (ret, "unix::uid", stbuf->st_uid);
g_file_info_set_attribute_uint32 (ret, "unix::gid", gid); g_file_info_set_attribute_uint32 (ret, "unix::gid", stbuf->st_gid);
g_file_info_set_attribute_uint32 (ret, "unix::mode", mode); g_file_info_set_attribute_uint32 (ret, "unix::mode", mode);
if (S_ISREG (mode))
g_file_info_set_attribute_uint64 (ret, "standard::size", stbuf->st_size);
return ret; return ret;
} }
GFileInfo *
_ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid)
{
struct stat stbuf;
stbuf.st_mode = mode;
stbuf.st_uid = uid;
stbuf.st_gid = gid;
return _ostree_stbuf_to_gfileinfo (&stbuf);
}
/* /*
* _ostree_get_relative_object_path: * _ostree_get_relative_object_path:
* @checksum: ASCII checksum string * @checksum: ASCII checksum string
@ -1680,8 +1705,7 @@ file_header_parse (GVariant *metadata,
uid = GUINT32_FROM_BE (uid); uid = GUINT32_FROM_BE (uid);
gid = GUINT32_FROM_BE (gid); gid = GUINT32_FROM_BE (gid);
mode = GUINT32_FROM_BE (mode); mode = GUINT32_FROM_BE (mode);
g_autoptr(GFileInfo) ret_file_info = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid);
g_autoptr(GFileInfo) ret_file_info = _ostree_header_gfile_info_new (mode, uid, gid);
if (S_ISREG (mode)) if (S_ISREG (mode))
{ {
@ -1731,7 +1755,7 @@ zlib_file_header_parse (GVariant *metadata,
uid = GUINT32_FROM_BE (uid); uid = GUINT32_FROM_BE (uid);
gid = GUINT32_FROM_BE (gid); gid = GUINT32_FROM_BE (gid);
mode = GUINT32_FROM_BE (mode); mode = GUINT32_FROM_BE (mode);
g_autoptr(GFileInfo) ret_file_info = _ostree_header_gfile_info_new (mode, uid, gid); g_autoptr(GFileInfo) ret_file_info = _ostree_mode_uidgid_to_gfileinfo (mode, uid, gid);
g_file_info_set_size (ret_file_info, GUINT64_FROM_BE (size)); g_file_info_set_size (ret_file_info, GUINT64_FROM_BE (size));
if (S_ISREG (mode)) if (S_ISREG (mode))

View File

@ -2748,7 +2748,7 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self,
if (fstat (src_dfd_iter->fd, &dir_stbuf) != 0) if (fstat (src_dfd_iter->fd, &dir_stbuf) != 0)
return glnx_throw_errno (error); return glnx_throw_errno (error);
child_info = _ostree_header_gfile_info_new (dir_stbuf.st_mode, dir_stbuf.st_uid, dir_stbuf.st_gid); child_info = _ostree_stbuf_to_gfileinfo (&dir_stbuf);
if (modifier != NULL) if (modifier != NULL)
{ {
@ -2809,13 +2809,11 @@ write_dfd_iter_to_mtree_internal (OstreeRepo *self,
continue; continue;
} }
child_info = _ostree_header_gfile_info_new (stbuf.st_mode, stbuf.st_uid, stbuf.st_gid); child_info = _ostree_stbuf_to_gfileinfo (&stbuf);
g_file_info_set_name (child_info, dent->d_name); g_file_info_set_name (child_info, dent->d_name);
if (S_ISREG (stbuf.st_mode)) if (S_ISREG (stbuf.st_mode))
{ ;
g_file_info_set_size (child_info, stbuf.st_size);
}
else if (S_ISLNK (stbuf.st_mode)) else if (S_ISLNK (stbuf.st_mode))
{ {
if (!ot_readlinkat_gfile_info (src_dfd_iter->fd, dent->d_name, if (!ot_readlinkat_gfile_info (src_dfd_iter->fd, dent->d_name,

View File

@ -126,33 +126,24 @@ squash_trailing_slashes (char *path)
static GFileInfo * static GFileInfo *
file_info_from_archive_entry (struct archive_entry *entry) file_info_from_archive_entry (struct archive_entry *entry)
{ {
g_autoptr(GFileInfo) info = NULL; const struct stat *st = archive_entry_stat (entry);
const struct stat *st = NULL; struct stat st_copy;
guint32 file_type;
mode_t mode;
st = archive_entry_stat (entry);
mode = st->st_mode;
/* Some archives only store the permission mode bits in hardlink entries, so /* Some archives only store the permission mode bits in hardlink entries, so
* let's just make it into a regular file. Yes, this hack will work even if * let's just make it into a regular file. Yes, this hack will work even if
* it's a hardlink to a symlink. */ * it's a hardlink to a symlink. */
if (archive_entry_hardlink (entry)) if (archive_entry_hardlink (entry))
mode |= S_IFREG;
info = _ostree_header_gfile_info_new (mode, st->st_uid, st->st_gid);
file_type = ot_gfile_type_for_mode (mode);
if (file_type == G_FILE_TYPE_REGULAR)
{ {
g_file_info_set_attribute_uint64 (info, "standard::size", st->st_size); st_copy = *st;
} st_copy.st_mode |= S_IFREG;
else if (file_type == G_FILE_TYPE_SYMBOLIC_LINK) st = &st_copy;
{
g_file_info_set_attribute_byte_string (info, "standard::symlink-target",
archive_entry_symlink (entry));
} }
g_autoptr(GFileInfo) info = _ostree_stbuf_to_gfileinfo (st);
if (S_ISLNK (st->st_mode))
g_file_info_set_attribute_byte_string (info, "standard::symlink-target",
archive_entry_symlink (entry));
return g_steal_pointer (&info); return g_steal_pointer (&info);
} }

View File

@ -515,18 +515,15 @@ dispatch_bspatch (OstreeRepo *repo,
static gboolean static gboolean
handle_untrusted_content_checksum (OstreeRepo *repo, handle_untrusted_content_checksum (OstreeRepo *repo,
StaticDeltaExecutionState *state, StaticDeltaExecutionState *state,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
g_autoptr(GVariant) header = NULL; g_autoptr(GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (state->mode, state->uid, state->gid);
g_autoptr(GFileInfo) finfo = NULL; g_autoptr(GVariant) header = _ostree_file_header_new (finfo, state->xattrs);
gsize bytes_written;
finfo = _ostree_header_gfile_info_new (state->mode, state->uid, state->gid);
header = _ostree_file_header_new (finfo, state->xattrs);
state->content_checksum = g_checksum_new (G_CHECKSUM_SHA256); state->content_checksum = g_checksum_new (G_CHECKSUM_SHA256);
gsize bytes_written;
if (!_ostree_write_variant_with_size (NULL, header, 0, &bytes_written, state->content_checksum, if (!_ostree_write_variant_with_size (NULL, header, 0, &bytes_written, state->content_checksum,
cancellable, error)) cancellable, error))
return FALSE; return FALSE;
@ -629,9 +626,8 @@ dispatch_open_splice_and_close (OstreeRepo *repo,
else else
{ {
/* Slower path, for symlinks and unpacking deltas into archive-z2 */ /* Slower path, for symlinks and unpacking deltas into archive-z2 */
g_autoptr(GFileInfo) finfo = NULL; g_autoptr(GFileInfo) finfo =
_ostree_mode_uidgid_to_gfileinfo (state->mode, state->uid, state->gid);
finfo = _ostree_header_gfile_info_new (state->mode, state->uid, state->gid);
if (S_ISLNK (state->mode)) if (S_ISLNK (state->mode))
{ {

View File

@ -2791,18 +2791,11 @@ ostree_repo_load_file (OstreeRepo *self,
} }
if (out_file_info) if (out_file_info)
{ {
*out_file_info = _ostree_header_gfile_info_new (stbuf.st_mode, stbuf.st_uid, stbuf.st_gid); *out_file_info = _ostree_stbuf_to_gfileinfo (&stbuf);
if (S_ISREG (stbuf.st_mode)) if (S_ISLNK (stbuf.st_mode))
{ g_file_info_set_symlink_target (*out_file_info, symlink_target);
g_file_info_set_size (*out_file_info, stbuf.st_size);
}
else if (S_ISLNK (stbuf.st_mode))
{
g_file_info_set_size (*out_file_info, 0);
g_file_info_set_symlink_target (*out_file_info, symlink_target);
}
else else
g_assert_not_reached (); g_assert (S_ISREG (stbuf.st_mode));
} }
ot_transfer_out_value (out_xattrs, &ret_xattrs); ot_transfer_out_value (out_xattrs, &ret_xattrs);

View File

@ -35,22 +35,6 @@
#define O_BINARY 0 #define O_BINARY 0
#endif #endif
GFileType
ot_gfile_type_for_mode (guint32 mode)
{
if (S_ISDIR (mode))
return G_FILE_TYPE_DIRECTORY;
else 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;
}
GFile * GFile *
ot_gfile_resolve_path_printf (GFile *path, ot_gfile_resolve_path_printf (GFile *path,
const char *format, const char *format,

View File

@ -33,8 +33,6 @@ G_BEGIN_DECLS
#define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \ #define OSTREE_GIO_FAST_QUERYINFO ("standard::name,standard::type,standard::size,standard::is-symlink,standard::symlink-target," \
"unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev") "unix::device,unix::inode,unix::mode,unix::uid,unix::gid,unix::rdev")
GFileType ot_gfile_type_for_mode (guint32 mode);
GFile * ot_gfile_resolve_path_printf (GFile *path, GFile * ot_gfile_resolve_path_printf (GFile *path,
const char *format, const char *format,
...) G_GNUC_PRINTF(2, 3); ...) G_GNUC_PRINTF(2, 3);