istream-rawlog.c revision 6a9bd9f9e6f3af9362160fdc886de116e4b08e9a
2454dfa32c93c20a8522c6ed42fe057baaac9f9aStephan Bosch/* Copyright (c) 2011-2013 Dovecot authors, see the included COPYING file */
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch#include "lib.h"
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch#include "iostream-rawlog-private.h"
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch#include "istream-private.h"
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch#include "istream-rawlog.h"
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Boschstruct rawlog_istream {
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch struct istream_private istream;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch struct rawlog_iostream riostream;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch};
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainenstatic void i_stream_rawlog_close(struct iostream_private *stream)
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch{
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch struct rawlog_istream *rstream = (struct rawlog_istream *)stream;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch iostream_rawlog_close(&rstream->riostream);
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch i_stream_close(rstream->istream.parent);
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch}
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Boschstatic void i_stream_rawlog_destroy(struct iostream_private *stream)
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch{
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen struct rawlog_istream *rstream = (struct rawlog_istream *)stream;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch uoff_t v_offset;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen v_offset = rstream->istream.parent_start_offset +
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen rstream->istream.istream.v_offset;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen if (rstream->istream.parent->seekable ||
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen v_offset > rstream->istream.parent->v_offset) {
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen /* get to same position in parent stream */
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen i_stream_seek(rstream->istream.parent, v_offset);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen }
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen i_stream_unref(&rstream->istream.parent);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen}
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainenstatic ssize_t i_stream_rawlog_read(struct istream_private *stream)
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen{
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen struct rawlog_istream *rstream = (struct rawlog_istream *)stream;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch ssize_t ret;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen size_t pos;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen i_stream_seek(stream->parent, rstream->istream.parent_start_offset +
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->istream.v_offset);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->pos -= stream->skip;
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->skip = 0;
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->buffer = i_stream_get_data(stream->parent, &pos);
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen if (pos > stream->pos)
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen ret = 0;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen else do {
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen if ((ret = i_stream_read(stream->parent)) == -2)
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen return -2;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen stream->istream.stream_errno = stream->parent->stream_errno;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen stream->istream.eof = stream->parent->eof;
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen stream->buffer = i_stream_get_data(stream->parent, &pos);
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen } while (pos <= stream->pos && ret > 0);
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen
a2583397219ebbb877fcf84107f0ca7f56362760Timo Sirainen if (pos <= stream->pos)
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen ret = ret == 0 ? 0 : -1;
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen else {
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen ret = (ssize_t)(pos - stream->pos);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen iostream_rawlog_write(&rstream->riostream,
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->buffer + stream->pos, ret);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen }
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->pos = pos;
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen i_assert(ret != -1 || stream->istream.eof ||
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen stream->istream.stream_errno != 0);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen return ret;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch}
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Boschstruct istream *
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Boschi_stream_create_rawlog(struct istream *input, const char *rawlog_path,
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch int rawlog_fd, enum iostream_rawlog_flags flags)
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch{
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch struct rawlog_istream *rstream;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch i_assert(rawlog_path != NULL);
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch i_assert(rawlog_fd != -1);
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream = i_new(struct rawlog_istream, 1);
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.stream_size_passthrough = TRUE;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->riostream.rawlog_path = i_strdup(rawlog_path);
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen rstream->riostream.rawlog_fd = rawlog_fd;
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen iostream_rawlog_init(&rstream->riostream, flags, TRUE);
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.read = i_stream_rawlog_read;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.iostream.close = i_stream_rawlog_close;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.iostream.destroy = i_stream_rawlog_destroy;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.istream.readable_fd = input->readable_fd;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.istream.blocking = input->blocking;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch rstream->istream.istream.seekable = input->seekable;
836e690c0e2d7494b8c0a6f4984dd13248841f2fStephan Bosch return i_stream_create(&rstream->istream, input,
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen i_stream_get_fd(input));
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen}
83773f7eb5e12e68f5efee7278bdab35d2ee84c0Timo Sirainen