unbzip2.c revision 166255
1256904Sray/* $NetBSD: unbzip2.c,v 1.10 2006/10/03 08:20:03 simonb Exp $ */ 2256904Sray 3256904Sray/*- 4256904Sray * Copyright (c) 2006 The NetBSD Foundation, Inc. 5256904Sray * All rights reserved. 6256904Sray * 7256904Sray * This code is derived from software contributed to The NetBSD Foundation 8256904Sray * by Simon Burge. 9256904Sray * 10256904Sray * Redistribution and use in source and binary forms, with or without 11256904Sray * modification, are permitted provided that the following conditions 12256904Sray * are met: 13256904Sray * 1. Redistributions of source code must retain the above copyright 14256904Sray * notice, this list of conditions and the following disclaimer. 15256904Sray * 2. Redistributions in binary form must reproduce the above copyright 16256904Sray * notice, this list of conditions and the following disclaimer in the 17256904Sray * documentation and/or other materials provided with the distribution. 18256904Sray * 3. All advertising materials mentioning features or use of this software 19256904Sray * must display the following acknowledgement: 20256904Sray * This product includes software developed by the NetBSD 21256904Sray * Foundation, Inc. and its contributors. 22256904Sray * 4. Neither the name of The NetBSD Foundation nor the names of its 23256904Sray * contributors may be used to endorse or promote products derived 24256904Sray * from this software without specific prior written permission. 25256904Sray * 26256904Sray * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27256904Sray * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28256904Sray * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29256904Sray * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30256904Sray * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31256904Sray * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32256904Sray * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33256904Sray * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34256904Sray * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35256904Sray * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36256904Sray * POSSIBILITY OF SUCH DAMAGE. 37256904Sray * 38256904Sray * $FreeBSD: head/usr.bin/gzip/unbzip2.c 166255 2007-01-26 10:19:08Z delphij $ 39256904Sray */ 40256904Sray 41256904Sray/* This file is #included by gzip.c */ 42256904Sray 43256904Sraystatic off_t 44256904Srayunbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) 45256904Sray{ 46256904Sray int ret, end_of_file; 47256904Sray off_t bytes_out = 0; 48256904Sray bz_stream bzs; 49256904Sray static char *inbuf, *outbuf; 50256904Sray 51256904Sray if (inbuf == NULL) 52257725Sray inbuf = malloc(BUFLEN); 53256904Sray if (outbuf == NULL) 54256904Sray outbuf = malloc(BUFLEN); 55256904Sray if (inbuf == NULL || outbuf == NULL) 56256904Sray maybe_err("malloc"); 57256904Sray 58256904Sray bzs.bzalloc = NULL; 59256904Sray bzs.bzfree = NULL; 60256904Sray bzs.opaque = NULL; 61257725Sray 62256904Sray end_of_file = 0; 63256904Sray ret = BZ2_bzDecompressInit(&bzs, 0, 0); 64256904Sray if (ret != BZ_OK) 65256904Sray maybe_errx("bzip2 init"); 66256904Sray 67256904Sray /* Prepend. */ 68256904Sray bzs.avail_in = prelen; 69256904Sray bzs.next_in = pre; 70256904Sray 71256904Sray if (bytes_in) 72256904Sray *bytes_in = prelen; 73256904Sray 74256904Sray while (ret >= BZ_OK && ret != BZ_STREAM_END) { 75256904Sray if (bzs.avail_in == 0 && !end_of_file) { 76256904Sray ssize_t n; 77256904Sray 78256904Sray n = read(in, inbuf, BUFLEN); 79256904Sray if (n < 0) 80256904Sray maybe_err("read"); 81256904Sray if (n == 0) 82256904Sray end_of_file = 1; 83256904Sray bzs.next_in = inbuf; 84256904Sray bzs.avail_in = n; 85256904Sray if (bytes_in) 86256904Sray *bytes_in += n; 87256904Sray } 88256904Sray 89257013Sray bzs.next_out = outbuf; 90257013Sray bzs.avail_out = BUFLEN; 91256904Sray ret = BZ2_bzDecompress(&bzs); 92256904Sray 93256904Sray switch (ret) { 94257725Sray case BZ_STREAM_END: 95257988Sray case BZ_OK: 96257988Sray if (ret == BZ_OK && end_of_file) 97257988Sray maybe_err("read"); 98256904Sray if (!tflag) { 99256904Sray ssize_t n; 100256904Sray 101256904Sray n = write(out, outbuf, BUFLEN - bzs.avail_out); 102256904Sray if (n < 0) 103257988Sray maybe_err("write"); 104257988Sray bytes_out += n; 105256904Sray } 106256904Sray break; 107256904Sray 108256904Sray case BZ_DATA_ERROR: 109256904Sray maybe_warnx("bzip2 data integrity error"); 110257988Sray break; 111257988Sray 112256904Sray case BZ_DATA_ERROR_MAGIC: 113257988Sray maybe_warnx("bzip2 magic number error"); 114257988Sray break; 115257988Sray 116257988Sray case BZ_MEM_ERROR: 117257988Sray maybe_warnx("bzip2 out of memory"); 118256904Sray break; 119256904Sray 120257988Sray } 121256904Sray } 122256904Sray 123257988Sray if (ret != BZ_STREAM_END || BZ2_bzDecompressEnd(&bzs) != BZ_OK) 124256904Sray return (-1); 125256904Sray 126257988Sray return (bytes_out); 127257988Sray} 128257988Sray 129257988Sray