summaryrefslogtreecommitdiff
path: root/bin/sqfs2tar/xattr.c
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2020-05-27 15:29:11 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2020-05-30 17:49:40 +0200
commit36e70b384e1360e47f473be54ef3c0599bf82844 (patch)
treea58bdb2cf0063904f8c602137e494c4d658bc574 /bin/sqfs2tar/xattr.c
parente5f99ba93e08e237962bcf337848e60730aa2d54 (diff)
Cleanup: sqfs2tar: break up and simplify the repacking code
- Move the xattr extraction and repacking to xattr.c - Don't on-the-fly delete the tar xattr list, use the function from libtar.a - Split minor tasks into static helper functions - creating a libtar xattr struct from libsqfs xattr data - finding a hard link entry from current path and inode number Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin/sqfs2tar/xattr.c')
-rw-r--r--bin/sqfs2tar/xattr.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/bin/sqfs2tar/xattr.c b/bin/sqfs2tar/xattr.c
new file mode 100644
index 0000000..9a9ec82
--- /dev/null
+++ b/bin/sqfs2tar/xattr.c
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * xattr.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "sqfs2tar.h"
+
+static tar_xattr_t *mkxattr(const sqfs_xattr_entry_t *key,
+ const sqfs_xattr_value_t *value)
+{
+ tar_xattr_t *ent;
+
+ ent = calloc(1, sizeof(*ent) + strlen((const char *)key->key) +
+ value->size + 2);
+
+ if (ent == NULL) {
+ perror("creating xattr entry");
+ return NULL;
+ }
+
+ ent->key = ent->data;
+ ent->value = (sqfs_u8 *)ent->key + strlen((const char *)key->key) + 1;
+ ent->value_len = value->size;
+
+ strcpy(ent->key, (const char *)key->key);
+ memcpy(ent->value, value->value, value->size + 1);
+ return ent;
+}
+
+int get_xattrs(const char *name, const sqfs_inode_generic_t *inode,
+ tar_xattr_t **out)
+{
+ tar_xattr_t *list = NULL, *ent;
+ sqfs_xattr_value_t *value;
+ sqfs_xattr_entry_t *key;
+ sqfs_xattr_id_t desc;
+ sqfs_u32 index;
+ size_t i;
+ int ret;
+
+ if (xr == NULL)
+ return 0;
+
+ sqfs_inode_get_xattr_index(inode, &index);
+ if (index == 0xFFFFFFFF)
+ return 0;
+
+ ret = sqfs_xattr_reader_get_desc(xr, index, &desc);
+ if (ret) {
+ sqfs_perror(name, "resolving xattr index", ret);
+ return -1;
+ }
+
+ ret = sqfs_xattr_reader_seek_kv(xr, &desc);
+ if (ret) {
+ sqfs_perror(name, "locating xattr key-value pairs", ret);
+ return -1;
+ }
+
+ for (i = 0; i < desc.count; ++i) {
+ ret = sqfs_xattr_reader_read_key(xr, &key);
+ if (ret) {
+ sqfs_perror(name, "reading xattr key", ret);
+ goto fail;
+ }
+
+ ret = sqfs_xattr_reader_read_value(xr, key, &value);
+ if (ret) {
+ sqfs_perror(name, "reading xattr value", ret);
+ free(key);
+ goto fail;
+ }
+
+ ent = mkxattr(key, value);
+ free(key);
+ free(value);
+
+ if (ent == NULL)
+ goto fail;
+
+ ent->next = list;
+ list = ent;
+ }
+
+ *out = list;
+ return 0;
+fail:
+ free_xattr_list(list);
+ return -1;
+}