aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-08-01 21:48:12 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-08-01 21:50:49 +0200
commiteddb62072f4d4d2402d520e5041d9677fa6efdff (patch)
treebfbde95d8b0e825de8fdd92d597ba226f67813b5
parent0b79e0cad88fe6494c1d5af9a5e990b491170d11 (diff)
Add flag to rdsquashfs to optionally set xattrs on unpacked files
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--configure.ac2
-rw-r--r--doc/rdsquashfs.14
-rw-r--r--unpack/options.c20
-rw-r--r--unpack/rdsquashfs.c2
-rw-r--r--unpack/rdsquashfs.h6
-rw-r--r--unpack/restore_fstree.c32
6 files changed, 59 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac
index e9aa634..19ee8d4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -159,6 +159,8 @@ fi
##### additional checks #####
AX_COMPILE_CHECK_SIZEOF(time_t)
+AC_CHECK_HEADERS([sys/xattr.h], [], [])
+
##### generate output #####
AC_CONFIG_HEADERS([config.h])
diff --git a/doc/rdsquashfs.1 b/doc/rdsquashfs.1
index ef2a8c6..c6c9330 100644
--- a/doc/rdsquashfs.1
+++ b/doc/rdsquashfs.1
@@ -65,6 +65,10 @@ empty after applying the above rules.
Do not create sparse files. Always unpack sparse files by
writing blocks of zeros to disk.
.TP
+\fB\-\-set\-xattr\fR, \fB\-X\fR
+When unpacking files to disk, set the extended attributes from the
+SquashFS image.
+.TP
\fB\-\-chmod\fR, \fB\-C\fR
Change permission flags of unpacked files to
those store in the SquashFS image.
diff --git a/unpack/options.c b/unpack/options.c
index e5e0389..594b610 100644
--- a/unpack/options.c
+++ b/unpack/options.c
@@ -18,6 +18,9 @@ static struct option long_opts[] = {
{ "no-slink", no_argument, NULL, 'L' },
{ "no-empty-dir", no_argument, NULL, 'E' },
{ "no-sparse", no_argument, NULL, 'Z' },
+#ifdef HAVE_SYS_XATTR_H
+ { "set-xattr", no_argument, NULL, 'X' },
+#endif
{ "jobs", required_argument, NULL, 'j' },
{ "describe", no_argument, NULL, 'd' },
{ "chmod", no_argument, NULL, 'C' },
@@ -27,7 +30,12 @@ static struct option long_opts[] = {
{ "version", no_argument, NULL, 'V' },
};
-static const char *short_opts = "l:c:u:p:x:DSFLCOEZj:dqhV";
+static const char *short_opts =
+ "l:c:u:p:x:DSFLCOEZj:dqhV"
+#ifdef HAVE_SYS_XATTR_H
+ "X"
+#endif
+ ;
static const char *help_string =
"Usage: %s [OPTIONS] <squashfs-file>\n"
@@ -59,6 +67,10 @@ static const char *help_string =
" empty after applying the above rules.\n"
" --no-sparse, -Z Do not create sparse files, always write zero\n"
" blocks to disk.\n"
+#ifdef HAVE_SYS_XATTR_H
+" --set-xattr, -X When unpacking files to disk, set the extended\n"
+" attributes from the squashfs image.\n"
+#endif
" --jobs, -j <count> Number of parallel unpacking jobs to start.\n"
" --chmod, -C Change permission flags of unpacked files to\n"
" those store in the squashfs image.\n"
@@ -135,6 +147,12 @@ void process_command_line(options_t *opt, int argc, char **argv)
case 'Z':
opt->flags |= UNPACK_NO_SPARSE;
break;
+#ifdef HAVE_SYS_XATTR_H
+ case 'X':
+ opt->flags |= UNPACK_SET_XATTR;
+ opt->rdtree_flags |= RDTREE_READ_XATTR;
+ break;
+#endif
case 'j':
for (j = 0; optarg[j] != '\0'; ++j) {
if (j > 6 || !isdigit(optarg[j]))
diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c
index 5eb10f2..2162cc4 100644
--- a/unpack/rdsquashfs.c
+++ b/unpack/rdsquashfs.c
@@ -112,7 +112,7 @@ int main(int argc, char **argv)
if (fill_unpacked_files(&fs, data, opt.flags, opt.num_jobs))
goto out_fs;
- if (update_tree_attribs(n, opt.flags))
+ if (update_tree_attribs(&fs, n, opt.flags))
goto out_fs;
if (opt.unpack_root != NULL && popd() != 0)
diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h
index 5990ab9..44635d8 100644
--- a/unpack/rdsquashfs.h
+++ b/unpack/rdsquashfs.h
@@ -20,6 +20,9 @@
#include <sys/sysmacros.h>
#include <sys/types.h>
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
#include <sys/prctl.h>
#include <sys/wait.h>
#include <string.h>
@@ -37,6 +40,7 @@ enum UNPACK_FLAGS {
UNPACK_CHOWN = 0x02,
UNPACK_QUIET = 0x04,
UNPACK_NO_SPARSE = 0x08,
+ UNPACK_SET_XATTR = 0x10,
};
enum {
@@ -62,7 +66,7 @@ void list_files(tree_node_t *node);
int restore_fstree(tree_node_t *root, int flags);
-int update_tree_attribs(tree_node_t *root, int flags);
+int update_tree_attribs(fstree_t *fs, tree_node_t *root, int flags);
int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags,
unsigned int num_jobs);
diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c
index c25763c..7fe074e 100644
--- a/unpack/restore_fstree.c
+++ b/unpack/restore_fstree.c
@@ -91,7 +91,7 @@ static int create_node(tree_node_t *n, int flags)
return 0;
}
-static int set_attribs(tree_node_t *n, int flags)
+static int set_attribs(fstree_t *fs, tree_node_t *n, int flags)
{
tree_node_t *c;
@@ -100,7 +100,7 @@ static int set_attribs(tree_node_t *n, int flags)
return -1;
for (c = n->data.dir->children; c != NULL; c = c->next) {
- if (set_attribs(c, flags))
+ if (set_attribs(fs, c, flags))
return -1;
}
@@ -125,6 +125,30 @@ static int set_attribs(tree_node_t *n, int flags)
return -1;
}
}
+#ifdef HAVE_SYS_XATTR_H
+ if ((flags & UNPACK_SET_XATTR) && n->xattr != NULL) {
+ size_t i, len, kidx, vidx;
+ const char *key, *value;
+
+ for (i = 0; i < n->xattr->num_attr; ++i) {
+ kidx = n->xattr->attr[i].key_index;
+ vidx = n->xattr->attr[i].value_index;
+
+ key = str_table_get_string(&fs->xattr_keys, kidx);
+ value = str_table_get_string(&fs->xattr_values, vidx);
+ len = strlen(value);
+
+ if (lsetxattr(n->name, key, value, len, 0)) {
+ fprintf(stderr,
+ "setting xattr '%s' on %s: %s\n",
+ key, n->name, strerror(errno));
+ return -1;
+ }
+ }
+ }
+#else
+ (void)fs;
+#endif
return 0;
}
@@ -150,10 +174,10 @@ int restore_fstree(tree_node_t *root, int flags)
return 0;
}
-int update_tree_attribs(tree_node_t *root, int flags)
+int update_tree_attribs(fstree_t *fs, tree_node_t *root, int flags)
{
if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD)) == 0)
return 0;
- return set_attribs(root, flags);
+ return set_attribs(fs, root, flags);
}