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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
4bcd507e8907 Added o_stream_get_fd().
Timo Sirainen <tss@iki.fi>
parents: 14739
diff changeset
332 return o_stream_create(&zstream->ostream, output,
4bcd507e8907 Added o_stream_get_fd().
Timo Sirainen <tss@iki.fi>
parents: 14739
diff changeset
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