summaryrefslogtreecommitdiff
path: root/lib/sqfshelper
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqfshelper')
-rw-r--r--lib/sqfshelper/Makemodule.am12
-rw-r--r--lib/sqfshelper/comp_opt.c379
-rw-r--r--lib/sqfshelper/compress.c33
-rw-r--r--lib/sqfshelper/data_reader_dump.c80
-rw-r--r--lib/sqfshelper/data_writer.c55
-rw-r--r--lib/sqfshelper/get_path.c41
-rw-r--r--lib/sqfshelper/inode_stat.c76
-rw-r--r--lib/sqfshelper/io_stdin.c174
-rw-r--r--lib/sqfshelper/perror.c67
-rw-r--r--lib/sqfshelper/print_version.c29
-rw-r--r--lib/sqfshelper/serialize_fstree.c220
-rw-r--r--lib/sqfshelper/statistics.c88
-rw-r--r--lib/sqfshelper/write_export_table.c43
-rw-r--r--lib/sqfshelper/writer.c281
14 files changed, 0 insertions, 1578 deletions
diff --git a/lib/sqfshelper/Makemodule.am b/lib/sqfshelper/Makemodule.am
deleted file mode 100644
index b72b904..0000000
--- a/lib/sqfshelper/Makemodule.am
+++ /dev/null
@@ -1,12 +0,0 @@
-libsqfshelper_a_SOURCES = lib/sqfshelper/serialize_fstree.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/statistics.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/write_export_table.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/print_version.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/inode_stat.c
-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/common.h
-libsqfshelper_a_SOURCES += lib/sqfshelper/get_path.c lib/sqfshelper/io_stdin.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/writer.c lib/sqfshelper/perror.c
-
-noinst_LIBRARIES += libsqfshelper.a
diff --git a/lib/sqfshelper/comp_opt.c b/lib/sqfshelper/comp_opt.c
deleted file mode 100644
index 2b92da3..0000000
--- a/lib/sqfshelper/comp_opt.c
+++ /dev/null
@@ -1,379 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * comp_opt.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <string.h>
-#include <stdlib.h>
-#include <getopt.h>
-#include <ctype.h>
-
-typedef struct {
- const char *name;
- sqfs_u16 flag;
-} flag_t;
-
-static const flag_t gzip_flags[] = {
- { "default", SQFS_COMP_FLAG_GZIP_DEFAULT },
- { "filtered", SQFS_COMP_FLAG_GZIP_FILTERED },
- { "huffman", SQFS_COMP_FLAG_GZIP_HUFFMAN },
- { "rle", SQFS_COMP_FLAG_GZIP_RLE },
- { "fixed", SQFS_COMP_FLAG_GZIP_FIXED },
-};
-
-static const flag_t xz_flags[] = {
- { "x86", SQFS_COMP_FLAG_XZ_X86 },
- { "powerpc", SQFS_COMP_FLAG_XZ_POWERPC },
- { "ia64", SQFS_COMP_FLAG_XZ_IA64 },
- { "arm", SQFS_COMP_FLAG_XZ_ARM },
- { "armthumb", SQFS_COMP_FLAG_XZ_ARMTHUMB },
- { "sparc", SQFS_COMP_FLAG_XZ_SPARC },
-};
-
-static const flag_t lz4_flags[] = {
- { "hc", SQFS_COMP_FLAG_LZ4_HC },
-};
-
-static const char *lzo_algs[] = {
- [SQFS_LZO1X_1] = "lzo1x_1",
- [SQFS_LZO1X_1_11] = "lzo1x_1_11",
- [SQFS_LZO1X_1_12] = "lzo1x_1_12",
- [SQFS_LZO1X_1_15] = "lzo1x_1_15",
- [SQFS_LZO1X_999] = "lzo1x_999",
-};
-
-static int set_flag(sqfs_compressor_config_t *cfg, const char *name,
- const flag_t *flags, size_t num_flags)
-{
- size_t i;
-
- for (i = 0; i < num_flags; ++i) {
- if (strcmp(flags[i].name, name) == 0) {
- cfg->flags |= flags[i].flag;
- return 0;
- }
- }
-
- return -1;
-}
-
-static int find_lzo_alg(sqfs_compressor_config_t *cfg, const char *name)
-{
- size_t i;
-
- for (i = 0; i < sizeof(lzo_algs) / sizeof(lzo_algs[0]); ++i) {
- if (strcmp(lzo_algs[i], name) == 0) {
- cfg->opt.lzo.algorithm = i;
- return 0;
- }
- }
-
- return -1;
-}
-
-static int get_size_value(const char *value, sqfs_u32 *out, sqfs_u32 block_size)
-{
- int i;
-
- for (i = 0; isdigit(value[i]) && i < 9; ++i)
- ;
-
- if (i < 1 || i > 9)
- return -1;
-
- *out = atol(value);
-
- switch (value[i]) {
- case '\0':
- break;
- case 'm':
- case 'M':
- *out <<= 20;
- break;
- case 'k':
- case 'K':
- *out <<= 10;
- break;
- case '%':
- *out = (*out * block_size) / 100;
- break;
- default:
- return -1;
- }
-
- return 0;
-}
-
-enum {
- OPT_WINDOW = 0,
- OPT_LEVEL,
- OPT_ALG,
- OPT_DICT,
-};
-static char *const token[] = {
- [OPT_WINDOW] = (char *)"window",
- [OPT_LEVEL] = (char *)"level",
- [OPT_ALG] = (char *)"algorithm",
- [OPT_DICT] = (char *)"dictsize",
- NULL
-};
-
-int compressor_cfg_init_options(sqfs_compressor_config_t *cfg,
- E_SQFS_COMPRESSOR id,
- size_t block_size, char *options)
-{
- size_t num_flags = 0, min_level = 0, max_level = 0, level;
- const flag_t *flags = NULL;
- char *subopts, *value;
- int i, opt;
-
- if (sqfs_compressor_config_init(cfg, id, block_size, 0))
- return -1;
-
- if (options == NULL)
- return 0;
-
- switch (cfg->id) {
- case SQFS_COMP_GZIP:
- min_level = SQFS_GZIP_MIN_LEVEL;
- max_level = SQFS_GZIP_MAX_LEVEL;
- flags = gzip_flags;
- num_flags = sizeof(gzip_flags) / sizeof(gzip_flags[0]);
- break;
- case SQFS_COMP_LZO:
- min_level = SQFS_LZO_MIN_LEVEL;
- max_level = SQFS_LZO_MAX_LEVEL;
- break;
- case SQFS_COMP_ZSTD:
- min_level = SQFS_ZSTD_MIN_LEVEL;
- max_level = SQFS_ZSTD_MAX_LEVEL;
- break;
- case SQFS_COMP_XZ:
- flags = xz_flags;
- num_flags = sizeof(xz_flags) / sizeof(xz_flags[0]);
- break;
- case SQFS_COMP_LZ4:
- flags = lz4_flags;
- num_flags = sizeof(lz4_flags) / sizeof(lz4_flags[0]);
- break;
- default:
- break;
- }
-
- subopts = options;
-
- while (*subopts != '\0') {
- opt = getsubopt(&subopts, token, &value);
-
- switch (opt) {
- case OPT_WINDOW:
- if (cfg->id != SQFS_COMP_GZIP)
- goto fail_opt;
-
- if (value == NULL)
- goto fail_value;
-
- for (i = 0; isdigit(value[i]); ++i)
- ;
-
- if (i < 1 || i > 3 || value[i] != '\0')
- goto fail_window;
-
- cfg->opt.gzip.window_size = atoi(value);
-
- if (cfg->opt.gzip.window_size < SQFS_GZIP_MIN_WINDOW ||
- cfg->opt.gzip.window_size > SQFS_GZIP_MAX_WINDOW)
- goto fail_window;
- break;
- case OPT_LEVEL:
- if (value == NULL)
- goto fail_value;
-
- for (i = 0; isdigit(value[i]) && i < 3; ++i)
- ;
-
- if (i < 1 || i > 3 || value[i] != '\0')
- goto fail_level;
-
- level = atoi(value);
-
- if (level < min_level || level > max_level)
- goto fail_level;
-
- switch (cfg->id) {
- case SQFS_COMP_GZIP:
- cfg->opt.gzip.level = level;
- break;
- case SQFS_COMP_LZO:
- cfg->opt.lzo.level = level;
- break;
- case SQFS_COMP_ZSTD:
- cfg->opt.zstd.level = level;
- break;
- default:
- goto fail_opt;
- }
- break;
- case OPT_ALG:
- if (cfg->id != SQFS_COMP_LZO)
- goto fail_opt;
-
- if (value == NULL)
- goto fail_value;
-
- if (find_lzo_alg(cfg, value))
- goto fail_lzo_alg;
- break;
- case OPT_DICT:
- if (cfg->id != SQFS_COMP_XZ)
- goto fail_opt;
-
- if (value == NULL)
- goto fail_value;
-
- if (get_size_value(value, &cfg->opt.xz.dict_size,
- cfg->block_size)) {
- goto fail_dict;
- }
- break;
- default:
- if (set_flag(cfg, value, flags, num_flags))
- goto fail_opt;
- break;
- }
- }
-
- return 0;
-fail_lzo_alg:
- fprintf(stderr, "Unknown lzo variant '%s'.\n", value);
- return -1;
-fail_window:
- fputs("Window size must be a number between 8 and 15.\n", stderr);
- return -1;
-fail_level:
- fprintf(stderr,
- "Compression level must be a number between %zu and %zu.\n",
- min_level, max_level);
- return -1;
-fail_opt:
- fprintf(stderr, "Unknown compressor option '%s'.\n", value);
- return -1;
-fail_value:
- fprintf(stderr, "Missing value for compressor option '%s'.\n",
- token[opt]);
- return -1;
-fail_dict:
- fputs("Dictionary size must be a number with the optional "
- "suffix 'm','k' or '%'.\n", stderr);
- return -1;
-}
-
-typedef void (*compressor_help_fun_t)(void);
-
-static void gzip_print_help(void)
-{
- size_t i;
-
- printf(
-"Available options for gzip compressor:\n"
-"\n"
-" level=<value> Compression level. Value from 1 to 9.\n"
-" Defaults to %d.\n"
-" window=<size> Deflate compression window size. Value from 8 to 15.\n"
-" Defaults to %d.\n"
-"\n"
-"In additon to the options, one or more strategies can be specified.\n"
-"If multiple stratgies are provided, the one yielding the best compression\n"
-"ratio will be used.\n"
-"\n"
-"The following strategies are available:\n",
- SQFS_GZIP_DEFAULT_LEVEL, SQFS_GZIP_DEFAULT_WINDOW);
-
- for (i = 0; i < sizeof(gzip_flags) / sizeof(gzip_flags[0]); ++i)
- printf("\t%s\n", gzip_flags[i].name);
-}
-
-static void lz4_print_help(void)
-{
- fputs("Available options for lz4 compressor:\n"
- "\n"
- " hc If present, use slower but better compressing\n"
- " variant of lz4.\n"
- "\n",
- stdout);
-}
-
-static void lzo_print_help(void)
-{
- size_t i;
-
- fputs("Available options for lzo compressor:\n"
- "\n"
- " algorithm=<name> Specify the variant of lzo to use.\n"
- " Defaults to 'lzo1x_999'.\n"
- " level=<value> For lzo1x_999, the compression level.\n"
- " Value from 1 to 9. Defaults to 8.\n"
- " Ignored if algorithm is not lzo1x_999.\n"
- "\n"
- "Available algorithms:\n",
- stdout);
-
- for (i = 0; i < sizeof(lzo_algs) / sizeof(lzo_algs[0]); ++i)
- printf("\t%s\n", lzo_algs[i]);
-}
-
-static void xz_print_help(void)
-{
- size_t i;
-
- fputs(
-"Available options for xz compressor:\n"
-"\n"
-" dictsize=<value> Dictionary size. Either a value in bytes or a\n"
-" percentage of the block size. Defaults to 100%.\n"
-" The suffix '%' indicates a percentage. 'K' and 'M'\n"
-" can also be used for kibi and mebi bytes\n"
-" respecitively.\n"
-"\n"
-"In additon to the options, one or more bcj filters can be specified.\n"
-"If multiple filters are provided, the one yielding the best compression\n"
-"ratio will be used.\n"
-"\n"
-"The following filters are available:\n",
- stdout);
-
- for (i = 0; i < sizeof(xz_flags) / sizeof(xz_flags[0]); ++i)
- printf("\t%s\n", xz_flags[i].name);
-}
-
-static void zstd_print_help(void)
-{
- printf("Available options for zstd compressor:\n"
- "\n"
- " level=<value> Set compression level. Defaults to %d.\n"
- " Maximum is %d.\n"
- "\n",
- SQFS_ZSTD_DEFAULT_LEVEL, SQFS_ZSTD_MAX_LEVEL);
-}
-
-static const compressor_help_fun_t helpfuns[SQFS_COMP_MAX + 1] = {
- [SQFS_COMP_GZIP] = gzip_print_help,
- [SQFS_COMP_XZ] = xz_print_help,
- [SQFS_COMP_LZO] = lzo_print_help,
- [SQFS_COMP_LZ4] = lz4_print_help,
- [SQFS_COMP_ZSTD] = zstd_print_help,
-};
-
-void compressor_print_help(E_SQFS_COMPRESSOR id)
-{
- if (id < SQFS_COMP_MIN || id > SQFS_COMP_MAX)
- return;
-
- if (helpfuns[id] == NULL)
- return;
-
- helpfuns[id]();
-}
diff --git a/lib/sqfshelper/compress.c b/lib/sqfshelper/compress.c
deleted file mode 100644
index 04e1f40..0000000
--- a/lib/sqfshelper/compress.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * compress.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-E_SQFS_COMPRESSOR compressor_get_default(void)
-{
- if (sqfs_compressor_exists(SQFS_COMP_XZ))
- return SQFS_COMP_XZ;
-
- if (sqfs_compressor_exists(SQFS_COMP_ZSTD))
- return SQFS_COMP_ZSTD;
-
- return SQFS_COMP_GZIP;
-}
-
-void compressor_print_available(void)
-{
- int i;
-
- fputs("Available compressors:\n", stdout);
-
- for (i = SQFS_COMP_MIN; i <= SQFS_COMP_MAX; ++i) {
- if (sqfs_compressor_exists(i))
- printf("\t%s\n", sqfs_compressor_name_from_id(i));
- }
-
- printf("\nDefault compressor: %s\n",
- sqfs_compressor_name_from_id(compressor_get_default()));
-}
diff --git a/lib/sqfshelper/data_reader_dump.c b/lib/sqfshelper/data_reader_dump.c
deleted file mode 100644
index 140f527..0000000
--- a/lib/sqfshelper/data_reader_dump.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * data_reader_dump.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-#include "util.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-int sqfs_data_reader_dump(const char *name, sqfs_data_reader_t *data,
- const sqfs_inode_generic_t *inode,
- int outfd, size_t block_size, bool allow_sparse)
-{
- sqfs_block_t *blk;
- sqfs_u64 filesz;
- size_t i, diff;
- int err;
-
- sqfs_inode_get_file_size(inode, &filesz);
-
- if (allow_sparse && ftruncate(outfd, filesz))
- goto fail_sparse;
-
- for (i = 0; i < inode->num_file_blocks; ++i) {
- if (SQFS_IS_SPARSE_BLOCK(inode->block_sizes[i]) &&
- allow_sparse) {
- if (filesz < block_size) {
- diff = filesz;
- filesz = 0;
- } else {
- diff = block_size;
- filesz -= block_size;
- }
-
- if (lseek(outfd, diff, SEEK_CUR) == (off_t)-1)
- goto fail_sparse;
- } else {
- err = sqfs_data_reader_get_block(data, inode, i, &blk);
- if (err) {
- sqfs_perror(name, "reading data block", err);
- return -1;
- }
-
- if (write_data("writing uncompressed block",
- outfd, blk->data, blk->size)) {
- free(blk);
- return -1;
- }
-
- filesz -= blk->size;
- free(blk);
- }
- }
-
- if (filesz > 0) {
- err = sqfs_data_reader_get_fragment(data, inode, &blk);
- if (err) {
- sqfs_perror(name, "reading fragment block", err);
- return -1;
- }
-
- if (write_data("writing uncompressed fragment", outfd,
- blk->data, blk->size)) {
- free(blk);
- return -1;
- }
-
- free(blk);
- }
-
- return 0;
-fail_sparse:
- perror("creating sparse output file");
- return -1;
-}
diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c
deleted file mode 100644
index 36de154..0000000
--- a/lib/sqfshelper/data_writer.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * data_writer.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-#include "util.h"
-
-static sqfs_u8 buffer[4096];
-
-int write_data_from_file(const char *filename, sqfs_data_writer_t *data,
- sqfs_inode_generic_t *inode, sqfs_file_t *file,
- int flags)
-{
- sqfs_u64 filesz, offset;
- size_t diff;
- int ret;
-
- ret = sqfs_data_writer_begin_file(data, inode, flags);
- if (ret) {
- sqfs_perror(filename, "beginning file data blocks", ret);
- return -1;
- }
-
- sqfs_inode_get_file_size(inode, &filesz);
-
- for (offset = 0; offset < filesz; offset += diff) {
- if (filesz - offset > sizeof(buffer)) {
- diff = sizeof(buffer);
- } else {
- diff = filesz - offset;
- }
-
- ret = file->read_at(file, offset, buffer, diff);
- if (ret) {
- sqfs_perror(filename, "reading file range", ret);
- return -1;
- }
-
- ret = sqfs_data_writer_append(data, buffer, diff);
- if (ret) {
- sqfs_perror(filename, "packing file data", ret);
- return -1;
- }
- }
-
- ret = sqfs_data_writer_end_file(data);
- if (ret) {
- sqfs_perror(filename, "finishing file data", ret);
- return -1;
- }
-
- return 0;
-}
diff --git a/lib/sqfshelper/get_path.c b/lib/sqfshelper/get_path.c
deleted file mode 100644
index bdc6c3f..0000000
--- a/lib/sqfshelper/get_path.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * get_path.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-char *sqfs_tree_node_get_path(const sqfs_tree_node_t *node)
-{
- const sqfs_tree_node_t *it;
- char *str, *ptr;
- size_t len = 0;
-
- if (node->parent == NULL)
- return strdup("/");
-
- for (it = node; it != NULL && it->parent != NULL; it = it->parent) {
- len += strlen((const char *)it->name) + 1;
- }
-
- str = malloc(len + 1);
- if (str == NULL)
- return NULL;
-
- ptr = str + len;
- *ptr = '\0';
-
- for (it = node; it != NULL && it->parent != NULL; it = it->parent) {
- len = strlen((const char *)it->name);
- ptr -= len;
-
- memcpy(ptr, (const char *)it->name, len);
- *(--ptr) = '/';
- }
-
- return str;
-}
diff --git a/lib/sqfshelper/inode_stat.c b/lib/sqfshelper/inode_stat.c
deleted file mode 100644
index a73436b..0000000
--- a/lib/sqfshelper/inode_stat.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * inode_stat.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-int inode_stat(const sqfs_tree_node_t *node, struct stat *sb)
-{
- memset(sb, 0, sizeof(*sb));
-
- sb->st_mode = node->inode->base.mode;
- sb->st_uid = node->uid;
- sb->st_gid = node->gid;
- sb->st_atime = node->inode->base.mod_time;
- sb->st_mtime = node->inode->base.mod_time;
- sb->st_ctime = node->inode->base.mod_time;
- sb->st_ino = node->inode->base.inode_number;
- sb->st_nlink = 1;
- sb->st_blksize = 512;
-
- switch (node->inode->base.type) {
- case SQFS_INODE_BDEV:
- case SQFS_INODE_CDEV:
- sb->st_rdev = node->inode->data.dev.devno;
- sb->st_nlink = node->inode->data.dev.nlink;
- break;
- case SQFS_INODE_EXT_BDEV:
- case SQFS_INODE_EXT_CDEV:
- sb->st_rdev = node->inode->data.dev_ext.devno;
- sb->st_nlink = node->inode->data.dev_ext.nlink;
- break;
- case SQFS_INODE_FIFO:
- case SQFS_INODE_SOCKET:
- sb->st_nlink = node->inode->data.ipc.nlink;
- break;
- case SQFS_INODE_EXT_FIFO:
- case SQFS_INODE_EXT_SOCKET:
- sb->st_nlink = node->inode->data.ipc_ext.nlink;
- break;
- case SQFS_INODE_SLINK:
- sb->st_size = node->inode->data.slink.target_size;
- sb->st_nlink = node->inode->data.slink.nlink;
- break;
- case SQFS_INODE_EXT_SLINK:
- sb->st_size = node->inode->data.slink_ext.target_size;
- sb->st_nlink = node->inode->data.slink_ext.nlink;
- break;
- case SQFS_INODE_FILE:
- sb->st_size = node->inode->data.file.file_size;
- break;
- case SQFS_INODE_EXT_FILE:
- sb->st_size = node->inode->data.file_ext.file_size;
- sb->st_nlink = node->inode->data.file_ext.nlink;
- break;
- case SQFS_INODE_DIR:
- sb->st_size = node->inode->data.dir.size;
- sb->st_nlink = node->inode->data.dir.nlink;
- break;
- case SQFS_INODE_EXT_DIR:
- sb->st_size = node->inode->data.dir_ext.size;
- sb->st_nlink = node->inode->data.dir_ext.nlink;
- break;
- }
-
- sb->st_blocks = sb->st_size / sb->st_blksize;
- if (sb->st_size % sb->st_blksize)
- sb->st_blocks += 1;
-
- return 0;
-}
diff --git a/lib/sqfshelper/io_stdin.c b/lib/sqfshelper/io_stdin.c
deleted file mode 100644
index 0e9fb17..0000000
--- a/lib/sqfshelper/io_stdin.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * io_stdin.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-
-typedef struct {
- sqfs_file_t base;
-
- const sparse_map_t *map;
- sqfs_u64 offset;
- sqfs_u64 size;
-} sqfs_file_stdin_t;
-
-
-static void stdin_destroy(sqfs_file_t *base)
-{
- free(base);
-}
-
-static int stdin_read_at(sqfs_file_t *base, sqfs_u64 offset,
- void *buffer, size_t size)
-{
- sqfs_file_stdin_t *file = (sqfs_file_stdin_t *)base;
- size_t temp_size = 0;
- sqfs_u8 *temp = NULL;
- sqfs_u64 diff;
- ssize_t ret;
-
- if (offset < file->offset)
- return SQFS_ERROR_IO;
-
- if (offset > file->offset) {
- temp_size = 1024;
- temp = alloca(temp_size);
- }
-
- if (offset >= file->size || (offset + size) > file->size)
- return SQFS_ERROR_OUT_OF_BOUNDS;
-
- while (size > 0) {
- if (offset > file->offset) {
- diff = file->offset - offset;
- diff = diff > (sqfs_u64)temp_size ? temp_size : diff;
-
- ret = read(STDIN_FILENO, temp, diff);
- } else {
- ret = read(STDIN_FILENO, buffer, size);
- }
-
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- return SQFS_ERROR_IO;
- }
-
- if (ret == 0)
- return SQFS_ERROR_OUT_OF_BOUNDS;
-
- if (offset <= file->offset) {
- buffer = (char *)buffer + ret;
- size -= ret;
- offset += ret;
- }
-
- file->offset += ret;
- }
-
- return 0;
-}
-
-static int stdin_read_condensed(sqfs_file_t *base, sqfs_u64 offset,
- void *buffer, size_t size)
-{
- sqfs_file_stdin_t *file = (sqfs_file_stdin_t *)base;
- sqfs_u64 poffset = 0, src_start;
- size_t dst_start, diff, count;
- const sparse_map_t *it;
- int err;
-
- memset(buffer, 0, size);
-
- for (it = file->map; it != NULL; it = it->next) {
- if (it->offset + it->count <= offset) {
- poffset += it->count;
- continue;
- }
-
- if (it->offset >= offset + size) {
- poffset += it->count;
- continue;
- }
-
- count = size;
-
- if (offset + count >= it->offset + it->count)
- count = it->offset + it->count - offset;
-
- if (it->offset < offset) {
- diff = offset - it->offset;
-
- src_start = poffset + diff;
- dst_start = 0;
- count -= diff;
- } else if (it->offset > offset) {
- diff = it->offset - offset;
-
- src_start = poffset;
- dst_start = diff;
- } else {
- src_start = poffset;
- dst_start = 0;
- }
-
- err = stdin_read_at(base, src_start,
- (char *)buffer + dst_start, count);
- if (err)
- return err;
-
- poffset += it->count;
- }
-
- return 0;
-}
-
-static int stdin_write_at(sqfs_file_t *base, sqfs_u64 offset,
- const void *buffer, size_t size)
-{
- (void)base; (void)offset; (void)buffer; (void)size;
- return SQFS_ERROR_IO;
-}
-
-static sqfs_u64 stdin_get_size(const sqfs_file_t *base)
-{
- return ((const sqfs_file_stdin_t *)base)->size;
-}
-
-static int stdin_truncate(sqfs_file_t *base, sqfs_u64 size)
-{
- (void)base; (void)size;
- return SQFS_ERROR_IO;
-}
-
-sqfs_file_t *sqfs_get_stdin_file(const sparse_map_t *map, sqfs_u64 size)
-{
- sqfs_file_stdin_t *file = calloc(1, sizeof(*file));
- sqfs_file_t *base = (sqfs_file_t *)file;
-
- if (file == NULL)
- return NULL;
-
- file->size = size;
- file->map = map;
-
- base->destroy = stdin_destroy;
- base->write_at = stdin_write_at;
- base->get_size = stdin_get_size;
- base->truncate = stdin_truncate;
-
- if (map == NULL) {
- base->read_at = stdin_read_at;
- } else {
- base->read_at = stdin_read_condensed;
- }
- return base;
-}
diff --git a/lib/sqfshelper/perror.c b/lib/sqfshelper/perror.c
deleted file mode 100644
index 9b9f041..0000000
--- a/lib/sqfshelper/perror.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * print_version.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <stdio.h>
-
-void sqfs_perror(const char *file, const char *action, int error_code)
-{
- const char *errstr;
-
- switch (error_code) {
- case SQFS_ERROR_ALLOC:
- errstr = "out of memory";
- break;
- case SQFS_ERROR_IO:
- errstr = "I/O error";
- break;
- case SQFS_ERROR_COMPRESSOR:
- errstr = "internal compressor error";
- break;
- case SQFS_ERROR_INTERNAL:
- errstr = "internal error";
- break;
- case SQFS_ERROR_CORRUPTED:
- errstr = "data corrupted";
- break;
- case SQFS_ERROR_UNSUPPORTED:
- errstr = "unknown or not supported";
- break;
- case SQFS_ERROR_OVERFLOW:
- errstr = "numeric overflow";
- break;
- case SQFS_ERROR_OUT_OF_BOUNDS:
- errstr = "location out of bounds";
- break;
- case SFQS_ERROR_SUPER_MAGIC:
- errstr = "wrong magic value in super block";
- break;
- case SFQS_ERROR_SUPER_VERSION:
- errstr = "wrong squashfs version in super block";
- break;
- case SQFS_ERROR_SUPER_BLOCK_SIZE:
- errstr = "invalid block size specified in super block";
- break;
- case SQFS_ERROR_NOT_DIR:
- errstr = "target is not a directory";
- break;
- case SQFS_ERROR_NO_ENTRY:
- errstr = "no such file or directory";
- break;
- case SQFS_ERROR_LINK_LOOP:
- errstr = "hard link loop detected";
- break;
- case SQFS_ERROR_NOT_FILE:
- errstr = "target is not a file";
- break;
- default:
- errstr = "libsquashfs returned an unknown error code";
- break;
- }
-
- fprintf(stderr, "%s: %s: %s.\n", file, action, errstr);
-}
diff --git a/lib/sqfshelper/print_version.c b/lib/sqfshelper/print_version.c
deleted file mode 100644
index b23e2bd..0000000
--- a/lib/sqfshelper/print_version.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * print_version.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "config.h"
-
-#include "util.h"
-
-#include <stdio.h>
-
-#define LICENSE_SHORT "GPLv3+"
-#define LICENSE_LONG "GNU GPL version 3 or later"
-#define LICENSE_URL "https://gnu.org/licenses/gpl.html"
-
-extern char *__progname;
-
-static const char *version_string =
-"%s (%s) %s\n"
-"Copyright (c) 2019 David Oberhollenzer et al\n"
-"License " LICENSE_SHORT ": " LICENSE_LONG " <" LICENSE_URL ">.\n"
-"This is free software: you are free to change and redistribute it.\n"
-"There is NO WARRANTY, to the extent permitted by law.\n";
-
-void print_version(void)
-{
- printf(version_string, __progname, PACKAGE_NAME, PACKAGE_VERSION);
-}
diff --git a/lib/sqfshelper/serialize_fstree.c b/lib/sqfshelper/serialize_fstree.c
deleted file mode 100644
index 14f0a42..0000000
--- a/lib/sqfshelper/serialize_fstree.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * serialize_fstree.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <assert.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-static sqfs_inode_generic_t *tree_node_to_inode(tree_node_t *node)
-{
- sqfs_inode_generic_t *inode;
- size_t extra = 0;
-
- if (S_ISLNK(node->mode))
- extra = strlen(node->data.slink_target);
-
- inode = alloc_flex(sizeof(*inode), 1, extra);
- if (inode == NULL) {
- perror("creating inode");
- return NULL;
- }
-
- switch (node->mode & S_IFMT) {
- case S_IFSOCK:
- inode->base.type = SQFS_INODE_SOCKET;
- inode->data.ipc.nlink = 1;
- break;
- case S_IFIFO:
- inode->base.type = SQFS_INODE_FIFO;
- inode->data.ipc.nlink = 1;
- break;
- case S_IFLNK:
- inode->base.type = SQFS_INODE_SLINK;
- inode->data.slink.nlink = 1;
- inode->data.slink.target_size = extra;
- inode->slink_target = (char *)inode->extra;
- memcpy(inode->extra, node->data.slink_target, extra);
- break;
- case S_IFBLK:
- inode->base.type = SQFS_INODE_BDEV;
- inode->data.dev.nlink = 1;
- inode->data.dev.devno = node->data.devno;
- break;
- case S_IFCHR:
- inode->base.type = SQFS_INODE_CDEV;
- inode->data.dev.nlink = 1;
- inode->data.dev.devno = node->data.devno;
- break;
- default:
- assert(0);
- }
-
- return inode;
-}
-
-static sqfs_inode_generic_t *write_dir_entries(const char *filename,
- sqfs_dir_writer_t *dirw,
- tree_node_t *node)
-{
- sqfs_u32 xattr, parent_inode;
- sqfs_inode_generic_t *inode;
- tree_node_t *it;
- int ret;
-
- ret = sqfs_dir_writer_begin(dirw, 0);
- if (ret)
- goto fail;
-
- for (it = node->data.dir.children; it != NULL; it = it->next) {
- ret = sqfs_dir_writer_add_entry(dirw, it->name, it->inode_num,
- it->inode_ref, it->mode);
- if (ret)
- goto fail;
- }
-
- ret = sqfs_dir_writer_end(dirw);
- if (ret)
- goto fail;
-
- xattr = node->xattr_idx;
- parent_inode = (node->parent == NULL) ? 0 : node->parent->inode_num;
-
- inode = sqfs_dir_writer_create_inode(dirw, 0, xattr, parent_inode);
- if (inode == NULL) {
- ret = SQFS_ERROR_ALLOC;
- goto fail;
- }
-
- return inode;
-fail:
- sqfs_perror(filename, "recoding directory entries", ret);
- return NULL;
-}
-
-int sqfs_serialize_fstree(const char *filename, sqfs_file_t *file,
- sqfs_super_t *super, fstree_t *fs,
- sqfs_compressor_t *cmp, sqfs_id_table_t *idtbl)
-{
- sqfs_inode_generic_t *inode;
- sqfs_meta_writer_t *im, *dm;
- sqfs_dir_writer_t *dirwr;
- sqfs_u32 offset;
- sqfs_u64 block;
- tree_node_t *n;
- int ret = -1;
- size_t i;
-
- im = sqfs_meta_writer_create(file, cmp, 0);
- if (im == NULL) {
- ret = SQFS_ERROR_ALLOC;
- goto out_err;
- }
-
- dm = sqfs_meta_writer_create(file, cmp,
- SQFS_META_WRITER_KEEP_IN_MEMORY);
- if (dm == NULL) {
- ret = SQFS_ERROR_ALLOC;
- goto out_im;
- }
-
- dirwr = sqfs_dir_writer_create(dm);
- if (dirwr == NULL) {
- ret = SQFS_ERROR_ALLOC;
- goto out_dm;
- }
-
- super->inode_table_start = file->get_size(file);
-
- for (i = 0; i < fs->inode_tbl_size; ++i) {
- n = fs->inode_table[i];
-
- if (S_ISDIR(n->mode)) {
- inode = write_dir_entries(filename, dirwr, n);
-
- if (inode == NULL) {
- ret = 1;
- goto out;
- }
- } else if (S_ISREG(n->mode)) {
- inode = n->data.file.user_ptr;
- n->data.file.user_ptr = NULL;
-
- if (inode == NULL) {
- ret = SQFS_ERROR_INTERNAL;
- goto out;
- }
- } else {
- inode = tree_node_to_inode(n);
-
- if (inode == NULL) {
- ret = SQFS_ERROR_ALLOC;
- goto out;
- }
- }
-
- inode->base.mode = n->mode;
- inode->base.mod_time = n->mod_time;
- inode->base.inode_number = n->inode_num;
-
- sqfs_inode_set_xattr_index(inode, n->xattr_idx);
-
- ret = sqfs_id_table_id_to_index(idtbl, n->uid,
- &inode->base.uid_idx);
- if (ret) {
- free(inode);
- goto out;
- }
-
- ret = sqfs_id_table_id_to_index(idtbl, n->gid,
- &inode->base.gid_idx);
- if (ret) {
- free(inode);
- goto out;
- }
-
- sqfs_meta_writer_get_position(im, &block, &offset);
- fs->inode_table[i]->inode_ref = (block << 16) | offset;
-
- ret = sqfs_meta_writer_write_inode(im, inode);
- free(inode);
-
- if (ret)
- goto out;
- }
-
- ret = sqfs_meta_writer_flush(im);
- if (ret)
- goto out;
-
- ret = sqfs_meta_writer_flush(dm);
- if (ret)
- goto out;
-
- super->root_inode_ref = fs->root->inode_ref;
- super->directory_table_start = file->get_size(file);
-
- ret = sqfs_meta_write_write_to_file(dm);
- if (ret)
- goto out;
-
- ret = 0;
-out:
- sqfs_dir_writer_destroy(dirwr);
-out_dm:
- sqfs_meta_writer_destroy(dm);
-out_im:
- sqfs_meta_writer_destroy(im);
-out_err:
- if (ret < 0) {
- sqfs_perror(filename, "storing filesystem tree",
- ret);
- }
- return ret;
-}
diff --git a/lib/sqfshelper/statistics.c b/lib/sqfshelper/statistics.c
deleted file mode 100644
index a209461..0000000
--- a/lib/sqfshelper/statistics.c
+++ /dev/null
@@ -1,88 +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>
-
-static void post_block_write(void *user, const sqfs_block_t *block,
- sqfs_file_t *file)
-{
- data_writer_stats_t *stats = user;
- (void)file;
-
- if (block->size == 0)
- return;
-
- if (block->flags & SQFS_BLK_FRAGMENT_BLOCK) {
- stats->frag_blocks_written += 1;
- } else {
- stats->blocks_written += 1;
- }
-
- stats->bytes_written += block->size;
-}
-
-static void pre_fragment_store(void *user, sqfs_block_t *block)
-{
- data_writer_stats_t *stats = user;
- (void)block;
-
- stats->frag_count += 1;
-}
-
-static void notify_blocks_erased(void *user, size_t count, sqfs_u64 bytes)
-{
- data_writer_stats_t *stats = user;
-
- stats->bytes_written -= bytes;
- stats->blocks_written -= count;
- stats->duplicate_blocks += count;
-}
-
-static void notify_fragment_discard(void *user, const sqfs_block_t *block)
-{
- data_writer_stats_t *stats = user;
- (void)block;
-
- stats->frag_dup += 1;
-}
-
-static const sqfs_block_hooks_t hooks = {
- .size = sizeof(hooks),
- .post_block_write = post_block_write,
- .pre_fragment_store = pre_fragment_store,
- .notify_blocks_erased = notify_blocks_erased,
- .notify_fragment_discard = notify_fragment_discard,
-};
-
-void register_stat_hooks(sqfs_data_writer_t *data, data_writer_stats_t *stats)
-{
- sqfs_data_writer_set_hooks(data, stats, &hooks);
-}
-
-void sqfs_print_statistics(sqfs_super_t *super, data_writer_stats_t *stats)
-{
- size_t ratio;
-
- if (stats->bytes_written > 0) {
- ratio = (100 * stats->bytes_written) / stats->bytes_read;
- } else {
- ratio = 100;
- }
-
- fputs("---------------------------------------------------\n", stdout);
- printf("Input files processed: %zu\n", stats->file_count);
- printf("Data blocks actually written: %zu\n", stats->blocks_written);
- printf("Fragment blocks written: %zu\n", stats->frag_blocks_written);
- printf("Duplicate data blocks omitted: %zu\n", stats->duplicate_blocks);
- printf("Sparse blocks omitted: %zu\n", stats->sparse_blocks);
- printf("Fragments actually written: %zu\n", stats->frag_count);
- printf("Duplicated fragments omitted: %zu\n", stats->frag_dup);
- printf("Total number of inodes: %u\n", super->inode_count);
- printf("Number of unique group/user IDs: %u\n", super->id_count);
- printf("Data compression ratio: %zu%%\n", ratio);
-}
diff --git a/lib/sqfshelper/write_export_table.c b/lib/sqfshelper/write_export_table.c
deleted file mode 100644
index c797577..0000000
--- a/lib/sqfshelper/write_export_table.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * write_export_table.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-
-int write_export_table(const char *filename, sqfs_file_t *file,
- fstree_t *fs, sqfs_super_t *super,
- sqfs_compressor_t *cmp)
-{
- sqfs_u64 *table, start;
- size_t i, size;
- int ret;
-
- if (fs->inode_tbl_size < 1)
- return 0;
-
- table = alloc_array(sizeof(sqfs_u64), fs->inode_tbl_size);
-
- if (table == NULL) {
- perror("Allocating NFS export table");
- return -1;
- }
-
- for (i = 0; i < fs->inode_tbl_size; ++i) {
- table[i] = htole64(fs->inode_table[i]->inode_ref);
- }
-
- size = sizeof(sqfs_u64) * fs->inode_tbl_size;
- ret = sqfs_write_table(file, cmp, table, size, &start);
- if (ret)
- sqfs_perror(filename, "writing NFS export table", ret);
-
- super->export_table_start = start;
- super->flags |= SQFS_FLAG_EXPORTABLE;
- free(table);
- return ret;
-}
diff --git a/lib/sqfshelper/writer.c b/lib/sqfshelper/writer.c
deleted file mode 100644
index fa732ad..0000000
--- a/lib/sqfshelper/writer.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * writer.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "common.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#ifdef HAVE_SYS_SYSINFO_H
-#include <sys/sysinfo.h>
-
-static size_t os_get_num_jobs(void)
-{
- int nprocs;
-
- nprocs = get_nprocs_conf();
- return nprocs < 1 ? 1 : nprocs;
-}
-
-static size_t os_get_max_ram(void)
-{
- struct sysinfo info;
-
- if (sysinfo(&info)) {
- perror("sysinfo");
- return 0;
- }
-
- return info.totalram;
-}
-#else
-static size_t os_get_num_jobs(void)
-{
- return 1;
-}
-
-static size_t os_get_max_ram(void)
-{
- (void)cfg;
- return 0;
-}
-#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)
-{
- size_t max_ram;
-
- memset(cfg, 0, sizeof(*cfg));
-
- cfg->num_jobs = os_get_num_jobs();
- cfg->block_size = SQFS_DEFAULT_BLOCK_SIZE;
- cfg->devblksize = SQFS_DEVBLK_SIZE;
- cfg->comp_id = compressor_get_default();
-
- max_ram = os_get_max_ram();
- cfg->max_backlog = (max_ram / 2) / cfg->block_size;
-
- if (cfg->max_backlog < 1)
- cfg->max_backlog = 10 * cfg->num_jobs;
-}
-
-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;
- }
-
- ret = sqfs_super_init(&sqfs->super, wrcfg->block_size,
- sqfs->fs.defaults.st_mtime, wrcfg->comp_id);
- if (ret) {
- sqfs_perror(wrcfg->filename, "initializing super block", ret);
- goto fail_cmp;
- }
-
- ret = sqfs_super_write(&sqfs->super, sqfs->outfile);
- if (ret) {
- sqfs_perror(wrcfg->filename, "writing super block", ret);
- goto fail_cmp;
- }
-
- ret = sqfs->cmp->write_options(sqfs->cmp, sqfs->outfile);
- if (ret < 0) {
- sqfs_perror(wrcfg->filename, "writing compressor options", ret);
- 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) {
- sqfs_perror(wrcfg->filename, "creating ID table",
- SQFS_ERROR_ALLOC);
- goto fail_data;
- }
-
- if (!wrcfg->no_xattr) {
- sqfs->xwr = sqfs_xattr_writer_create();
-
- if (sqfs->xwr == NULL) {
- sqfs_perror(wrcfg->filename, "creating xattr writer",
- SQFS_ERROR_ALLOC);
- 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)
-{
- int ret;
-
- if (!cfg->quiet)
- fputs("Waiting for remaining data blocks...\n", stdout);
-
- ret = sqfs_data_writer_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);
-
- 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(cfg->filename, sqfs->outfile, &sqfs->super,
- &sqfs->fs, sqfs->cmp, sqfs->idtbl)) {
- return -1;
- }
-
- if (!cfg->quiet)
- fputs("Writing fragment table...\n", stdout);
-
- ret = sqfs_data_writer_write_fragment_table(sqfs->data, &sqfs->super);
- if (ret) {
- sqfs_perror(cfg->filename, "writing fragment table", ret);
- return -1;
- }
-
- if (cfg->exportable) {
- if (!cfg->quiet)
- fputs("Writing export table...\n", stdout);
-
- if (write_export_table(cfg->filename, sqfs->outfile, &sqfs->fs,
- &sqfs->super, sqfs->cmp)) {
- 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->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->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);
-}