Mercurial > dovecot > core-2.2
annotate src/lib-compression/ostream-zlib.c @ 23017:c1d36f2575c7 default tip
lib-imap: Fix "Don't accept strings with NULs" cherry-pick
author | Timo Sirainen <timo.sirainen@open-xchange.com> |
---|---|
date | Thu, 29 Aug 2019 09:55:25 +0300 |
parents | cb108f786fb4 |
children |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21390
diff
changeset
|
1 /* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */ |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
5 #ifdef HAVE_ZLIB |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 #include "crc32.h" |
13529
cf77e448295c
Renamed lib/*-internal.h files to lib/*-private.h for consistency.
Timo Sirainen <tss@iki.fi>
parents:
13417
diff
changeset
|
8 #include "ostream-private.h" |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 #include "ostream-zlib.h" |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include <zlib.h> |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 #define CHUNK_SIZE (1024*32) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #define ZLIB_OS_CODE 0x03 /* Unix */ |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
14 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
15 struct zlib_ostream { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 struct ostream_private ostream; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 z_stream zs; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
19 unsigned char gz_header[10]; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
20 unsigned char outbuf[CHUNK_SIZE]; |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
21 unsigned int outbuf_offset, outbuf_used; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
22 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
23 uint32_t crc, bytes32; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
24 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
25 unsigned int gz:1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 unsigned int header_sent:1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 unsigned int flushed:1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 }; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
29 |
16020
6cabb95d32ec
iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
30 static void o_stream_zlib_close(struct iostream_private *stream, |
6cabb95d32ec
iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
31 bool close_parent) |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
32 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 struct zlib_ostream *zstream = (struct zlib_ostream *)stream; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 |
14681
ca37d1577291
Added o_stream_nsend*() and related functions to make delayed error handling safer.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
35 (void)o_stream_flush(&zstream->ostream.ostream); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
36 (void)deflateEnd(&zstream->zs); |
16020
6cabb95d32ec
iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
37 if (close_parent) |
6cabb95d32ec
iostreams: Added close_parent flag to close() handler and clarified close/destroy APIs.
Timo Sirainen <tss@iki.fi>
parents:
15715
diff
changeset
|
38 o_stream_close(zstream->ostream.parent); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
39 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
40 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
41 static int o_stream_zlib_send_gz_header(struct zlib_ostream *zstream) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
42 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
43 ssize_t ret; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
44 |
13530
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
45 ret = o_stream_send(zstream->ostream.parent, zstream->gz_header, |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 sizeof(zstream->gz_header)); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
47 if ((size_t)ret != sizeof(zstream->gz_header)) { |
13530
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
48 o_stream_copy_error_from_parent(&zstream->ostream); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
49 return -1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
51 zstream->header_sent = TRUE; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
52 return 0; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
53 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
54 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
55 static int o_stream_zlib_lsb_uint32(struct ostream *output, uint32_t num) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 unsigned char buf[sizeof(uint32_t)]; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 unsigned int i; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
59 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
60 for (i = 0; i < sizeof(buf); i++) { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 buf[i] = num & 0xff; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
62 num >>= 8; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
63 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
64 if (o_stream_send(output, buf, sizeof(buf)) != sizeof(buf)) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 return -1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
66 return 0; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 static int o_stream_zlib_send_gz_trailer(struct zlib_ostream *zstream) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
70 { |
13530
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
71 struct ostream *output = zstream->ostream.parent; |
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
72 |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
73 if (!zstream->gz) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 return 0; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 |
13530
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
76 if (o_stream_zlib_lsb_uint32(output, zstream->crc) < 0 || |
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
77 o_stream_zlib_lsb_uint32(output, zstream->bytes32) < 0) { |
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
78 o_stream_copy_error_from_parent(&zstream->ostream); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
79 return -1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
80 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
81 return 0; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
82 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
83 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
84 static int o_stream_zlib_send_outbuf(struct zlib_ostream *zstream) |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
85 { |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
86 ssize_t ret; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
87 size_t size; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
88 |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
89 if (zstream->outbuf_used == 0) |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
90 return 1; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
91 |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
92 size = zstream->outbuf_used - zstream->outbuf_offset; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
93 i_assert(size > 0); |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
94 ret = o_stream_send(zstream->ostream.parent, |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
95 zstream->outbuf + zstream->outbuf_offset, size); |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
96 if (ret < 0) { |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
97 o_stream_copy_error_from_parent(&zstream->ostream); |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
98 return -1; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
99 } |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
100 if ((size_t)ret != size) { |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
101 zstream->outbuf_offset += ret; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
102 return 0; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
103 } |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
104 zstream->outbuf_offset = 0; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
105 zstream->outbuf_used = 0; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
106 return 1; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
107 } |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
108 |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
109 static ssize_t |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
110 o_stream_zlib_send_chunk(struct zlib_ostream *zstream, |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
111 const void *data, size_t size) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
112 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
113 z_stream *zs = &zstream->zs; |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
114 int ret, flush; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
115 |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
116 i_assert(zstream->outbuf_used == 0); |
10709
52e1f46fe0ba
zlib: If writing without being corked, flush the stream.
Timo Sirainen <tss@iki.fi>
parents:
10698
diff
changeset
|
117 |
52e1f46fe0ba
zlib: If writing without being corked, flush the stream.
Timo Sirainen <tss@iki.fi>
parents:
10698
diff
changeset
|
118 flush = zstream->ostream.corked || zstream->gz ? |
52e1f46fe0ba
zlib: If writing without being corked, flush the stream.
Timo Sirainen <tss@iki.fi>
parents:
10698
diff
changeset
|
119 Z_NO_FLUSH : Z_SYNC_FLUSH; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
120 |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
121 if (!zstream->header_sent) { |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
122 if (o_stream_zlib_send_gz_header(zstream) < 0) |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
123 return -1; |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
124 } |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
125 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
126 zs->next_in = (void *)data; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
127 zs->avail_in = size; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
128 while (zs->avail_in > 0) { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
129 if (zs->avail_out == 0) { |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
130 /* previous block was compressed. send it and start |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
131 compression for a new block. */ |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
132 zs->next_out = zstream->outbuf; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
133 zs->avail_out = sizeof(zstream->outbuf); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
134 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
135 zstream->outbuf_used = sizeof(zstream->outbuf); |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
136 if ((ret = o_stream_zlib_send_outbuf(zstream)) < 0) |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
137 return -1; |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
138 if (ret == 0) { |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
139 /* parent stream's buffer full */ |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
140 break; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
141 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
142 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
144 ret = deflate(zs, flush); |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
145 switch (ret) { |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
146 case Z_OK: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
147 case Z_BUF_ERROR: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
148 break; |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
149 case Z_STREAM_ERROR: |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
150 i_assert(zstream->gz); |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
151 i_panic("zlib.write(%s) failed: Can't write more data to .gz after flushing", |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
152 o_stream_get_name(&zstream->ostream.ostream)); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
153 default: |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
154 i_panic("zlib.write(%s) failed with unexpected code %d", |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
155 o_stream_get_name(&zstream->ostream.ostream), ret); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
156 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
157 } |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
158 size -= zs->avail_in; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
159 |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
160 zstream->crc = crc32_data_more(zstream->crc, data, size); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
161 zstream->bytes32 += size; |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
162 zstream->flushed = flush == Z_SYNC_FLUSH && zs->avail_in == 0 && |
12707
b71834419ea3
zlib: Make sure output stream flushes the stream automatically when not corked.
Timo Sirainen <tss@iki.fi>
parents:
12408
diff
changeset
|
163 zs->avail_out == sizeof(zstream->outbuf); |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
164 return size; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
165 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
166 |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
167 static int |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
168 o_stream_zlib_send_flush(struct zlib_ostream *zstream, bool final) |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
169 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
170 z_stream *zs = &zstream->zs; |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
171 size_t len; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
172 bool done = FALSE; |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
173 int ret, flush; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
174 |
13837
aefc17d5b99e
zlib: Avoid assert-crashing if parent ostream's write had failed earlier.
Timo Sirainen <tss@iki.fi>
parents:
13530
diff
changeset
|
175 if (zs->avail_in != 0) { |
aefc17d5b99e
zlib: Avoid assert-crashing if parent ostream's write had failed earlier.
Timo Sirainen <tss@iki.fi>
parents:
13530
diff
changeset
|
176 i_assert(zstream->ostream.ostream.last_failed_errno != 0); |
aefc17d5b99e
zlib: Avoid assert-crashing if parent ostream's write had failed earlier.
Timo Sirainen <tss@iki.fi>
parents:
13530
diff
changeset
|
177 zstream->ostream.ostream.stream_errno = |
aefc17d5b99e
zlib: Avoid assert-crashing if parent ostream's write had failed earlier.
Timo Sirainen <tss@iki.fi>
parents:
13530
diff
changeset
|
178 zstream->ostream.ostream.last_failed_errno; |
aefc17d5b99e
zlib: Avoid assert-crashing if parent ostream's write had failed earlier.
Timo Sirainen <tss@iki.fi>
parents:
13530
diff
changeset
|
179 return -1; |
aefc17d5b99e
zlib: Avoid assert-crashing if parent ostream's write had failed earlier.
Timo Sirainen <tss@iki.fi>
parents:
13530
diff
changeset
|
180 } |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
181 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
182 if (zstream->flushed) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
183 return 0; |
17591
00b3aa3842b7
lib-compression: Compression ostreams may have caused parent ostream to use too much memory.
Timo Sirainen <tss@iki.fi>
parents:
17328
diff
changeset
|
184 |
00b3aa3842b7
lib-compression: Compression ostreams may have caused parent ostream to use too much memory.
Timo Sirainen <tss@iki.fi>
parents:
17328
diff
changeset
|
185 if ((ret = o_stream_flush_parent_if_needed(&zstream->ostream)) <= 0) |
00b3aa3842b7
lib-compression: Compression ostreams may have caused parent ostream to use too much memory.
Timo Sirainen <tss@iki.fi>
parents:
17328
diff
changeset
|
186 return ret; |
14682
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
187 if (!zstream->header_sent) { |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
188 if (o_stream_zlib_send_gz_header(zstream) < 0) |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
189 return -1; |
d0d7b810646b
Make sure we check all the functions' return values. Minor API changes to simplify this.
Timo Sirainen <tss@iki.fi>
parents:
14681
diff
changeset
|
190 } |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
191 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
192 if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
193 return ret; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
194 |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
195 flush = !zstream->gz ? Z_SYNC_FLUSH : |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
196 (final ? Z_FINISH : Z_NO_FLUSH); |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
197 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
198 i_assert(zstream->outbuf_used == 0); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
199 do { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
200 len = sizeof(zstream->outbuf) - zs->avail_out; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
201 if (len != 0) { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
202 zs->next_out = zstream->outbuf; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
203 zs->avail_out = sizeof(zstream->outbuf); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
204 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
205 zstream->outbuf_used = len; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
206 if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
207 return ret; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
208 if (done) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
209 break; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
210 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
211 |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
212 switch (deflate(zs, flush)) { |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
213 case Z_OK: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
214 case Z_BUF_ERROR: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
215 break; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
216 case Z_STREAM_END: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
217 done = TRUE; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
218 break; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
219 default: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
220 i_unreached(); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
221 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
222 } while (zs->avail_out != sizeof(zstream->outbuf)); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
223 |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
224 if (final) { |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
225 if (o_stream_zlib_send_gz_trailer(zstream) < 0) |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
226 return -1; |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
227 } |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
228 if (final || flush != Z_NO_FLUSH) |
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
229 zstream->flushed = TRUE; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
230 return 0; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
231 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
232 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
233 static int o_stream_zlib_flush(struct ostream_private *stream) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
234 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
235 struct zlib_ostream *zstream = (struct zlib_ostream *)stream; |
11226
c8f4cb187343
zlib: Fixed zlib/bzlib ostream flushing to report correctly when it's finished.
Timo Sirainen <tss@iki.fi>
parents:
10709
diff
changeset
|
236 int ret; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
237 |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
238 if (o_stream_zlib_send_flush(zstream, TRUE) < 0) |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
239 return -1; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
240 |
13530
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
241 ret = o_stream_flush(stream->parent); |
11226
c8f4cb187343
zlib: Fixed zlib/bzlib ostream flushing to report correctly when it's finished.
Timo Sirainen <tss@iki.fi>
parents:
10709
diff
changeset
|
242 if (ret < 0) |
13530
8c3c0e01e00d
Simplified creating filter ostreams.
Timo Sirainen <tss@iki.fi>
parents:
13529
diff
changeset
|
243 o_stream_copy_error_from_parent(stream); |
11226
c8f4cb187343
zlib: Fixed zlib/bzlib ostream flushing to report correctly when it's finished.
Timo Sirainen <tss@iki.fi>
parents:
10709
diff
changeset
|
244 return ret; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
245 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
246 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
247 static ssize_t |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
248 o_stream_zlib_sendv(struct ostream_private *stream, |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
249 const struct const_iovec *iov, unsigned int iov_count) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
250 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
251 struct zlib_ostream *zstream = (struct zlib_ostream *)stream; |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
252 ssize_t ret, bytes = 0; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
253 unsigned int i; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
254 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
255 if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) { |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
256 /* error / we still couldn't flush existing data to |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
257 parent stream. */ |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
258 return ret; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
259 } |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
260 |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
261 for (i = 0; i < iov_count; i++) { |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
262 ret = o_stream_zlib_send_chunk(zstream, iov[i].iov_base, |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
263 iov[i].iov_len); |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
264 if (ret < 0) |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
265 return -1; |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
266 bytes += ret; |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
267 if ((size_t)ret != iov[i].iov_len) |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
268 break; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
269 } |
12707
b71834419ea3
zlib: Make sure output stream flushes the stream automatically when not corked.
Timo Sirainen <tss@iki.fi>
parents:
12408
diff
changeset
|
270 stream->ostream.offset += bytes; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
271 |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
272 if (!zstream->ostream.corked && i == iov_count) { |
17328
625249382745
lib-compression: gz compression didn't handle multiple flushes correctly.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
273 if (o_stream_zlib_send_flush(zstream, FALSE) < 0) |
12707
b71834419ea3
zlib: Make sure output stream flushes the stream automatically when not corked.
Timo Sirainen <tss@iki.fi>
parents:
12408
diff
changeset
|
274 return -1; |
b71834419ea3
zlib: Make sure output stream flushes the stream automatically when not corked.
Timo Sirainen <tss@iki.fi>
parents:
12408
diff
changeset
|
275 } |
14032
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
276 /* avail_in!=0 check is used to detect errors. if it's non-zero here |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
277 it simply means we didn't send all the data */ |
3c0bd1fd035b
zlib: zlib/bzlib ostreams no longer assert-crash if parent stream becomes full.
Timo Sirainen <tss@iki.fi>
parents:
13837
diff
changeset
|
278 zstream->zs.avail_in = 0; |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
279 return bytes; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
280 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
281 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
282 static void o_stream_zlib_init_gz_header(struct zlib_ostream *zstream, |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
283 int level, int strategy) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
284 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
285 unsigned char *hdr = zstream->gz_header; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
286 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
287 hdr[0] = 0x1f; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
288 hdr[1] = 0x8b; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
289 hdr[2] = Z_DEFLATED; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
290 hdr[8] = level == 9 ? 2 : |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
291 (strategy >= Z_HUFFMAN_ONLY || |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
292 (level != Z_DEFAULT_COMPRESSION && level < 2) ? 4 : 0); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
293 hdr[9] = ZLIB_OS_CODE; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
294 i_assert(sizeof(zstream->gz_header) == 10); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
295 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
296 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
297 static struct ostream * |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
298 o_stream_create_zlib(struct ostream *output, int level, bool gz) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
299 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
300 const int strategy = Z_DEFAULT_STRATEGY; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
301 struct zlib_ostream *zstream; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
302 int ret; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
303 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
304 i_assert(level >= 1 && level <= 9); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
305 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
306 zstream = i_new(struct zlib_ostream, 1); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
307 zstream->ostream.sendv = o_stream_zlib_sendv; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
308 zstream->ostream.flush = o_stream_zlib_flush; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
309 zstream->ostream.iostream.close = o_stream_zlib_close; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
310 zstream->crc = 0; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
311 zstream->gz = gz; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
312 if (!gz) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
313 zstream->header_sent = TRUE; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
314 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
315 o_stream_zlib_init_gz_header(zstream, level, strategy); |
10698
15feca627630
zlib: o_stream_create_deflate() shouldn't have enabled zlib header.
Timo Sirainen <tss@iki.fi>
parents:
10642
diff
changeset
|
316 ret = deflateInit2(&zstream->zs, level, Z_DEFLATED, -15, 8, strategy); |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
317 switch (ret) { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
318 case Z_OK: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
319 break; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
320 case Z_MEM_ERROR: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
321 i_fatal_status(FATAL_OUTOFMEM, "deflateInit(): Out of memory"); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
322 case Z_VERSION_ERROR: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
323 i_fatal("Wrong zlib library version (broken compilation)"); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
324 case Z_STREAM_ERROR: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
325 i_fatal("Invalid compression level %d", level); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
326 default: |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
327 i_fatal("deflateInit() failed with %d", ret); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
328 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
329 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
330 zstream->zs.next_out = zstream->outbuf; |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
331 zstream->zs.avail_out = sizeof(zstream->outbuf); |
14851 | 332 return o_stream_create(&zstream->ostream, output, |
333 o_stream_get_fd(output)); | |
10642
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
334 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
335 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
336 struct ostream *o_stream_create_gz(struct ostream *output, int level) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
337 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
338 return o_stream_create_zlib(output, level, TRUE); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
339 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
340 |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
341 struct ostream *o_stream_create_deflate(struct ostream *output, int level) |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
342 { |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
343 return o_stream_create_zlib(output, level, FALSE); |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
344 } |
9f0e01905171
zlib plugin: Added support for compressing Maildir mails while saving.
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
345 #endif |