diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | doc/rdsquashfs.1 | 4 | ||||
-rw-r--r-- | unpack/options.c | 20 | ||||
-rw-r--r-- | unpack/rdsquashfs.c | 2 | ||||
-rw-r--r-- | unpack/rdsquashfs.h | 6 | ||||
-rw-r--r-- | unpack/restore_fstree.c | 32 |
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); } |