libarchive: fix xmalloc_open_zipped_read_close() on NOMMU

The somewhat new "unpack in memory" code was broken
for xmalloc_open_zipped_read_close() on NOMMU: we seek back
over signature, but then expect it to be already consumed.
Stop seeking back in this case.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
index 20e4d9a..c7fa5b5 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -1201,7 +1201,7 @@
 	if (check_signature16(xstate, GZIP_MAGIC))
 		return -1;
 #else
-	if (xstate->check_signature) {
+	if (!xstate->signature_skipped) {
 		uint16_t magic2;
 
 		if (full_read(xstate->src_fd, &magic2, 2) != 2) {
@@ -1210,7 +1210,7 @@
 			return -1;
 		}
 		if (magic2 == COMPRESS_MAGIC) {
-			xstate->check_signature = 0;
+			xstate->signature_skipped = 2;
 			return unpack_Z_stream(xstate);
 		}
 		if (magic2 != GZIP_MAGIC)
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c
index 1f408ab..cd32cc7 100644
--- a/archival/libarchive/decompress_unxz.c
+++ b/archival/libarchive/decompress_unxz.c
@@ -55,7 +55,7 @@
 	iobuf.out = membuf + BUFSIZ;
 	iobuf.out_size = BUFSIZ;
 
-	if (!xstate || xstate->check_signature == 0) {
+	if (!xstate || xstate->signature_skipped) {
 		/* Preload XZ file signature */
 		strcpy((char*)membuf, HEADER_MAGIC);
 		iobuf.in_size = HEADER_MAGIC_SIZE;
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c
index be536a3..d93c836 100644
--- a/archival/libarchive/open_transformer.c
+++ b/archival/libarchive/open_transformer.c
@@ -13,16 +13,13 @@
 
 int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16)
 {
-	if (xstate->check_signature) {
+	if (!xstate->signature_skipped) {
 		uint16_t magic2;
 		if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) {
 			bb_error_msg("invalid magic");
-#if 0 /* possible future extension */
-			if (xstate->check_signature > 1)
-				xfunc_die();
-#endif
 			return -1;
 		}
+		xstate->signature_skipped = 2;
 	}
 	return 0;
 }
@@ -102,7 +99,7 @@
 /* transformer(), more than meets the eye */
 #if BB_MMU
 void FAST_FUNC fork_transformer(int fd,
-	int check_signature,
+	int signature_skipped,
 	IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate)
 )
 #else
@@ -123,7 +120,7 @@
 			IF_DESKTOP(long long) int r;
 			transformer_state_t xstate;
 			init_transformer_state(&xstate);
-			xstate.check_signature = check_signature;
+			xstate.signature_skipped = signature_skipped;
 			xstate.src_fd = fd;
 			xstate.dst_fd = fd_pipe.wr;
 			r = transformer(&xstate);
@@ -168,12 +165,11 @@
 		uint16_t b16[2];
 		uint32_t b32[1];
 	} magic;
-	int offset;
 	transformer_state_t *xstate;
 
-	offset = -2;
 	xstate = xzalloc(sizeof(*xstate));
 	xstate->src_fd = fd;
+	xstate->signature_skipped = 2;
 
 	/* .gz and .bz2 both have 2-byte signature, and their
 	 * unpack_XXX_stream wants this header skipped. */
@@ -202,7 +198,7 @@
 	if (ENABLE_FEATURE_SEAMLESS_XZ
 	 && magic.b16[0] == XZ_MAGIC1
 	) {
-		offset = -6;
+		xstate->signature_skipped = 6;
 		xread(fd, magic.b32, sizeof(magic.b32[0]));
 		if (magic.b32[0] == XZ_MAGIC2) {
 			xstate->xformer = unpack_xz_stream;
@@ -226,16 +222,7 @@
 //	USE_FOR_NOMMU(xstate->xformer_prog = "cat";)
 	/* fall through to seeking bck over bytes we read earlier */
 
- USE_FOR_NOMMU(found_magic:)
-	/* NOMMU version of fork_transformer execs
-	 * an external unzipper that wants
-	 * file position at the start of the file.
-	 */
-	xlseek(fd, offset, SEEK_CUR);
-
- USE_FOR_MMU(found_magic:)
-	/* In MMU case, if magic was found, seeking back is not necessary */
-
+ found_magic:
 	return xstate;
 }
 
@@ -254,6 +241,12 @@
 # if BB_MMU
 	fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer);
 # else
+	/* NOMMU version of fork_transformer execs
+	 * an external unzipper that wants
+	 * file position at the start of the file.
+	 */
+	xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
+	xstate->signature_skipped = 0;
 	fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog);
 # endif
 	free(xstate);
@@ -300,6 +293,8 @@
 # if BB_MMU
 		fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer);
 # else
+		xlseek(fd, - xstate->signature_skipped, SEEK_CUR);
+		xstate->signature_skipped = 0;
 		fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog);
 # endif
 	}