istream-header-filter.c revision 9e095dd6a77097356aca8216356d4d71ef1bea45
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen#include "buffer.h"
d9076f5939edf5d20a261494b1a861dcbb0d32e2Timo Sirainen#include "message-parser.h"
d9fdacd5fb3e07997e5c389739d2054f0c8441d8Timo Sirainen#include "istream-internal.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "istream-header-filter.h"
5666a3d6a7ea89362b8d9e8b39b15424cd9d6388Timo Sirainen
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen#include <stdlib.h>
146f9076cd456ea1e9b3f8536456d9d3c962fadbStephan Bosch
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstruct header_filter_istream {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct _istream istream;
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen pool_t pool;
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen
8c909e451d14075c05d90382cf8eebc4e354f569Timo Sirainen struct istream *input;
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen struct message_header_parser_ctx *hdr_ctx;
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen
573f0491a5733fe21fa062a455acb4790b4e0499Timo Sirainen const char **headers;
3ed2d0f6b5e67e2663d44489d9da3176823789a8Timo Sirainen size_t headers_count;
65f8fb656051f1059f7b5a2da9c5555adcc30439Timo Sirainen
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen header_filter_callback *callback;
1a5573ebc32fae2fe576ec544e1781323c1db609Timo Sirainen void *context;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen buffer_t *hdr_buf;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen struct message_size header_size;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen uoff_t skip_count;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int cur_line, parsed_lines;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen unsigned int header_read:1;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen unsigned int filter:1;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen};
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen
f7539a17ea306191b53b8f5e752e228937df9ec3Timo Sirainenstatic void _close(struct _iostream *stream __attr_unused__)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen{
2dd39e478269d6fb0bb26d12b394aa30ee965e38Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenstatic void _destroy(struct _iostream *stream)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct header_filter_istream *mstream =
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen (struct header_filter_istream *)stream;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if (mstream->hdr_ctx != NULL)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen message_parse_header_deinit(mstream->hdr_ctx);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_unref(mstream->input);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen pool_unref(mstream->pool);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen}
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
3e564425db51f3921ce4de11859777135fdedd15Timo Sirainen{
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen struct header_filter_istream *mstream =
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen (struct header_filter_istream *)stream;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen i_stream_set_max_buffer_size(mstream->input, max_size);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic ssize_t read_header(struct header_filter_istream *mstream)
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen{
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen struct message_header_line *hdr;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen size_t pos;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen ssize_t ret;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen int matched, hdr_ret;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainen
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen if (mstream->header_read &&
4ba9a1d3facc515b3feb5238a16bcf91f76fac61Timo Sirainen mstream->istream.istream.v_offset + mstream->istream.pos ==
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen mstream->header_size.virtual_size) {
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen /* we don't support mixing headers and body.
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen it shouldn't be needed. */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen return -2;
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen }
8b31f966d9688e07672ef1958dcbdb7686523c04Timo Sirainen
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen if (mstream->hdr_ctx == NULL) {
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen mstream->hdr_ctx =
9847ec56efa15fa063eea9988eee2d4ed9ec7d58Timo Sirainen message_parse_header_init(mstream->input, NULL, FALSE);
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen }
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen
d46a1e3f999dda802dc5137e883adcd7a6629cd3Timo Sirainen buffer_copy(mstream->hdr_buf, 0,
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen mstream->hdr_buf, mstream->istream.skip, (size_t)-1);
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen mstream->istream.pos -= mstream->istream.skip;
d1e843e77f4760e303c53d9fce10123fc8d230a1Timo Sirainen mstream->istream.skip = 0;
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen buffer_set_used_size(mstream->hdr_buf, mstream->istream.pos);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen while ((hdr_ret = message_parse_header_next(mstream->hdr_ctx,
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen &hdr)) > 0) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen mstream->cur_line++;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (hdr->eoh) {
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen buffer_append(mstream->hdr_buf, "\r\n", 2);
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen break;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen }
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen matched = bsearch(hdr->name, mstream->headers,
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen mstream->headers_count,
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen sizeof(*mstream->headers),
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen bsearch_strcasecmp) != NULL;
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen if (mstream->cur_line > mstream->parsed_lines &&
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen mstream->callback != NULL) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen mstream->parsed_lines = mstream->cur_line;
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen mstream->callback(hdr, &matched, mstream->context);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen }
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen if (matched == mstream->filter) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* ignore */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (!hdr->continued) {
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen buffer_append(mstream->hdr_buf,
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen hdr->name, hdr->name_len);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen buffer_append(mstream->hdr_buf,
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen hdr->middle, hdr->middle_len);
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen }
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen buffer_append(mstream->hdr_buf,
420040a5930a2b497e79ff0b5f59ba4b764a5b39Timo Sirainen hdr->value, hdr->value_len);
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen buffer_append(mstream->hdr_buf, "\r\n", 2);
eecb235c14b49c01774134ea593c266f2d2c2be1Timo Sirainen
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen if (mstream->skip_count >= mstream->hdr_buf->used) {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* we need more */
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen mstream->skip_count -= mstream->hdr_buf->used;
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen buffer_set_used_size(mstream->hdr_buf, 0);
97ae33602db7d5bc8eede82512a965d49ab8853bTimo Sirainen } else {
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen if (mstream->skip_count > 0) {
f1743785713e7632459d623d5df2108f4b93accbTimo Sirainen mstream->istream.skip =
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen mstream->skip_count;
70ead6466f9baa8294e71fc2fba0a4f54f488b5eTimo Sirainen mstream->skip_count = 0;
a64adf62fa33f2463a86f990217b0c9078531a40Timo Sirainen }
ccc895c0358108d2304239063e940b7d75f364abTimo Sirainen break;
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
ee116df08d0fdab703483e18fe8076b2ef9fd9d7Timo Sirainen }
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen mstream->istream.istream.eof = mstream->input->eof;
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen mstream->istream.buffer = buffer_get_data(mstream->hdr_buf, &pos);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen ret = (ssize_t)(pos - mstream->istream.pos - mstream->istream.skip);
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen mstream->istream.pos = pos;
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen
306b3f41b05da642d87e7ca7a1496efce9f5902fTimo Sirainen if (hdr_ret == 0)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen return ret;
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen
c6afd726060aae56b6622c6c52aec10231c4bf1cTimo Sirainen if (hdr == NULL) {
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen /* finished */
9fd2181788a61500641c66aec0f8c746b19bf830Timo Sirainen mstream->header_read = TRUE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen message_parse_header_deinit(mstream->hdr_ctx);
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen mstream->hdr_ctx = NULL;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen mstream->header_size.physical_size = mstream->input->v_offset;
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen mstream->header_size.virtual_size =
b9f564d00b7a115f465ffd6840341c7b8f9bfc8aTimo Sirainen mstream->istream.istream.v_offset + pos;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret == 0) {
a2f250a332dfc1e6cd4ffd196c621eb9dbf7b8a1Timo Sirainen i_assert(hdr == NULL);
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen i_assert(mstream->istream.istream.v_offset +
cff1f182205e674285cf3ff446a0dcf7afea277dTimo Sirainen mstream->istream.pos ==
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen mstream->header_size.virtual_size);
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen return -2;
e03d986a74128f5ba30fcfda9f6e36578f5d8decTimo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen return ret;
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen}
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainenstatic ssize_t _read(struct _istream *stream)
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen{
f318b3dbe2acc177b8ee1c160e4b5b14e7f2cd41Timo Sirainen struct header_filter_istream *mstream =
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainen (struct header_filter_istream *)stream;
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen ssize_t ret;
d3280fe317a4598c0868cc440e7a1191c06d0db3Timo Sirainen size_t pos;
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen if (!mstream->header_read ||
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen stream->istream.v_offset < mstream->header_size.virtual_size) {
6469cf211a57433335641725dc236ebb2b9fdd3bTimo Sirainen ret = read_header(mstream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ret != -2 || stream->pos != stream->skip)
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen return ret;
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen }
6cc4cce2078aca138fbce19305e69e77edcee614Timo Sirainen
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen if (mstream->input->v_offset - mstream->header_size.physical_size !=
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen stream->istream.v_offset - mstream->header_size.virtual_size) {
50c617761ee9653bd44646a95178773a3686d62eTimo Sirainen i_stream_seek(mstream->input, stream->istream.v_offset -
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen mstream->header_size.virtual_size +
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen mstream->header_size.physical_size);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen }
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen stream->buffer = i_stream_get_data(mstream->input, &pos);
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen if (pos <= stream->pos) {
62041dfb7d6ac6e9c633a557075999cdfcff7bd5Timo Sirainen if (i_stream_read(mstream->input) == -2) {
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen if (stream->skip == 0)
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen return -2;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen }
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen stream->istream.eof = mstream->input->eof;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen stream->buffer = i_stream_get_data(mstream->input, &pos);
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen }
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen stream->pos -= stream->skip;
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen stream->skip = 0;
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen ret = pos <= stream->pos ? -1 :
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen (ssize_t) (pos - stream->pos);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen stream->pos = pos;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen return ret;
c979eeda1f46483d9c963e265786b701d7683d77Timo Sirainen}
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen
2584e86cc2d8c31ba30a4109cf4ba09d1e37e28aTimo Sirainenstatic void _seek(struct _istream *stream, uoff_t v_offset)
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen{
4b41116563110d00330896a568eff1078c382827Timo Sirainen struct header_filter_istream *mstream =
4b41116563110d00330896a568eff1078c382827Timo Sirainen (struct header_filter_istream *)stream;
4b41116563110d00330896a568eff1078c382827Timo Sirainen
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen stream->istream.v_offset = v_offset;
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen stream->skip = stream->pos = 0;
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen stream->buffer = NULL;
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mstream->hdr_ctx != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen message_parse_header_deinit(mstream->hdr_ctx);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen mstream->hdr_ctx = NULL;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen }
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen if (v_offset < mstream->header_size.virtual_size) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* seek into headers. we'll have to re-parse them, use
dbe64f3893616a4005c8946be75d2dc8f6823d72Timo Sirainen skip_count to set the wanted position */
8a13b020f90e080570658b18c042e7e352c8b14fTimo Sirainen i_stream_seek(mstream->input, 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mstream->skip_count = v_offset;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen mstream->cur_line = 0;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen } else {
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* body */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen v_offset += mstream->header_size.physical_size -
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen mstream->header_size.virtual_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_stream_seek(mstream->input, v_offset);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen }
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen}
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainenstruct istream *
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Siraineni_stream_create_header_filter(struct istream *input, int filter,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const char *const *headers, size_t headers_count,
f3bb2fbe87425dc89a839908985af496f7f65702Timo Sirainen header_filter_callback *callback, void *context)
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen{
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen struct header_filter_istream *mstream;
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen pool_t pool;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen size_t i;
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen pool = pool_alloconly_create("header filter stream", 1024);
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen mstream = p_new(pool, struct header_filter_istream, 1);
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen mstream->pool = pool;
2ebeb22b9a8a8bb7fbe2f2e2908478a220792b87Timo Sirainen
a423d985ba7261661475811c22b21b80ec765a71Timo Sirainen mstream->input = input;
bd4d0a1a7c0626452b8d82f37e3ec07267ac9896Timo Sirainen i_stream_ref(mstream->input);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->headers = p_new(pool, const char *, headers_count);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen for (i = 0; i < headers_count; i++)
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->headers[i] = p_strdup(pool, headers[i]);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->headers_count = headers_count;
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->hdr_buf = buffer_create_dynamic(pool, 512, (size_t)-1);
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen
1460ef7a18c53216ddb4a94bb62fba96076aae8eTimo Sirainen mstream->callback = callback;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen mstream->context = context;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mstream->filter = filter;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mstream->istream.iostream.close = _close;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mstream->istream.iostream.destroy = _destroy;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen mstream->istream.read = _read;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen mstream->istream.seek = _seek;
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen return _i_stream_create(&mstream->istream, pool, -1, 0);
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen}
0177594fa5217b02001f4ec8752154fd2b05c545Timo Sirainen