1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Portions Copyright 2022 Mikhail Zakharov <zmey20000@yahoo.com> 29 */ 30 31 #include <contrib/zlib/zlib.h> 32 #include <contrib/zlib/zutil.h> 33 34 static void * 35 zfs_zcalloc(void *opaque __unused, uint_t items, uint_t size) 36 { 37 38 return (calloc(items, size)); 39 } 40 41 static void 42 zfs_zcfree(void *opaque __unused, void *ptr) 43 { 44 free(ptr); 45 } 46 47 /* 48 * Uncompress the buffer 'src' into the buffer 'dst'. The caller must store 49 * the expected decompressed data size externally so it can be passed in. 50 * The resulting decompressed size is then returned through dstlen. This 51 * function return Z_OK on success, or another error code on failure. 52 */ 53 static inline int 54 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen) 55 { 56 z_stream zs; 57 int err; 58 59 bzero(&zs, sizeof (zs)); 60 zs.next_in = (unsigned char *)src; 61 zs.avail_in = srclen; 62 zs.next_out = dst; 63 zs.avail_out = *dstlen; 64 zs.zalloc = zfs_zcalloc; 65 zs.zfree = zfs_zcfree; 66 67 /* 68 * Call inflateInit2() specifying a window size of DEF_WBITS 69 * with the 6th bit set to indicate that the compression format 70 * type (zlib or gzip) should be automatically detected. 71 */ 72 if ((err = inflateInit2(&zs, DEF_WBITS | 0x20)) != Z_OK) 73 return (err); 74 75 if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) { 76 (void) inflateEnd(&zs); 77 return (err == Z_OK ? Z_BUF_ERROR : err); 78 } 79 80 *dstlen = zs.total_out; 81 return (inflateEnd(&zs)); 82 } 83 84 static int 85 gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len, 86 int n __unused) 87 { 88 size_t dstlen = d_len; 89 90 ASSERT(d_len >= s_len); 91 92 if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK) 93 return (-1); 94 95 return (0); 96 } 97