aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--unpack/extract_file.c43
-rw-r--r--unpack/rdsquashfs.c25
-rw-r--r--unpack/rdsquashfs.h3
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,