summaryrefslogtreecommitdiff
path: root/libbb/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbb/read.c')
-rw-r--r--libbb/read.c103
1 files changed, 61 insertions, 42 deletions
diff --git a/libbb/read.c b/libbb/read.c
index 06ce29718..f3af144f0 100644
--- a/libbb/read.c
+++ b/libbb/read.c
@@ -6,7 +6,6 @@
6 * 6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
8 */ 8 */
9
10#include "libbb.h" 9#include "libbb.h"
11 10
12#define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \ 11#define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \
@@ -16,7 +15,7 @@
16) 15)
17 16
18#if ZIPPED 17#if ZIPPED
19#include "unarchive.h" 18# include "unarchive.h"
20#endif 19#endif
21 20
22ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count) 21ssize_t FAST_FUNC safe_read(int fd, void *buf, size_t count)
@@ -306,14 +305,11 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p)
306 return buf; 305 return buf;
307} 306}
308 307
309int FAST_FUNC open_zipped(const char *fname) 308#if ZIPPED
309int FAST_FUNC setup_unzip_on_fd(int fd /*, int fail_if_not_detected*/)
310{ 310{
311#if !ZIPPED 311 const int fail_if_not_detected = 1;
312 return open(fname, O_RDONLY);
313#else
314 unsigned char magic[2]; 312 unsigned char magic[2];
315 char *sfx;
316 int fd;
317#if BB_MMU 313#if BB_MMU
318 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd); 314 IF_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
319 enum { xformer_prog = 0 }; 315 enum { xformer_prog = 0 };
@@ -322,6 +318,62 @@ int FAST_FUNC open_zipped(const char *fname)
322 const char *xformer_prog; 318 const char *xformer_prog;
323#endif 319#endif
324 320
321 /* .gz and .bz2 both have 2-byte signature, and their
322 * unpack_XXX_stream wants this header skipped. */
323 xread(fd, &magic, 2);
324 if (ENABLE_FEATURE_SEAMLESS_GZ
325 && magic[0] == 0x1f && magic[1] == 0x8b
326 ) {
327# if BB_MMU
328 xformer = unpack_gz_stream;
329# else
330 xformer_prog = "gunzip";
331# endif
332 goto found_magic;
333 }
334 if (ENABLE_FEATURE_SEAMLESS_BZ2
335 && magic[0] == 'B' && magic[1] == 'Z'
336 ) {
337# if BB_MMU
338 xformer = unpack_bz2_stream;
339# else
340 xformer_prog = "bunzip2";
341# endif
342 goto found_magic;
343 }
344// TODO: xz format support. rpm adopted it, "rpm -i FILE.rpm" badly needs this.
345// Signature: 0xFD, '7', 'z', 'X', 'Z', 0x00
346// More info at: http://tukaani.org/xz/xz-file-format.txt
347
348 /* No known magic seen */
349 if (fail_if_not_detected)
350 bb_error_msg_and_die("no gzip"
351 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
352 " magic");
353 xlseek(fd, -2, SEEK_CUR);
354 return fd;
355
356 found_magic:
357# if !BB_MMU
358 /* NOMMU version of open_transformer execs
359 * an external unzipper that wants
360 * file position at the start of the file */
361 xlseek(fd, -2, SEEK_CUR);
362# endif
363 open_transformer(fd, xformer, xformer_prog);
364
365 return fd;
366}
367#endif /* ZIPPED */
368
369int FAST_FUNC open_zipped(const char *fname)
370{
371#if !ZIPPED
372 return open(fname, O_RDONLY);
373#else
374 char *sfx;
375 int fd;
376
325 fd = open(fname, O_RDONLY); 377 fd = open(fname, O_RDONLY);
326 if (fd < 0) 378 if (fd < 0)
327 return fd; 379 return fd;
@@ -335,40 +387,7 @@ int FAST_FUNC open_zipped(const char *fname)
335 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0) 387 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0)
336 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0) 388 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0)
337 ) { 389 ) {
338 /* .gz and .bz2 both have 2-byte signature, and their 390 setup_unzip_on_fd(fd /*, fail_if_not_detected: 1*/);
339 * unpack_XXX_stream wants this header skipped. */
340 xread(fd, &magic, 2);
341#if ENABLE_FEATURE_SEAMLESS_GZ
342#if BB_MMU
343 xformer = unpack_gz_stream;
344#else
345 xformer_prog = "gunzip";
346#endif
347#endif
348 if (!ENABLE_FEATURE_SEAMLESS_GZ
349 || magic[0] != 0x1f || magic[1] != 0x8b
350 ) {
351 if (!ENABLE_FEATURE_SEAMLESS_BZ2
352 || magic[0] != 'B' || magic[1] != 'Z'
353 ) {
354 bb_error_msg_and_die("no gzip"
355 IF_FEATURE_SEAMLESS_BZ2("/bzip2")
356 " magic");
357 }
358#if BB_MMU
359 xformer = unpack_bz2_stream;
360#else
361 xformer_prog = "bunzip2";
362#endif
363 } else {
364#if !BB_MMU
365 /* NOMMU version of open_transformer execs
366 * an external unzipper that wants
367 * file position at the start of the file */
368 xlseek(fd, 0, SEEK_SET);
369#endif
370 }
371 open_transformer(fd, xformer, xformer_prog);
372 } 391 }
373 } 392 }
374 393