aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-08-05 13:10:34 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-08-05 13:10:34 +0000
commite9ad84dfd4c7eb2936374f02989dacf7026a7276 (patch)
tree37412d21c0a2ccec7c162e0fb42833058f5934e3 /libbb
parent9b44613202a6f2f080ec23746d0680dcef88628d (diff)
downloadbusybox-w32-e9ad84dfd4c7eb2936374f02989dacf7026a7276.tar.gz
busybox-w32-e9ad84dfd4c7eb2936374f02989dacf7026a7276.tar.bz2
busybox-w32-e9ad84dfd4c7eb2936374f02989dacf7026a7276.zip
*: refactor handling of archived files. "tar f file.tar.lzma" now works too.
function old new delta unpack_Z_stream - 1229 +1229 open_zipped - 176 +176 unpack_bz2_stream_prime - 60 +60 tar_main 642 677 +35 find_main 406 418 +12 sv_main 1222 1233 +11 decode_format_string 829 837 +8 cmp_main 641 649 +8 popstring 134 140 +6 filter_accept_list_reassign 120 125 +5 parse_and_put_prompt 800 804 +4 passwd_main 1053 1049 -4 make_new_name_gunzip 119 114 -5 rpm_main 1688 1670 -18 prepare 302 283 -19 xmalloc_open_zipped_read_close 135 61 -74 uncompress 1229 - -1229 ------------------------------------------------------------------------------ (add/remove: 3/1 grow/shrink: 8/5 up/down: 1554/-1349) Total: 205 bytes
Diffstat (limited to 'libbb')
-rw-r--r--libbb/appletlib.c3
-rw-r--r--libbb/read.c89
2 files changed, 78 insertions, 14 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index beb1d6fcb..2bab0eba6 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -73,7 +73,8 @@ static const char *unpack_usage_messages(void)
73 73
74 i = start_bunzip(&bd, 74 i = start_bunzip(&bd,
75 /* src_fd: */ -1, 75 /* src_fd: */ -1,
76 /* inbuf: */ (void *)packed_usage, 76//FIXME: can avoid storing these 2 bytes!
77 /* inbuf: */ (void *)packed_usage + 2,
77 /* len: */ sizeof(packed_usage)); 78 /* len: */ sizeof(packed_usage));
78 /* read_bunzip can longjmp to start_bunzip, and ultimately 79 /* read_bunzip can longjmp to start_bunzip, and ultimately
79 * end up here with i != 0 on read data errors! Not trivial */ 80 * end up here with i != 0 on read data errors! Not trivial */
diff --git a/libbb/read.c b/libbb/read.c
index 18f62838e..9f6bfcd1b 100644
--- a/libbb/read.c
+++ b/libbb/read.c
@@ -8,7 +8,14 @@
8 */ 8 */
9 9
10#include "libbb.h" 10#include "libbb.h"
11#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED 11
12#define ZIPPED (ENABLE_FEATURE_SEAMLESS_LZMA \
13 || ENABLE_FEATURE_SEAMLESS_BZ2 \
14 || ENABLE_FEATURE_SEAMLESS_GZ \
15 /* || ENABLE_FEATURE_SEAMLESS_Z */ \
16)
17
18#if ZIPPED
12#include "unarchive.h" 19#include "unarchive.h"
13#endif 20#endif
14 21
@@ -299,24 +306,81 @@ void* FAST_FUNC xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p)
299 return buf; 306 return buf;
300} 307}
301 308
302#if ENABLE_FEATURE_MODPROBE_SMALL_ZIPPED 309int FAST_FUNC open_zipped(const char *fname)
310{
311#if !ZIPPED
312 return open(fname, O_RDONLY);
313#else
314 unsigned char magic[2];
315 char *sfx;
316 int fd;
317#if BB_MMU
318 USE_DESKTOP(long long) int FAST_FUNC (*xformer)(int src_fd, int dst_fd);
319 enum { xformer_prog = 0 };
320#else
321 enum { xformer = 0 };
322 const char *xformer_prog;
323#endif
324
325 fd = open(fname, O_RDONLY);
326 if (fd < 0)
327 return fd;
328
329 sfx = strrchr(fname, '.');
330 if (sfx) {
331 if (ENABLE_FEATURE_SEAMLESS_LZMA && strcmp(sfx, ".lzma") == 0)
332 /* .lzma has no header/signature, just trust it */
333 open_transformer(fd, unpack_lzma_stream, "unlzma");
334 else
335 if ((ENABLE_FEATURE_SEAMLESS_GZ && strcmp(sfx, ".gz") == 0)
336 || (ENABLE_FEATURE_SEAMLESS_BZ2 && strcmp(sfx, ".bz2") == 0)
337 ) {
338 /* .gz and .bz2 both have 2-byte signature, and their
339 * unpack_XXX_stream want this header skipped. */
340 xread(fd, &magic, 2);
341#if BB_MMU
342 xformer = unpack_gz_stream;
343#else
344 xformer_prog = "gunzip";
345#endif
346 if (magic[0] != 0x1f || magic[1] != 0x8b) {
347 if (!ENABLE_FEATURE_SEAMLESS_BZ2
348 || magic[0] != 'B' || magic[1] != 'Z'
349 ) {
350 bb_error_msg_and_die("no gzip"
351 USE_FEATURE_SEAMLESS_BZ2("/bzip2")
352 " magic");
353 }
354#if BB_MMU
355 xformer = unpack_bz2_stream;
356#else
357 xformer_prog = "bunzip2";
358#endif
359 } else {
360#if !BB_MMU
361 /* NOMMU version of open_transformer execs
362 * an external unzipper that wants
363 * file position at the start of the file */
364 xlseek(fd, 0, SEEK_SET);
365#endif
366 }
367 open_transformer(fd, xformer, xformer_prog);
368 }
369 }
370
371 return fd;
372#endif
373}
374
303void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) 375void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p)
304{ 376{
377 int fd;
305 char *image; 378 char *image;
306 char *suffix;
307 379
308 int fd = open(fname, O_RDONLY); 380 fd = open_zipped(fname);
309 if (fd < 0) 381 if (fd < 0)
310 return NULL; 382 return NULL;
311 383
312 suffix = strrchr(fname, '.');
313 if (suffix) {
314 if (strcmp(suffix, ".gz") == 0)
315 open_transformer(fd, unpack_gz_stream, "gunzip");
316 else if (strcmp(suffix, ".bz2") == 0)
317 open_transformer(fd, unpack_bz2_stream, "bunzip2");
318 }
319
320 image = xmalloc_read(fd, maxsz_p); 384 image = xmalloc_read(fd, maxsz_p);
321 if (!image) 385 if (!image)
322 bb_perror_msg("read error from '%s'", fname); 386 bb_perror_msg("read error from '%s'", fname);
@@ -324,4 +388,3 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_
324 388
325 return image; 389 return image;
326} 390}
327#endif