blob: a2ce0a13cd5a3accec4edc5a0a70a3bd9bb4aa26 [file] [log] [blame]
Denis Vlasenkoab9eef22007-03-07 22:02:23 +00001/* vi: set sw=4 ts=4: */
2/*
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02003 * Common code for gunzip-like applets
Denis Vlasenkoab9eef22007-03-07 22:02:23 +00004 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02005 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Denis Vlasenkoab9eef22007-03-07 22:02:23 +00006 */
Denys Vlasenkod4e4fdb2017-07-03 21:31:16 +02007//kbuild:lib-$(CONFIG_ZCAT) += bbunzip.o
8//kbuild:lib-$(CONFIG_GUNZIP) += bbunzip.o
9//kbuild:lib-$(CONFIG_BZCAT) += bbunzip.o
10//kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o
11
Denys Vlasenko66620fa2013-11-14 09:53:52 +010012/* lzop_main() uses bbunpack(), need this: */
13//kbuild:lib-$(CONFIG_LZOP) += bbunzip.o
Denys Vlasenko9cc3d3a2016-12-23 02:42:26 +010014//kbuild:lib-$(CONFIG_LZOPCAT) += bbunzip.o
15//kbuild:lib-$(CONFIG_UNLZOP) += bbunzip.o
Denys Vlasenko548620c2016-12-08 12:24:48 +010016/* bzip2_main() too: */
Denys Vlasenkod4e4fdb2017-07-03 21:31:16 +020017//kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o
Denys Vlasenko9cc3d3a2016-12-23 02:42:26 +010018/* gzip_main() too: */
Denys Vlasenkod4e4fdb2017-07-03 21:31:16 +020019//kbuild:lib-$(CONFIG_GZIP) += bbunzip.o
Denys Vlasenko66620fa2013-11-14 09:53:52 +010020
Denys Vlasenko0c4dbd42017-09-18 16:28:43 +020021#include "libbb.h"
22#include "bb_archive.h"
23
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000024static
25int open_to_or_warn(int to_fd, const char *filename, int flags, int mode)
26{
Denis Vlasenko50f7f442007-04-11 23:20:53 +000027 int fd = open3_or_warn(filename, flags, mode);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000028 if (fd < 0) {
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000029 return 1;
30 }
Denis Vlasenko50f7f442007-04-11 23:20:53 +000031 xmove_fd(fd, to_fd);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000032 return 0;
33}
34
Denys Vlasenko39a04f72010-05-31 14:18:57 +020035char* FAST_FUNC append_ext(char *filename, const char *expected_ext)
36{
37 return xasprintf("%s.%s", filename, expected_ext);
38}
39
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000040int FAST_FUNC bbunpack(char **argv,
Denys Vlasenkoe7800f32014-12-07 00:42:49 +010041 IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_state_t *xstate),
Denys Vlasenko39a04f72010-05-31 14:18:57 +020042 char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
43 const char *expected_ext
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000044)
45{
46 struct stat stat_buf;
Denys Vlasenko8e96efa2013-02-28 18:06:09 +010047 IF_DESKTOP(long long) int status = 0;
Denis Vlasenko6c939e02007-03-07 23:22:47 +000048 char *filename, *new_name;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000049 smallint exitcode = 0;
Denys Vlasenkoe7800f32014-12-07 00:42:49 +010050 transformer_state_t xstate;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000051
52 do {
Denis Vlasenko6c939e02007-03-07 23:22:47 +000053 /* NB: new_name is *maybe* malloc'ed! */
54 new_name = NULL;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000055 filename = *argv; /* can be NULL - 'streaming' bunzip2 */
Denis Vlasenko6c939e02007-03-07 23:22:47 +000056
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000057 if (filename && LONE_DASH(filename))
58 filename = NULL;
59
60 /* Open src */
61 if (filename) {
Denys Vlasenkod6f0f032018-02-01 09:13:14 +010062 if (!(option_mask32 & BBUNPK_SEAMLESS_MAGIC)) {
Denys Vlasenko8e96efa2013-02-28 18:06:09 +010063 if (stat(filename, &stat_buf) != 0) {
64 err_name:
65 bb_simple_perror_msg(filename);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000066 err:
Denys Vlasenko8e96efa2013-02-28 18:06:09 +010067 exitcode = 1;
68 goto free_name;
69 }
70 if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0))
71 goto err;
72 } else {
Denys Vlasenko41655432013-02-28 18:37:04 +010073 /* "clever zcat" with FILE */
Denys Vlasenko640ce3d2014-02-02 02:06:38 +010074 /* fail_if_not_compressed because zcat refuses uncompressed input */
75 int fd = open_zipped(filename, /*fail_if_not_compressed:*/ 1);
Denys Vlasenko8e96efa2013-02-28 18:06:09 +010076 if (fd < 0)
77 goto err_name;
78 xmove_fd(fd, STDIN_FILENO);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000079 }
Denys Vlasenko41655432013-02-28 18:37:04 +010080 } else
Denys Vlasenkod6f0f032018-02-01 09:13:14 +010081 if (option_mask32 & BBUNPK_SEAMLESS_MAGIC) {
Denys Vlasenko41655432013-02-28 18:37:04 +010082 /* "clever zcat" on stdin */
Denys Vlasenko640ce3d2014-02-02 02:06:38 +010083 if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_compressed*/ 1))
Denys Vlasenko41655432013-02-28 18:37:04 +010084 goto err;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000085 }
86
87 /* Special cases: test, stdout */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +010088 if (option_mask32 & (BBUNPK_OPT_STDOUT|BBUNPK_OPT_TEST)) {
89 if (option_mask32 & BBUNPK_OPT_TEST)
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000090 if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0))
Denys Vlasenkof2d84782013-02-28 18:04:22 +010091 xfunc_die();
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000092 filename = NULL;
93 }
94
Denis Vlasenko6c939e02007-03-07 23:22:47 +000095 /* Open dst if we are going to unpack to file */
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000096 if (filename) {
Denys Vlasenko39a04f72010-05-31 14:18:57 +020097 new_name = make_new_name(filename, expected_ext);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +000098 if (!new_name) {
99 bb_error_msg("%s: unknown suffix - ignored", filename);
100 goto err;
101 }
Denis Vlasenkoa04cc472008-06-25 20:54:45 +0000102
103 /* -f: overwrite existing output files */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100104 if (option_mask32 & BBUNPK_OPT_FORCE) {
Denis Vlasenkoa04cc472008-06-25 20:54:45 +0000105 unlink(new_name);
106 }
107
Denis Vlasenko6c939e02007-03-07 23:22:47 +0000108 /* O_EXCL: "real" bunzip2 doesn't overwrite files */
Denis Vlasenko5dd8a032007-10-05 15:26:08 +0000109 /* GNU gunzip does not bail out, but goes to next file */
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000110 if (open_to_or_warn(STDOUT_FILENO, new_name, O_WRONLY | O_CREAT | O_EXCL,
111 stat_buf.st_mode))
112 goto err;
113 }
114
Denis Vlasenko6c939e02007-03-07 23:22:47 +0000115 /* Check that the input is sane */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100116 if (!(option_mask32 & BBUNPK_OPT_FORCE) && isatty(STDIN_FILENO)) {
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000117 bb_error_msg_and_die("compressed data not read from terminal, "
118 "use -f to force it");
119 }
120
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100121 if (!(option_mask32 & BBUNPK_SEAMLESS_MAGIC)) {
Denys Vlasenkoe7800f32014-12-07 00:42:49 +0100122 init_transformer_state(&xstate);
Denys Vlasenko2a0867a2017-01-09 10:58:37 +0100123 /*xstate.signature_skipped = 0; - already is */
Denys Vlasenkob4c11c12014-12-07 00:44:00 +0100124 /*xstate.src_fd = STDIN_FILENO; - already is */
125 xstate.dst_fd = STDOUT_FILENO;
Denys Vlasenkoe7800f32014-12-07 00:42:49 +0100126 status = unpacker(&xstate);
Denys Vlasenko8e96efa2013-02-28 18:06:09 +0100127 if (status < 0)
128 exitcode = 1;
129 } else {
Denys Vlasenko41655432013-02-28 18:37:04 +0100130 if (bb_copyfd_eof(STDIN_FILENO, STDOUT_FILENO) < 0)
Denys Vlasenko8e96efa2013-02-28 18:06:09 +0100131 /* Disk full, tty closed, etc. No point in continuing */
132 xfunc_die();
Denys Vlasenko8e96efa2013-02-28 18:06:09 +0100133 }
Denys Vlasenkoc531b9a2011-10-31 01:05:16 +0100134
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100135 if (!(option_mask32 & BBUNPK_OPT_STDOUT))
Denys Vlasenkoc531b9a2011-10-31 01:05:16 +0100136 xclose(STDOUT_FILENO); /* with error check! */
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000137
138 if (filename) {
139 char *del = new_name;
Denys Vlasenkod0bc7082013-07-30 05:41:11 +0200140
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000141 if (status >= 0) {
Denys Vlasenkod0bc7082013-07-30 05:41:11 +0200142 unsigned new_name_len;
143
Denis Vlasenko1a9e9bd2008-11-01 12:54:56 +0000144 /* TODO: restore other things? */
Denys Vlasenkoe7800f32014-12-07 00:42:49 +0100145 if (xstate.mtime != 0) {
Denys Vlasenkodcbfaba2009-11-29 19:40:36 +0100146 struct timeval times[2];
Denys Vlasenko389cca42009-11-15 02:28:56 +0100147
Denys Vlasenkoe7800f32014-12-07 00:42:49 +0100148 times[1].tv_sec = times[0].tv_sec = xstate.mtime;
Denys Vlasenkodcbfaba2009-11-29 19:40:36 +0100149 times[1].tv_usec = times[0].tv_usec = 0;
Denys Vlasenkodcd27ab2009-10-05 03:03:07 +0200150 /* Note: we closed it first.
Denys Vlasenko389cca42009-11-15 02:28:56 +0100151 * On some systems calling utimes
Denys Vlasenkodcd27ab2009-10-05 03:03:07 +0200152 * then closing resets the mtime
153 * back to current time. */
Denys Vlasenkodcbfaba2009-11-29 19:40:36 +0100154 utimes(new_name, times); /* ignoring errors */
Denis Vlasenko1a9e9bd2008-11-01 12:54:56 +0000155 }
156
Denys Vlasenkod0bc7082013-07-30 05:41:11 +0200157 if (ENABLE_DESKTOP)
158 new_name_len = strlen(new_name);
159 /* Restore source filename (unless tgz -> tar case) */
160 if (new_name == filename) {
161 new_name_len = strlen(filename);
162 filename[new_name_len] = '.';
163 }
164 /* Extreme bloat for gunzip compat */
165 /* Some users do want this info... */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100166 if (ENABLE_DESKTOP && (option_mask32 & BBUNPK_OPT_VERBOSE)) {
Denys Vlasenkod0bc7082013-07-30 05:41:11 +0200167 unsigned percent = status
168 ? ((uoff_t)stat_buf.st_size * 100u / (unsigned long long)status)
169 : 0;
170 fprintf(stderr, "%s: %u%% - replaced with %.*s\n",
171 filename,
172 100u - percent,
173 new_name_len, new_name
174 );
175 }
176 /* Delete _source_ file */
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000177 del = filename;
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100178 if (option_mask32 & BBUNPK_OPT_KEEP) /* ... unless -k */
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200179 del = NULL;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000180 }
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200181 if (del)
182 xunlink(del);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000183 free_name:
184 if (new_name != filename)
185 free(new_name);
186 }
187 } while (*argv && *++argv);
188
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100189 if (option_mask32 & BBUNPK_OPT_STDOUT)
Denys Vlasenkoc531b9a2011-10-31 01:05:16 +0100190 xclose(STDOUT_FILENO); /* with error check! */
191
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000192 return exitcode;
193}
194
Denys Vlasenko548620c2016-12-08 12:24:48 +0100195#if ENABLE_UNCOMPRESS \
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800196 || ENABLE_FEATURE_BZIP2_DECOMPRESS \
Denys Vlasenko548620c2016-12-08 12:24:48 +0100197 || ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA \
198 || ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000199static
Denys Vlasenko39a04f72010-05-31 14:18:57 +0200200char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000201{
202 char *extension = strrchr(filename, '.');
Denis Vlasenkobebbd8c2007-03-09 20:49:55 +0000203 if (!extension || strcmp(extension + 1, expected_ext) != 0) {
Denis Vlasenko6c939e02007-03-07 23:22:47 +0000204 /* Mimic GNU gunzip - "real" bunzip2 tries to */
205 /* unpack file anyway, to file.out */
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000206 return NULL;
207 }
208 *extension = '\0';
209 return filename;
210}
Denis Vlasenkoa4688bf2007-03-11 10:56:37 +0000211#endif
212
213
Denis Vlasenkoa4688bf2007-03-11 10:56:37 +0000214/*
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200215 * Uncompress applet for busybox (c) 2002 Glenn McGrath
Denis Vlasenkoa4688bf2007-03-11 10:56:37 +0000216 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +0200217 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Denis Vlasenkoa4688bf2007-03-11 10:56:37 +0000218 */
Pere Orga1f4447b2011-03-27 22:40:30 +0200219//usage:#define uncompress_trivial_usage
220//usage: "[-cf] [FILE]..."
221//usage:#define uncompress_full_usage "\n\n"
222//usage: "Decompress .Z file[s]\n"
Pere Orga1f4447b2011-03-27 22:40:30 +0200223//usage: "\n -c Write to stdout"
224//usage: "\n -f Overwrite"
225
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100226//config:config UNCOMPRESS
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200227//config: bool "uncompress (7.1 kb)"
Denys Vlasenkodb700332015-10-25 20:36:03 +0100228//config: default n # ancient
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100229//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200230//config: uncompress is used to decompress archives created by compress.
231//config: Not much used anymore, replaced by gzip/gunzip.
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100232
Denys Vlasenko36184a42013-11-14 09:54:24 +0100233//applet:IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP))
Denys Vlasenko66620fa2013-11-14 09:53:52 +0100234//kbuild:lib-$(CONFIG_UNCOMPRESS) += bbunzip.o
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200235#if ENABLE_UNCOMPRESS
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200236int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
237int uncompress_main(int argc UNUSED_PARAM, char **argv)
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000238{
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200239// (N)compress 4.2.4.4:
240// -d If given, decompression is done instead
241// -c Write output on stdout, don't remove original
242// -b Parameter limits the max number of bits/code
243// -f Forces output file to be generated
244// -v Write compression statistics
245// -V Output vesion and compile options
246// -r Recursive. If a filename is a directory, descend into it and compress everything
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200247 getopt32(argv, "cf");
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200248
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000249 argv += optind;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000250
Denys Vlasenkob4c11c12014-12-07 00:44:00 +0100251 return bbunpack(argv, unpack_Z_stream, make_new_name_generic, "Z");
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000252}
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000253#endif
254
255
256/*
257 * Gzip implementation for busybox
258 *
259 * Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
260 *
261 * Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
262 * based on gzip sources
263 *
264 * Adjusted further by Erik Andersen <andersen@codepoet.org> to support files as
265 * well as stdin/stdout, and to generally behave itself wrt command line
266 * handling.
267 *
268 * General cleanup to better adhere to the style guide and make use of standard
Denis Vlasenko0beaff82007-09-21 13:16:32 +0000269 * busybox functions by Glenn McGrath
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000270 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +0200271 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000272 *
273 * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
274 * Copyright (C) 1992-1993 Jean-loup Gailly
275 * The unzip code was written and put in the public domain by Mark Adler.
276 * Portions of the lzw code are derived from the public domain 'compress'
277 * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
278 * Ken Turkowski, Dave Mack and Peter Jannesen.
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000279 */
Pere Orga1f4447b2011-03-27 22:40:30 +0200280//usage:#define gunzip_trivial_usage
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200281//usage: "[-cfkt] [FILE]..."
Pere Orga1f4447b2011-03-27 22:40:30 +0200282//usage:#define gunzip_full_usage "\n\n"
283//usage: "Decompress FILEs (or stdin)\n"
Pere Orga1f4447b2011-03-27 22:40:30 +0200284//usage: "\n -c Write to stdout"
285//usage: "\n -f Force"
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200286//usage: "\n -k Keep input files"
Pere Orga1f4447b2011-03-27 22:40:30 +0200287//usage: "\n -t Test file integrity"
288//usage:
289//usage:#define gunzip_example_usage
290//usage: "$ ls -la /tmp/BusyBox*\n"
291//usage: "-rw-rw-r-- 1 andersen andersen 557009 Apr 11 10:55 /tmp/BusyBox-0.43.tar.gz\n"
292//usage: "$ gunzip /tmp/BusyBox-0.43.tar.gz\n"
293//usage: "$ ls -la /tmp/BusyBox*\n"
294//usage: "-rw-rw-r-- 1 andersen andersen 1761280 Apr 14 17:47 /tmp/BusyBox-0.43.tar\n"
295//usage:
296//usage:#define zcat_trivial_usage
Denys Vlasenkof2d84782013-02-28 18:04:22 +0100297//usage: "[FILE]..."
Pere Orga1f4447b2011-03-27 22:40:30 +0200298//usage:#define zcat_full_usage "\n\n"
299//usage: "Decompress to stdout"
300
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100301//config:config GUNZIP
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200302//config: bool "gunzip (12 kb)"
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100303//config: default y
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800304//config: select FEATURE_GZIP_DECOMPRESS
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100305//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200306//config: gunzip is used to decompress archives created by gzip.
Denys Vlasenko18e781d2017-08-02 14:12:48 +0200307//config: You can use the '-t' option to test the integrity of
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200308//config: an archive, without decompressing it.
Aaro Koskinenfbe50cf2015-10-26 23:42:32 +0200309//config:
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100310//config:config ZCAT
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200311//config: bool "zcat (25 kb)"
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100312//config: default y
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800313//config: select FEATURE_GZIP_DECOMPRESS
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100314//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200315//config: Alias to "gunzip -c".
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100316//config:
Aaro Koskinenfbe50cf2015-10-26 23:42:32 +0200317//config:config FEATURE_GUNZIP_LONG_OPTIONS
318//config: bool "Enable long options"
319//config: default y
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100320//config: depends on (GUNZIP || ZCAT) && LONG_OPTS
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100321
Denys Vlasenko36184a42013-11-14 09:54:24 +0100322//applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP))
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100323// APPLET_ODDNAME:name main location suid_type help
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100324//applet:IF_ZCAT(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat))
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800325#if ENABLE_FEATURE_GZIP_DECOMPRESS
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000326static
Denys Vlasenko39a04f72010-05-31 14:18:57 +0200327char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM)
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000328{
329 char *extension = strrchr(filename, '.');
330
331 if (!extension)
332 return NULL;
333
Denis Vlasenkobebbd8c2007-03-09 20:49:55 +0000334 extension++;
335 if (strcmp(extension, "tgz" + 1) == 0
Denis Vlasenkoe9ad84d2008-08-05 13:10:34 +0000336#if ENABLE_FEATURE_SEAMLESS_Z
337 || (extension[0] == 'Z' && extension[1] == '\0')
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000338#endif
339 ) {
Denis Vlasenkobebbd8c2007-03-09 20:49:55 +0000340 extension[-1] = '\0';
Denis Vlasenko51742f42007-04-12 00:32:05 +0000341 } else if (strcmp(extension, "tgz") == 0) {
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000342 filename = xstrdup(filename);
343 extension = strrchr(filename, '.');
344 extension[2] = 'a';
345 extension[3] = 'r';
346 } else {
347 return NULL;
348 }
349 return filename;
350}
Aaro Koskinenfbe50cf2015-10-26 23:42:32 +0200351
352#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
353static const char gunzip_longopts[] ALIGN1 =
354 "stdout\0" No_argument "c"
355 "to-stdout\0" No_argument "c"
356 "force\0" No_argument "f"
357 "test\0" No_argument "t"
Aaro Koskinencddc98e2015-10-26 23:42:33 +0200358 "no-name\0" No_argument "n"
Aaro Koskinenfbe50cf2015-10-26 23:42:32 +0200359 ;
360#endif
361
Denis Vlasenko52978092008-03-30 13:11:47 +0000362/*
363 * Linux kernel build uses gzip -d -n. We accept and ignore it.
364 * Man page says:
365 * -n --no-name
366 * gzip: do not save the original file name and time stamp.
367 * (The original name is always saved if the name had to be truncated.)
368 * gunzip: do not restore the original file name/time even if present
369 * (remove only the gzip suffix from the compressed file name).
370 * This option is the default when decompressing.
371 * -N --name
372 * gzip: always save the original file name and time stamp (this is the default)
373 * gunzip: restore the original file name and time stamp if present.
374 */
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +0000375int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +0000376int gunzip_main(int argc UNUSED_PARAM, char **argv)
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000377{
Aaro Koskinenfbe50cf2015-10-26 23:42:32 +0200378#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100379 getopt32long(argv, BBUNPK_OPTSTR "dtn", gunzip_longopts);
Denys Vlasenko036585a2017-08-08 16:38:18 +0200380#else
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100381 getopt32(argv, BBUNPK_OPTSTR "dtn");
Denys Vlasenko036585a2017-08-08 16:38:18 +0200382#endif
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000383 argv += optind;
Denys Vlasenko8e96efa2013-02-28 18:06:09 +0100384
385 /* If called as zcat...
386 * Normally, "zcat" is just "gunzip -c".
387 * But if seamless magic is enabled, then we are much more clever.
388 */
Denys Vlasenkoebe3c352017-07-20 16:25:03 +0200389 if (ENABLE_ZCAT && (!ENABLE_GUNZIP || applet_name[1] == 'c'))
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100390 option_mask32 |= BBUNPK_OPT_STDOUT | BBUNPK_SEAMLESS_MAGIC;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000391
Denys Vlasenkob4c11c12014-12-07 00:44:00 +0100392 return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL);
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000393}
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800394#endif /* FEATURE_GZIP_DECOMPRESS */
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000395
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200396
397/*
398 * Modified for busybox by Glenn McGrath
399 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
400 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +0200401 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200402 */
Denys Vlasenkof0f94702010-06-06 01:53:38 +0200403//usage:#define bunzip2_trivial_usage
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200404//usage: "[-cfk] [FILE]..."
Denys Vlasenkof0f94702010-06-06 01:53:38 +0200405//usage:#define bunzip2_full_usage "\n\n"
406//usage: "Decompress FILEs (or stdin)\n"
Denys Vlasenkof0f94702010-06-06 01:53:38 +0200407//usage: "\n -c Write to stdout"
408//usage: "\n -f Force"
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200409//usage: "\n -k Keep input files"
Denys Vlasenkof0f94702010-06-06 01:53:38 +0200410//usage:#define bzcat_trivial_usage
Denys Vlasenkof2d84782013-02-28 18:04:22 +0100411//usage: "[FILE]..."
Denys Vlasenkof0f94702010-06-06 01:53:38 +0200412//usage:#define bzcat_full_usage "\n\n"
413//usage: "Decompress to stdout"
Denys Vlasenko66620fa2013-11-14 09:53:52 +0100414
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100415//config:config BUNZIP2
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200416//config: bool "bunzip2 (8.8 kb)"
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100417//config: default y
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800418//config: select FEATURE_BZIP2_DECOMPRESS
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100419//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200420//config: bunzip2 is a compression utility using the Burrows-Wheeler block
421//config: sorting text compression algorithm, and Huffman coding. Compression
422//config: is generally considerably better than that achieved by more
423//config: conventional LZ77/LZ78-based compressors, and approaches the
424//config: performance of the PPM family of statistical compressors.
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100425//config:
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200426//config: Unless you have a specific application which requires bunzip2, you
427//config: should probably say N here.
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100428//config:
429//config:config BZCAT
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200430//config: bool "bzcat (8.8 kb)"
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100431//config: default y
Kang-Che Sungb130f9f2017-01-08 14:28:34 +0800432//config: select FEATURE_BZIP2_DECOMPRESS
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100433//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200434//config: Alias to "bunzip2 -c".
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100435
Denys Vlasenkob9f2d9f2011-01-18 13:58:01 +0100436//applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP))
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100437// APPLET_ODDNAME:name main location suid_type help
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100438//applet:IF_BZCAT(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat))
Denys Vlasenko034ceab2017-07-04 16:23:36 +0200439#if ENABLE_FEATURE_BZIP2_DECOMPRESS || ENABLE_BUNZIP2 || ENABLE_BZCAT
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200440int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
441int bunzip2_main(int argc UNUSED_PARAM, char **argv)
442{
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100443 getopt32(argv, BBUNPK_OPTSTR "dt");
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200444 argv += optind;
Denys Vlasenkoebe3c352017-07-20 16:25:03 +0200445 if (ENABLE_BZCAT && (!ENABLE_BUNZIP2 || applet_name[2] == 'c')) /* bzcat */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100446 option_mask32 |= BBUNPK_OPT_STDOUT;
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200447
Denys Vlasenkob4c11c12014-12-07 00:44:00 +0100448 return bbunpack(argv, unpack_bz2_stream, make_new_name_generic, "bz2");
Denys Vlasenkod93f19e2010-05-30 03:46:54 +0200449}
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000450#endif
451
452
453/*
454 * Small lzma deflate implementation.
455 * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
456 *
457 * Based on bunzip.c from busybox
458 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +0200459 * Licensed under GPLv2, see file LICENSE in this source tree.
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000460 */
Pere Orga1f4447b2011-03-27 22:40:30 +0200461//usage:#define unlzma_trivial_usage
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200462//usage: "[-cfk] [FILE]..."
Pere Orga1f4447b2011-03-27 22:40:30 +0200463//usage:#define unlzma_full_usage "\n\n"
464//usage: "Decompress FILE (or stdin)\n"
Pere Orga1f4447b2011-03-27 22:40:30 +0200465//usage: "\n -c Write to stdout"
466//usage: "\n -f Force"
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200467//usage: "\n -k Keep input files"
Pere Orga1f4447b2011-03-27 22:40:30 +0200468//usage:
469//usage:#define lzma_trivial_usage
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200470//usage: "-d [-cfk] [FILE]..."
Pere Orga1f4447b2011-03-27 22:40:30 +0200471//usage:#define lzma_full_usage "\n\n"
472//usage: "Decompress FILE (or stdin)\n"
Pere Orga1f4447b2011-03-27 22:40:30 +0200473//usage: "\n -d Decompress"
474//usage: "\n -c Write to stdout"
475//usage: "\n -f Force"
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200476//usage: "\n -k Keep input files"
Pere Orga1f4447b2011-03-27 22:40:30 +0200477//usage:
478//usage:#define lzcat_trivial_usage
Denys Vlasenkof2d84782013-02-28 18:04:22 +0100479//usage: "[FILE]..."
Pere Orga1f4447b2011-03-27 22:40:30 +0200480//usage:#define lzcat_full_usage "\n\n"
481//usage: "Decompress to stdout"
Pere Orga1f4447b2011-03-27 22:40:30 +0200482
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100483//config:config UNLZMA
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200484//config: bool "unlzma (8.6 kb)"
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100485//config: default y
486//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200487//config: unlzma is a compression utility using the Lempel-Ziv-Markov chain
488//config: compression algorithm, and range coding. Compression
489//config: is generally considerably better than that achieved by the bzip2
490//config: compressors.
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100491//config:
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100492//config:config LZCAT
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200493//config: bool "lzcat (8.5 kb)"
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100494//config: default y
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100495//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200496//config: Alias to "unlzma -c".
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100497//config:
498//config:config LZMA
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100499//config: bool "lzma -d"
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100500//config: default y
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100501//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200502//config: Enable this option if you want commands like "lzma -d" to work.
503//config: IOW: you'll get lzma applet, but it will always require -d option.
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100504
Denys Vlasenko36184a42013-11-14 09:54:24 +0100505//applet:IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP))
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100506// APPLET_ODDNAME:name main location suid_type help
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100507//applet:IF_LZCAT(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat))
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100508//applet:IF_LZMA( APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma))
Denys Vlasenko66620fa2013-11-14 09:53:52 +0100509//kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100510//kbuild:lib-$(CONFIG_LZCAT) += bbunzip.o
511//kbuild:lib-$(CONFIG_LZMA) += bbunzip.o
512#if ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +0000513int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Denis Vlasenkoa60f84e2008-07-05 09:18:54 +0000514int unlzma_main(int argc UNUSED_PARAM, char **argv)
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000515{
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100516 IF_LZMA(int opts =) getopt32(argv, BBUNPK_OPTSTR "dt");
Denys Vlasenkoe04c8672010-05-30 03:33:50 +0200517# if ENABLE_LZMA
Denys Vlasenkoccb88a62010-05-27 02:22:54 +0200518 /* lzma without -d or -t? */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100519 if (applet_name[2] == 'm' && !(opts & (BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST)))
Denys Vlasenkoccb88a62010-05-27 02:22:54 +0200520 bb_show_usage();
521# endif
522 /* lzcat? */
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100523 if (ENABLE_LZCAT && applet_name[2] == 'c')
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100524 option_mask32 |= BBUNPK_OPT_STDOUT;
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000525
Denys Vlasenkoccb88a62010-05-27 02:22:54 +0200526 argv += optind;
Denys Vlasenkob4c11c12014-12-07 00:44:00 +0100527 return bbunpack(argv, unpack_lzma_stream, make_new_name_generic, "lzma");
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000528}
Denis Vlasenkoab9eef22007-03-07 22:02:23 +0000529#endif
530
531
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100532//usage:#define unxz_trivial_usage
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200533//usage: "[-cfk] [FILE]..."
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100534//usage:#define unxz_full_usage "\n\n"
535//usage: "Decompress FILE (or stdin)\n"
536//usage: "\n -c Write to stdout"
537//usage: "\n -f Force"
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200538//usage: "\n -k Keep input files"
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100539//usage:
540//usage:#define xz_trivial_usage
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200541//usage: "-d [-cfk] [FILE]..."
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100542//usage:#define xz_full_usage "\n\n"
543//usage: "Decompress FILE (or stdin)\n"
544//usage: "\n -d Decompress"
545//usage: "\n -c Write to stdout"
546//usage: "\n -f Force"
Denys Vlasenko1c013fa2017-06-15 18:07:04 +0200547//usage: "\n -k Keep input files"
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100548//usage:
549//usage:#define xzcat_trivial_usage
550//usage: "[FILE]..."
551//usage:#define xzcat_full_usage "\n\n"
552//usage: "Decompress to stdout"
553
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100554//config:config UNXZ
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200555//config: bool "unxz (13 kb)"
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100556//config: default y
557//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200558//config: unxz is a unlzma successor.
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100559//config:
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100560//config:config XZCAT
Denys Vlasenko4eed2c62017-07-18 22:01:24 +0200561//config: bool "xzcat (13 kb)"
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100562//config: default y
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100563//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200564//config: Alias to "unxz -c".
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100565//config:
566//config:config XZ
567//config: bool "xz -d"
568//config: default y
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100569//config: help
Denys Vlasenko72089cf2017-07-21 09:50:55 +0200570//config: Enable this option if you want commands like "xz -d" to work.
571//config: IOW: you'll get xz applet, but it will always require -d option.
Denys Vlasenkof6beef62013-11-14 11:39:00 +0100572
Denys Vlasenko36184a42013-11-14 09:54:24 +0100573//applet:IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP))
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100574// APPLET_ODDNAME:name main location suid_type help
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100575//applet:IF_XZCAT(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat))
Denys Vlasenko205d48e2017-01-29 14:57:33 +0100576//applet:IF_XZ( APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz))
Denys Vlasenko66620fa2013-11-14 09:53:52 +0100577//kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100578//kbuild:lib-$(CONFIG_XZCAT) += bbunzip.o
579//kbuild:lib-$(CONFIG_XZ) += bbunzip.o
580#if ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ
Denys Vlasenko602ce692010-05-30 03:35:18 +0200581int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
582int unxz_main(int argc UNUSED_PARAM, char **argv)
583{
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100584 IF_XZ(int opts =) getopt32(argv, BBUNPK_OPTSTR "dt");
Denys Vlasenko602ce692010-05-30 03:35:18 +0200585# if ENABLE_XZ
586 /* xz without -d or -t? */
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100587 if (applet_name[2] == '\0' && !(opts & (BBUNPK_OPT_DECOMPRESS|BBUNPK_OPT_TEST)))
Denys Vlasenko602ce692010-05-30 03:35:18 +0200588 bb_show_usage();
589# endif
590 /* xzcat? */
Denys Vlasenkoeb3fdc82016-11-16 15:45:05 +0100591 if (ENABLE_XZCAT && applet_name[2] == 'c')
Denys Vlasenkod6f0f032018-02-01 09:13:14 +0100592 option_mask32 |= BBUNPK_OPT_STDOUT;
Denys Vlasenko602ce692010-05-30 03:35:18 +0200593
594 argv += optind;
Denys Vlasenkob4c11c12014-12-07 00:44:00 +0100595 return bbunpack(argv, unpack_xz_stream, make_new_name_generic, "xz");
Denys Vlasenko602ce692010-05-30 03:35:18 +0200596}
Denys Vlasenko602ce692010-05-30 03:35:18 +0200597#endif