~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/lib-mail/istream-header-filter.c

  • Committer: Package Import Robot
  • Author(s): Jaldhar H. Vyas
  • Date: 2013-09-09 00:57:32 UTC
  • mfrom: (1.13.11)
  • mto: (4.8.5 experimental) (1.16.1)
  • mto: This revision was merged to the branch mainline in revision 97.
  • Revision ID: package-import@ubuntu.com-20130909005732-dn1eell8srqbhh0e
Tags: upstream-2.2.5
ImportĀ upstreamĀ versionĀ 2.2.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2003-2012 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2003-2013 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "lib.h"
4
4
#include "array.h"
26
26
        uoff_t last_lf_offset;
27
27
 
28
28
        unsigned int cur_line, parsed_lines;
29
 
        ARRAY_DEFINE(match_change_lines, unsigned int);
 
29
        ARRAY(unsigned int) match_change_lines;
30
30
 
31
31
        unsigned int header_read:1;
32
32
        unsigned int seen_eoh:1;
133
133
                buffer_append_c(mstream->hdr_buf, '\n');
134
134
}
135
135
 
 
136
static ssize_t hdr_stream_update_pos(struct header_filter_istream *mstream)
 
137
{
 
138
        ssize_t ret;
 
139
        size_t pos;
 
140
 
 
141
        mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos);
 
142
        ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip);
 
143
        i_assert(ret >= 0);
 
144
        mstream->istream.pos = pos;
 
145
        return ret;
 
146
}
 
147
 
136
148
static ssize_t read_header(struct header_filter_istream *mstream)
137
149
{
138
150
        struct message_header_line *hdr;
139
151
        uoff_t highwater_offset;
140
 
        size_t pos;
141
 
        ssize_t ret;
 
152
        ssize_t ret, ret2;
142
153
        bool matched;
143
154
        int hdr_ret;
144
155
 
177
188
                        matched = TRUE;
178
189
                        if (!mstream->header_parsed &&
179
190
                            mstream->callback != NULL) {
180
 
                                mstream->callback(hdr, &matched,
 
191
                                mstream->callback(mstream, hdr, &matched,
181
192
                                                  mstream->context);
182
193
                        }
183
194
 
184
 
                        if (!matched)
 
195
                        if (!matched) {
 
196
                                mstream->seen_eoh = FALSE;
185
197
                                continue;
 
198
                        }
186
199
 
187
200
                        add_eol(mstream);
188
201
                        continue;
189
202
                }
190
203
 
191
204
                matched = mstream->headers_count == 0 ? FALSE :
192
 
                        bsearch(hdr->name, mstream->headers,
193
 
                                mstream->headers_count,
194
 
                                sizeof(*mstream->headers),
195
 
                                bsearch_strcasecmp) != NULL;
 
205
                        i_bsearch(hdr->name, mstream->headers,
 
206
                                  mstream->headers_count,
 
207
                                  sizeof(*mstream->headers),
 
208
                                  bsearch_strcasecmp) != NULL;
196
209
                if (mstream->callback == NULL) {
197
210
                        /* nothing gets excluded */
198
211
                } else if (mstream->cur_line > mstream->parsed_lines) {
200
213
                        bool orig_matched = matched;
201
214
 
202
215
                        mstream->parsed_lines = mstream->cur_line;
203
 
                        mstream->callback(hdr, &matched, mstream->context);
 
216
                        mstream->callback(mstream, hdr, &matched,
 
217
                                          mstream->context);
204
218
                        if (matched != orig_matched) {
205
219
                                i_array_init(&mstream->match_change_lines, 8);
206
220
                                array_append(&mstream->match_change_lines,
258
272
 
259
273
        /* don't copy eof here because we're only returning headers here.
260
274
           the body will be returned in separate read() call. */
261
 
        mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos);
262
 
        ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip);
263
 
        i_assert(ret >= 0);
264
 
        mstream->istream.pos = pos;
 
275
        ret = hdr_stream_update_pos(mstream);
265
276
 
266
277
        if (hdr_ret == 0) {
267
278
                /* need more data to finish parsing headers. we may have some
274
285
                message_parse_header_deinit(&mstream->hdr_ctx);
275
286
                mstream->hdr_ctx = NULL;
276
287
 
277
 
                if (!mstream->header_parsed && mstream->callback != NULL)
278
 
                        mstream->callback(NULL, &matched, mstream->context);
 
288
                if (!mstream->header_parsed && mstream->callback != NULL) {
 
289
                        mstream->callback(mstream, NULL,
 
290
                                          &matched, mstream->context);
 
291
                        /* check if the callback added more headers.
 
292
                           this is allowed only of EOH wasn't added yet. */
 
293
                        ret2 = hdr_stream_update_pos(mstream);
 
294
                        if (!mstream->seen_eoh)
 
295
                                ret += ret2;
 
296
                        else {
 
297
                                i_assert(ret2 == 0);
 
298
                        }
 
299
                }
279
300
                mstream->header_parsed = TRUE;
280
301
                mstream->header_read = TRUE;
281
302
 
282
303
                mstream->header_size.physical_size =
283
304
                        mstream->istream.parent->v_offset;
284
305
                mstream->header_size.virtual_size =
285
 
                        mstream->istream.istream.v_offset + pos;
 
306
                        mstream->istream.istream.v_offset +
 
307
                        mstream->istream.pos;
286
308
        }
287
309
 
288
310
        if (ret == 0) {
407
429
 
408
430
        while (!mstream->header_read &&
409
431
               i_stream_read(&mstream->istream.istream) != -1) {
410
 
                (void)i_stream_get_data(&mstream->istream.istream, &pos);
 
432
                pos = i_stream_get_data_size(&mstream->istream.istream);
411
433
                i_stream_skip(&mstream->istream.istream, pos);
412
434
        }
413
435
}
470
492
        i_panic("istream-header-filter sync() not implemented");
471
493
}
472
494
 
473
 
static const struct stat *
 
495
static int
474
496
i_stream_header_filter_stat(struct istream_private *stream, bool exact)
475
497
{
476
498
        struct header_filter_istream *mstream =
478
500
        const struct stat *st;
479
501
        uoff_t old_offset;
480
502
 
481
 
        st = i_stream_stat(stream->parent, exact);
482
 
        if (st == NULL || st->st_size == -1 || !exact)
483
 
                return st;
 
503
        if (i_stream_stat(stream->parent, exact, &st) < 0)
 
504
                return -1;
 
505
        stream->statbuf = *st;
 
506
        if (stream->statbuf.st_size == -1 || !exact)
 
507
                return 0;
484
508
 
 
509
        /* fix the filtered header size */
485
510
        old_offset = stream->istream.v_offset;
486
511
        skip_header(mstream);
487
512
 
488
 
        stream->statbuf = *st;
489
513
        stream->statbuf.st_size -=
490
514
                (off_t)mstream->header_size.physical_size -
491
515
                (off_t)mstream->header_size.virtual_size;
492
516
        i_stream_seek(&stream->istream, old_offset);
493
 
        return &stream->statbuf;
 
517
        return 0;
494
518
}
495
519
 
496
520
#undef i_stream_create_header_filter
548
572
 
549
573
        return i_stream_create(&mstream->istream, input, -1);
550
574
}
 
575
 
 
576
void i_stream_header_filter_add(struct header_filter_istream *input,
 
577
                                const void *data, size_t size)
 
578
{
 
579
        buffer_append(input->hdr_buf, data, size);
 
580
}