diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-07-23 16:46:42 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-07-25 22:10:24 +0200 | 
| commit | 2fcf04928a0eaf7332503753a4866a0f2031a50e (patch) | |
| tree | fb7c5ae31faa21850ec283bd14d91818ceeb21a0 /unpack | |
| parent | 22fba34bcd0f2944def234fa684d1c9cc4d65310 (diff) | |
rdsquashfs: seperate creating of the hierarchy, unpacking and chmod/chown
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'unpack')
| -rw-r--r-- | unpack/Makemodule.am | 1 | ||||
| -rw-r--r-- | unpack/fill_files.c | 39 | ||||
| -rw-r--r-- | unpack/rdsquashfs.c | 21 | ||||
| -rw-r--r-- | unpack/rdsquashfs.h | 7 | ||||
| -rw-r--r-- | unpack/restore_fstree.c | 71 | 
5 files changed, 116 insertions, 23 deletions
| diff --git a/unpack/Makemodule.am b/unpack/Makemodule.am index b958851..08a8b76 100644 --- a/unpack/Makemodule.am +++ b/unpack/Makemodule.am @@ -1,6 +1,7 @@  rdsquashfs_SOURCES = unpack/rdsquashfs.c unpack/rdsquashfs.h  rdsquashfs_SOURCES += unpack/list_files.c unpack/options.c  rdsquashfs_SOURCES += unpack/restore_fstree.c unpack/describe.c +rdsquashfs_SOURCES += unpack/fill_files.c  rdsquashfs_LDADD = libsquashfs.a libfstree.a libcompress.a libutil.a  rdsquashfs_LDADD += $(XZ_LIBS) $(ZLIB_LIBS) $(LZO_LIBS) $(LZ4_LIBS) $(ZSTD_LIBS) diff --git a/unpack/fill_files.c b/unpack/fill_files.c new file mode 100644 index 0000000..6584699 --- /dev/null +++ b/unpack/fill_files.c @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#include "config.h" +#include "rdsquashfs.h" + +static int fill_files(data_reader_t *data, file_info_t *list, int flags) +{ +	file_info_t *fi; +	int fd; + +	for (fi = list; fi != NULL; fi = fi->next) { +		if (fi->input_file == NULL) +			continue; + +		fd = open(fi->input_file, O_WRONLY); +		if (fd < 0) { +			fprintf(stderr, "unpacking %s: %s\n", +				fi->input_file, strerror(errno)); +			return -1; +		} + +		if (!(flags & UNPACK_QUIET)) +			printf("unpacking %s\n", fi->input_file); + +		if (data_reader_dump_file(data, fi, fd, +					  (flags & UNPACK_NO_SPARSE) == 0)) { +			close(fd); +			return -1; +		} + +		close(fd); +	} + +	return 0; +} + +int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags) +{ +	return fill_files(data, fs->files, flags); +} diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index 4a0f12b..a3618e3 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -42,6 +42,8 @@ int main(int argc, char **argv)  	if (deserialize_fstree(&fs, &super, cmp, sqfsfd, opt.rdtree_flags))  		goto out_cmp; +	fstree_gen_file_list(&fs); +  	if (opt.cmdpath != NULL) {  		n = fstree_node_from_path(&fs, opt.cmdpath);  		if (n == NULL) { @@ -72,11 +74,28 @@ int main(int argc, char **argv)  			goto out_fs;  		break;  	case OP_UNPACK: +		if (opt.unpack_root != NULL) { +			if (mkdir_p(opt.unpack_root)) +				return -1; + +			if (pushd(opt.unpack_root)) +				return -1; +		} + +		if (restore_fstree(n, opt.flags)) +			goto out_fs; +  		data = data_reader_create(sqfsfd, &super, cmp);  		if (data == NULL)  			goto out_fs; -		if (restore_fstree(opt.unpack_root, n, data, opt.flags)) +		if (fill_unpacked_files(&fs, data, opt.flags)) +			goto out_fs; + +		if (update_tree_attribs(n, opt.flags)) +			goto out_fs; + +		if (opt.unpack_root != NULL && popd() != 0)  			goto out_fs;  		break;  	case OP_DESCRIBE: diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h index ed882ff..45c91db 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -48,8 +48,11 @@ typedef struct {  void list_files(tree_node_t *node); -int restore_fstree(const char *rootdir, tree_node_t *root, -		   data_reader_t *data, int flags); +int restore_fstree(tree_node_t *root, int flags); + +int update_tree_attribs(tree_node_t *root, int flags); + +int fill_unpacked_files(fstree_t *fs, data_reader_t *data, int flags);  void describe_tree(tree_node_t *root, const char *unpack_root); diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 455e604..5027625 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -1,7 +1,7 @@  /* SPDX-License-Identifier: GPL-3.0-or-later */  #include "rdsquashfs.h" -static int create_node(tree_node_t *n, data_reader_t *data, int flags) +static int create_node(tree_node_t *n, int flags)  {  	tree_node_t *c;  	char *name; @@ -9,7 +9,7 @@ static int create_node(tree_node_t *n, data_reader_t *data, int flags)  	if (!(flags & UNPACK_QUIET)) {  		name = fstree_get_path(n); -		printf("unpacking %s\n", name); +		printf("creating %s\n", name);  		free(name);  	} @@ -25,7 +25,7 @@ static int create_node(tree_node_t *n, data_reader_t *data, int flags)  			return -1;  		for (c = n->data.dir->children; c != NULL; c = c->next) { -			if (create_node(c, data, flags)) +			if (create_node(c, flags))  				return -1;  		} @@ -64,18 +64,45 @@ static int create_node(tree_node_t *n, data_reader_t *data, int flags)  			return -1;  		} -		if (data_reader_dump_file(data, n->data.file, fd, -					  (flags & UNPACK_NO_SPARSE) == 0)) { -			close(fd); +		close(fd); + +		if (n->parent != NULL) { +			n->data.file->input_file = fstree_get_path(n); +		} else { +			n->data.file->input_file = strdup(n->name); +		} + +		if (n->data.file->input_file == NULL) { +			perror("restoring file path");  			return -1;  		} -		close(fd); +		canonicalize_name(n->data.file->input_file);  		break;  	default:  		break;  	} +	return 0; +} + +static int set_attribs(tree_node_t *n, int flags) +{ +	tree_node_t *c; + +	if (S_ISDIR(n->mode)) { +		if (pushd(n->name)) +			return -1; + +		for (c = n->data.dir->children; c != NULL; c = c->next) { +			if (set_attribs(c, flags)) +				return -1; +		} + +		if (popd()) +			return -1; +	} +  	if (flags & UNPACK_CHOWN) {  		if (fchownat(AT_FDCWD, n->name, n->uid, n->gid,  			     AT_SYMLINK_NOFOLLOW)) { @@ -96,28 +123,32 @@ static int create_node(tree_node_t *n, data_reader_t *data, int flags)  	return 0;  } -int restore_fstree(const char *rootdir, tree_node_t *root, -		   data_reader_t *data, int flags) +int restore_fstree(tree_node_t *root, int flags)  { -	tree_node_t *n; +	tree_node_t *n, *old_parent; -	if (rootdir != NULL) { -		if (mkdir_p(rootdir)) -			return -1; - -		if (pushd(rootdir)) -			return -1; -	} +	/* make sure fstree_get_path() stops at this node */ +	old_parent = root->parent; +	root->parent = NULL;  	if (S_ISDIR(root->mode)) {  		for (n = root->data.dir->children; n != NULL; n = n->next) { -			if (create_node(n, data, flags)) +			if (create_node(n, flags))  				return -1;  		}  	} else { -		if (create_node(root, data, flags)) +		if (create_node(root, flags))  			return -1;  	} -	return rootdir == NULL ? 0 : popd(); +	root->parent = old_parent; +	return 0; +} + +int update_tree_attribs(tree_node_t *root, int flags) +{ +	if ((flags & (UNPACK_CHOWN | UNPACK_CHMOD)) == 0) +		return 0; + +	return set_attribs(root, flags);  } | 
