unbzip2.c revision 199066
1199066Sdelphij/* $NetBSD: unbzip2.c,v 1.12 2009/10/11 05:17:20 mrg Exp $ */ 2166255Sdelphij 3166255Sdelphij/*- 4166255Sdelphij * Copyright (c) 2006 The NetBSD Foundation, Inc. 5166255Sdelphij * All rights reserved. 6166255Sdelphij * 7166255Sdelphij * This code is derived from software contributed to The NetBSD Foundation 8166255Sdelphij * by Simon Burge. 9166255Sdelphij * 10166255Sdelphij * Redistribution and use in source and binary forms, with or without 11166255Sdelphij * modification, are permitted provided that the following conditions 12166255Sdelphij * are met: 13166255Sdelphij * 1. Redistributions of source code must retain the above copyright 14166255Sdelphij * notice, this list of conditions and the following disclaimer. 15166255Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 16166255Sdelphij * notice, this list of conditions and the following disclaimer in the 17166255Sdelphij * documentation and/or other materials provided with the distribution. 18166255Sdelphij * 19166255Sdelphij * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20166255Sdelphij * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21166255Sdelphij * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22166255Sdelphij * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23166255Sdelphij * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24166255Sdelphij * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25166255Sdelphij * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26166255Sdelphij * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27166255Sdelphij * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28166255Sdelphij * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29166255Sdelphij * POSSIBILITY OF SUCH DAMAGE. 30166255Sdelphij * 31166255Sdelphij * $FreeBSD: head/usr.bin/gzip/unbzip2.c 199066 2009-11-09 02:37:02Z delphij $ 32166255Sdelphij */ 33166255Sdelphij 34166255Sdelphij/* This file is #included by gzip.c */ 35166255Sdelphij 36166255Sdelphijstatic off_t 37166255Sdelphijunbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) 38166255Sdelphij{ 39166255Sdelphij int ret, end_of_file; 40166255Sdelphij off_t bytes_out = 0; 41166255Sdelphij bz_stream bzs; 42166255Sdelphij static char *inbuf, *outbuf; 43166255Sdelphij 44166255Sdelphij if (inbuf == NULL) 45166255Sdelphij inbuf = malloc(BUFLEN); 46166255Sdelphij if (outbuf == NULL) 47166255Sdelphij outbuf = malloc(BUFLEN); 48166255Sdelphij if (inbuf == NULL || outbuf == NULL) 49166255Sdelphij maybe_err("malloc"); 50166255Sdelphij 51166255Sdelphij bzs.bzalloc = NULL; 52166255Sdelphij bzs.bzfree = NULL; 53166255Sdelphij bzs.opaque = NULL; 54166255Sdelphij 55166255Sdelphij end_of_file = 0; 56166255Sdelphij ret = BZ2_bzDecompressInit(&bzs, 0, 0); 57166255Sdelphij if (ret != BZ_OK) 58166255Sdelphij maybe_errx("bzip2 init"); 59166255Sdelphij 60166255Sdelphij /* Prepend. */ 61166255Sdelphij bzs.avail_in = prelen; 62166255Sdelphij bzs.next_in = pre; 63166255Sdelphij 64166255Sdelphij if (bytes_in) 65166255Sdelphij *bytes_in = prelen; 66166255Sdelphij 67199066Sdelphij while (ret == BZ_OK) { 68166255Sdelphij if (bzs.avail_in == 0 && !end_of_file) { 69166255Sdelphij ssize_t n; 70166255Sdelphij 71166255Sdelphij n = read(in, inbuf, BUFLEN); 72166255Sdelphij if (n < 0) 73166255Sdelphij maybe_err("read"); 74166255Sdelphij if (n == 0) 75166255Sdelphij end_of_file = 1; 76166255Sdelphij bzs.next_in = inbuf; 77166255Sdelphij bzs.avail_in = n; 78166255Sdelphij if (bytes_in) 79166255Sdelphij *bytes_in += n; 80166255Sdelphij } 81166255Sdelphij 82166255Sdelphij bzs.next_out = outbuf; 83166255Sdelphij bzs.avail_out = BUFLEN; 84166255Sdelphij ret = BZ2_bzDecompress(&bzs); 85166255Sdelphij 86166255Sdelphij switch (ret) { 87166255Sdelphij case BZ_STREAM_END: 88166255Sdelphij case BZ_OK: 89166255Sdelphij if (ret == BZ_OK && end_of_file) 90166255Sdelphij maybe_err("read"); 91199066Sdelphij if (!tflag && bzs.avail_out != BUFLEN) { 92166255Sdelphij ssize_t n; 93166255Sdelphij 94166255Sdelphij n = write(out, outbuf, BUFLEN - bzs.avail_out); 95166255Sdelphij if (n < 0) 96166255Sdelphij maybe_err("write"); 97166255Sdelphij bytes_out += n; 98166255Sdelphij } 99199066Sdelphij if (ret == BZ_STREAM_END && !end_of_file) { 100199066Sdelphij if (BZ2_bzDecompressEnd(&bzs) != BZ_OK || 101199066Sdelphij BZ2_bzDecompressInit(&bzs, 0, 0) != BZ_OK) 102199066Sdelphij maybe_errx("bzip2 re-init"); 103199066Sdelphij ret = BZ_OK; 104199066Sdelphij } 105199066Sdelphij break; 106166255Sdelphij 107166255Sdelphij case BZ_DATA_ERROR: 108166255Sdelphij maybe_warnx("bzip2 data integrity error"); 109166255Sdelphij break; 110166255Sdelphij 111166255Sdelphij case BZ_DATA_ERROR_MAGIC: 112166255Sdelphij maybe_warnx("bzip2 magic number error"); 113166255Sdelphij break; 114166255Sdelphij 115166255Sdelphij case BZ_MEM_ERROR: 116166255Sdelphij maybe_warnx("bzip2 out of memory"); 117166255Sdelphij break; 118199066Sdelphij 119199066Sdelphij default: 120199066Sdelphij maybe_warnx("unknown bzip2 error: %d", ret); 121199066Sdelphij break; 122166255Sdelphij } 123166255Sdelphij } 124166255Sdelphij 125166255Sdelphij if (ret != BZ_STREAM_END || BZ2_bzDecompressEnd(&bzs) != BZ_OK) 126166255Sdelphij return (-1); 127166255Sdelphij 128166255Sdelphij return (bytes_out); 129166255Sdelphij} 130166255Sdelphij 131