diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-08-01 16:17:38 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-08-01 16:23:07 +0200 | 
| commit | 78e35e9d44b2ec7a36a0acac1ab63343b56b9c2c (patch) | |
| tree | 79125d4f92e5d2fab68d958cf76cfde8fc642c2e /tar | |
| parent | cccbd5aa139b8e0cac233f317cb3e7252daae0d9 (diff) | |
Add ability to sqfs2tar to optionally copy over xattrs
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'tar')
| -rw-r--r-- | tar/sqfs2tar.c | 60 | 
1 files changed, 55 insertions, 5 deletions
| diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c index 07be2b4..3a7d92d 100644 --- a/tar/sqfs2tar.c +++ b/tar/sqfs2tar.c @@ -27,11 +27,12 @@ static struct option long_opts[] = {  	{ "subdir", required_argument, NULL, 'd' },  	{ "keep-as-dir", no_argument, NULL, 'k' },  	{ "no-skip", no_argument, NULL, 's' }, +	{ "no-xattr", no_argument, NULL, 'X' },  	{ "help", no_argument, NULL, 'h' },  	{ "version", no_argument, NULL, 'V' },  }; -static const char *short_opts = "d:kshV"; +static const char *short_opts = "d:ksXhV";  static const char *usagestr =  "Usage: sqfs2tar [OPTIONS...] <sqfsfile>\n" @@ -52,8 +53,9 @@ static const char *usagestr =  "                            prefix for all unpacked files.\n"  "                            Using --subdir more than once implies\n"  "                            --keep-as-dir.\n" +"  --no-xattr, -X            Do not copy extended attributes.\n"  "\n" -"  --no-skip                 Abort if a file cannot be stored in a tar\n" +"  --no-skip, -s             Abort if a file cannot be stored in a tar\n"  "                            archive. By default, it is simply skipped\n"  "                            and a warning is written to stderr.\n"  "\n" @@ -71,6 +73,7 @@ static const char *filename;  static unsigned int record_counter;  static bool dont_skip = false;  static bool keep_as_dir = false; +static bool no_xattr = false;  static const char *current_subdir = NULL; @@ -119,6 +122,9 @@ static void process_args(int argc, char **argv)  		case 's':  			dont_skip = true;  			break; +		case 'X': +			no_xattr = true; +			break;  		case 'h':  			fputs(usagestr, stdout);  			goto out_success; @@ -175,8 +181,40 @@ static int terminate_archive(void)  			  buffer, sizeof(buffer));  } +static tar_xattr_t *gen_xattr_list(fstree_t *fs, tree_xattr_t *xattr) +{ +	const char *key, *value; +	tar_xattr_t *list; +	size_t i; + +	list = malloc(sizeof(list[0]) * xattr->num_attr); +	if (list == NULL) { +		perror("creating xattr list"); +		return NULL; +	} + +	for (i = 0; i < xattr->num_attr; ++i) { +		key = str_table_get_string(&fs->xattr_keys, +					   xattr->attr[i].key_index); +		value = str_table_get_string(&fs->xattr_values, +					     xattr->attr[i].value_index); + +		list[i].key = (char *)key; +		list[i].value = (char *)value; + +		if (i + 1 < xattr->num_attr) { +			list[i].next = list + i + 1; +		} else { +			list[i].next = NULL; +		} +	} + +	return list; +} +  static int write_tree_dfs(fstree_t *fs, tree_node_t *n, data_reader_t *data)  { +	tar_xattr_t *xattr = NULL;  	size_t len, name_len;  	char *name, *target;  	struct stat sb; @@ -210,9 +248,18 @@ static int write_tree_dfs(fstree_t *fs, tree_node_t *n, data_reader_t *data)  	fstree_node_stat(fs, n, &sb); +	if (!no_xattr && n->xattr != NULL) { +		xattr = gen_xattr_list(fs, n->xattr); +		if (xattr == NULL) { +			free(name); +			return -1; +		} +	} +  	target = S_ISLNK(sb.st_mode) ? n->data.slink_target : NULL; -	ret = write_tar_header(STDOUT_FILENO, &sb, name, target, NULL, +	ret = write_tar_header(STDOUT_FILENO, &sb, name, target, xattr,  			       record_counter++); +	free(xattr);  	if (ret > 0) {  		if (dont_skip) { @@ -254,13 +301,13 @@ skip_hdr:  int main(int argc, char **argv)  { +	int sqfsfd, rdtree_flags = 0;  	data_reader_t *data = NULL;  	int status = EXIT_FAILURE;  	sqfs_super_t super;  	compressor_t *cmp;  	tree_node_t *root;  	fstree_t fs; -	int sqfsfd;  	size_t i;  	process_args(argc, argv); @@ -290,7 +337,10 @@ int main(int argc, char **argv)  			goto out_cmp;  	} -	if (deserialize_fstree(&fs, &super, cmp, sqfsfd, 0)) +	if (!no_xattr) +		rdtree_flags |= RDTREE_READ_XATTR; + +	if (deserialize_fstree(&fs, &super, cmp, sqfsfd, rdtree_flags))  		goto out_cmp;  	data = data_reader_create(sqfsfd, &super, cmp); | 
