diff options
-rw-r--r-- | include/common.h | 90 | ||||
-rw-r--r-- | include/compress_cli.h | 42 | ||||
-rw-r--r-- | include/simple_writer.h | 87 | ||||
-rw-r--r-- | lib/common/Makemodule.am | 11 | ||||
-rw-r--r-- | lib/common/comp_lzo.c | 2 | ||||
-rw-r--r-- | lib/common/comp_opt.c | 2 | ||||
-rw-r--r-- | lib/common/compress.c | 5 | ||||
-rw-r--r-- | lib/common/statistics.c | 59 | ||||
-rw-r--r-- | lib/common/writer/cleanup.c | 40 | ||||
-rw-r--r-- | lib/common/writer/finish.c | 176 | ||||
-rw-r--r-- | lib/common/writer/init.c (renamed from lib/common/writer.c) | 149 | ||||
-rw-r--r-- | lib/common/writer/serialize_fstree.c (renamed from lib/common/serialize_fstree.c) | 0 |
12 files changed, 364 insertions, 299 deletions
diff --git a/include/common.h b/include/common.h index ea27edc..b0c7abb 100644 --- a/include/common.h +++ b/include/common.h @@ -9,25 +9,17 @@ #include "config.h" -#include "sqfs/xattr_writer.h" #include "sqfs/xattr_reader.h" -#include "sqfs/compressor.h" -#include "sqfs/id_table.h" #include "sqfs/inode.h" #include "sqfs/table.h" -#include "sqfs/error.h" -#include "sqfs/meta_writer.h" #include "sqfs/data_reader.h" -#include "sqfs/block_processor.h" -#include "sqfs/block_writer.h" -#include "sqfs/frag_table.h" -#include "sqfs/dir_writer.h" #include "sqfs/dir_reader.h" #include "sqfs/block.h" #include "sqfs/xattr.h" #include "sqfs/dir.h" -#include "sqfs/io.h" +#include "simple_writer.h" +#include "compress_cli.h" #include "fstream.h" #include "compat.h" #include "fstree.h" @@ -35,39 +27,6 @@ #include <stddef.h> -typedef struct { - const char *filename; - sqfs_block_writer_t *blkwr; - sqfs_frag_table_t *fragtbl; - sqfs_block_processor_t *data; - sqfs_dir_writer_t *dirwr; - sqfs_meta_writer_t *dm; - sqfs_meta_writer_t *im; - sqfs_compressor_t *cmp; - sqfs_id_table_t *idtbl; - sqfs_file_t *outfile; - sqfs_super_t super; - fstree_t fs; - sqfs_xattr_writer_t *xwr; -} sqfs_writer_t; - -typedef struct { - const char *filename; - char *fs_defaults; - char *comp_extra; - size_t block_size; - size_t devblksize; - size_t max_backlog; - size_t num_jobs; - - int outmode; - SQFS_COMPRESSOR comp_id; - - bool exportable; - bool no_xattr; - bool quiet; -} sqfs_writer_cfg_t; - typedef struct sqfs_hard_link_t { struct sqfs_hard_link_t *next; sqfs_u32 inode_number; @@ -77,35 +36,6 @@ typedef struct sqfs_hard_link_t { #define container_of(ptr, type, member) \ ((type *)((char *)ptr - offsetof(type, member))) -/* - High level helper function to serialize an entire file system tree to - a squashfs inode table and directory table. - - The data is written to the given file descriptor and the super block is - update accordingly (inode and directory table start and total size). - - The function internally creates two meta data writers and uses - meta_writer_write_inode to serialize the inode table of the fstree. - - Returns 0 on success. Prints error messages to stderr on failure. - */ -int sqfs_serialize_fstree(const char *filename, sqfs_writer_t *wr); - -/* Print out fancy statistics for squashfs packing tools */ -void sqfs_print_statistics(const sqfs_super_t *super, - const sqfs_block_processor_t *blk, - const sqfs_block_writer_t *wr); - -void compressor_print_available(void); - -SQFS_COMPRESSOR compressor_get_default(void); - -int compressor_cfg_init_options(sqfs_compressor_config_t *cfg, - SQFS_COMPRESSOR id, - size_t block_size, char *options); - -void compressor_print_help(SQFS_COMPRESSOR id); - int inode_stat(const sqfs_tree_node_t *node, struct stat *sb); char *sqfs_tree_node_get_path(const sqfs_tree_node_t *node); @@ -118,14 +48,6 @@ int write_data_from_file(const char *filename, sqfs_block_processor_t *data, sqfs_inode_generic_t **inode, sqfs_file_t *file, int flags); -void sqfs_writer_cfg_init(sqfs_writer_cfg_t *cfg); - -int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg); - -int sqfs_writer_finish(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *cfg); - -void sqfs_writer_cleanup(sqfs_writer_t *sqfs, int status); - void sqfs_perror(const char *file, const char *action, int error_code); int sqfs_tree_find_hard_links(const sqfs_tree_node_t *root, @@ -143,14 +65,6 @@ int mkdir_p(const char *path); void print_version(const char *progname); /* - Create an liblzo2 based LZO compressor. - - XXX: This must be in libcommon instead of libsquashfs for legal reasons. - */ -int lzo_compressor_create(const sqfs_compressor_config_t *cfg, - sqfs_compressor_t **out); - -/* Parse a number optionally followed by a KMG suffix (case insensitive). Prints an error message to stderr and returns -1 on failure, 0 on success. diff --git a/include/compress_cli.h b/include/compress_cli.h new file mode 100644 index 0000000..1ac7972 --- /dev/null +++ b/include/compress_cli.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * compress_cli.h + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#ifndef COMPRESS_CLI_H +#define COMPRESS_CLI_H + +#include "sqfs/compressor.h" +#include "sqfs/super.h" +#include "sqfs/block.h" +#include "sqfs/error.h" +#include "sqfs/io.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void compressor_print_available(void); + +SQFS_COMPRESSOR compressor_get_default(void); + +int compressor_cfg_init_options(sqfs_compressor_config_t *cfg, + SQFS_COMPRESSOR id, + size_t block_size, char *options); + +void compressor_print_help(SQFS_COMPRESSOR id); + +/* + Create an liblzo2 based LZO compressor. + + XXX: This must be in libcommon instead of libsquashfs for legal reasons. + */ +int lzo_compressor_create(const sqfs_compressor_config_t *cfg, + sqfs_compressor_t **out); + +#ifdef __cplusplus +} +#endif + +#endif /* COMPRESS_CLI_H */ diff --git a/include/simple_writer.h b/include/simple_writer.h new file mode 100644 index 0000000..1a3302b --- /dev/null +++ b/include/simple_writer.h @@ -0,0 +1,87 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * simple_writer.h + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#ifndef SIMPLE_WRITER_H +#define SIMPLE_WRITER_H + +#include "config.h" + +#include "sqfs/block_processor.h" +#include "sqfs/block_writer.h" +#include "sqfs/xattr_writer.h" +#include "sqfs/meta_writer.h" +#include "sqfs/frag_table.h" +#include "sqfs/dir_writer.h" +#include "sqfs/compressor.h" +#include "sqfs/id_table.h" +#include "sqfs/error.h" +#include "sqfs/io.h" + +#include "fstree.h" + +typedef struct { + const char *filename; + sqfs_block_writer_t *blkwr; + sqfs_frag_table_t *fragtbl; + sqfs_block_processor_t *data; + sqfs_dir_writer_t *dirwr; + sqfs_meta_writer_t *dm; + sqfs_meta_writer_t *im; + sqfs_compressor_t *cmp; + sqfs_id_table_t *idtbl; + sqfs_file_t *outfile; + sqfs_super_t super; + fstree_t fs; + sqfs_xattr_writer_t *xwr; +} sqfs_writer_t; + +typedef struct { + const char *filename; + char *fs_defaults; + char *comp_extra; + size_t block_size; + size_t devblksize; + size_t max_backlog; + size_t num_jobs; + + int outmode; + SQFS_COMPRESSOR comp_id; + + bool exportable; + bool no_xattr; + bool quiet; +} sqfs_writer_cfg_t; + +#ifdef __cplusplus +extern "C" { +#endif + +void sqfs_writer_cfg_init(sqfs_writer_cfg_t *cfg); + +int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg); + +int sqfs_writer_finish(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *cfg); + +void sqfs_writer_cleanup(sqfs_writer_t *sqfs, int status); + +/* + High level helper function to serialize an entire file system tree to + a squashfs inode table and directory table. The super block is update + accordingly. + + The function internally creates two meta data writers and uses + meta_writer_write_inode to serialize the inode table of the fstree. + + Returns 0 on success. Prints error messages to stderr on failure. + The filename is used to prefix error messages. + */ +int sqfs_serialize_fstree(const char *filename, sqfs_writer_t *wr); + +#ifdef __cplusplus +} +#endif + +#endif /* SIMPLE_WRITER_H */ diff --git a/lib/common/Makemodule.am b/lib/common/Makemodule.am index e191e29..dd0a0d0 100644 --- a/lib/common/Makemodule.am +++ b/lib/common/Makemodule.am @@ -1,12 +1,15 @@ -libcommon_a_SOURCES = lib/common/serialize_fstree.c lib/common/statistics.c -libcommon_a_SOURCES += lib/common/inode_stat.c lib/common/hardlink.c +libcommon_a_SOURCES = lib/common/inode_stat.c lib/common/hardlink.c libcommon_a_SOURCES += lib/common/print_version.c lib/common/data_reader_dump.c libcommon_a_SOURCES += lib/common/compress.c lib/common/comp_opt.c libcommon_a_SOURCES += lib/common/data_writer.c include/common.h libcommon_a_SOURCES += lib/common/get_path.c lib/common/data_writer_ostream.c -libcommon_a_SOURCES += lib/common/writer.c lib/common/perror.c +libcommon_a_SOURCES += lib/common/perror.c libcommon_a_SOURCES += lib/common/mkdir_p.c lib/common/parse_size.c -libcommon_a_SOURCES += lib/common/print_size.c +libcommon_a_SOURCES += lib/common/print_size.c include/simple_writer.h +libcommon_a_SOURCES += include/compress_cli.h +libcommon_a_SOURCES += lib/common/writer/init.c lib/common/writer/cleanup.c +libcommon_a_SOURCES += lib/common/writer/serialize_fstree.c +libcommon_a_SOURCES += lib/common/writer/finish.c libcommon_a_CFLAGS = $(AM_CFLAGS) $(LZO_CFLAGS) if WITH_LZO diff --git a/lib/common/comp_lzo.c b/lib/common/comp_lzo.c index 3452647..21dc7b2 100644 --- a/lib/common/comp_lzo.c +++ b/lib/common/comp_lzo.c @@ -5,7 +5,7 @@ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> */ #include "config.h" -#include "common.h" +#include "compress_cli.h" #include <stdbool.h> #include <stdlib.h> diff --git a/lib/common/comp_opt.c b/lib/common/comp_opt.c index f77ac20..a0d4cf7 100644 --- a/lib/common/comp_opt.c +++ b/lib/common/comp_opt.c @@ -4,11 +4,13 @@ * * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> */ +#include "config.h" #include "common.h" #include <string.h> #include <stdlib.h> #include <getopt.h> +#include <stdio.h> #include <ctype.h> typedef struct { diff --git a/lib/common/compress.c b/lib/common/compress.c index 9a66095..b11efbd 100644 --- a/lib/common/compress.c +++ b/lib/common/compress.c @@ -4,8 +4,11 @@ * * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> */ -#include "common.h" +#include "config.h" +#include "compress_cli.h" + #include <assert.h> +#include <stdio.h> static int cmp_ids[] = { SQFS_COMP_XZ, diff --git a/lib/common/statistics.c b/lib/common/statistics.c deleted file mode 100644 index 82e545d..0000000 --- a/lib/common/statistics.c +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * statistics.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "common.h" - -#include <stdio.h> - -void sqfs_print_statistics(const sqfs_super_t *super, - const sqfs_block_processor_t *blk, - const sqfs_block_writer_t *wr) -{ - const sqfs_block_processor_stats_t *proc_stats; - sqfs_u64 bytes_written, blocks_written; - char read_sz[32], written_sz[32]; - size_t ratio; - - proc_stats = sqfs_block_processor_get_stats(blk); - blocks_written = wr->get_block_count(wr); - - bytes_written = super->inode_table_start - sizeof(*super); - - if (proc_stats->input_bytes_read > 0) { - ratio = (100 * bytes_written) / proc_stats->input_bytes_read; - } else { - ratio = 100; - } - - print_size(proc_stats->input_bytes_read, read_sz, false); - print_size(bytes_written, written_sz, false); - - fputs("---------------------------------------------------\n", stdout); - printf("Data bytes read: %s\n", read_sz); - printf("Data bytes written: %s\n", written_sz); - printf("Data compression ratio: " PRI_SZ "%%\n", ratio); - fputc('\n', stdout); - - printf("Data blocks written: " PRI_U64 "\n", blocks_written); - printf("Out of which where fragment blocks: " PRI_U64 "\n", - proc_stats->frag_block_count); - - printf("Duplicate blocks omitted: " PRI_U64 "\n", - proc_stats->data_block_count + proc_stats->frag_block_count - - blocks_written); - - printf("Sparse blocks omitted: " PRI_U64 "\n", - proc_stats->sparse_block_count); - fputc('\n', stdout); - - printf("Fragments actually written: " PRI_U64 "\n", - proc_stats->actual_frag_count); - printf("Duplicated fragments omitted: " PRI_U64 "\n", - proc_stats->total_frag_count - proc_stats->actual_frag_count); - printf("Total number of inodes: %u\n", super->inode_count); - printf("Number of unique group/user IDs: %u\n", super->id_count); - fputc('\n', stdout); -} diff --git a/lib/common/writer/cleanup.c b/lib/common/writer/cleanup.c new file mode 100644 index 0000000..16e846b --- /dev/null +++ b/lib/common/writer/cleanup.c @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * cleanup.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "simple_writer.h" + +#include <stdlib.h> + +void sqfs_writer_cleanup(sqfs_writer_t *sqfs, int status) +{ + if (sqfs->xwr != NULL) + sqfs_destroy(sqfs->xwr); + + sqfs_destroy(sqfs->dirwr); + sqfs_destroy(sqfs->dm); + sqfs_destroy(sqfs->im); + sqfs_destroy(sqfs->idtbl); + sqfs_destroy(sqfs->data); + sqfs_destroy(sqfs->blkwr); + sqfs_destroy(sqfs->fragtbl); + sqfs_destroy(sqfs->cmp); + fstree_cleanup(&sqfs->fs); + sqfs_destroy(sqfs->outfile); + + if (status != EXIT_SUCCESS) { +#if defined(_WIN32) || defined(__WINDOWS__) + WCHAR *path = path_to_windows(sqfs->filename); + + if (path != NULL) + DeleteFileW(path); + + free(path); +#else + unlink(sqfs->filename); +#endif + } +} + diff --git a/lib/common/writer/finish.c b/lib/common/writer/finish.c new file mode 100644 index 0000000..e005628 --- /dev/null +++ b/lib/common/writer/finish.c @@ -0,0 +1,176 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * finish.c + * + * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> + */ +#include "simple_writer.h" +#include "common.h" + +#include <stdlib.h> + +static void print_statistics(const sqfs_super_t *super, + const sqfs_block_processor_t *blk, + const sqfs_block_writer_t *wr) +{ + const sqfs_block_processor_stats_t *proc_stats; + sqfs_u64 bytes_written, blocks_written; + char read_sz[32], written_sz[32]; + size_t ratio; + + proc_stats = sqfs_block_processor_get_stats(blk); + blocks_written = wr->get_block_count(wr); + + bytes_written = super->inode_table_start - sizeof(*super); + + if (proc_stats->input_bytes_read > 0) { + ratio = (100 * bytes_written) / proc_stats->input_bytes_read; + } else { + ratio = 100; + } + + print_size(proc_stats->input_bytes_read, read_sz, false); + print_size(bytes_written, written_sz, false); + + fputs("---------------------------------------------------\n", stdout); + printf("Data bytes read: %s\n", read_sz); + printf("Data bytes written: %s\n", written_sz); + printf("Data compression ratio: " PRI_SZ "%%\n", ratio); + fputc('\n', stdout); + + printf("Data blocks written: " PRI_U64 "\n", blocks_written); + printf("Out of which where fragment blocks: " PRI_U64 "\n", + proc_stats->frag_block_count); + + printf("Duplicate blocks omitted: " PRI_U64 "\n", + proc_stats->data_block_count + proc_stats->frag_block_count - + blocks_written); + + printf("Sparse blocks omitted: " PRI_U64 "\n", + proc_stats->sparse_block_count); + fputc('\n', stdout); + + printf("Fragments actually written: " PRI_U64 "\n", + proc_stats->actual_frag_count); + printf("Duplicated fragments omitted: " PRI_U64 "\n", + proc_stats->total_frag_count - proc_stats->actual_frag_count); + printf("Total number of inodes: %u\n", super->inode_count); + printf("Number of unique group/user IDs: %u\n", super->id_count); + fputc('\n', stdout); +} + +static int padd_sqfs(sqfs_file_t *file, sqfs_u64 size, size_t blocksize) +{ + size_t padd_sz = size % blocksize; + int status = -1; + sqfs_u8 *buffer; + + if (padd_sz == 0) + return 0; + + padd_sz = blocksize - padd_sz; + + buffer = calloc(1, padd_sz); + if (buffer == NULL) + goto fail_errno; + + if (file->write_at(file, file->get_size(file), + buffer, padd_sz)) { + goto fail_errno; + } + + status = 0; +out: + free(buffer); + return status; +fail_errno: + perror("padding output file to block size"); + goto out; +} + +int sqfs_writer_finish(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *cfg) +{ + int ret; + + if (!cfg->quiet) + fputs("Waiting for remaining data blocks...\n", stdout); + + ret = sqfs_block_processor_finish(sqfs->data); + if (ret) { + sqfs_perror(cfg->filename, "finishing data blocks", ret); + return -1; + } + + if (!cfg->quiet) + fputs("Writing inodes and directories...\n", stdout); + + sqfs->super.inode_count = sqfs->fs.unique_inode_count; + + if (sqfs_serialize_fstree(cfg->filename, sqfs)) + return -1; + + if (!cfg->quiet) + fputs("Writing fragment table...\n", stdout); + + ret = sqfs_frag_table_write(sqfs->fragtbl, sqfs->outfile, + &sqfs->super, sqfs->cmp); + if (ret) { + sqfs_perror(cfg->filename, "writing fragment table", ret); + return -1; + } + + if (cfg->exportable) { + if (!cfg->quiet) + fputs("Writing export table...\n", stdout); + + + ret = sqfs_dir_writer_write_export_table(sqfs->dirwr, + sqfs->outfile, sqfs->cmp, + sqfs->fs.root->inode_num, + sqfs->fs.root->inode_ref, + &sqfs->super); + if (ret) + return -1; + } + + if (!cfg->quiet) + fputs("Writing ID table...\n", stdout); + + ret = sqfs_id_table_write(sqfs->idtbl, sqfs->outfile, + &sqfs->super, sqfs->cmp); + if (ret) { + sqfs_perror(cfg->filename, "writing ID table", ret); + return -1; + } + + if (!cfg->no_xattr) { + if (!cfg->quiet) + fputs("Writing extended attributes...\n", stdout); + + ret = sqfs_xattr_writer_flush(sqfs->xwr, sqfs->outfile, + &sqfs->super, sqfs->cmp); + if (ret) { + sqfs_perror(cfg->filename, + "writing extended attributes", ret); + return -1; + } + } + + sqfs->super.bytes_used = sqfs->outfile->get_size(sqfs->outfile); + + ret = sqfs_super_write(&sqfs->super, sqfs->outfile); + if (ret) { + sqfs_perror(cfg->filename, "updating super block", ret); + return -1; + } + + if (padd_sqfs(sqfs->outfile, sqfs->super.bytes_used, + cfg->devblksize)) { + return -1; + } + + if (!cfg->quiet) + print_statistics(&sqfs->super, sqfs->data, sqfs->blkwr); + + return 0; +} diff --git a/lib/common/writer.c b/lib/common/writer/init.c index 9032a99..d606d26 100644 --- a/lib/common/writer.c +++ b/lib/common/writer/init.c @@ -1,9 +1,11 @@ /* SPDX-License-Identifier: GPL-3.0-or-later */ /* - * writer.c + * init.c * * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> */ +#include "simple_writer.h" +#include "compress_cli.h" #include "common.h" #include <string.h> @@ -26,35 +28,6 @@ static size_t os_get_num_jobs(void) } #endif -static int padd_sqfs(sqfs_file_t *file, sqfs_u64 size, size_t blocksize) -{ - size_t padd_sz = size % blocksize; - int status = -1; - sqfs_u8 *buffer; - - if (padd_sz == 0) - return 0; - - padd_sz = blocksize - padd_sz; - - buffer = calloc(1, padd_sz); - if (buffer == NULL) - goto fail_errno; - - if (file->write_at(file, file->get_size(file), - buffer, padd_sz)) { - goto fail_errno; - } - - status = 0; -out: - free(buffer); - return status; -fail_errno: - perror("padding output file to block size"); - goto out; -} - void sqfs_writer_cfg_init(sqfs_writer_cfg_t *cfg) { memset(cfg, 0, sizeof(*cfg)); @@ -211,119 +184,3 @@ fail_file: sqfs_destroy(sqfs->outfile); return -1; } - -int sqfs_writer_finish(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *cfg) -{ - int ret; - - if (!cfg->quiet) - fputs("Waiting for remaining data blocks...\n", stdout); - - ret = sqfs_block_processor_finish(sqfs->data); - if (ret) { - sqfs_perror(cfg->filename, "finishing data blocks", ret); - return -1; - } - - if (!cfg->quiet) - fputs("Writing inodes and directories...\n", stdout); - - sqfs->super.inode_count = sqfs->fs.unique_inode_count; - - if (sqfs_serialize_fstree(cfg->filename, sqfs)) - return -1; - - if (!cfg->quiet) - fputs("Writing fragment table...\n", stdout); - - ret = sqfs_frag_table_write(sqfs->fragtbl, sqfs->outfile, - &sqfs->super, sqfs->cmp); - if (ret) { - sqfs_perror(cfg->filename, "writing fragment table", ret); - return -1; - } - - if (cfg->exportable) { - if (!cfg->quiet) - fputs("Writing export table...\n", stdout); - - - ret = sqfs_dir_writer_write_export_table(sqfs->dirwr, - sqfs->outfile, sqfs->cmp, - sqfs->fs.root->inode_num, - sqfs->fs.root->inode_ref, - &sqfs->super); - if (ret) - return -1; - } - - if (!cfg->quiet) - fputs("Writing ID table...\n", stdout); - - ret = sqfs_id_table_write(sqfs->idtbl, sqfs->outfile, - &sqfs->super, sqfs->cmp); - if (ret) { - sqfs_perror(cfg->filename, "writing ID table", ret); - return -1; - } - - if (!cfg->no_xattr) { - if (!cfg->quiet) - fputs("Writing extended attributes...\n", stdout); - - ret = sqfs_xattr_writer_flush(sqfs->xwr, sqfs->outfile, - &sqfs->super, sqfs->cmp); - if (ret) { - sqfs_perror(cfg->filename, "writing extended attributes", ret); - return -1; - } - } - - sqfs->super.bytes_used = sqfs->outfile->get_size(sqfs->outfile); - - ret = sqfs_super_write(&sqfs->super, sqfs->outfile); - if (ret) { - sqfs_perror(cfg->filename, "updating super block", ret); - return -1; - } - - if (padd_sqfs(sqfs->outfile, sqfs->super.bytes_used, - cfg->devblksize)) { - return -1; - } - - if (!cfg->quiet) - sqfs_print_statistics(&sqfs->super, sqfs->data, sqfs->blkwr); - - return 0; -} - -void sqfs_writer_cleanup(sqfs_writer_t *sqfs, int status) -{ - if (sqfs->xwr != NULL) - sqfs_destroy(sqfs->xwr); - - sqfs_destroy(sqfs->dirwr); - sqfs_destroy(sqfs->dm); - sqfs_destroy(sqfs->im); - sqfs_destroy(sqfs->idtbl); - sqfs_destroy(sqfs->data); - sqfs_destroy(sqfs->blkwr); - sqfs_destroy(sqfs->fragtbl); - sqfs_destroy(sqfs->cmp); - fstree_cleanup(&sqfs->fs); - sqfs_destroy(sqfs->outfile); - - if (status != EXIT_SUCCESS) { -#if defined(_WIN32) || defined(__WINDOWS__) - WCHAR *path = path_to_windows(sqfs->filename); - - if (path != NULL) - DeleteFileW(path); - - free(path); -#else - unlink(sqfs->filename); -#endif - } -} diff --git a/lib/common/serialize_fstree.c b/lib/common/writer/serialize_fstree.c index c69f0ea..c69f0ea 100644 --- a/lib/common/serialize_fstree.c +++ b/lib/common/writer/serialize_fstree.c |