istream-tee.c revision 0a70a2e71658d168f75d1f075661d7936701343c
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */
87a6b7df39d6822a5a8289a62f32deabff9b75e4Timo Sirainenstatic void tee_streams_update_buffer(struct tee_istream *tee)
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen struct tee_child_istream *tstream = tee->children;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen const unsigned char *data;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen for (; tstream != NULL; tstream = tstream->next) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen tstream->istream.skip = tstream->istream.pos = 0;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen old_used = tstream->istream.pos - tstream->istream.skip;
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi tstream->istream.skip = tstream->istream.istream.v_offset -
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen i_assert(tstream->istream.skip + old_used <= size);
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainen tstream->istream.pos = tstream->istream.skip + old_used;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenstatic void tee_streams_skip(struct tee_istream *tee)
a9a928e40e3b691924c8e5e444e3e1a4320aa3bdStephan Bosch struct tee_child_istream *tstream = tee->children;
212a34c06ff45952c008ae9eec387ced783de6cfPhil Carmody for (; tstream != NULL; tstream = tstream->next) {
10c96a244935de4add8213ba0b894178dfb889a5Timo Sirainenstatic void i_stream_tee_close(struct iostream_private *stream)
bdcb00145ad87765e3fd22d4ebc4d2c029a326b9Timo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void i_stream_tee_destroy(struct iostream_private *stream)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen if (tstream->istream.istream.v_offset > tee->max_read_offset)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen tee->max_read_offset = tstream->istream.istream.v_offset;
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainen for (p = &tee->children; *p != NULL; p = &(*p)->next) {
1a0ece3e873e3864269ed7eaed957dc10c56d25fTimo Sirainen i_assert(tee->input->v_offset <= tee->max_read_offset);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Siraineni_stream_tee_set_max_buffer_size(struct iostream_private *stream,
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
5af5137f6dc0c9f358b7813e941e26f7bd735b3aTimo Sirainen i_stream_set_max_buffer_size(tstream->tee->input, max_size);
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic ssize_t i_stream_tee_read(struct istream_private *stream)
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen const unsigned char *data;
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen (tstream->istream.pos - tstream->istream.skip);
71aed7ba87b5fd5e96e97a22d89ac025b883d60aTimo Sirainen i_assert(last_high_offset <= input->v_offset + size);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen if (last_high_offset == input->v_offset + size) {
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen /* someone else is holding the data,
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen wait for it */
463f6ea04af934a68facaca0ff089bc306de3f98Timo Sirainen stream->istream.stream_errno = input->stream_errno;
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Siraineni_stream_tee_seek(struct istream_private *stream ATTR_UNUSED,
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen uoff_t v_offset ATTR_UNUSED, bool mark ATTR_UNUSED)
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen i_panic("tee-istream: seeking unsupported currently");
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainenstatic const struct stat *
01f4ee4a0243f3fe9af763e1a540cd5cff0d63f5Timo Siraineni_stream_tee_stat(struct istream_private *stream, bool exact)
4b9f99761df5014c659cd87fddaf6854af428cfcTimo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen return i_stream_stat(tstream->tee->input, exact);
a3c197999dfe2b0c8ea38cb77cfa5e95026005c0Timo Sirainenstatic void i_stream_tee_sync(struct istream_private *stream)
923115fd382904fa13bb09bf307bf2835b52df60Timo Sirainen struct tee_child_istream *tstream = (struct tee_child_istream *)stream;
51e1a1c280ccb461a15827f7987d09cb9708b6e3Timo Sirainen (void)i_stream_get_data(tstream->tee->input, &size);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen i_panic("tee-istream: i_stream_sync() called "
89e195dfb5c4b0efd9b9f459771a4467674e5b1fTimo Sirainen "with data still buffered");
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainenstruct tee_istream *tee_i_stream_create(struct istream *input)
699fdc186f982f70d990820796eaa0f12133e27cTimo Sirainenstruct istream *tee_i_stream_create_child(struct tee_istream *tee)
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody tstream->istream.iostream.close = i_stream_tee_close;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody tstream->istream.iostream.destroy = i_stream_tee_destroy;
09142ea11662746ea07475b1a4f69a6a406fb996Phil Carmody tstream->istream.iostream.set_max_buffer_size =