diff --git a/doc/magic.header.txt b/doc/magic.header.txt index 1eea48b..d0ef0b1 100644 --- a/doc/magic.header.txt +++ b/doc/magic.header.txt @@ -28,7 +28,7 @@ Encrypted salt (bytes 6->14 in magic if encrypted): Rzip Chunk Data: 0 Data offsets byte width (meaning length is < (2 * 8)^RCD0) 1 Flag that there is no chunk beyond this -(RCD0 bytes) Chunk decompressed size (not stored in encrypted file) +(RCD0 bytes) Chunk decompressed size (only stored in stdout chunked file) XX Stream 0 header data XX Stream 1 header data diff --git a/liblrzip.h b/liblrzip.h index d817af0..e62cd0f 100644 --- a/liblrzip.h +++ b/liblrzip.h @@ -49,6 +49,7 @@ #define TMP_OUTBUF (control->flags & FLAG_TMP_OUTBUF) #define TMP_INBUF (control->flags & FLAG_TMP_INBUF) #define ENCRYPT (control->flags & FLAG_ENCRYPT) +#define CHUNKED (control->flags & FLAG_CHUNKED) #define print_output(format, args...) do {\ fprintf(control->msgout, format, ##args); \ diff --git a/lrzip.c b/lrzip.c index 7c8c330..bfe25ad 100644 --- a/lrzip.c +++ b/lrzip.c @@ -175,6 +175,10 @@ static void get_magic(rzip_control *control, char *magic) print_output("Asked to decrypt a non-encrypted archive. Bypassing decryption.\n"); control->flags &= ~FLAG_ENCRYPT; } + /* If the file was generated from STDOUT and !ENCRYPT, an extra field + * describing the chunk length exists */ + if (!ENCRYPT && !expected_size) + control->flags |= FLAG_CHUNKED; } void read_magic(rzip_control *control, int fd_in, i64 *expected_size) @@ -777,9 +781,11 @@ void get_fileinfo(rzip_control *control) if (control->major_version == 0 && control->minor_version > 5) { if (unlikely(read(fd_in, &control->eof, 1) != 1)) fatal("Failed to read eof in get_fileinfo\n"); - if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) - fatal("Failed to read chunk_size in get_fileinfo\n"); - chunk_size = le64toh(chunk_size); + if (CHUNKED) { + if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) + fatal("Failed to read chunk_size in get_fileinfo\n"); + chunk_size = le64toh(chunk_size); + } } } @@ -793,7 +799,7 @@ void get_fileinfo(rzip_control *control) ofs = 25; header_length = 25; } else { - ofs = 26 + chunk_byte; + ofs = 26 + (CHUNKED ? chunk_byte: 0); header_length = 1 + (chunk_byte * 3); } next_chunk: @@ -867,10 +873,13 @@ next_chunk: if (control->major_version == 0 && control->minor_version > 5) { if (unlikely(read(fd_in, &control->eof, 1) != 1)) fatal("Failed to read eof in get_fileinfo\n"); - if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) - fatal("Failed to read chunk_size in get_fileinfo\n"); - chunk_size = le64toh(chunk_size); - ofs += 1 + chunk_byte; + ofs++; + if (CHUNKED) { + if (unlikely(read(fd_in, &chunk_size, chunk_byte) != chunk_byte)) + fatal("Failed to read chunk_size in get_fileinfo\n"); + chunk_size = le64toh(chunk_size); + ofs += chunk_byte; + } header_length = 1 + (chunk_byte * 3); } } @@ -949,6 +958,9 @@ void compress_file(rzip_control *control) if (ENCRYPT) get_hash(control, 1); + else if (STDOUT) + control->flags |= FLAG_CHUNKED; + memset(header, 0, sizeof(header)); if (!STDIN) { diff --git a/lrzip_private.h b/lrzip_private.h index f0b31a6..30baa57 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -158,6 +158,7 @@ typedef struct md5_ctx md5_ctx; #define FLAG_TMP_OUTBUF (1 << 21) #define FLAG_TMP_INBUF (1 << 22) #define FLAG_ENCRYPT (1 << 23) +#define FLAG_CHUNKED (1 << 24) #define NO_MD5 (!(HASH_CHECK) && !(HAS_MD5)) diff --git a/main.c b/main.c index ed89039..b225925 100644 --- a/main.c +++ b/main.c @@ -85,6 +85,7 @@ #define TMP_OUTBUF (control.flags & FLAG_TMP_OUTBUF) #define TMP_INBUF (control.flags & FLAG_TMP_INBUF) #define ENCRYPT (control.flags & FLAG_ENCRYPT) +#define CHUNKED (control.flags & FLAG_CHUNKED) #define print_output(format, args...) do {\ fprintf(control.msgout, format, ##args); \ diff --git a/stream.c b/stream.c index 2859c9e..76b70dc 100644 --- a/stream.c +++ b/stream.c @@ -1104,7 +1104,7 @@ void *open_stream_in(rzip_control *control, int f, int n, int chunk_bytes) goto failed; } /* Read in the expected chunk size */ - if (!ENCRYPT) { + if (CHUNKED) { if (unlikely(read_val(control, f, &sinfo->size, sinfo->chunk_bytes))) { print_err("Failed to read in chunk size in open_stream_in\n"); goto failed; @@ -1323,9 +1323,9 @@ retry: write_u8(control, ctis->fd, ctis->chunk_bytes); /* Write whether this is the last chunk, followed by the size - * of this chunk */ + * of this chunk if working with STDOUT and !ENCRYPT */ write_u8(control, ctis->fd, control->eof); - if (!ENCRYPT) + if (CHUNKED) write_val(control, ctis->fd, ctis->size, ctis->chunk_bytes); /* First chunk of this stream, write headers */