summaryrefslogtreecommitdiff
path: root/archival/bbunzip.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/bbunzip.c')
-rw-r--r--archival/bbunzip.c173
1 files changed, 85 insertions, 88 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c
index df674bc6c..08db2752c 100644
--- a/archival/bbunzip.c
+++ b/archival/bbunzip.c
@@ -4,17 +4,16 @@
4 * 4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
6 */ 6 */
7
8#include "libbb.h" 7#include "libbb.h"
9#include "unarchive.h" 8#include "unarchive.h"
10 9
11enum { 10enum {
12 OPT_STDOUT = 0x1, 11 OPT_STDOUT = 1 << 0,
13 OPT_FORCE = 0x2, 12 OPT_FORCE = 1 << 1,
14/* gunzip and bunzip2 only: */ 13 /* only some decompressors: */
15 OPT_VERBOSE = 0x4, 14 OPT_VERBOSE = 1 << 2,
16 OPT_DECOMPRESS = 0x8, 15 OPT_DECOMPRESS = 1 << 3,
17 OPT_TEST = 0x10, 16 OPT_TEST = 1 << 4,
18}; 17};
19 18
20static 19static
@@ -28,9 +27,15 @@ int open_to_or_warn(int to_fd, const char *filename, int flags, int mode)
28 return 0; 27 return 0;
29} 28}
30 29
30char* FAST_FUNC append_ext(char *filename, const char *expected_ext)
31{
32 return xasprintf("%s.%s", filename, expected_ext);
33}
34
31int FAST_FUNC bbunpack(char **argv, 35int FAST_FUNC bbunpack(char **argv,
32 char* (*make_new_name)(char *filename), 36 IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info),
33 IF_DESKTOP(long long) int (*unpacker)(unpack_info_t *info) 37 char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
38 const char *expected_ext
34) 39)
35{ 40{
36 struct stat stat_buf; 41 struct stat stat_buf;
@@ -69,7 +74,7 @@ int FAST_FUNC bbunpack(char **argv,
69 74
70 /* Open dst if we are going to unpack to file */ 75 /* Open dst if we are going to unpack to file */
71 if (filename) { 76 if (filename) {
72 new_name = make_new_name(filename); 77 new_name = make_new_name(filename, expected_ext);
73 if (!new_name) { 78 if (!new_name) {
74 bb_error_msg("%s: unknown suffix - ignored", filename); 79 bb_error_msg("%s: unknown suffix - ignored", filename);
75 goto err; 80 goto err;
@@ -141,10 +146,9 @@ int FAST_FUNC bbunpack(char **argv,
141 return exitcode; 146 return exitcode;
142} 147}
143 148
144#if ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNCOMPRESS 149#if ENABLE_UNCOMPRESS || ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNXZ
145
146static 150static
147char* make_new_name_generic(char *filename, const char *expected_ext) 151char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
148{ 152{
149 char *extension = strrchr(filename, '.'); 153 char *extension = strrchr(filename, '.');
150 if (!extension || strcmp(extension + 1, expected_ext) != 0) { 154 if (!extension || strcmp(extension + 1, expected_ext) != 0) {
@@ -155,42 +159,35 @@ char* make_new_name_generic(char *filename, const char *expected_ext)
155 *extension = '\0'; 159 *extension = '\0';
156 return filename; 160 return filename;
157} 161}
158
159#endif 162#endif
160 163
161 164
162/* 165/*
163 * Modified for busybox by Glenn McGrath 166 * Uncompress applet for busybox (c) 2002 Glenn McGrath
164 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
165 * 167 *
166 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 168 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
167 */ 169 */
168 170#if ENABLE_UNCOMPRESS
169#if ENABLE_BUNZIP2
170
171static 171static
172char* make_new_name_bunzip2(char *filename) 172IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM)
173{ 173{
174 return make_new_name_generic(filename, "bz2"); 174 IF_DESKTOP(long long) int status = -1;
175}
176 175
177static 176 if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {
178IF_DESKTOP(long long) int unpack_bunzip2(unpack_info_t *info UNUSED_PARAM) 177 bb_error_msg("invalid magic");
179{ 178 } else {
180 return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO); 179 status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
180 }
181 return status;
181} 182}
182 183int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
183int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 184int uncompress_main(int argc UNUSED_PARAM, char **argv)
184int bunzip2_main(int argc UNUSED_PARAM, char **argv)
185{ 185{
186 getopt32(argv, "cfvdt"); 186 getopt32(argv, "cf");
187 argv += optind; 187 argv += optind;
188 if (applet_name[2] == 'c')
189 option_mask32 |= OPT_STDOUT;
190 188
191 return bbunpack(argv, make_new_name_bunzip2, unpack_bunzip2); 189 return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z");
192} 190}
193
194#endif 191#endif
195 192
196 193
@@ -221,11 +218,9 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv)
221 * See the license_msg below and the file COPYING for the software license. 218 * See the license_msg below and the file COPYING for the software license.
222 * See the file algorithm.doc for the compression algorithms and file formats. 219 * See the file algorithm.doc for the compression algorithms and file formats.
223 */ 220 */
224
225#if ENABLE_GUNZIP 221#if ENABLE_GUNZIP
226
227static 222static
228char* make_new_name_gunzip(char *filename) 223char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM)
229{ 224{
230 char *extension = strrchr(filename, '.'); 225 char *extension = strrchr(filename, '.');
231 226
@@ -249,9 +244,8 @@ char* make_new_name_gunzip(char *filename)
249 } 244 }
250 return filename; 245 return filename;
251} 246}
252
253static 247static
254IF_DESKTOP(long long) int unpack_gunzip(unpack_info_t *info) 248IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info)
255{ 249{
256 IF_DESKTOP(long long) int status = -1; 250 IF_DESKTOP(long long) int status = -1;
257 251
@@ -277,7 +271,6 @@ IF_DESKTOP(long long) int unpack_gunzip(unpack_info_t *info)
277 } 271 }
278 return status; 272 return status;
279} 273}
280
281/* 274/*
282 * Linux kernel build uses gzip -d -n. We accept and ignore it. 275 * Linux kernel build uses gzip -d -n. We accept and ignore it.
283 * Man page says: 276 * Man page says:
@@ -291,7 +284,6 @@ IF_DESKTOP(long long) int unpack_gunzip(unpack_info_t *info)
291 * gzip: always save the original file name and time stamp (this is the default) 284 * gzip: always save the original file name and time stamp (this is the default)
292 * gunzip: restore the original file name and time stamp if present. 285 * gunzip: restore the original file name and time stamp if present.
293 */ 286 */
294
295int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 287int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
296int gunzip_main(int argc UNUSED_PARAM, char **argv) 288int gunzip_main(int argc UNUSED_PARAM, char **argv)
297{ 289{
@@ -301,9 +293,33 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv)
301 if (applet_name[1] == 'c') 293 if (applet_name[1] == 'c')
302 option_mask32 |= OPT_STDOUT; 294 option_mask32 |= OPT_STDOUT;
303 295
304 return bbunpack(argv, make_new_name_gunzip, unpack_gunzip); 296 return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL);
305} 297}
298#endif
306 299
300
301/*
302 * Modified for busybox by Glenn McGrath
303 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
304 *
305 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
306 */
307#if ENABLE_BUNZIP2
308static
309IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM)
310{
311 return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO);
312}
313int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
314int bunzip2_main(int argc UNUSED_PARAM, char **argv)
315{
316 getopt32(argv, "cfvdt");
317 argv += optind;
318 if (applet_name[2] == 'c') /* bzcat */
319 option_mask32 |= OPT_STDOUT;
320
321 return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2");
322}
307#endif 323#endif
308 324
309 325
@@ -315,70 +331,51 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv)
315 * 331 *
316 * Licensed under GPL v2, see file LICENSE in this tarball for details. 332 * Licensed under GPL v2, see file LICENSE in this tarball for details.
317 */ 333 */
318
319#if ENABLE_UNLZMA 334#if ENABLE_UNLZMA
320
321static
322char* make_new_name_unlzma(char *filename)
323{
324 return make_new_name_generic(filename, "lzma");
325}
326
327static 335static
328IF_DESKTOP(long long) int unpack_unlzma(unpack_info_t *info UNUSED_PARAM) 336IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM)
329{ 337{
330 return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO); 338 return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO);
331} 339}
332
333int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 340int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
334int unlzma_main(int argc UNUSED_PARAM, char **argv) 341int unlzma_main(int argc UNUSED_PARAM, char **argv)
335{ 342{
336 getopt32(argv, "cf"); 343 IF_LZMA(int opts =) getopt32(argv, "cfvdt");
337 argv += optind; 344# if ENABLE_LZMA
338 /* lzmacat? */ 345 /* lzma without -d or -t? */
339 if (applet_name[4] == 'c') 346 if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
347 bb_show_usage();
348# endif
349 /* lzcat? */
350 if (applet_name[2] == 'c')
340 option_mask32 |= OPT_STDOUT; 351 option_mask32 |= OPT_STDOUT;
341 352
342 return bbunpack(argv, make_new_name_unlzma, unpack_unlzma); 353 argv += optind;
354 return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma");
343} 355}
344
345#endif 356#endif
346 357
347 358
348/* 359#if ENABLE_UNXZ
349 * Uncompress applet for busybox (c) 2002 Glenn McGrath
350 *
351 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
352 */
353
354#if ENABLE_UNCOMPRESS
355
356static 360static
357char* make_new_name_uncompress(char *filename) 361IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM)
358{ 362{
359 return make_new_name_generic(filename, "Z"); 363 return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO);
360} 364}
361 365int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
362static 366int unxz_main(int argc UNUSED_PARAM, char **argv)
363IF_DESKTOP(long long) int unpack_uncompress(unpack_info_t *info UNUSED_PARAM)
364{ 367{
365 IF_DESKTOP(long long) int status = -1; 368 int opts = getopt32(argv, "cfvdt");
366 369# if ENABLE_XZ
367 if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) { 370 /* xz without -d or -t? */
368 bb_error_msg("invalid magic"); 371 if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
369 } else { 372 bb_show_usage();
370 status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO); 373# endif
371 } 374 /* xzcat? */
372 return status; 375 if (applet_name[2] == 'c')
373} 376 option_mask32 |= OPT_STDOUT;
374 377
375int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
376int uncompress_main(int argc UNUSED_PARAM, char **argv)
377{
378 getopt32(argv, "cf");
379 argv += optind; 378 argv += optind;
380 379 return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz");
381 return bbunpack(argv, make_new_name_uncompress, unpack_uncompress);
382} 380}
383
384#endif 381#endif