aboutsummaryrefslogtreecommitdiff
path: root/bin/tar2sqfs
diff options
context:
space:
mode:
Diffstat (limited to 'bin/tar2sqfs')
-rw-r--r--bin/tar2sqfs/Makemodule.am2
-rw-r--r--bin/tar2sqfs/process_tarball.c81
-rw-r--r--bin/tar2sqfs/tar2sqfs.c18
-rw-r--r--bin/tar2sqfs/tar2sqfs.h7
4 files changed, 72 insertions, 36 deletions
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 <getopt.h>
#include <string.h>
#include <stdio.h>
-#include <fcntl.h>
-
-#ifdef _WIN32
-#include <io.h>
-#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 */