1 /*  $Id: zlib.c 10135 2017-01-12 21:09:58Z iulius $
2 **
3 **  COMPRESS functionality.  RFC 8054.
4 */
5 
6 #include "config.h"
7 #include "clibrary.h"
8 
9 #include "inn/messages.h"
10 #include "nnrpd.h"
11 
12 #if defined(HAVE_ZLIB)
13 # define ZBUFSIZE 65536
14 # define MEM_LEVEL 9
15 # define WINDOW_BITS (-15)      /* Raw deflate. */
16 bool compression_layer_on = false;
17 bool tls_compression_on = false;
18 z_stream *zstream_in = NULL;
19 z_stream *zstream_out = NULL;
20 bool zstream_inflate_needed = false;
21 bool zstream_flush_needed = false;
22 unsigned char *zbuf_in = NULL;
23 unsigned char *zbuf_out = NULL;
24 size_t zbuf_in_size = NNTP_MAXLEN_COMMAND;  /* Initial size of the input
25                                              * buffer.  Can be reallocated. */
26 size_t zbuf_in_allocated = 0;
27 size_t zbuf_out_size = ZBUFSIZE;  /* Initial size of the output buffer.
28                                    * Can be reallocated, when needed. */
29 
30 /*
31 **  Wrappers for our memory management functions.
32 */
zalloc(voidpf opaque UNUSED,uInt items,uInt size)33 static voidpf zalloc(voidpf opaque UNUSED, uInt items, uInt size)
34 {
35     return (voidpf) xcalloc(items, size);
36 }
37 
zfree(voidpf opaque UNUSED,voidpf address)38 static void zfree(voidpf opaque UNUSED, voidpf address)
39 {
40     free(address);
41 }
42 
43 
44 /*
45 **  The function called by nnrpd to initialize compression support.  Calls
46 **  both deflateInit2 and inflateInit2, and then checks the result.
47 **
48 **  Returns false on error.
49 */
50 bool
zlib_init(void)51 zlib_init(void)
52 {
53     int result;
54     zstream_in = (z_stream *) xmalloc(sizeof(z_stream));
55     zstream_out = (z_stream *) xmalloc(sizeof(z_stream));
56 
57     /* Allocate the buffer for compressed input data given to inflate(). */
58     zbuf_in = (unsigned char *) xmalloc(zbuf_in_size);
59 
60     /* Allocate the buffer for compressed output data produced by deflate(). */
61     zbuf_out = (unsigned char *) xmalloc(zbuf_out_size);
62 
63     zstream_in->zalloc = zalloc;
64     zstream_in->zfree = zfree;
65     zstream_in->opaque = Z_NULL;
66     zstream_in->next_in = Z_NULL;
67     zstream_in->avail_in = 0;
68 
69     zstream_out->zalloc = zalloc;
70     zstream_out->zfree = zfree;
71     zstream_out->opaque = Z_NULL;
72 
73     result = inflateInit2(zstream_in, WINDOW_BITS);
74 
75     if (result != Z_OK) {
76         syslog(L_NOTICE, "inflateInit2() failed with error %d", result);
77         free(zstream_in);
78         free(zstream_out);
79         free(zbuf_in);
80         free(zbuf_out);
81         return false;
82     }
83 
84     result = deflateInit2(zstream_out, Z_BEST_COMPRESSION, Z_DEFLATED,
85                           WINDOW_BITS, MEM_LEVEL, Z_DEFAULT_STRATEGY);
86 
87     if (result != Z_OK) {
88         syslog(L_NOTICE, "deflateInit2() failed with error %d", result);
89         inflateEnd(zstream_in);
90         free(zstream_in);
91         free(zstream_out);
92         free(zbuf_in);
93         free(zbuf_out);
94         return false;
95     }
96 
97     return true;
98 }
99 
100 #endif /* HAVE_ZLIB */
101