diff options
Diffstat (limited to 'extras')
| -rw-r--r-- | extras/Makemodule.am | 5 | ||||
| -rw-r--r-- | extras/browse.c | 6 | ||||
| -rw-r--r-- | extras/extract_one.c | 184 | ||||
| -rw-r--r-- | extras/list_files.c | 6 | ||||
| -rw-r--r-- | extras/mk42sqfs.c | 6 | ||||
| -rw-r--r-- | extras/mknastyfs.c | 6 | 
6 files changed, 212 insertions, 1 deletions
| diff --git a/extras/Makemodule.am b/extras/Makemodule.am index d3b80f2..9ebe037 100644 --- a/extras/Makemodule.am +++ b/extras/Makemodule.am @@ -7,6 +7,9 @@ mk42sqfs_LDADD = libsquashfs.la  list_files_SOURCES = extras/list_files.c  list_files_LDADD = libsquashfs.la +extract_one_SOURCES = extras/extract_one.c +extract_one_LDADD = libsquashfs.la +  if WITH_READLINE  sqfsbrowse_SOURCES = extras/browse.c  sqfsbrowse_CFLAGS = $(AM_CFLAGS) $(READLINE_CFLAGS) @@ -15,4 +18,4 @@ sqfsbrowse_LDADD = libsquashfs.la $(READLINE_LIBS)  noinst_PROGRAMS += sqfsbrowse  endif -noinst_PROGRAMS += mknastyfs mk42sqfs list_files +noinst_PROGRAMS += mknastyfs mk42sqfs list_files extract_one diff --git a/extras/browse.c b/extras/browse.c index 6d03312..fe5bfd8 100644 --- a/extras/browse.c +++ b/extras/browse.c @@ -1,3 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ +/* + * browse.c + * + * Copyright (C) 2020 David Oberhollenzer <goliath@infraroot.at> + */  #include "sqfs/data_reader.h"  #include "sqfs/compressor.h"  #include "sqfs/dir_reader.h" diff --git a/extras/extract_one.c b/extras/extract_one.c new file mode 100644 index 0000000..4f5b547 --- /dev/null +++ b/extras/extract_one.c @@ -0,0 +1,184 @@ +/* SPDX-License-Identifier: 0BSD */ +/* + * extract_one.c + * + * Copyright (C) 2021 Luca Boccassi <luca.boccassi@microsoft.com> + */ + +#include "sqfs/compressor.h" +#include "sqfs/data_reader.h" +#include "sqfs/dir_reader.h" +#include "sqfs/error.h" +#include "sqfs/id_table.h" +#include "sqfs/io.h" +#include "sqfs/inode.h" +#include "sqfs/super.h" +#include "sqfs/xattr_reader.h" + +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +int main(int argc, char **argv) +{ +	sqfs_xattr_reader_t *xattr = NULL; +	sqfs_data_reader_t *data = NULL; +	sqfs_dir_reader_t *dirrd = NULL; +	sqfs_compressor_t *cmp = NULL; +	sqfs_id_table_t *idtbl = NULL; +	sqfs_tree_node_t *n = NULL; +	sqfs_file_t *file = NULL; +	sqfs_u8 *p, *output = NULL; +	sqfs_compressor_config_t cfg; +	sqfs_super_t super; +	sqfs_u64 file_size; +	int status = EXIT_FAILURE, ret; + +	if (argc != 3) { +		fputs("Usage: extract_one <squashfs-file> <source-file-path>\n", stderr); +		return EXIT_FAILURE; +	} + +	file = sqfs_open_file(argv[1], SQFS_FILE_OPEN_READ_ONLY); +	if (file == NULL) { +		perror(argv[1]); +		return EXIT_FAILURE; +	} + +	ret = sqfs_super_read(&super, file); +	if (ret) { +		fprintf(stderr, "%s: error reading super block.\n", argv[1]); +		goto out_file; +	} + +	sqfs_compressor_config_init(&cfg, super.compression_id, +								super.block_size, +								SQFS_COMP_FLAG_UNCOMPRESS); + +	ret = sqfs_compressor_create(&cfg, &cmp); +	if (ret != 0) { +		fprintf(stderr, "%s: error creating compressor: %d.\n", argv[1], ret); +		goto out_file; +	} + +	if (!(super.flags & SQFS_FLAG_NO_XATTRS)) { +		xattr = sqfs_xattr_reader_create(0); +		if (xattr == NULL) { +			fprintf(stderr, "%s: error creating xattr reader: %d.\n", argv[1], SQFS_ERROR_ALLOC); +			goto out_cmp; +		} + +		ret = sqfs_xattr_reader_load(xattr, &super, file, cmp); +		if (ret) { +			fprintf(stderr, "%s: error loading xattr reader: %d.\n", argv[1], ret); +			goto out_xattr; +		} +	} + +	idtbl = sqfs_id_table_create(0); +	if (idtbl == NULL) { +		fprintf(stderr, "%s: error creating ID table: %d.\n", argv[1], ret); +		goto out_xattr; +	} + +	ret = sqfs_id_table_read(idtbl, file, &super, cmp); +	if (ret) { +		fprintf(stderr, "%s: error loading ID table: %d.\n", argv[1], ret); +		goto out_idtbl; +	} + +	dirrd = sqfs_dir_reader_create(&super, cmp, file, 0); +	if (dirrd == NULL) { +		fprintf(stderr, "%s: error creating dir reader: %d.\n", argv[1], SQFS_ERROR_ALLOC); +		goto out_idtbl; +	} + +	data = sqfs_data_reader_create(file, super.block_size, cmp, 0); +	if (data == NULL) { +		fprintf(stderr, "%s: error creating data reader: %d.\n", argv[1], SQFS_ERROR_ALLOC); +		goto out_dirrd; +	} + +	ret = sqfs_data_reader_load_fragment_table(data, &super); +	if (ret) { +		fprintf(stderr, "%s: error loading fragment table: %d.\n", argv[1], ret); +		goto out_data; +	} + +	ret = sqfs_dir_reader_get_full_hierarchy(dirrd, idtbl, argv[2], 0, &n); +	if (ret) { +		fprintf(stderr, "%s: error reading filesystem hierarchy: %d.\n", argv[1], ret); +		goto out_data; +	} + +	if (!S_ISREG(n->inode->base.mode)) { +		fprintf(stderr, "/%s is not a file\n", argv[2]); +		goto out_tree; +	} + +	sqfs_inode_get_file_size(n->inode, &file_size); + +	output = p = malloc(file_size); +	if (output == NULL) { +		fprintf(stderr, "malloc failed: %d\n", errno); +		goto out_tree; +	} + +	for (size_t i = 0; i < sqfs_inode_get_file_block_count(n->inode); ++i) { +		size_t chunk_size, read = (file_size < super.block_size) ? file_size : super.block_size; +		sqfs_u8 *chunk; + +		ret = sqfs_data_reader_get_block(data, n->inode, i, &chunk_size, &chunk); +		if (ret) { +			fprintf(stderr, "reading data block: %d\n", ret); +			goto out_tree; +		} + +		memcpy(p, chunk, chunk_size); +		p += chunk_size; +		free(chunk); + +		file_size -= read; +	} + +	if (file_size > 0) { +		size_t chunk_size; +		sqfs_u8 *chunk; + +		ret = sqfs_data_reader_get_fragment(data, n->inode, &chunk_size, &chunk); +		if (ret) { +			fprintf(stderr, "reading fragment block: %d\n", ret); +			goto out_tree; +		} + +		memcpy(p, chunk, chunk_size); +		free(chunk); +	} + +	/* for example simplicity, assume this is a text file */ +	fprintf(stdout, "%s\n", (char *)output); + +	status = EXIT_SUCCESS; +out_tree: +	sqfs_dir_tree_destroy(n); +out_data: +	sqfs_destroy(data); +out_dirrd: +	sqfs_destroy(dirrd); +out_idtbl: +	sqfs_destroy(idtbl); +out_xattr: +	if (xattr != NULL) +		sqfs_destroy(xattr); +out_cmp: +	sqfs_destroy(cmp); +out_file: +	sqfs_destroy(file); +	free(output); + +	return status; +} diff --git a/extras/list_files.c b/extras/list_files.c index 5f0742d..e368f2a 100644 --- a/extras/list_files.c +++ b/extras/list_files.c @@ -1,3 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ +/* + * list_files.c + * + * Copyright (C) 2020 David Oberhollenzer <goliath@infraroot.at> + */  #include "sqfs/compressor.h"  #include "sqfs/dir_reader.h"  #include "sqfs/id_table.h" diff --git a/extras/mk42sqfs.c b/extras/mk42sqfs.c index 08dffe6..d437ce7 100644 --- a/extras/mk42sqfs.c +++ b/extras/mk42sqfs.c @@ -1,3 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ +/* + * mk42sqfs.c + * + * Copyright (C) 2020 David Oberhollenzer <goliath@infraroot.at> + */  #include "sqfs/meta_writer.h"  #include "sqfs/dir_writer.h"  #include "sqfs/compressor.h" diff --git a/extras/mknastyfs.c b/extras/mknastyfs.c index 20074d3..ecc6b8a 100644 --- a/extras/mknastyfs.c +++ b/extras/mknastyfs.c @@ -1,3 +1,9 @@ +/* SPDX-License-Identifier: 0BSD */ +/* + * mknastyfs.c + * + * Copyright (C) 2020 David Oberhollenzer <goliath@infraroot.at> + */  #include "sqfs/meta_writer.h"  #include "sqfs/dir_writer.h"  #include "sqfs/compressor.h" | 
