1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2015 Toomas Soome <tsoome@me.com>
14 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
15 * Use is subject to license terms.
16 */
17
18 #include <zlib.h>
19 #include <strings.h>
20
21 int gzip_decompress(void *, void *, size_t, size_t, int);
22 /*
23 * Uncompress the buffer 'src' into the buffer 'dst'. The caller must store
24 * the expected decompressed data size externally so it can be passed in.
25 * The resulting decompressed size is then returned through dstlen. This
26 * function return Z_OK on success, or another error code on failure.
27 */
28 static int
z_uncompress(void * dst,size_t * dstlen,const void * src,size_t srclen)29 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
30 {
31 z_stream zs;
32 int err;
33
34 bzero(&zs, sizeof (zs));
35 zs.next_in = (unsigned char *)src;
36 zs.avail_in = srclen;
37 zs.next_out = dst;
38 zs.avail_out = *dstlen;
39
40 /*
41 * Call inflateInit2() specifying a window size of DEF_WBITS
42 * with the 6th bit set to indicate that the compression format
43 * type (zlib or gzip) should be automatically detected.
44 */
45 if ((err = inflateInit2(&zs, 15 | 0x20)) != Z_OK)
46 return (err);
47
48 if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) {
49 (void) inflateEnd(&zs);
50 return (err == Z_OK ? Z_BUF_ERROR : err);
51 }
52
53 *dstlen = zs.total_out;
54 return (inflateEnd(&zs));
55 }
56
57 int
gzip_decompress(void * s_start,void * d_start,size_t s_len,size_t d_len,int n __unused)58 gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len,
59 int n __unused)
60 {
61 size_t dstlen = d_len;
62
63 if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK)
64 return (-1);
65
66 return (0);
67 }
68