diff options
Diffstat (limited to 'unpack')
| -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 | 
4 files changed, 53 insertions, 7 deletions
| 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);  } | 
