mirror of
https://github.com/ostreedev/ostree.git
synced 2024-12-22 17:35:55 +03:00
Actually checksum xattr values, not just names
We need to call lgetxattr() and not just llistxattr().
This commit is contained in:
parent
88c9851795
commit
05c35f2cf7
@ -61,16 +61,64 @@ canonicalize_xattrs (char *xattr_string, size_t len)
|
||||
return g_string_free (result, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
hacktree_get_xattrs_for_directory (const char *path,
|
||||
char **out_xattrs, /* out */
|
||||
gsize *out_len, /* out */
|
||||
GError **error)
|
||||
static gboolean
|
||||
read_xattr_name_array (const char *path,
|
||||
const char *xattrs,
|
||||
size_t len,
|
||||
GVariantBuilder *builder,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
char *xattrs = NULL;
|
||||
const char *p;
|
||||
|
||||
p = xattrs;
|
||||
while (p < xattrs+len)
|
||||
{
|
||||
ssize_t bytes_read;
|
||||
char *buf;
|
||||
|
||||
bytes_read = lgetxattr (path, p, NULL, 0);
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
ht_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
if (bytes_read == 0)
|
||||
continue;
|
||||
|
||||
buf = g_malloc (bytes_read);
|
||||
if (lgetxattr (path, p, buf, bytes_read) < 0)
|
||||
{
|
||||
ht_util_set_error_from_errno (error, errno);
|
||||
g_free (buf);
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_variant_builder_add (builder, "(@ay@ay)",
|
||||
g_variant_new_bytestring (p),
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE ("y"), buf, bytes_read, 1));
|
||||
|
||||
g_free (buf);
|
||||
p = p + strlen (p) + 1;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
hacktree_get_xattrs_for_path (const char *path,
|
||||
GError **error)
|
||||
{
|
||||
GVariant *ret = NULL;
|
||||
GVariantBuilder builder;
|
||||
char *xattr_names = NULL;
|
||||
char *xattr_names_canonical = NULL;
|
||||
ssize_t bytes_read;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ayay)"));
|
||||
|
||||
bytes_read = llistxattr (path, NULL, 0);
|
||||
|
||||
if (bytes_read < 0)
|
||||
@ -83,27 +131,25 @@ hacktree_get_xattrs_for_directory (const char *path,
|
||||
}
|
||||
else if (bytes_read > 0)
|
||||
{
|
||||
xattrs = g_malloc (bytes_read);
|
||||
if (!llistxattr (path, xattrs, bytes_read))
|
||||
const char *p;
|
||||
xattr_names = g_malloc (bytes_read);
|
||||
if (llistxattr (path, xattr_names, bytes_read) < 0)
|
||||
{
|
||||
ht_util_set_error_from_errno (error, errno);
|
||||
g_free (xattrs);
|
||||
xattrs = NULL;
|
||||
goto out;
|
||||
}
|
||||
xattr_names_canonical = canonicalize_xattrs (xattr_names, bytes_read);
|
||||
|
||||
*out_xattrs = canonicalize_xattrs (xattrs, bytes_read);
|
||||
*out_len = (gsize)bytes_read;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out_xattrs = NULL;
|
||||
*out_len = 0;
|
||||
if (!read_xattr_name_array (path, xattr_names_canonical, bytes_read, &builder, error))
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
ret = g_variant_builder_end (&builder);
|
||||
out:
|
||||
g_free (xattrs);
|
||||
if (!ret)
|
||||
g_variant_builder_clear (&builder);
|
||||
g_free (xattr_names);
|
||||
g_free (xattr_names_canonical);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -117,8 +163,7 @@ hacktree_stat_and_checksum_file (int dir_fd, const char *path,
|
||||
GChecksum *content_and_meta_sha256 = NULL;
|
||||
char *stat_string = NULL;
|
||||
ssize_t bytes_read;
|
||||
char *xattrs = NULL;
|
||||
char *xattrs_canonicalized = NULL;
|
||||
GVariant *xattrs = NULL;
|
||||
int fd = -1;
|
||||
DIR *temp_dir = NULL;
|
||||
char *basename = NULL;
|
||||
@ -159,39 +204,9 @@ hacktree_stat_and_checksum_file (int dir_fd, const char *path,
|
||||
}
|
||||
|
||||
stat_string = stat_to_string (&stbuf);
|
||||
|
||||
/* FIXME - Add llistxattrat */
|
||||
if (!S_ISLNK(stbuf.st_mode))
|
||||
bytes_read = flistxattr (fd, NULL, 0);
|
||||
else
|
||||
bytes_read = llistxattr (path, NULL, 0);
|
||||
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
if (errno != ENOTSUP)
|
||||
{
|
||||
ht_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (bytes_read > 0)
|
||||
{
|
||||
gboolean tmp;
|
||||
xattrs = g_malloc (bytes_read);
|
||||
/* FIXME - Add llistxattrat */
|
||||
if (!S_ISLNK(stbuf.st_mode))
|
||||
tmp = flistxattr (fd, xattrs, bytes_read);
|
||||
else
|
||||
tmp = llistxattr (path, xattrs, bytes_read);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
ht_util_set_error_from_errno (error, errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
xattrs_canonicalized = canonicalize_xattrs (xattrs, bytes_read);
|
||||
}
|
||||
xattrs = hacktree_get_xattrs_for_path (path, error);
|
||||
if (!xattrs)
|
||||
goto out;
|
||||
|
||||
content_sha256 = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
|
||||
@ -235,7 +250,7 @@ hacktree_stat_and_checksum_file (int dir_fd, const char *path,
|
||||
content_and_meta_sha256 = g_checksum_copy (content_sha256);
|
||||
|
||||
g_checksum_update (content_and_meta_sha256, (guint8*)stat_string, strlen (stat_string));
|
||||
g_checksum_update (content_and_meta_sha256, (guint8*)xattrs_canonicalized, strlen (stat_string));
|
||||
g_checksum_update (content_and_meta_sha256, (guint8*)g_variant_get_data (xattrs), g_variant_get_size (xattrs));
|
||||
|
||||
*out_stbuf = stbuf;
|
||||
*out_checksum = content_and_meta_sha256;
|
||||
@ -248,8 +263,8 @@ hacktree_stat_and_checksum_file (int dir_fd, const char *path,
|
||||
g_free (symlink_target);
|
||||
g_free (basename);
|
||||
g_free (stat_string);
|
||||
g_free (xattrs);
|
||||
g_free (xattrs_canonicalized);
|
||||
if (xattrs)
|
||||
g_variant_unref (xattrs);
|
||||
if (content_sha256)
|
||||
g_checksum_free (content_sha256);
|
||||
|
||||
|
@ -36,11 +36,18 @@ typedef enum {
|
||||
typedef enum {
|
||||
HACKTREE_SERIALIZED_TREE_VARIANT = 1,
|
||||
HACKTREE_SERIALIZED_COMMIT_VARIANT = 2,
|
||||
HACKTREE_SERIALIZED_DIRMETA_VARIANT = 3
|
||||
HACKTREE_SERIALIZED_DIRMETA_VARIANT = 3,
|
||||
HACKTREE_SERIALIZED_XATTR_VARIANT = 4
|
||||
} HacktreeSerializedVariantType;
|
||||
|
||||
#define HACKTREE_SERIALIZED_VARIANT_FORMAT "(uv)"
|
||||
|
||||
/*
|
||||
* xattr objects:
|
||||
* a(ayay) - array of (name, value) pairs, both binary data, though name is a bytestring
|
||||
*/
|
||||
#define HACKTREE_XATTR_GVARIANT_FORMAT "a(ayay)"
|
||||
|
||||
#define HACKTREE_DIR_META_VERSION 0
|
||||
/*
|
||||
* dirmeta objects:
|
||||
@ -48,9 +55,9 @@ typedef enum {
|
||||
* u - uid
|
||||
* u - gid
|
||||
* u - mode
|
||||
* ay - xattrs
|
||||
* a(ayay) - xattrs
|
||||
*/
|
||||
#define HACKTREE_DIRMETA_GVARIANT_FORMAT "(uuuuay)"
|
||||
#define HACKTREE_DIRMETA_GVARIANT_FORMAT "(uuuua(ayay))"
|
||||
|
||||
#define HACKTREE_TREE_VERSION 0
|
||||
/*
|
||||
@ -75,10 +82,8 @@ typedef enum {
|
||||
*/
|
||||
#define HACKTREE_COMMIT_GVARIANT_FORMAT "(ua{sv}sssts)"
|
||||
|
||||
gboolean hacktree_get_xattrs_for_directory (const char *path,
|
||||
char **out_xattrs,
|
||||
gsize *out_len,
|
||||
GError **error);
|
||||
GVariant *hacktree_get_xattrs_for_path (const char *path,
|
||||
GError **error);
|
||||
|
||||
gboolean hacktree_stat_and_checksum_file (int dirfd, const char *path,
|
||||
GChecksum **out_checksum,
|
||||
|
@ -402,7 +402,7 @@ import_directory_meta (HacktreeRepo *self,
|
||||
struct stat stbuf;
|
||||
GChecksum *ret_checksum = NULL;
|
||||
GVariant *dirmeta = NULL;
|
||||
char *xattrs = NULL;
|
||||
GVariant *xattrs = NULL;
|
||||
gsize xattr_len;
|
||||
|
||||
if (lstat (path, &stbuf) < 0)
|
||||
@ -418,16 +418,17 @@ import_directory_meta (HacktreeRepo *self,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!hacktree_get_xattrs_for_directory (path, &xattrs, &xattr_len, error))
|
||||
xattrs = hacktree_get_xattrs_for_path (path, error);
|
||||
if (!xattrs)
|
||||
goto out;
|
||||
|
||||
dirmeta = g_variant_new ("(uuuu@ay)",
|
||||
dirmeta = g_variant_new ("(uuuu@a(ayay))",
|
||||
HACKTREE_DIR_META_VERSION,
|
||||
(guint32)stbuf.st_uid,
|
||||
(guint32)stbuf.st_gid,
|
||||
(guint32)(stbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
|
||||
g_variant_new_fixed_array (G_VARIANT_TYPE ("y"),
|
||||
xattrs, xattr_len, 1));
|
||||
xattrs);
|
||||
xattrs = NULL; /* was floating */
|
||||
g_variant_ref_sink (dirmeta);
|
||||
|
||||
if (!import_gvariant_object (self, HACKTREE_SERIALIZED_DIRMETA_VARIANT,
|
||||
@ -448,7 +449,8 @@ import_directory_meta (HacktreeRepo *self,
|
||||
*out_checksum = ret_checksum;
|
||||
*out_variant = dirmeta;
|
||||
}
|
||||
g_free (xattrs);
|
||||
if (xattrs)
|
||||
g_variant_unref (xattrs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1473,10 +1475,9 @@ checkout_one_directory (HacktreeRepo *self,
|
||||
|
||||
dest_path = g_build_filename (destination, dirname, NULL);
|
||||
|
||||
g_variant_get (dir->meta_data, "(uuuu@ay)",
|
||||
g_variant_get (dir->meta_data, "(uuuu@a(ayay))",
|
||||
&version, &uid, &gid, &mode,
|
||||
&xattr_variant);
|
||||
xattrs = g_variant_get_fixed_array (xattr_variant, &xattr_len, 1);
|
||||
|
||||
if (mkdir (dest_path, (mode_t)mode) < 0)
|
||||
{
|
||||
|
@ -22,7 +22,7 @@ set -e
|
||||
|
||||
. libtest.sh
|
||||
|
||||
echo '1..3'
|
||||
echo '1..5'
|
||||
|
||||
setup_test_repository2
|
||||
echo 'ok setup'
|
||||
@ -30,8 +30,10 @@ hacktree checkout $ht_repo HEAD $test_tmpdir/checkout2-head
|
||||
echo 'ok checkout cmd'
|
||||
cd $test_tmpdir/checkout2-head
|
||||
assert_has_file firstfile
|
||||
echo 'ok checkout firstfile'
|
||||
assert_has_file baz/cow
|
||||
assert_has_file baz/saucer
|
||||
echo 'ok checkout baz (2)'
|
||||
assert_has_file baz/deeper/ohyeah
|
||||
assert_has_file baz/another/y
|
||||
echo 'ok checkout verify exists'
|
||||
|
Loading…
Reference in New Issue
Block a user