diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-05-27 15:29:11 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-05-30 17:49:40 +0200 | 
| commit | 36e70b384e1360e47f473be54ef3c0599bf82844 (patch) | |
| tree | a58bdb2cf0063904f8c602137e494c4d658bc574 /bin/sqfs2tar | |
| parent | e5f99ba93e08e237962bcf337848e60730aa2d54 (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')
| -rw-r--r-- | bin/sqfs2tar/Makemodule.am | 1 | ||||
| -rw-r--r-- | bin/sqfs2tar/sqfs2tar.h | 4 | ||||
| -rw-r--r-- | bin/sqfs2tar/write_tree.c | 110 | ||||
| -rw-r--r-- | bin/sqfs2tar/xattr.c | 91 | 
4 files changed, 113 insertions, 93 deletions
| diff --git a/bin/sqfs2tar/Makemodule.am b/bin/sqfs2tar/Makemodule.am index 3c5662d..f8d95cc 100644 --- a/bin/sqfs2tar/Makemodule.am +++ b/bin/sqfs2tar/Makemodule.am @@ -1,5 +1,6 @@  sqfs2tar_SOURCES = bin/sqfs2tar/sqfs2tar.c bin/sqfs2tar/sqfs2tar.h  sqfs2tar_SOURCES += bin/sqfs2tar/options.c bin/sqfs2tar/write_tree.c +sqfs2tar_SOURCES += bin/sqfs2tar/xattr.c  sqfs2tar_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS)  sqfs2tar_LDADD = libcommon.a libutil.a libsquashfs.la libtar.a libcompat.a  sqfs2tar_LDADD += libfstree.a $(LZO_LIBS) $(PTHREAD_LIBS) diff --git a/bin/sqfs2tar/sqfs2tar.h b/bin/sqfs2tar/sqfs2tar.h index afd267e..47d82ef 100644 --- a/bin/sqfs2tar/sqfs2tar.h +++ b/bin/sqfs2tar/sqfs2tar.h @@ -42,6 +42,10 @@ extern FILE *out_file;  char *assemble_tar_path(char *name, bool is_dir); +/* xattr.c */ +int get_xattrs(const char *name, const sqfs_inode_generic_t *inode, +	       tar_xattr_t **out); +  /* write_tree.c */  int write_tree_dfs(const sqfs_tree_node_t *n); diff --git a/bin/sqfs2tar/write_tree.c b/bin/sqfs2tar/write_tree.c index 545adc1..a84c20e 100644 --- a/bin/sqfs2tar/write_tree.c +++ b/bin/sqfs2tar/write_tree.c @@ -8,89 +8,25 @@  static unsigned int record_counter; -static int get_xattrs(const char *name, const sqfs_inode_generic_t *inode, -		      tar_xattr_t **out) +static sqfs_hard_link_t *find_hard_link(const char *name, sqfs_u32 inum)  { -	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; -		} +	sqfs_hard_link_t *lnk = NULL; -		ent = calloc(1, sizeof(*ent) + strlen((const char *)key->key) + -			     value->size + 2); -		if (ent == NULL) { -			perror("creating xattr entry"); -			free(key); -			free(value); -			goto fail; +	for (lnk = links; lnk != NULL; lnk = lnk->next) { +		if (lnk->inode_number == inum) { +			if (strcmp(name, lnk->target) == 0) +				lnk = NULL; +			break;  		} - -		ent->key = ent->data; -		strcpy(ent->key, (const char *)key->key); - -		ent->value = (sqfs_u8 *)ent->key + strlen(ent->key) + 1; -		memcpy(ent->value, value->value, value->size + 1); - -		ent->value_len = value->size; -		ent->next = list; -		list = ent; - -		free(key); -		free(value);  	} -	*out = list; -	return 0; -fail: -	while (list != NULL) { -		ent = list; -		list = list->next; -		free(ent); -	} -	return -1; +	return lnk;  }  int write_tree_dfs(const sqfs_tree_node_t *n)  { -	tar_xattr_t *xattr = NULL, *xit;  	sqfs_hard_link_t *lnk = NULL; +	tar_xattr_t *xattr = NULL;  	char *name, *target;  	struct stat sb;  	size_t len; @@ -133,24 +69,17 @@ int write_tree_dfs(const sqfs_tree_node_t *n)  		if (canonicalize_name(name))  			goto out_skip; -		for (lnk = links; lnk != NULL; lnk = lnk->next) { -			if (lnk->inode_number == n->inode->base.inode_number) { -				if (strcmp(name, lnk->target) == 0) -					lnk = NULL; -				break; -			} -		} -  		name = assemble_tar_path(name, S_ISDIR(sb.st_mode));  		if (name == NULL)  			return -1; -	} -	if (lnk != NULL) { -		ret = write_hard_link(out_file, &sb, name, lnk->target, -				      record_counter++); -		free(name); -		return ret; +		lnk = find_hard_link(name, n->inode->base.inode_number); +		if (lnk != NULL) { +			ret = write_hard_link(out_file, &sb, name, lnk->target, +					      record_counter++); +			free(name); +			return ret; +		}  	}  	if (!no_xattr) { @@ -163,12 +92,7 @@ int write_tree_dfs(const sqfs_tree_node_t *n)  	target = S_ISLNK(sb.st_mode) ? (char *)n->inode->extra : NULL;  	ret = write_tar_header(out_file, &sb, name, target, xattr,  			       record_counter++); - -	while (xattr != NULL) { -		xit = xattr; -		xattr = xattr->next; -		free(xit); -	} +	free_xattr_list(xattr);  	if (ret > 0)  		goto out_skip; 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; +} | 
