1 /* $NetBSD: unbzip2.c,v 1.11 2008/04/28 20:24:13 martin Exp $ */ 2 /* $DragonFly: src/usr.bin/gzip/unbzip2.c,v 1.1 2004/10/26 11:19:31 joerg Exp $ */ 3 4 /*- 5 * Copyright (c) 2006 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Simon Burge. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* This file is #included by gzip.c */ 34 35 static off_t 36 unbzip2(int in, int out, char *pre, size_t prelen, off_t *bytes_in) 37 { 38 int ret, end_of_file; 39 off_t bytes_out = 0; 40 bz_stream bzs; 41 static char *inbuf, *outbuf; 42 43 if (inbuf == NULL) 44 inbuf = malloc(BUFLEN); 45 if (outbuf == NULL) 46 outbuf = malloc(BUFLEN); 47 if (inbuf == NULL || outbuf == NULL) 48 maybe_err("malloc"); 49 50 bzs.bzalloc = NULL; 51 bzs.bzfree = NULL; 52 bzs.opaque = NULL; 53 54 end_of_file = 0; 55 ret = BZ2_bzDecompressInit(&bzs, 0, 0); 56 if (ret != BZ_OK) 57 maybe_errx("bzip2 init"); 58 59 /* Prepend. */ 60 bzs.avail_in = prelen; 61 bzs.next_in = pre; 62 63 if (bytes_in) 64 *bytes_in = prelen; 65 66 while (ret >= BZ_OK && ret != BZ_STREAM_END) { 67 if (bzs.avail_in == 0 && !end_of_file) { 68 ssize_t n; 69 70 n = read(in, inbuf, BUFLEN); 71 if (n < 0) 72 maybe_err("read"); 73 if (n == 0) 74 end_of_file = 1; 75 bzs.next_in = inbuf; 76 bzs.avail_in = n; 77 if (bytes_in) 78 *bytes_in += n; 79 } 80 81 bzs.next_out = outbuf; 82 bzs.avail_out = BUFLEN; 83 ret = BZ2_bzDecompress(&bzs); 84 85 switch (ret) { 86 case BZ_STREAM_END: 87 case BZ_OK: 88 if (ret == BZ_OK && end_of_file) 89 maybe_err("read"); 90 if (!tflag) { 91 ssize_t n; 92 93 n = write(out, outbuf, BUFLEN - bzs.avail_out); 94 if (n < 0) 95 maybe_err("write"); 96 bytes_out += n; 97 } 98 break; 99 100 case BZ_DATA_ERROR: 101 maybe_warnx("bzip2 data integrity error"); 102 break; 103 104 case BZ_DATA_ERROR_MAGIC: 105 maybe_warnx("bzip2 magic number error"); 106 break; 107 108 case BZ_MEM_ERROR: 109 maybe_warnx("bzip2 out of memory"); 110 break; 111 112 } 113 } 114 115 if (ret != BZ_STREAM_END || BZ2_bzDecompressEnd(&bzs) != BZ_OK) 116 return (-1); 117 118 return (bytes_out); 119 } 120