xref: /illumos-gate/usr/src/uts/common/zmod/zmod.c (revision 7c478bd9)
1 /*
2  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 
8 #include <sys/modctl.h>
9 #include <sys/zmod.h>
10 #include <sys/systm.h>
11 
12 #include "zlib.h"
13 
14 /*
15  * Uncompress the buffer 'src' into the buffer 'dst'.  The caller must store
16  * the expected decompressed data size externally so it can be passed in.
17  * The resulting decompressed size is then returned through dstlen.  This
18  * function return Z_OK on success, or another error code on failure.
19  */
20 int
21 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
22 {
23 	z_stream zs;
24 	int err;
25 
26 	bzero(&zs, sizeof (zs));
27 	zs.next_in = (uchar_t *)src;
28 	zs.avail_in = srclen;
29 	zs.next_out = dst;
30 	zs.avail_out = *dstlen;
31 
32 	if ((err = inflateInit(&zs)) != Z_OK)
33 		return (err);
34 
35 	if ((err = inflate(&zs, Z_FINISH)) != Z_STREAM_END) {
36 		(void) inflateEnd(&zs);
37 		return (err == Z_OK ? Z_BUF_ERROR : err);
38 	}
39 
40 	*dstlen = zs.total_out;
41 	return (inflateEnd(&zs));
42 }
43 
44 static const char *const z_errmsg[] = {
45 	"need dictionary",	/* Z_NEED_DICT		2  */
46 	"stream end",		/* Z_STREAM_END		1  */
47 	"",			/* Z_OK			0  */
48 	"file error",		/* Z_ERRNO		(-1) */
49 	"stream error",		/* Z_STREAM_ERROR	(-2) */
50 	"data error",		/* Z_DATA_ERROR		(-3) */
51 	"insufficient memory",	/* Z_MEM_ERROR		(-4) */
52 	"buffer error",		/* Z_BUF_ERROR		(-5) */
53 	"incompatible version"	/* Z_VERSION_ERROR	(-6) */
54 };
55 
56 /*
57  * Convert a zlib error code into a string error message.
58  */
59 const char *
60 z_strerror(int err)
61 {
62 	int i = Z_NEED_DICT - err;
63 
64 	if (i < 0 || i >= sizeof (z_errmsg) / sizeof (z_errmsg[0]))
65 		return ("unknown error");
66 
67 	return (z_errmsg[i]);
68 }
69 
70 static struct modlmisc modlmisc = {
71 	&mod_miscops, "RFC 1950 decompression routines"
72 };
73 
74 static struct modlinkage modlinkage = {
75 	MODREV_1, &modlmisc, NULL
76 };
77 
78 int
79 _init(void)
80 {
81 	return (mod_install(&modlinkage));
82 }
83 
84 int
85 _info(struct modinfo *mip)
86 {
87 	return (mod_info(&modlinkage, mip));
88 }
89 
90 int
91 _fini(void)
92 {
93 	return (mod_remove(&modlinkage));
94 }
95