diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-10-09 11:41:46 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2020-01-12 08:23:56 +0100 | 
| commit | ae3caba461401a32c23fb92569d3a22ca74c2bd0 (patch) | |
| tree | 9d2b634e19647a84ea016f684c4a519f8bad8a0c /extras | |
| parent | a25185263160eb5b04861072bfab0fac114abdb6 (diff) | |
Port mknastyfs to libsquashfs
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'extras')
| -rw-r--r-- | extras/Makemodule.am | 4 | ||||
| -rw-r--r-- | extras/mknastyfs.c | 184 | 
2 files changed, 188 insertions, 0 deletions
| diff --git a/extras/Makemodule.am b/extras/Makemodule.am index e69de29..83d9e8b 100644 --- a/extras/Makemodule.am +++ b/extras/Makemodule.am @@ -0,0 +1,4 @@ +mknastyfs_SOURCES = extras/mknastyfs.c +mknastyfs_LDADD = libsquashfs.la + +noinst_PROGRAMS += mknastyfs diff --git a/extras/mknastyfs.c b/extras/mknastyfs.c new file mode 100644 index 0000000..823bcf8 --- /dev/null +++ b/extras/mknastyfs.c @@ -0,0 +1,184 @@ +#include "sqfs/meta_writer.h" +#include "sqfs/dir_writer.h" +#include "sqfs/compressor.h" +#include "sqfs/id_table.h" +#include "sqfs/inode.h" +#include "sqfs/super.h" +#include "sqfs/io.h" + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +static void add_padding(sqfs_file_t *file) +{ +	sqfs_u64 diff, size; + +	size = file->get_size(file); +	diff = size % 4096; + +	if (diff > 0) +		file->truncate(file, size + (4096 - diff)); +} + +static sqfs_inode_generic_t *create_file_inode(sqfs_id_table_t *idtbl, +					       unsigned int inode_num) +{ +	sqfs_inode_generic_t *inode; + +	inode = calloc(1, sizeof(*inode) + sizeof(sqfs_u32)); +	inode->base.type = SQFS_INODE_FILE; +	inode->base.mode = SQFS_INODE_MODE_REG | 0644; +	inode->base.inode_number = inode_num; + +	sqfs_id_table_id_to_index(idtbl, 0, &inode->base.uid_idx); +	sqfs_id_table_id_to_index(idtbl, 0, &inode->base.gid_idx); + +	inode->data.file.file_size = 1337; +	inode->data.file.fragment_index = 0xFFFFFFFF; + +	inode->num_file_blocks = 1; +	inode->block_sizes = (sqfs_u32 *)inode->extra; +	inode->block_sizes[0] = (1 << 24) | inode->data.file.file_size; +	return inode; +} + +int main(void) +{ +	sqfs_meta_writer_t *inode_m, *dir_m; +	sqfs_compressor_config_t cfg; +	sqfs_inode_generic_t *inode; +	int status = EXIT_FAILURE; +	sqfs_dir_writer_t *dirwr; +	sqfs_compressor_t *cmp; +	sqfs_id_table_t *idtbl; +	unsigned int inode_num; +	sqfs_u64 block_start; +	sqfs_super_t super; +	sqfs_file_t *file; +	sqfs_u32 offset; + +	/* get a file object referring to our destination file */ +	file = sqfs_open_file("nasty.sqfs", 0); +	if (file == NULL) { +		fputs("Error opening output file.\n", stderr); +		return EXIT_FAILURE; +	} + +	/* initialize the super block with sane values */ +	sqfs_super_init(&super, 4096, 0, SQFS_COMP_GZIP); + +	if (sqfs_super_write(&super, file)) { +		fputs("Error witing super block.\n", stderr); +		goto out_file; +	} + +	/* create a compressor */ +	sqfs_compressor_config_init(&cfg, super.compression_id, +				    super.block_size, 0); + +	cmp = sqfs_compressor_create(&cfg); +	if (cmp == NULL) { +		fputs("Error creating compressor.\n", stderr); +		goto out_file; +	} + +	/* create meta data writers for inodes and directories */ +	inode_m = sqfs_meta_writer_create(file, cmp, 0); +	if (inode_m == NULL) { +		fputs("Error creating inode meta data writer.\n", stderr); +		goto out_cmp; +	} + +	dir_m = sqfs_meta_writer_create(file, cmp, +					SQFS_META_WRITER_KEEP_IN_MEMORY); +	if (dir_m == NULL) { +		fputs("Error creating directory meta data writer.\n", stderr); +		goto out_im; +	} + +	/* create a higher level directory writer on top of the meta writer */ +	dirwr = sqfs_dir_writer_create(dir_m, 0); +	if (dirwr == NULL) { +		fputs("Error creating directory writer.\n", stderr); +		goto out_dm; +	} + +	/* create an ID table */ +	idtbl = sqfs_id_table_create(); +	if (idtbl == NULL) { +		fputs("Error creating ID table.\n", stderr); +		goto out_dirwr; +	} + +	/* generate inodes and directories */ +	super.inode_table_start = file->get_size(file); +	inode_num = 1; + +	sqfs_dir_writer_begin(dirwr, 0); + +	inode = create_file_inode(idtbl, inode_num++); +	sqfs_meta_writer_get_position(inode_m, &block_start, &offset); +	sqfs_meta_writer_write_inode(inode_m, inode); +	sqfs_dir_writer_add_entry(dirwr, "..", inode->base.inode_number, +				  (block_start << 16) | offset, +				  inode->base.mode); +	free(inode); + +	inode = create_file_inode(idtbl, inode_num++); +	sqfs_meta_writer_get_position(inode_m, &block_start, &offset); +	sqfs_meta_writer_write_inode(inode_m, inode); +	sqfs_dir_writer_add_entry(dirwr, "/etc/passwd", +				  inode->base.inode_number, +				  (block_start << 16) | offset, +				  inode->base.mode); +	free(inode); + +	sqfs_dir_writer_end(dirwr); + +	inode = sqfs_dir_writer_create_inode(dirwr, 0, 0xFFFFFFFF, 0); + +	inode->base.mode = SQFS_INODE_MODE_DIR | 0755; +	inode->base.inode_number = inode_num++; +	sqfs_id_table_id_to_index(idtbl, 0, &inode->base.uid_idx); +	sqfs_id_table_id_to_index(idtbl, 0, &inode->base.gid_idx); + +	sqfs_meta_writer_get_position(inode_m, &block_start, &offset); +	super.root_inode_ref = (block_start << 16) | offset; +	sqfs_meta_writer_write_inode(inode_m, inode); +	free(inode); + +	/* flush the meta data to the file */ +	sqfs_meta_writer_flush(inode_m); +	sqfs_meta_writer_flush(dir_m); + +	super.directory_table_start = file->get_size(file); +	sqfs_meta_write_write_to_file(dir_m); + +	sqfs_id_table_write(idtbl, file, &super, cmp); + +	super.inode_count = inode_num - 2; +	super.bytes_used = file->get_size(file); + +	if (sqfs_super_write(&super, file)) { +		fputs("Error update the final super block.\n", stderr); +		goto out_file; +	} + +	add_padding(file); + +	/* cleanup */ +	status = EXIT_SUCCESS; +	sqfs_id_table_destroy(idtbl); +out_dirwr: +	sqfs_dir_writer_destroy(dirwr); +out_dm: +	sqfs_meta_writer_destroy(dir_m); +out_im: +	sqfs_meta_writer_destroy(inode_m); +out_cmp: +	cmp->destroy(cmp); +out_file: +	file->destroy(file); +	return status; +} | 
