From f757737060d4daebb24a32e90d912661428708a8 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 13 Sep 2020 13:37:42 +0200 Subject: Remodel libtar/tar2sqfs to read data from an istream_t Signed-off-by: David Oberhollenzer --- bin/tar2sqfs/Makemodule.am | 2 +- bin/tar2sqfs/process_tarball.c | 81 +++++++++++++++++++++++++++++++++--------- bin/tar2sqfs/tar2sqfs.c | 18 ++++------ bin/tar2sqfs/tar2sqfs.h | 7 +--- 4 files changed, 72 insertions(+), 36 deletions(-) (limited to 'bin') diff --git a/bin/tar2sqfs/Makemodule.am b/bin/tar2sqfs/Makemodule.am index 16bec99..0a74419 100644 --- a/bin/tar2sqfs/Makemodule.am +++ b/bin/tar2sqfs/Makemodule.am @@ -1,7 +1,7 @@ tar2sqfs_SOURCES = bin/tar2sqfs/tar2sqfs.c bin/tar2sqfs/tar2sqfs.h tar2sqfs_SOURCES += bin/tar2sqfs/options.c bin/tar2sqfs/process_tarball.c tar2sqfs_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) -tar2sqfs_LDADD = libcommon.a libsquashfs.la libtar.a +tar2sqfs_LDADD = libcommon.a libsquashfs.la libtar.a libfstream.a tar2sqfs_LDADD += libfstree.a libcompat.a libfstree.a $(LZO_LIBS) tar2sqfs_LDADD += $(PTHREAD_LIBS) diff --git a/bin/tar2sqfs/process_tarball.c b/bin/tar2sqfs/process_tarball.c index 415e362..4d7f0a1 100644 --- a/bin/tar2sqfs/process_tarball.c +++ b/bin/tar2sqfs/process_tarball.c @@ -6,28 +6,74 @@ */ #include "tar2sqfs.h" -static int write_file(FILE *input_file, sqfs_writer_t *sqfs, +static int write_file(istream_t *input_file, sqfs_writer_t *sqfs, const tar_header_decoded_t *hdr, file_info_t *fi, sqfs_u64 filesize) { - sqfs_file_t *file; - int flags; - int ret; + const sparse_map_t *list; + int flags = 0, ret = 0; + sqfs_u64 offset, diff; + bool sparse_region; + ostream_t *out; - file = sqfs_get_stdin_file(input_file, hdr->sparse, filesize); - if (file == NULL) { - perror("packing files"); - return -1; - } - - flags = 0; if (no_tail_pack && filesize > cfg.block_size) flags |= SQFS_BLK_DONT_FRAGMENT; - ret = write_data_from_file(hdr->name, sqfs->data, - (sqfs_inode_generic_t **)&fi->user_ptr, - file, flags); - sqfs_destroy(file); + out = data_writer_ostream_create(hdr->name, sqfs->data, + (sqfs_inode_generic_t **)&fi->user_ptr, + flags); + + if (out == NULL) + return -1; + + list = hdr->sparse; + + for (offset = 0; offset < filesize; offset += diff) { + if (hdr->sparse != NULL) { + if (list == NULL) { + sparse_region = true; + diff = filesize - offset; + } else if (offset < list->offset) { + sparse_region = true; + diff = list->offset - offset; + } else if (offset - list->offset >= list->count) { + list = list->next; + diff = 0; + continue; + } else { + sparse_region = false; + diff = list->count - (offset - list->offset); + } + } else { + sparse_region = false; + diff = filesize - offset; + } + + if (sizeof(diff) > sizeof(size_t) && diff > 0x7FFFFFFFUL) + diff = 0x7FFFFFFFUL; + + if (sparse_region) { + ret = ostream_append_sparse(out, diff); + } else { + ret = ostream_append_from_istream(out, input_file, + diff); + + if (ret == 0) { + fprintf(stderr, "%s: unexpected end-of-file\n", + hdr->name); + ret = -1; + } else if (ret > 0) { + diff = ret; + ret = 0; + } + } + + if (ret < 0) + break; + } + + ostream_flush(out); + sqfs_destroy(out); if (ret) return -1; @@ -78,7 +124,8 @@ static int copy_xattr(sqfs_writer_t *sqfs, tree_node_t *node, return 0; } -static int create_node_and_repack_data(FILE *input_file, sqfs_writer_t *sqfs, +static int create_node_and_repack_data(istream_t *input_file, + sqfs_writer_t *sqfs, tar_header_decoded_t *hdr) { tree_node_t *node; @@ -149,7 +196,7 @@ static int set_root_attribs(sqfs_writer_t *sqfs, return 0; } -int process_tarball(FILE *input_file, sqfs_writer_t *sqfs) +int process_tarball(istream_t *input_file, sqfs_writer_t *sqfs) { bool skip, is_root, is_prefixed; tar_header_decoded_t hdr; diff --git a/bin/tar2sqfs/tar2sqfs.c b/bin/tar2sqfs/tar2sqfs.c index ae56e6b..6cab231 100644 --- a/bin/tar2sqfs/tar2sqfs.c +++ b/bin/tar2sqfs/tar2sqfs.c @@ -9,26 +9,18 @@ int main(int argc, char **argv) { int status = EXIT_FAILURE; - FILE *input_file = NULL; + istream_t *input_file = NULL; sqfs_writer_t sqfs; process_args(argc, argv); -#ifdef _WIN32 - _setmode(_fileno(stdin), _O_BINARY); - input_file = stdin; -#else - input_file = freopen(NULL, "rb", stdin); -#endif - - if (input_file == NULL) { - perror("changing stdin to binary mode"); + input_file = istream_open_stdin(); + if (input_file == NULL) return EXIT_FAILURE; - } memset(&sqfs, 0, sizeof(sqfs)); if (sqfs_writer_init(&sqfs, &cfg)) - return EXIT_FAILURE; + goto out_if; if (process_tarball(input_file, &sqfs)) goto out; @@ -42,5 +34,7 @@ int main(int argc, char **argv) status = EXIT_SUCCESS; out: sqfs_writer_cleanup(&sqfs, status); +out_if: + sqfs_destroy(input_file); return status; } diff --git a/bin/tar2sqfs/tar2sqfs.h b/bin/tar2sqfs/tar2sqfs.h index a27a50b..d127aa0 100644 --- a/bin/tar2sqfs/tar2sqfs.h +++ b/bin/tar2sqfs/tar2sqfs.h @@ -16,11 +16,6 @@ #include #include #include -#include - -#ifdef _WIN32 -#include -#endif /* options.c */ extern bool dont_skip; @@ -32,6 +27,6 @@ extern char *root_becomes; void process_args(int argc, char **argv); /* process_tarball.c */ -int process_tarball(FILE *input_file, sqfs_writer_t *sqfs); +int process_tarball(istream_t *input_file, sqfs_writer_t *sqfs); #endif /* TAR2SQFS_H */ -- cgit v1.2.3