summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/highlevel.h37
-rw-r--r--lib/sqfshelper/Makemodule.am1
-rw-r--r--lib/sqfshelper/writer.c168
-rw-r--r--mkfs/mkfs.c138
-rw-r--r--mkfs/mkfs.h19
-rw-r--r--mkfs/options.c46
-rw-r--r--tar/tar2sqfs.c226
7 files changed, 293 insertions, 342 deletions
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 <goliath@infraroot.at>
+ */
+#include "config.h"
+
+#include "highlevel.h"
+#include "util.h"
+
+#include <string.h>
+
+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 <ctype.h>
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 <stdlib.h>
#include <getopt.h>
#include <unistd.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
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;
}