From 1e24f45ab120ea83a6faab2e4e14038547898f64 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 5 Oct 2019 20:06:50 +0200 Subject: Merge all the common code for generating images Signed-off-by: David Oberhollenzer --- include/highlevel.h | 37 +++++++ lib/sqfshelper/Makemodule.am | 1 + lib/sqfshelper/writer.c | 168 ++++++++++++++++++++++++++++++++ mkfs/mkfs.c | 138 ++++---------------------- mkfs/mkfs.h | 19 +--- mkfs/options.c | 46 ++++----- tar/tar2sqfs.c | 226 +++++++++---------------------------------- 7 files changed, 293 insertions(+), 342 deletions(-) create mode 100644 lib/sqfshelper/writer.c diff --git a/include/highlevel.h b/include/highlevel.h index 3b91007..44872cf 100644 --- a/include/highlevel.h +++ b/include/highlevel.h @@ -9,6 +9,7 @@ #include "config.h" +#include "sqfs/xattr_writer.h" #include "sqfs/compressor.h" #include "sqfs/id_table.h" #include "sqfs/inode.h" @@ -41,6 +42,34 @@ typedef struct { sqfs_u64 bytes_read; } data_writer_stats_t; +typedef struct { + sqfs_data_writer_t *data; + sqfs_compressor_t *cmp; + sqfs_id_table_t *idtbl; + sqfs_file_t *outfile; + sqfs_super_t super; + fstree_t fs; + data_writer_stats_t stats; + 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; + E_SQFS_COMPRESSOR comp_id; + + bool exportable; + bool no_xattr; + bool quiet; +} sqfs_writer_cfg_t; + /* High level helper function to serialize an entire file system tree to a squashfs inode table and directory table. @@ -92,4 +121,12 @@ void register_stat_hooks(sqfs_data_writer_t *data, data_writer_stats_t *stats); int write_data_from_file(sqfs_data_writer_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); + #endif /* HIGHLEVEL_H */ diff --git a/lib/sqfshelper/Makemodule.am b/lib/sqfshelper/Makemodule.am index 62990fa..90a25d2 100644 --- a/lib/sqfshelper/Makemodule.am +++ b/lib/sqfshelper/Makemodule.am @@ -7,5 +7,6 @@ libsqfshelper_a_SOURCES += lib/sqfshelper/data_reader_dump.c libsqfshelper_a_SOURCES += lib/sqfshelper/compress.c lib/sqfshelper/comp_opt.c libsqfshelper_a_SOURCES += lib/sqfshelper/data_writer.c include/highlevel.h libsqfshelper_a_SOURCES += lib/sqfshelper/get_path.c lib/sqfshelper/io_stdin.c +libsqfshelper_a_SOURCES += lib/sqfshelper/writer.c noinst_LIBRARIES += libsqfshelper.a diff --git a/lib/sqfshelper/writer.c b/lib/sqfshelper/writer.c new file mode 100644 index 0000000..76a12fc --- /dev/null +++ b/lib/sqfshelper/writer.c @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * writer.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "config.h" + +#include "highlevel.h" +#include "util.h" + +#include + +void sqfs_writer_cfg_init(sqfs_writer_cfg_t *cfg) +{ + memset(cfg, 0, sizeof(*cfg)); + + cfg->num_jobs = 1; + cfg->block_size = SQFS_DEFAULT_BLOCK_SIZE; + cfg->devblksize = SQFS_DEVBLK_SIZE; + cfg->comp_id = compressor_get_default(); +} + +int sqfs_writer_init(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *wrcfg) +{ + sqfs_compressor_config_t cfg; + int ret; + + if (compressor_cfg_init_options(&cfg, wrcfg->comp_id, + wrcfg->block_size, + wrcfg->comp_extra)) { + return -1; + } + + sqfs->outfile = sqfs_open_file(wrcfg->filename, wrcfg->outmode); + if (sqfs->outfile == NULL) { + perror(wrcfg->filename); + return -1; + } + + if (fstree_init(&sqfs->fs, wrcfg->fs_defaults)) + goto fail_file; + + sqfs->cmp = sqfs_compressor_create(&cfg); + if (sqfs->cmp == NULL) { + fputs("Error creating compressor\n", stderr); + goto fail_fs; + } + + if (sqfs_super_init(&sqfs->super, wrcfg->block_size, + sqfs->fs.defaults.st_mtime, wrcfg->comp_id)) { + goto fail_cmp; + } + + if (sqfs_super_write(&sqfs->super, sqfs->outfile)) + goto fail_cmp; + + ret = sqfs->cmp->write_options(sqfs->cmp, sqfs->outfile); + if (ret < 0) + goto fail_cmp; + + if (ret > 0) + sqfs->super.flags |= SQFS_FLAG_COMPRESSOR_OPTIONS; + + sqfs->data = sqfs_data_writer_create(sqfs->super.block_size, + sqfs->cmp, wrcfg->num_jobs, + wrcfg->max_backlog, + wrcfg->devblksize, + sqfs->outfile); + if (sqfs->data == NULL) { + perror("creating data block processor"); + goto fail_cmp; + } + + register_stat_hooks(sqfs->data, &sqfs->stats); + + sqfs->idtbl = sqfs_id_table_create(); + if (sqfs->idtbl == NULL) + goto fail_data; + + if (!wrcfg->no_xattr) { + sqfs->xwr = sqfs_xattr_writer_create(); + + if (sqfs->xwr == NULL) { + perror("creating xattr writer"); + goto fail; + } + } + + return 0; +fail: + if (sqfs->xwr != NULL) + sqfs_xattr_writer_destroy(sqfs->xwr); + sqfs_id_table_destroy(sqfs->idtbl); +fail_data: + sqfs_data_writer_destroy(sqfs->data); +fail_cmp: + sqfs->cmp->destroy(sqfs->cmp); +fail_fs: + fstree_cleanup(&sqfs->fs); +fail_file: + sqfs->outfile->destroy(sqfs->outfile); + return -1; +} + +int sqfs_writer_finish(sqfs_writer_t *sqfs, const sqfs_writer_cfg_t *cfg) +{ + if (sqfs_data_writer_finish(sqfs->data)) + return -1; + + tree_node_sort_recursive(sqfs->fs.root); + if (fstree_gen_inode_table(&sqfs->fs)) + return -1; + + sqfs->super.inode_count = sqfs->fs.inode_tbl_size; + + if (sqfs_serialize_fstree(sqfs->outfile, &sqfs->super, + &sqfs->fs, sqfs->cmp, sqfs->idtbl)) { + return -1; + } + + if (sqfs_data_writer_write_fragment_table(sqfs->data, &sqfs->super)) + return -1; + + if (cfg->exportable) { + if (write_export_table(sqfs->outfile, &sqfs->fs, + &sqfs->super, sqfs->cmp)) { + return -1; + } + } + + if (sqfs_id_table_write(sqfs->idtbl, sqfs->outfile, + &sqfs->super, sqfs->cmp)) { + return -1; + } + + if (sqfs_xattr_writer_flush(sqfs->xwr, sqfs->outfile, + &sqfs->super, sqfs->cmp)) { + fputs("Error writing xattr table\n", stderr); + return -1; + } + + sqfs->super.bytes_used = sqfs->outfile->get_size(sqfs->outfile); + + if (sqfs_super_write(&sqfs->super, sqfs->outfile)) + return 0; + + if (padd_sqfs(sqfs->outfile, sqfs->super.bytes_used, + cfg->devblksize)) { + return -1; + } + + if (!cfg->quiet) + sqfs_print_statistics(&sqfs->super, &sqfs->stats); + + return 0; +} + +void sqfs_writer_cleanup(sqfs_writer_t *sqfs) +{ + if (sqfs->xwr != NULL) + sqfs_xattr_writer_destroy(sqfs->xwr); + sqfs_id_table_destroy(sqfs->idtbl); + sqfs_data_writer_destroy(sqfs->data); + sqfs->cmp->destroy(sqfs->cmp); + fstree_cleanup(&sqfs->fs); + sqfs->outfile->destroy(sqfs->outfile); +} diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index e36f2f4..16f9bc0 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -42,7 +42,7 @@ static int pack_files(sqfs_data_writer_t *data, fstree_t *fs, return -1; for (fi = fs->files; fi != NULL; fi = fi->next) { - if (!opt->quiet) + if (!opt->cfg.quiet) printf("packing %s\n", fi->input_file); file = sqfs_open_file(fi->input_file, @@ -54,8 +54,8 @@ static int pack_files(sqfs_data_writer_t *data, fstree_t *fs, filesize = file->get_size(file); - max_blk_count = filesize / opt->blksz; - if (filesize % opt->blksz) + max_blk_count = filesize / opt->cfg.block_size; + if (filesize % opt->cfg.block_size) ++max_blk_count; inode = alloc_flex(sizeof(*inode), sizeof(sqfs_u32), @@ -83,9 +83,6 @@ static int pack_files(sqfs_data_writer_t *data, fstree_t *fs, stats->bytes_read += filesize; } - if (sqfs_data_writer_finish(data)) - return -1; - return restore_working_dir(opt); } @@ -154,63 +151,26 @@ static int read_fstree(fstree_t *fs, options_t *opt, sqfs_xattr_writer_t *xwr, int main(int argc, char **argv) { - int status = EXIT_FAILURE, ret; - sqfs_compressor_config_t cfg; - data_writer_stats_t stats; - sqfs_data_writer_t *data; - sqfs_xattr_writer_t *xwr; - sqfs_compressor_t *cmp; - sqfs_id_table_t *idtbl; - sqfs_file_t *outfile; + int status = EXIT_FAILURE; void *sehnd = NULL; - sqfs_super_t super; + sqfs_writer_t sqfs; options_t opt; - fstree_t fs; process_command_line(&opt, argc, argv); - if (compressor_cfg_init_options(&cfg, opt.compressor, - opt.blksz, opt.comp_extra)) { - return EXIT_FAILURE; - } - - if (fstree_init(&fs, opt.fs_defaults)) + if (sqfs_writer_init(&sqfs, &opt.cfg)) return EXIT_FAILURE; - if (sqfs_super_init(&super, opt.blksz, fs.defaults.st_mtime, - opt.compressor)) { - goto out_fstree; - } - - idtbl = sqfs_id_table_create(); - if (idtbl == NULL) - goto out_fstree; - - outfile = sqfs_open_file(opt.outfile, opt.outmode); - if (outfile == NULL) { - perror(opt.outfile); - goto out_idtbl; - } - - if (sqfs_super_write(&super, outfile)) - goto out_outfile; - if (opt.selinux != NULL) { sehnd = selinux_open_context_file(opt.selinux); if (sehnd == NULL) - goto out_outfile; - } - - xwr = sqfs_xattr_writer_create(); - if (xwr == NULL) { - perror("creating Xattr writer"); - goto out_outfile; + goto out; } - if (read_fstree(&fs, &opt, xwr, sehnd)) { + if (read_fstree(&sqfs.fs, &opt, sqfs.xwr, sehnd)) { if (sehnd != NULL) selinux_close_context_file(sehnd); - goto out_xwr; + goto out; } if (sehnd != NULL) { @@ -218,81 +178,17 @@ int main(int argc, char **argv) sehnd = NULL; } - tree_node_sort_recursive(fs.root); - - if (fstree_gen_inode_table(&fs)) - goto out_xwr; - - fstree_gen_file_list(&fs); - - super.inode_count = fs.inode_tbl_size; - - cmp = sqfs_compressor_create(&cfg); - if (cmp == NULL) { - fputs("Error creating compressor\n", stderr); - goto out_xwr; - } - - ret = cmp->write_options(cmp, outfile); - if (ret < 0) - goto out_cmp; - - if (ret > 0) - super.flags |= SQFS_FLAG_COMPRESSOR_OPTIONS; - - data = sqfs_data_writer_create(super.block_size, cmp, opt.num_jobs, - opt.max_backlog, opt.devblksz, outfile); - if (data == NULL) - goto out_cmp; - - memset(&stats, 0, sizeof(stats)); - register_stat_hooks(data, &stats); - - if (pack_files(data, &fs, &stats, &opt)) - goto out_data; - - if (sqfs_serialize_fstree(outfile, &super, &fs, cmp, idtbl)) - goto out_data; - - if (sqfs_data_writer_write_fragment_table(data, &super)) - goto out_data; - - if (opt.exportable) { - if (write_export_table(outfile, &fs, &super, cmp)) - goto out_data; - } - - if (sqfs_id_table_write(idtbl, outfile, &super, cmp)) - goto out_data; - - if (sqfs_xattr_writer_flush(xwr, outfile, &super, cmp)) { - fputs("Error writing xattr table\n", stderr); - goto out_data; - } - - super.bytes_used = outfile->get_size(outfile); - - if (sqfs_super_write(&super, outfile)) - goto out_data; + tree_node_sort_recursive(sqfs.fs.root); + fstree_gen_file_list(&sqfs.fs); - if (padd_sqfs(outfile, super.bytes_used, opt.devblksz)) - goto out_data; + if (pack_files(sqfs.data, &sqfs.fs, &sqfs.stats, &opt)) + goto out; - if (!opt.quiet) - sqfs_print_statistics(&super, &stats); + if (sqfs_writer_finish(&sqfs, &opt.cfg)) + goto out; status = EXIT_SUCCESS; -out_data: - sqfs_data_writer_destroy(data); -out_cmp: - cmp->destroy(cmp); -out_xwr: - sqfs_xattr_writer_destroy(xwr); -out_outfile: - outfile->destroy(outfile); -out_idtbl: - sqfs_id_table_destroy(idtbl); -out_fstree: - fstree_cleanup(&fs); +out: + sqfs_writer_cleanup(&sqfs); return status; } diff --git a/mkfs/mkfs.h b/mkfs/mkfs.h index 686938e..0c204e0 100644 --- a/mkfs/mkfs.h +++ b/mkfs/mkfs.h @@ -9,13 +9,6 @@ #include "config.h" -#include "sqfs/xattr_writer.h" -#include "sqfs/meta_writer.h" -#include "sqfs/compressor.h" -#include "sqfs/id_table.h" -#include "sqfs/block.h" -#include "sqfs/io.h" - #include "highlevel.h" #include "fstree.h" #include "util.h" @@ -42,21 +35,11 @@ #include typedef struct { - E_SQFS_COMPRESSOR compressor; - char *fs_defaults; - int outmode; - int blksz; - int devblksz; + sqfs_writer_cfg_t cfg; unsigned int dirscan_flags; - unsigned int num_jobs; - size_t max_backlog; - bool exportable; - bool quiet; const char *infile; const char *packdir; - const char *outfile; const char *selinux; - char *comp_extra; } options_t; enum { diff --git a/mkfs/options.c b/mkfs/options.c index f15569a..d741d1a 100644 --- a/mkfs/options.c +++ b/mkfs/options.c @@ -151,12 +151,7 @@ void process_command_line(options_t *opt, int argc, char **argv) int i; memset(opt, 0, sizeof(*opt)); - opt->outmode = 0; - opt->compressor = compressor_get_default(); - opt->blksz = SQFS_DEFAULT_BLOCK_SIZE; - opt->devblksz = SQFS_DEVBLK_SIZE; - opt->num_jobs = 1; - opt->max_backlog = 0; + sqfs_writer_cfg_init(&opt->cfg); for (;;) { i = getopt_long(argc, argv, short_opts, long_opts, NULL); @@ -168,11 +163,11 @@ void process_command_line(options_t *opt, int argc, char **argv) have_compressor = true; if (sqfs_compressor_id_from_name(optarg, - &opt->compressor)) { + &opt->cfg.comp_id)) { have_compressor = false; } - if (!sqfs_compressor_exists(opt->compressor)) + if (!sqfs_compressor_exists(opt->cfg.comp_id)) have_compressor = false; if (!have_compressor) { @@ -182,24 +177,24 @@ void process_command_line(options_t *opt, int argc, char **argv) } break; case 'b': - opt->blksz = strtol(optarg, NULL, 0); + opt->cfg.block_size = strtol(optarg, NULL, 0); break; case 'j': - opt->num_jobs = strtol(optarg, NULL, 0); + opt->cfg.num_jobs = strtol(optarg, NULL, 0); break; case 'Q': - opt->max_backlog = strtol(optarg, NULL, 0); + opt->cfg.max_backlog = strtol(optarg, NULL, 0); break; case 'B': - opt->devblksz = strtol(optarg, NULL, 0); - if (opt->devblksz < 1024) { + opt->cfg.devblksize = strtol(optarg, NULL, 0); + if (opt->cfg.devblksize < 1024) { fputs("Device block size must be at " "least 1024\n", stderr); exit(EXIT_FAILURE); } break; case 'd': - opt->fs_defaults = optarg; + opt->cfg.fs_defaults = optarg; break; case 'k': opt->dirscan_flags |= DIR_SCAN_KEEP_TIME; @@ -213,16 +208,16 @@ void process_command_line(options_t *opt, int argc, char **argv) opt->dirscan_flags |= DIR_SCAN_ONE_FILESYSTEM; break; case 'e': - opt->exportable = true; + opt->cfg.exportable = true; break; case 'f': - opt->outmode |= SQFS_FILE_OPEN_OVERWRITE; + opt->cfg.outmode |= SQFS_FILE_OPEN_OVERWRITE; break; case 'q': - opt->quiet = true; + opt->cfg.quiet = true; break; case 'X': - opt->comp_extra = optarg; + opt->cfg.comp_extra = optarg; break; case 'F': opt->infile = optarg; @@ -249,14 +244,15 @@ void process_command_line(options_t *opt, int argc, char **argv) } } - if (opt->num_jobs < 1) - opt->num_jobs = 1; + if (opt->cfg.num_jobs < 1) + opt->cfg.num_jobs = 1; - if (opt->max_backlog < 1) - opt->max_backlog = 10 * opt->num_jobs; + if (opt->cfg.max_backlog < 1) + opt->cfg.max_backlog = 10 * opt->cfg.num_jobs; - if (opt->comp_extra != NULL && strcmp(opt->comp_extra, "help") == 0) { - compressor_print_help(opt->compressor); + if (opt->cfg.comp_extra != NULL && + strcmp(opt->cfg.comp_extra, "help") == 0) { + compressor_print_help(opt->cfg.comp_id); exit(EXIT_SUCCESS); } @@ -270,7 +266,7 @@ void process_command_line(options_t *opt, int argc, char **argv) goto fail_arg; } - opt->outfile = argv[optind++]; + opt->cfg.filename = argv[optind++]; return; fail_arg: fprintf(stderr, "Try `%s --help' for more information.\n", __progname); diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index efdc0d3..9533229 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -6,26 +6,14 @@ */ #include "config.h" -#include "sqfs/xattr_writer.h" -#include "sqfs/compressor.h" -#include "sqfs/id_table.h" -#include "sqfs/xattr.h" -#include "sqfs/block.h" -#include "sqfs/io.h" - #include "highlevel.h" -#include "fstree.h" -#include "util.h" #include "tar.h" #include #include #include #include -#include #include -#include -#include static struct option long_opts[] = { { "compressor", required_argument, NULL, 'c' }, @@ -96,29 +84,17 @@ static const char *usagestr = "\txzcat rootfs.tar.xz | tar2sqfs rootfs.sqfs\n" "\n"; -static const char *filename; -static int block_size = SQFS_DEFAULT_BLOCK_SIZE; -static size_t devblksize = SQFS_DEVBLK_SIZE; -static bool quiet = false; -static int outmode = 0; -static unsigned int num_jobs = 1; -static size_t max_backlog = 0; -static E_SQFS_COMPRESSOR comp_id; -static char *comp_extra = NULL; -static char *fs_defaults = NULL; static bool dont_skip = false; -static bool no_xattr = false; -static bool exportable = false; static bool keep_time = false; -static sqfs_xattr_writer_t *xwr = NULL; -static data_writer_stats_t stats; +static sqfs_writer_cfg_t cfg; +static sqfs_writer_t sqfs; static void process_args(int argc, char **argv) { bool have_compressor; int i; - comp_id = compressor_get_default(); + sqfs_writer_cfg_init(&cfg); for (;;) { i = getopt_long(argc, argv, short_opts, long_opts, NULL); @@ -127,11 +103,11 @@ static void process_args(int argc, char **argv) switch (i) { case 'b': - block_size = strtol(optarg, NULL, 0); + cfg.block_size = strtol(optarg, NULL, 0); break; case 'B': - devblksize = strtol(optarg, NULL, 0); - if (devblksize < 1024) { + cfg.devblksize = strtol(optarg, NULL, 0); + if (cfg.devblksize < 1024) { fputs("Device block size must be at " "least 1024\n", stderr); exit(EXIT_FAILURE); @@ -140,10 +116,10 @@ static void process_args(int argc, char **argv) case 'c': have_compressor = true; - if (sqfs_compressor_id_from_name(optarg, &comp_id)) + if (sqfs_compressor_id_from_name(optarg, &cfg.comp_id)) have_compressor = false; - if (!sqfs_compressor_exists(comp_id)) + if (!sqfs_compressor_exists(cfg.comp_id)) have_compressor = false; if (!have_compressor) { @@ -153,19 +129,19 @@ static void process_args(int argc, char **argv) } break; case 'j': - num_jobs = strtol(optarg, NULL, 0); + cfg.num_jobs = strtol(optarg, NULL, 0); break; case 'Q': - max_backlog = strtol(optarg, NULL, 0); + cfg.max_backlog = strtol(optarg, NULL, 0); break; case 'X': - comp_extra = optarg; + cfg.comp_extra = optarg; break; case 'd': - fs_defaults = optarg; + cfg.fs_defaults = optarg; break; case 'x': - no_xattr = true; + cfg.no_xattr = true; break; case 'k': keep_time = true; @@ -174,13 +150,13 @@ static void process_args(int argc, char **argv) dont_skip = true; break; case 'e': - exportable = true; + cfg.exportable = true; break; case 'f': - outmode |= SQFS_FILE_OPEN_OVERWRITE; + cfg.outmode |= SQFS_FILE_OPEN_OVERWRITE; break; case 'q': - quiet = true; + cfg.quiet = true; break; case 'h': printf(usagestr, SQFS_DEFAULT_BLOCK_SIZE, @@ -195,14 +171,14 @@ static void process_args(int argc, char **argv) } } - if (num_jobs < 1) - num_jobs = 1; + if (cfg.num_jobs < 1) + cfg.num_jobs = 1; - if (max_backlog < 1) - max_backlog = 10 * num_jobs; + if (cfg.max_backlog < 1) + cfg.max_backlog = 10 * cfg.num_jobs; - if (comp_extra != NULL && strcmp(comp_extra, "help") == 0) { - compressor_print_help(comp_id); + if (cfg.comp_extra != NULL && strcmp(cfg.comp_extra, "help") == 0) { + compressor_print_help(cfg.comp_id); exit(EXIT_SUCCESS); } @@ -211,7 +187,7 @@ static void process_args(int argc, char **argv) goto fail_arg; } - filename = argv[optind++]; + cfg.filename = argv[optind++]; if (optind < argc) { fputs("Unknown extra arguments\n", stderr); @@ -224,7 +200,7 @@ fail_arg: } static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, - sqfs_data_writer_t *data, sqfs_u64 filesize) + sqfs_u64 filesize) { const sparse_map_t *it; sqfs_inode_generic_t *inode; @@ -233,8 +209,8 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, sqfs_u64 sum; int ret; - max_blk_count = filesize / block_size; - if (filesize % block_size) + max_blk_count = filesize / cfg.block_size; + if (filesize % cfg.block_size) ++max_blk_count; inode = alloc_flex(sizeof(*inode), sizeof(sqfs_u32), max_blk_count); @@ -267,11 +243,11 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, } } - ret = write_data_from_file(data, inode, file, 0); + ret = write_data_from_file(sqfs.data, inode, file, 0); file->destroy(file); - stats.bytes_read += filesize; - stats.file_count += 1; + sqfs.stats.bytes_read += filesize; + sqfs.stats.file_count += 1; if (ret) return -1; @@ -280,12 +256,11 @@ static int write_file(tar_header_decoded_t *hdr, file_info_t *fi, filesize : hdr->record_size); } -static int copy_xattr(sqfs_xattr_writer_t *xwr, tree_node_t *node, - tar_header_decoded_t *hdr) +static int copy_xattr(tree_node_t *node, tar_header_decoded_t *hdr) { tar_xattr_t *xattr; - if (sqfs_xattr_writer_begin(xwr)) { + if (sqfs_xattr_writer_begin(sqfs.xwr)) { fputs("Error beginning xattr block\n", stderr); return -1; } @@ -303,7 +278,7 @@ static int copy_xattr(sqfs_xattr_writer_t *xwr, tree_node_t *node, continue; } - if (sqfs_xattr_writer_add(xwr, xattr->key, xattr->value, + if (sqfs_xattr_writer_add(sqfs.xwr, xattr->key, xattr->value, strlen(xattr->value))) { fputs("Error converting xattr key-value pair\n", stderr); @@ -311,7 +286,7 @@ static int copy_xattr(sqfs_xattr_writer_t *xwr, tree_node_t *node, } } - if (sqfs_xattr_writer_end(xwr, &node->xattr_idx)) { + if (sqfs_xattr_writer_end(sqfs.xwr, &node->xattr_idx)) { fputs("Error completing xattr block\n", stderr); return -1; } @@ -319,29 +294,29 @@ static int copy_xattr(sqfs_xattr_writer_t *xwr, tree_node_t *node, return 0; } -static int create_node_and_repack_data(tar_header_decoded_t *hdr, fstree_t *fs, - sqfs_data_writer_t *data) +static int create_node_and_repack_data(tar_header_decoded_t *hdr) { tree_node_t *node; if (!keep_time) { - hdr->sb.st_mtime = fs->defaults.st_mtime; + hdr->sb.st_mtime = sqfs.fs.defaults.st_mtime; } - node = fstree_add_generic(fs, hdr->name, &hdr->sb, hdr->link_target); + node = fstree_add_generic(&sqfs.fs, hdr->name, + &hdr->sb, hdr->link_target); if (node == NULL) goto fail_errno; - if (!quiet) + if (!cfg.quiet) printf("Packing %s\n", hdr->name); - if (!no_xattr) { - if (copy_xattr(xwr, node, hdr)) + if (!cfg.no_xattr) { + if (copy_xattr(node, hdr)) return -1; } if (S_ISREG(hdr->sb.st_mode)) { - if (write_file(hdr, &node->data.file, data, hdr->sb.st_size)) + if (write_file(hdr, &node->data.file, hdr->sb.st_size)) return -1; } @@ -351,7 +326,7 @@ fail_errno: return -1; } -static int process_tar_ball(fstree_t *fs, sqfs_data_writer_t *data) +static int process_tar_ball(void) { tar_header_decoded_t hdr; sqfs_u64 offset, count; @@ -409,7 +384,7 @@ static int process_tar_ball(fstree_t *fs, sqfs_data_writer_t *data) continue; } - if (create_node_and_repack_data(&hdr, fs, data)) + if (create_node_and_repack_data(&hdr)) goto fail; clear_header(&hdr); @@ -423,126 +398,21 @@ fail: int main(int argc, char **argv) { - sqfs_compressor_config_t cfg; - int status = EXIT_SUCCESS; - sqfs_data_writer_t *data; - sqfs_compressor_t *cmp; - sqfs_id_table_t *idtbl; - sqfs_file_t *outfile; - sqfs_super_t super; - fstree_t fs; - int ret; + int status = EXIT_FAILURE; process_args(argc, argv); - if (compressor_cfg_init_options(&cfg, comp_id, - block_size, comp_extra)) { - return EXIT_FAILURE; - } - - outfile = sqfs_open_file(filename, outmode); - if (outfile == NULL) { - perror(filename); + if (sqfs_writer_init(&sqfs, &cfg)) return EXIT_FAILURE; - } - - if (fstree_init(&fs, fs_defaults)) - goto out_fd; - - cmp = sqfs_compressor_create(&cfg); - if (cmp == NULL) { - fputs("Error creating compressor\n", stderr); - goto out_fs; - } - - if (sqfs_super_init(&super, block_size, fs.defaults.st_mtime, comp_id)) - goto out_cmp; - - if (sqfs_super_write(&super, outfile)) - goto out_cmp; - - ret = cmp->write_options(cmp, outfile); - if (ret < 0) - goto out_cmp; - - if (ret > 0) - super.flags |= SQFS_FLAG_COMPRESSOR_OPTIONS; - - data = sqfs_data_writer_create(super.block_size, cmp, num_jobs, - max_backlog, devblksize, outfile); - if (data == NULL) { - perror("creating data block processor"); - goto out_cmp; - } - - register_stat_hooks(data, &stats); - - idtbl = sqfs_id_table_create(); - if (idtbl == NULL) - goto out_data; - - if (!no_xattr) { - xwr = sqfs_xattr_writer_create(); - if (xwr == NULL) { - perror("creating xattr writer"); - goto out; - } - } - if (process_tar_ball(&fs, data)) + if (process_tar_ball()) goto out; - if (sqfs_data_writer_finish(data)) + if (sqfs_writer_finish(&sqfs, &cfg)) goto out; - tree_node_sort_recursive(fs.root); - if (fstree_gen_inode_table(&fs)) - goto out; - - super.inode_count = fs.inode_tbl_size; - - if (sqfs_serialize_fstree(outfile, &super, &fs, cmp, idtbl)) - goto out; - - if (sqfs_data_writer_write_fragment_table(data, &super)) - goto out; - - if (exportable) { - if (write_export_table(outfile, &fs, &super, cmp)) - goto out; - } - - if (sqfs_id_table_write(idtbl, outfile, &super, cmp)) - goto out; - - if (sqfs_xattr_writer_flush(xwr, outfile, &super, cmp)) { - fputs("Error writing xattr table\n", stderr); - goto out; - } - - super.bytes_used = outfile->get_size(outfile); - - if (sqfs_super_write(&super, outfile)) - goto out; - - if (padd_sqfs(outfile, super.bytes_used, devblksize)) - goto out; - - if (!quiet) - sqfs_print_statistics(&super, &stats); - status = EXIT_SUCCESS; out: - if (xwr != NULL) - sqfs_xattr_writer_destroy(xwr); - sqfs_id_table_destroy(idtbl); -out_data: - sqfs_data_writer_destroy(data); -out_cmp: - cmp->destroy(cmp); -out_fs: - fstree_cleanup(&fs); -out_fd: - outfile->destroy(outfile); + sqfs_writer_cleanup(&sqfs); return status; } -- cgit v1.2.3