From d5068781ec2528f88aaa92fbc9a5b9c256d53499 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 6 May 2019 12:09:56 +0200 Subject: Implement reading and writing of compressor options - gensquashfs simply asks the backend compressor to write its options to the file and does accounting - rdsquasfs simply asks the backend compressor to transparentyl snort the options from the file - not implemented in any compressor backend yet Signed-off-by: David Oberhollenzer --- include/compress.h | 20 ++++++++++++++++++++ lib/comp/gzip.c | 17 +++++++++++++++++ lib/comp/lzo.c | 17 +++++++++++++++++ lib/comp/xz.c | 17 +++++++++++++++++ mkfs/mkfs.c | 11 ++++++++++- unpack/rdsquashfs.c | 12 +++++------- 6 files changed, 86 insertions(+), 8 deletions(-) diff --git a/include/compress.h b/include/compress.h index 5bb689b..a8542f2 100644 --- a/include/compress.h +++ b/include/compress.h @@ -18,6 +18,26 @@ typedef struct compressor_t compressor_t; * uncompress/extract blocks of data */ struct compressor_t { + /** + * @brief Write compressor options to the output file if necessary + * + * @param cmp A pointer to the compressor object + * @param fd The file descriptor to write to + * + * @return The number of bytes written or -1 on failure + */ + int (*write_options)(compressor_t *cmp, int fd); + + /** + * @brief Read compressor options to the input file + * + * @param cmp A pointer to the compressor object + * @param fd The file descriptor to write to + * + * @return Zero on success, -1 on failure + */ + int (*read_options)(compressor_t *cmp, int fd); + /** * @brief Compress or uncompress a chunk of data * diff --git a/lib/comp/gzip.c b/lib/comp/gzip.c index ea634b8..ea86f98 100644 --- a/lib/comp/gzip.c +++ b/lib/comp/gzip.c @@ -29,6 +29,21 @@ static void gzip_destroy(compressor_t *base) free(gzip); } +static int gzip_write_options(compressor_t *base, int fd) +{ + (void)base; + (void)fd; + return 0; +} + +static int gzip_read_options(compressor_t *base, int fd) +{ + (void)base; + (void)fd; + fputs("gzip extra options are not yet implemented\n", stderr); + return -1; +} + static ssize_t gzip_do_block(compressor_t *base, const uint8_t *in, size_t size, uint8_t *out, size_t outsize) { @@ -90,6 +105,8 @@ compressor_t *create_gzip_compressor(bool compress, size_t block_size) gzip->block_size = block_size; base->do_block = gzip_do_block; base->destroy = gzip_destroy; + base->write_options = gzip_write_options; + base->read_options = gzip_read_options; if (compress) { ret = deflateInit(&gzip->strm, Z_BEST_COMPRESSION); diff --git a/lib/comp/lzo.c b/lib/comp/lzo.c index 30b14cb..95ab485 100644 --- a/lib/comp/lzo.c +++ b/lib/comp/lzo.c @@ -14,6 +14,21 @@ typedef struct { uint8_t buffer[LZO1X_999_MEM_COMPRESS]; } lzo_compressor_t; +static int lzo_write_options(compressor_t *base, int fd) +{ + (void)base; + (void)fd; + return 0; +} + +static int lzo_read_options(compressor_t *base, int fd) +{ + (void)base; + (void)fd; + fputs("lzo extra options are not yet implemented\n", stderr); + return -1; +} + static ssize_t lzo_comp_block(compressor_t *base, const uint8_t *in, size_t size, uint8_t *out, size_t outsize) { @@ -67,5 +82,7 @@ compressor_t *create_lzo_compressor(bool compress, size_t block_size) base->destroy = lzo_destroy; base->do_block = compress ? lzo_comp_block : lzo_uncomp_block; + base->write_options = lzo_write_options; + base->read_options = lzo_read_options; return base; } diff --git a/lib/comp/xz.c b/lib/comp/xz.c index 98d740c..dd608ba 100644 --- a/lib/comp/xz.c +++ b/lib/comp/xz.c @@ -12,6 +12,21 @@ typedef struct { size_t block_size; } xz_compressor_t; +static int xz_write_options(compressor_t *base, int fd) +{ + (void)base; + (void)fd; + return 0; +} + +static int xz_read_options(compressor_t *base, int fd) +{ + (void)base; + (void)fd; + fputs("xz extra options are not yet implemented\n", stderr); + return -1; +} + static ssize_t xz_comp_block(compressor_t *base, const uint8_t *in, size_t size, uint8_t *out, size_t outsize) { @@ -86,5 +101,7 @@ compressor_t *create_xz_compressor(bool compress, size_t block_size) xz->block_size = block_size; base->destroy = xz_destroy; base->do_block = compress ? xz_comp_block : xz_uncomp_block; + base->write_options = xz_write_options; + base->read_options = xz_read_options; return base; } diff --git a/mkfs/mkfs.c b/mkfs/mkfs.c index d708d37..ae6210b 100644 --- a/mkfs/mkfs.c +++ b/mkfs/mkfs.c @@ -39,7 +39,7 @@ static int padd_file(sqfs_info_t *info) int main(int argc, char **argv) { - int status = EXIT_FAILURE; + int status = EXIT_FAILURE, ret; sqfs_info_t info; memset(&info, 0, sizeof(info)); @@ -81,6 +81,15 @@ int main(int argc, char **argv) goto out_outfd; } + ret = info.cmp->write_options(info.cmp, info.outfd); + if (ret < 0) + goto out_cmp; + + if (ret > 0) { + info.super.flags |= SQFS_FLAG_COMPRESSOR_OPTIONS; + info.super.bytes_used += ret; + } + if (write_data_to_image(&info)) goto out_cmp; diff --git a/unpack/rdsquashfs.c b/unpack/rdsquashfs.c index a24434c..8ee3dbd 100644 --- a/unpack/rdsquashfs.c +++ b/unpack/rdsquashfs.c @@ -260,13 +260,6 @@ int main(int argc, char **argv) goto out_fd; } - if (super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) { - fputs("Image has been built with compressor options.\n" - "This is not yet supported.\n", - stderr); - goto out_fd; - } - if (!compressor_exists(super.compression_id)) { fputs("Image uses a compressor that has not been built in\n", stderr); @@ -278,6 +271,11 @@ int main(int argc, char **argv) if (info.cmp == NULL) goto out_fd; + if (super.flags & SQFS_FLAG_COMPRESSOR_OPTIONS) { + if (info.cmp->read_options(info.cmp, info.sqfsfd)) + goto out_cmp; + } + if (read_fstree(&fs, &super, &info)) goto out_cmp; -- cgit v1.2.3