blob: 1deac7b53586d14ead0103c8136334a9de670def [file] [log] [blame]
"Robert P. J. Day"63fc1a92006-07-02 19:47:05 +00001/* vi: set sw=4 ts=4: */
Glenn L McGrath60bce492002-11-03 07:28:38 +00002/*
Glenn L McGrathc6992fe2004-04-25 05:11:19 +00003 * Modified for busybox by Glenn McGrath <bug1@iinet.net.au>
Glenn L McGrath60bce492002-11-03 07:28:38 +00004 * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
5 *
Rob Landley0edbad12006-04-17 22:49:30 +00006 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
Glenn L McGrath60bce492002-11-03 07:28:38 +00007 */
Glenn L McGrath24e28332001-10-05 03:48:57 +00008
Glenn L McGrath60bce492002-11-03 07:28:38 +00009#include "busybox.h"
10#include "unarchive.h"
Glenn L McGrath24e28332001-10-05 03:48:57 +000011
Glenn L McGrath6cb3bc02004-01-05 11:49:55 +000012#define BUNZIP2_OPT_STDOUT 1
13#define BUNZIP2_OPT_FORCE 2
14
Denis Vlasenko06af2162007-02-03 17:28:39 +000015int bunzip2_main(int argc, char **argv);
Glenn L McGrath24e28332001-10-05 03:48:57 +000016int bunzip2_main(int argc, char **argv)
17{
Denis Vlasenko97a8dd32006-10-01 15:55:11 +000018 USE_DESKTOP(long long) int status;
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000019 char *filename;
Denis Vlasenko67b23e62006-10-03 21:00:06 +000020 unsigned opt;
Denis Vlasenko97a8dd32006-10-01 15:55:11 +000021 int src_fd, dst_fd;
Glenn L McGrathfff11f12001-11-18 14:20:25 +000022
Denis Vlasenko67b23e62006-10-03 21:00:06 +000023 opt = getopt32(argc, argv, "cf");
Glenn L McGrathfff11f12001-11-18 14:20:25 +000024
Matt Kraai9cdb0602002-03-27 17:31:01 +000025 /* Set input filename and number */
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000026 filename = argv[optind];
Denis Vlasenko9f739442006-12-16 23:49:13 +000027 if (filename && NOT_LONE_DASH(filename)) {
Matt Kraai9cdb0602002-03-27 17:31:01 +000028 /* Open input file */
Rob Landleyd921b2e2006-08-03 15:41:12 +000029 src_fd = xopen(filename, O_RDONLY);
Glenn L McGrath6cb3bc02004-01-05 11:49:55 +000030 } else {
Eric Andersen70060d22004-03-27 10:02:48 +000031 src_fd = STDIN_FILENO;
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000032 filename = 0;
Glenn L McGrath24e28332001-10-05 03:48:57 +000033 }
Rob Landleyb7128c62005-09-11 01:05:30 +000034
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000035 /* if called as bzcat force the stdout flag */
Denis Vlasenko8f8f2682006-10-03 21:00:43 +000036 if ((opt & BUNZIP2_OPT_STDOUT) || applet_name[2] == 'c')
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000037 filename = 0;
Glenn L McGrathfff11f12001-11-18 14:20:25 +000038
Matt Kraai9cdb0602002-03-27 17:31:01 +000039 /* Check that the input is sane. */
Glenn L McGrath6cb3bc02004-01-05 11:49:55 +000040 if (isatty(src_fd) && (opt & BUNZIP2_OPT_FORCE) == 0) {
Denis Vlasenko9c267b82006-10-12 20:06:18 +000041 bb_error_msg_and_die("compressed data not read from terminal, "
42 "use -f to force it");
Glenn L McGrathfff11f12001-11-18 14:20:25 +000043 }
Glenn L McGrath24e28332001-10-05 03:48:57 +000044
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000045 if (filename) {
Rob Landley9a202c92006-06-13 14:54:42 +000046 struct stat stat_buf;
Denis Vlasenko22dca232006-09-03 14:23:29 +000047 /* extension = filename+strlen(filename)-4 is buggy:
48 * strlen may be less than 4 */
49 char *extension = strrchr(filename, '.');
50 if (!extension || strcmp(extension, ".bz2") != 0) {
Denis Vlasenkoce979602006-09-27 23:31:08 +000051 bb_error_msg_and_die("invalid extension");
Glenn L McGrath6cb3bc02004-01-05 11:49:55 +000052 }
Rob Landleyc4b67392006-06-13 16:09:16 +000053 xstat(filename, &stat_buf);
Denis Vlasenko22dca232006-09-03 14:23:29 +000054 *extension = '\0';
55 dst_fd = xopen3(filename, O_WRONLY | O_CREAT | O_TRUNC,
56 stat_buf.st_mode);
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000057 } else dst_fd = STDOUT_FILENO;
Glenn L McGrathf235d052003-10-29 03:37:54 +000058 status = uncompressStream(src_fd, dst_fd);
Denis Vlasenkoce979602006-09-27 23:31:08 +000059 if (filename) {
Denis Vlasenko97a8dd32006-10-01 15:55:11 +000060 if (status >= 0) filename[strlen(filename)] = '.';
Rob Landleyc8b8a2d2005-08-30 20:26:17 +000061 if (unlink(filename) < 0) {
Denis Vlasenkoce979602006-09-27 23:31:08 +000062 bb_error_msg_and_die("cannot remove %s", filename);
Glenn L McGrath6cb3bc02004-01-05 11:49:55 +000063 }
Matt Kraaicf32ac52002-03-27 17:46:44 +000064 }
65
66 return status;
Glenn L McGrath24e28332001-10-05 03:48:57 +000067}