diff options
Diffstat (limited to 'unpack')
| -rw-r--r-- | unpack/Makemodule.am | 2 | ||||
| -rw-r--r-- | unpack/extract_file.c | 93 | ||||
| -rw-r--r-- | unpack/rdsquashfs.c | 61 | ||||
| -rw-r--r-- | unpack/rdsquashfs.h | 10 | ||||
| -rw-r--r-- | unpack/restore_fstree.c | 2 | 
5 files changed, 13 insertions, 155 deletions
| diff --git a/unpack/Makemodule.am b/unpack/Makemodule.am index 5f4269e..c70026d 100644 --- a/unpack/Makemodule.am +++ b/unpack/Makemodule.am @@ -1,5 +1,5 @@  rdsquashfs_SOURCES = unpack/rdsquashfs.c unpack/rdsquashfs.h -rdsquashfs_SOURCES += unpack/list_files.c unpack/extract_file.c +rdsquashfs_SOURCES += unpack/list_files.c  rdsquashfs_SOURCES += unpack/restore_fstree.c unpack/describe.c  rdsquashfs_LDADD = libsquashfs.a libfstree.a libcompress.a libutil.a diff --git a/unpack/extract_file.c b/unpack/extract_file.c deleted file mode 100644 index 62d1086..0000000 --- a/unpack/extract_file.c +++ /dev/null @@ -1,93 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -#include "rdsquashfs.h" - -int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd) -{ -	size_t i, count, fragsz; -	bool compressed; -	uint32_t bs; -	ssize_t ret; -	void *ptr; - -	count = fi->size / info->block_size; - -	if (count > 0) { -		if (lseek(info->sqfsfd, fi->startblock, SEEK_SET) == (off_t)-1) -			goto fail_seek; - -		for (i = 0; i < count; ++i) { -			bs = fi->blocksizes[i]; - -			compressed = (bs & (1 << 24)) == 0; -			bs &= (1 << 24) - 1; - -			if (bs > info->block_size) -				goto fail_bs; - -			ret = read_retry(info->sqfsfd, info->buffer, bs); -			if (ret < 0) -				goto fail_rd; - -			if ((size_t)ret < bs) -				goto fail_trunc; - -			if (compressed) { -				ret = info->cmp->do_block(info->cmp, -							  info->buffer, bs, -							  info->scratch, -							  info->block_size); -				if (ret <= 0) -					return -1; - -				bs = ret; -				ptr = info->scratch; -			} else { -				ptr = info->buffer; -			} - -			ret = write_retry(outfd, ptr, bs); -			if (ret < 0) -				goto fail_wr; - -			if ((size_t)ret < bs) -				goto fail_wr_trunc; -		} -	} - -	fragsz = fi->size % info->block_size; - -	if (fragsz > 0) { -		if (frag_reader_read(info->frag, fi->fragment, -				     fi->fragment_offset, info->buffer, -				     fragsz)) { -			return -1; -		} - -		ret = write_retry(outfd, info->buffer, fragsz); -		if (ret < 0) -			goto fail_wr; - -		if ((size_t)ret < fragsz) -			goto fail_wr_trunc; -	} - -	return 0; -fail_seek: -	perror("seek on squashfs"); -	return -1; -fail_wr: -	perror("writing uncompressed block"); -	return -1; -fail_wr_trunc: -	fputs("writing uncompressed block: truncated write\n", stderr); -	return -1; -fail_rd: -	perror("reading from squashfs"); -	return -1; -fail_trunc: -	fputs("reading from squashfs: unexpected end of file\n", stderr); -	return -1; -fail_bs: -	fputs("found compressed block larger than block size\n", stderr); -	return -1; -} diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index 81da226..7fd2947 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -121,43 +121,6 @@ static char *get_path(char *old, const char *arg)  	return path;  } -static int alloc_buffers(unsqfs_info_t *info, sqfs_super_t *super) -{ -	info->buffer = malloc(super->block_size); -	if (info->buffer == NULL) { -		perror("allocating block buffer"); -		return -1; -	} - -	info->scratch = malloc(super->block_size); -	if (info->scratch == NULL) { -		perror("allocating scrtach buffer for extracting blocks"); -		return -1; -	} - -	return 0; -} - -static int load_fragment_table(unsqfs_info_t *info, sqfs_super_t *super) -{ -	if (super->fragment_entry_count == 0) -		return 0; - -	if (super->flags & SQFS_FLAG_NO_FRAGMENTS) -		return 0; - -	if (super->fragment_table_start >= super->bytes_used) { -		fputs("Fragment table start is past end of file\n", stderr); -		return -1; -	} - -	info->frag = frag_reader_create(super, info->sqfsfd, info->cmp); -	if (info->frag == NULL) -		return -1; - -	return 0; -} -  int main(int argc, char **argv)  {  	int i, status = EXIT_FAILURE, op = OP_NONE; @@ -281,8 +244,6 @@ int main(int argc, char **argv)  		goto out_cmp;  	} -	info.block_size = super.block_size; -  	switch (op) {  	case OP_LS:  		n = find_node(fs.root, cmdpath); @@ -305,14 +266,14 @@ int main(int argc, char **argv)  			goto out_fs;  		} -		if (load_fragment_table(&info, &super)) +		info.data = data_reader_create(info.sqfsfd, &super, info.cmp); +		if (info.data == NULL)  			goto out_fs; -		if (alloc_buffers(&info, &super)) -			goto out_fs; - -		if (extract_file(n->data.file, &info, STDOUT_FILENO)) +		if (data_reader_dump_file(info.data, n->data.file, +					  STDOUT_FILENO)) {  			goto out_fs; +		}  		break;  	case OP_UNPACK:  		n = find_node(fs.root, cmdpath); @@ -321,10 +282,8 @@ int main(int argc, char **argv)  			goto out_fs;  		} -		if (load_fragment_table(&info, &super)) -			goto out_fs; - -		if (alloc_buffers(&info, &super)) +		info.data = data_reader_create(info.sqfsfd, &super, info.cmp); +		if (info.data == NULL)  			goto out_fs;  		if (restore_fstree(unpack_root, n, &info)) @@ -337,8 +296,8 @@ int main(int argc, char **argv)  	status = EXIT_SUCCESS;  out_fs: -	if (info.frag != NULL) -		frag_reader_destroy(info.frag); +	if (info.data != NULL) +		data_reader_destroy(info.data);  	fstree_cleanup(&fs);  out_cmp:  	info.cmp->destroy(info.cmp); @@ -346,8 +305,6 @@ out_fd:  	close(info.sqfsfd);  out_cmd:  	free(cmdpath); -	free(info.buffer); -	free(info.scratch);  	return status;  fail_arg:  	fprintf(stderr, "Try `%s --help' for more information.\n", __progname); diff --git a/unpack/rdsquashfs.h b/unpack/rdsquashfs.h index a615bb5..b927bab 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -3,7 +3,7 @@  #define RDSQUASHFS_H  #include "meta_reader.h" -#include "frag_reader.h" +#include "data_reader.h"  #include "highlevel.h"  #include "squashfs.h"  #include "compress.h" @@ -27,21 +27,15 @@ enum UNPACK_FLAGS {  };  typedef struct { +	data_reader_t *data;  	compressor_t *cmp; -	size_t block_size; -	frag_reader_t *frag;  	int rdtree_flags;  	int sqfsfd;  	int flags; - -	void *buffer; -	void *scratch;  } unsqfs_info_t;  void list_files(tree_node_t *node); -int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd); -  int restore_fstree(const char *rootdir, tree_node_t *root,  		   unsqfs_info_t *info); diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 355bbb5..a39ec97 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -63,7 +63,7 @@ static int create_node(tree_node_t *n, unsqfs_info_t *info)  			return -1;  		} -		if (extract_file(n->data.file, info, fd)) { +		if (data_reader_dump_file(info->data, n->data.file, fd)) {  			close(fd);  			return -1;  		} | 
