diff options
Diffstat (limited to 'unpack')
| -rw-r--r-- | unpack/extract_file.c | 43 | ||||
| -rw-r--r-- | unpack/rdsquashfs.c | 25 | ||||
| -rw-r--r-- | unpack/rdsquashfs.h | 3 | 
3 files changed, 45 insertions, 26 deletions
| diff --git a/unpack/extract_file.c b/unpack/extract_file.c index 4d5997a..62d1086 100644 --- a/unpack/extract_file.c +++ b/unpack/extract_file.c @@ -3,19 +3,12 @@  int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd)  { -	void *buffer, *scratch, *ptr;  	size_t i, count, fragsz;  	bool compressed;  	uint32_t bs;  	ssize_t ret; +	void *ptr; -	buffer = malloc(info->block_size * 2); -	if (buffer == NULL) { -		perror("allocating scratch buffer"); -		return -1; -	} - -	scratch = (char *)buffer + info->block_size;  	count = fi->size / info->block_size;  	if (count > 0) { @@ -31,7 +24,7 @@ int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd)  			if (bs > info->block_size)  				goto fail_bs; -			ret = read_retry(info->sqfsfd, buffer, bs); +			ret = read_retry(info->sqfsfd, info->buffer, bs);  			if (ret < 0)  				goto fail_rd; @@ -39,16 +32,17 @@ int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd)  				goto fail_trunc;  			if (compressed) { -				ret = info->cmp->do_block(info->cmp, buffer, bs, -							  scratch, +				ret = info->cmp->do_block(info->cmp, +							  info->buffer, bs, +							  info->scratch,  							  info->block_size);  				if (ret <= 0) -					goto fail; +					return -1;  				bs = ret; -				ptr = scratch; +				ptr = info->scratch;  			} else { -				ptr = buffer; +				ptr = info->buffer;  			}  			ret = write_retry(outfd, ptr, bs); @@ -64,11 +58,12 @@ int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd)  	if (fragsz > 0) {  		if (frag_reader_read(info->frag, fi->fragment, -				     fi->fragment_offset, buffer, fragsz)) { -			goto fail; +				     fi->fragment_offset, info->buffer, +				     fragsz)) { +			return -1;  		} -		ret = write_retry(outfd, buffer, fragsz); +		ret = write_retry(outfd, info->buffer, fragsz);  		if (ret < 0)  			goto fail_wr; @@ -76,27 +71,23 @@ int extract_file(file_info_t *fi, unsqfs_info_t *info, int outfd)  			goto fail_wr_trunc;  	} -	free(buffer);  	return 0;  fail_seek:  	perror("seek on squashfs"); -	goto fail; +	return -1;  fail_wr:  	perror("writing uncompressed block"); -	goto fail; +	return -1;  fail_wr_trunc:  	fputs("writing uncompressed block: truncated write\n", stderr); -	goto fail; +	return -1;  fail_rd:  	perror("reading from squashfs"); -	goto fail; +	return -1;  fail_trunc:  	fputs("reading from squashfs: unexpected end of file\n", stderr); -	goto fail; +	return -1;  fail_bs:  	fputs("found compressed block larger than block size\n", stderr); -	goto fail; -fail: -	free(buffer);  	return -1;  } diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index 3c80853..c286a78 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -110,6 +110,23 @@ 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) @@ -274,6 +291,9 @@ int main(int argc, char **argv)  		if (load_fragment_table(&info, &super))  			goto out_fs; +		if (alloc_buffers(&info, &super)) +			goto out_fs; +  		if (extract_file(n->data.file, &info, STDOUT_FILENO))  			goto out_fs;  		break; @@ -291,6 +311,9 @@ int main(int argc, char **argv)  		if (load_fragment_table(&info, &super))  			goto out_fs; +		if (alloc_buffers(&info, &super)) +			goto out_fs; +  		if (restore_fstree(unpack_root, n, &info))  			goto out_fs;  		break; @@ -307,6 +330,8 @@ 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 0961591..c06afb2 100644 --- a/unpack/rdsquashfs.h +++ b/unpack/rdsquashfs.h @@ -35,6 +35,9 @@ typedef struct {  	frag_reader_t *frag;  	int sqfsfd;  	int flags; + +	void *buffer; +	void *scratch;  } unsqfs_info_t;  tree_node_t *tree_node_from_inode(sqfs_inode_generic_t *inode, | 
