summaryrefslogtreecommitdiff
path: root/librpc
diff options
context:
space:
mode:
authorAurelien Aptel <aaptel@suse.com>2017-05-23 12:02:33 +0200
committerJeremy Allison <jra@samba.org>2017-07-19 21:22:13 +0200
commit1edf126693b8bafe5f94a6ab4d34e0d21a05cb3d (patch)
treed01aa0df57a21d088e0ea1cc426bdcb5b3ae0877 /librpc
parent096efc93df490117b1de3bd2647bad52a7175a7f (diff)
downloadsamba-1edf126693b8bafe5f94a6ab4d34e0d21a05cb3d.tar.gz
librpc/ndr: add helper functions to setup and free compression states.
Signed-off-by: Aurelien Aptel <aaptel@suse.com> Reviewed-by: Guenther Deschner <gd@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'librpc')
-rw-r--r--librpc/ndr/ndr_compression.c145
-rw-r--r--librpc/ndr/ndr_compression.h10
2 files changed, 155 insertions, 0 deletions
diff --git a/librpc/ndr/ndr_compression.c b/librpc/ndr/ndr_compression.c
index b2cb4341058..b0408d58a15 100644
--- a/librpc/ndr/ndr_compression.c
+++ b/librpc/ndr/ndr_compression.c
@@ -524,3 +524,148 @@ enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr,
talloc_free(uncomndr);
return NDR_ERR_SUCCESS;
}
+
+static enum ndr_err_code generic_mszip_init(TALLOC_CTX *mem_ctx,
+ struct ndr_compression_state *state)
+{
+ z_stream *z = talloc_zero(mem_ctx, z_stream);
+ NDR_ERR_HAVE_NO_MEMORY(z);
+
+ z->zalloc = ndr_zlib_alloc;
+ z->zfree = ndr_zlib_free;
+ z->opaque = mem_ctx;
+
+ state->mszip.z = z;
+ state->mszip.dict_size = 0;
+ /* pre-alloc dictionnary */
+ state->mszip.dict = talloc_array(mem_ctx, uint8_t, 0x8000);
+ NDR_ERR_HAVE_NO_MEMORY(state->mszip.dict);
+
+ return NDR_ERR_SUCCESS;
+}
+
+static void generic_mszip_free(struct ndr_compression_state *state)
+{
+ if (state == NULL) {
+ return;
+ }
+
+ TALLOC_FREE(state->mszip.z);
+ TALLOC_FREE(state->mszip.dict);
+}
+
+
+enum ndr_err_code ndr_pull_compression_state_init(struct ndr_pull *ndr,
+ enum ndr_compression_alg compression_alg,
+ struct ndr_compression_state **state)
+{
+ struct ndr_compression_state *s;
+ int z_ret;
+
+ s = talloc_zero(ndr, struct ndr_compression_state);
+ NDR_ERR_HAVE_NO_MEMORY(s);
+ s->type = compression_alg;
+
+ switch (compression_alg) {
+ case NDR_COMPRESSION_MSZIP:
+ case NDR_COMPRESSION_XPRESS:
+ break;
+ case NDR_COMPRESSION_MSZIP_CAB:
+ NDR_CHECK(generic_mszip_init(ndr, s));
+ z_ret = inflateInit2(s->mszip.z, -MAX_WBITS);
+ if (z_ret != Z_OK) {
+ return ndr_pull_error(ndr, NDR_ERR_COMPRESSION,
+ "zlib inflateinit2 error %s (%d) %s (PULL)",
+ zError(z_ret), z_ret, s->mszip.z->msg);
+ }
+ break;
+ default:
+ return ndr_pull_error(ndr, NDR_ERR_COMPRESSION,
+ "Bad compression algorithm %d (PULL)",
+ compression_alg);
+ break;
+ }
+
+ *state = s;
+
+ return NDR_ERR_SUCCESS;
+}
+
+void ndr_pull_compression_state_free(struct ndr_compression_state *state)
+{
+ if (state == NULL) {
+ return;
+ }
+
+ switch (state->type) {
+ case NDR_COMPRESSION_MSZIP:
+ case NDR_COMPRESSION_XPRESS:
+ break;
+ case NDR_COMPRESSION_MSZIP_CAB:
+ generic_mszip_free(state);
+ break;
+ default:
+ break;
+ }
+ TALLOC_FREE(state);
+}
+
+enum ndr_err_code ndr_push_compression_state_init(struct ndr_push *ndr,
+ enum ndr_compression_alg compression_alg,
+ struct ndr_compression_state **state)
+{
+ struct ndr_compression_state *s;
+ int z_ret;
+
+ s = talloc_zero(ndr, struct ndr_compression_state);
+ NDR_ERR_HAVE_NO_MEMORY(s);
+ s->type = compression_alg;
+
+ switch (compression_alg) {
+ case NDR_COMPRESSION_XPRESS:
+ case NDR_COMPRESSION_MSZIP:
+ break;
+ case NDR_COMPRESSION_MSZIP_CAB:
+ NDR_CHECK(generic_mszip_init(ndr, s));
+ z_ret = deflateInit2(s->mszip.z,
+ Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED,
+ -MAX_WBITS,
+ 8, /* memLevel */
+ Z_DEFAULT_STRATEGY);
+ if (z_ret != Z_OK) {
+ return ndr_push_error(ndr, NDR_ERR_COMPRESSION,
+ "zlib inflateinit2 error %s (%d) %s (PUSH)",
+ zError(z_ret), z_ret, s->mszip.z->msg);
+ }
+ break;
+ default:
+ return ndr_push_error(ndr, NDR_ERR_COMPRESSION,
+ "Bad compression algorithm %d (PUSH)",
+ compression_alg);
+ break;
+ }
+
+ *state = s;
+
+ return NDR_ERR_SUCCESS;
+}
+
+void ndr_push_compression_state_free(struct ndr_compression_state *state)
+{
+ if (state == NULL) {
+ return;
+ }
+
+ switch (state->type) {
+ case NDR_COMPRESSION_MSZIP:
+ case NDR_COMPRESSION_XPRESS:
+ break;
+ case NDR_COMPRESSION_MSZIP_CAB:
+ generic_mszip_free(state);
+ break;
+ default:
+ break;
+ }
+ TALLOC_FREE(state);
+}
diff --git a/librpc/ndr/ndr_compression.h b/librpc/ndr/ndr_compression.h
index d682d4d3693..a67a73ed7d6 100644
--- a/librpc/ndr/ndr_compression.h
+++ b/librpc/ndr/ndr_compression.h
@@ -51,6 +51,16 @@ enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr,
struct ndr_push *uncomndr,
enum ndr_compression_alg compression_alg,
ssize_t decompressed_len);
+
+enum ndr_err_code ndr_pull_compression_state_init(struct ndr_pull *ndr,
+ enum ndr_compression_alg compression_alg,
+ struct ndr_compression_state **state);
+void ndr_pull_compression_state_free(struct ndr_compression_state *state);
+enum ndr_err_code ndr_push_compression_state_init(struct ndr_push *ndr,
+ enum ndr_compression_alg compression_alg,
+ struct ndr_compression_state **state);
+void ndr_push_compression_state_free(struct ndr_compression_state *state);
+
#undef _PRINTF_ATTRIBUTE
#define _PRINTF_ATTRIBUTE(a1, a2)