/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License (the "License").5* You may not use this file except in compliance with the License.6*7* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE8* or http://www.opensolaris.org/os/licensing.9* See the License for the specific language governing permissions10* and limitations under the License.11*12* When distributing Covered Code, include this CDDL HEADER in each13* file and include the License file at usr/src/OPENSOLARIS.LICENSE.14* If applicable, add the following below this CDDL HEADER, with the15* fields enclosed by brackets "[]" replaced with your own identifying16* information: Portions Copyright [yyyy] [name of copyright owner]17*18* CDDL HEADER END19*/2021/*22* Copyright 2007 Sun Microsystems, Inc. All rights reserved.23* Use is subject to license terms.24*/2526/*27* Portions Copyright 2022 Mikhail Zakharov <[email protected]>28*/2930#include <contrib/zlib/zlib.h>31#include <contrib/zlib/zutil.h>3233static void *34zfs_zcalloc(void *opaque __unused, uint_t items, uint_t size)35{3637return (calloc(items, size));38}3940static void41zfs_zcfree(void *opaque __unused, void *ptr)42{43free(ptr);44}4546/*47* Uncompress the buffer 'src' into the buffer 'dst'. The caller must store48* the expected decompressed data size externally so it can be passed in.49* The resulting decompressed size is then returned through dstlen. This50* function return Z_OK on success, or another error code on failure.51*/52static inline int53z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)54{55z_stream zs;56int err;5758bzero(&zs, sizeof (zs));59zs.next_in = (unsigned char *)src;60zs.avail_in = srclen;61zs.next_out = dst;62zs.avail_out = *dstlen;63zs.zalloc = zfs_zcalloc;64zs.zfree = zfs_zcfree;6566/*67* Call inflateInit2() specifying a window size of DEF_WBITS68* with the 6th bit set to indicate that the compression format69* type (zlib or gzip) should be automatically detected.70*/71if ((err = inflateInit2(&zs, DEF_WBITS | 0x20)) != Z_OK)72return (err);7374if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) {75(void) inflateEnd(&zs);76return (err == Z_OK ? Z_BUF_ERROR : err);77}7879*dstlen = zs.total_out;80return (inflateEnd(&zs));81}8283static int84gzip_decompress(void *s_start, void *d_start, size_t s_len, size_t d_len,85int n __unused)86{87size_t dstlen = d_len;8889ASSERT(d_len >= s_len);9091if (z_uncompress(d_start, &dstlen, s_start, s_len) != Z_OK)92return (-1);9394return (0);95}969798