190f528e8SXin LI /* $NetBSD: unbzip2.c,v 1.14 2017/08/04 07:27:08 mrg Exp $ */ 29a9ea25fSXin LI 39a9ea25fSXin LI /*- 4*b61a5730SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 51de7b4b8SPedro F. Giffuni * 69a9ea25fSXin LI * Copyright (c) 2006 The NetBSD Foundation, Inc. 79a9ea25fSXin LI * All rights reserved. 89a9ea25fSXin LI * 99a9ea25fSXin LI * This code is derived from software contributed to The NetBSD Foundation 109a9ea25fSXin LI * by Simon Burge. 119a9ea25fSXin LI * 129a9ea25fSXin LI * Redistribution and use in source and binary forms, with or without 139a9ea25fSXin LI * modification, are permitted provided that the following conditions 149a9ea25fSXin LI * are met: 159a9ea25fSXin LI * 1. Redistributions of source code must retain the above copyright 169a9ea25fSXin LI * notice, this list of conditions and the following disclaimer. 179a9ea25fSXin LI * 2. Redistributions in binary form must reproduce the above copyright 189a9ea25fSXin LI * notice, this list of conditions and the following disclaimer in the 199a9ea25fSXin LI * documentation and/or other materials provided with the distribution. 209a9ea25fSXin LI * 219a9ea25fSXin LI * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 229a9ea25fSXin LI * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 239a9ea25fSXin LI * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 249a9ea25fSXin LI * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 259a9ea25fSXin LI * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 269a9ea25fSXin LI * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 279a9ea25fSXin LI * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 289a9ea25fSXin LI * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 299a9ea25fSXin LI * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 309a9ea25fSXin LI * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 319a9ea25fSXin LI * POSSIBILITY OF SUCH DAMAGE. 329a9ea25fSXin LI * 339a9ea25fSXin LI * $FreeBSD$ 349a9ea25fSXin LI */ 359a9ea25fSXin LI 369a9ea25fSXin LI /* This file is #included by gzip.c */ 379a9ea25fSXin LI 389a9ea25fSXin LI static off_t 399a9ea25fSXin LI unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) 409a9ea25fSXin LI { 41a0b4046bSXin LI int ret, end_of_file, cold = 0; 429a9ea25fSXin LI off_t bytes_out = 0; 439a9ea25fSXin LI bz_stream bzs; 449a9ea25fSXin LI static char *inbuf, *outbuf; 459a9ea25fSXin LI 469a9ea25fSXin LI if (inbuf == NULL) 479a9ea25fSXin LI inbuf = malloc(BUFLEN); 489a9ea25fSXin LI if (outbuf == NULL) 499a9ea25fSXin LI outbuf = malloc(BUFLEN); 509a9ea25fSXin LI if (inbuf == NULL || outbuf == NULL) 519a9ea25fSXin LI maybe_err("malloc"); 529a9ea25fSXin LI 539a9ea25fSXin LI bzs.bzalloc = NULL; 549a9ea25fSXin LI bzs.bzfree = NULL; 559a9ea25fSXin LI bzs.opaque = NULL; 569a9ea25fSXin LI 579a9ea25fSXin LI end_of_file = 0; 589a9ea25fSXin LI ret = BZ2_bzDecompressInit(&bzs, 0, 0); 599a9ea25fSXin LI if (ret != BZ_OK) 609a9ea25fSXin LI maybe_errx("bzip2 init"); 619a9ea25fSXin LI 629a9ea25fSXin LI /* Prepend. */ 639a9ea25fSXin LI bzs.avail_in = prelen; 649a9ea25fSXin LI bzs.next_in = pre; 659a9ea25fSXin LI 669a9ea25fSXin LI if (bytes_in) 679a9ea25fSXin LI *bytes_in = prelen; 689a9ea25fSXin LI 690c10c611SXin LI while (ret == BZ_OK) { 7090f528e8SXin LI check_siginfo(); 719a9ea25fSXin LI if (bzs.avail_in == 0 && !end_of_file) { 729a9ea25fSXin LI ssize_t n; 739a9ea25fSXin LI 749a9ea25fSXin LI n = read(in, inbuf, BUFLEN); 759a9ea25fSXin LI if (n < 0) 769a9ea25fSXin LI maybe_err("read"); 779a9ea25fSXin LI if (n == 0) 789a9ea25fSXin LI end_of_file = 1; 7990f528e8SXin LI infile_newdata(n); 809a9ea25fSXin LI bzs.next_in = inbuf; 819a9ea25fSXin LI bzs.avail_in = n; 829a9ea25fSXin LI if (bytes_in) 839a9ea25fSXin LI *bytes_in += n; 849a9ea25fSXin LI } 859a9ea25fSXin LI 869a9ea25fSXin LI bzs.next_out = outbuf; 879a9ea25fSXin LI bzs.avail_out = BUFLEN; 889a9ea25fSXin LI ret = BZ2_bzDecompress(&bzs); 899a9ea25fSXin LI 909a9ea25fSXin LI switch (ret) { 919a9ea25fSXin LI case BZ_STREAM_END: 929a9ea25fSXin LI case BZ_OK: 93a0b4046bSXin LI if (ret == BZ_OK && end_of_file) { 94a0b4046bSXin LI /* 95a0b4046bSXin LI * If we hit this after a stream end, consider 96a0b4046bSXin LI * it as the end of the whole file and don't 97a0b4046bSXin LI * bail out. 98a0b4046bSXin LI */ 99a0b4046bSXin LI if (cold == 1) 100a0b4046bSXin LI ret = BZ_STREAM_END; 101a0b4046bSXin LI else 102a0b4046bSXin LI maybe_errx("truncated file"); 103a0b4046bSXin LI } 104a0b4046bSXin LI cold = 0; 1050c10c611SXin LI if (!tflag && bzs.avail_out != BUFLEN) { 1069a9ea25fSXin LI ssize_t n; 1079a9ea25fSXin LI 1089a9ea25fSXin LI n = write(out, outbuf, BUFLEN - bzs.avail_out); 1099a9ea25fSXin LI if (n < 0) 1109a9ea25fSXin LI maybe_err("write"); 1119a9ea25fSXin LI bytes_out += n; 1129a9ea25fSXin LI } 1130c10c611SXin LI if (ret == BZ_STREAM_END && !end_of_file) { 1140c10c611SXin LI if (BZ2_bzDecompressEnd(&bzs) != BZ_OK || 1150c10c611SXin LI BZ2_bzDecompressInit(&bzs, 0, 0) != BZ_OK) 1160c10c611SXin LI maybe_errx("bzip2 re-init"); 117a0b4046bSXin LI cold = 1; 1180c10c611SXin LI ret = BZ_OK; 1190c10c611SXin LI } 1209a9ea25fSXin LI break; 1219a9ea25fSXin LI 1229a9ea25fSXin LI case BZ_DATA_ERROR: 1239a9ea25fSXin LI maybe_warnx("bzip2 data integrity error"); 1249a9ea25fSXin LI break; 1259a9ea25fSXin LI 1269a9ea25fSXin LI case BZ_DATA_ERROR_MAGIC: 1279a9ea25fSXin LI maybe_warnx("bzip2 magic number error"); 1289a9ea25fSXin LI break; 1299a9ea25fSXin LI 1309a9ea25fSXin LI case BZ_MEM_ERROR: 1319a9ea25fSXin LI maybe_warnx("bzip2 out of memory"); 1329a9ea25fSXin LI break; 1339a9ea25fSXin LI 1340c10c611SXin LI default: 1350c10c611SXin LI maybe_warnx("unknown bzip2 error: %d", ret); 1360c10c611SXin LI break; 1379a9ea25fSXin LI } 1389a9ea25fSXin LI } 1399a9ea25fSXin LI 1409a9ea25fSXin LI if (ret != BZ_STREAM_END || BZ2_bzDecompressEnd(&bzs) != BZ_OK) 1419a9ea25fSXin LI return (-1); 1429a9ea25fSXin LI 1439a9ea25fSXin LI return (bytes_out); 1449a9ea25fSXin LI } 1459a9ea25fSXin LI 146