bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include "lib.h"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include "iostream-rawlog-private.h"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include "ostream-private.h"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen#include "ostream-rawlog.h"
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainenstruct rawlog_ostream {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct ostream_private ostream;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct rawlog_iostream riostream;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen};
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainenstatic void o_stream_rawlog_close(struct iostream_private *stream,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen bool close_parent)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen{
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct rawlog_ostream *rstream = (struct rawlog_ostream *)stream;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen iostream_rawlog_close(&rstream->riostream);
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen if (close_parent)
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen o_stream_close(rstream->ostream.parent);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen}
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainenstatic ssize_t
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Siraineno_stream_rawlog_sendv(struct ostream_private *stream,
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen const struct const_iovec *iov, unsigned int iov_count)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen{
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen struct rawlog_ostream *rstream = (struct rawlog_ostream *)stream;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen unsigned int i;
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen ssize_t ret, bytes;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen if ((ret = o_stream_sendv(stream->parent, iov, iov_count)) < 0) {
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen o_stream_copy_error_from_parent(stream);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return -1;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen }
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen bytes = ret;
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen for (i = 0; i < iov_count && bytes > 0; i++) {
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen if (iov[i].iov_len < (size_t)bytes) {
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen iostream_rawlog_write(&rstream->riostream,
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen iov[i].iov_base, iov[i].iov_len);
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen bytes -= iov[i].iov_len;
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen } else {
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen iostream_rawlog_write(&rstream->riostream,
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen iov[i].iov_base, bytes);
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen break;
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen }
3f7b9d04c1fb9b0a55ea2082214ea66a0ace96c7Timo Sirainen }
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen stream->ostream.offset += ret;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen return ret;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen}
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainenstruct ostream *
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Siraineno_stream_create_rawlog(struct ostream *output, const char *rawlog_path,
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen int rawlog_fd, enum iostream_rawlog_flags flags)
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen{
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen struct ostream *rawlog_output;
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen bool autoclose_fd = (flags & IOSTREAM_RAWLOG_FLAG_AUTOCLOSE) != 0;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen i_assert(rawlog_path != NULL);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen i_assert(rawlog_fd != -1);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi rawlog_output = autoclose_fd ?
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi o_stream_create_fd_autoclose(&rawlog_fd, 0):
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi o_stream_create_fd(rawlog_fd, 0);
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen o_stream_set_name(rawlog_output,
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen t_strdup_printf("rawlog(%s)", rawlog_path));
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen return o_stream_create_rawlog_from_stream(output, rawlog_output, flags);
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen}
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainenstruct ostream *
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Siraineno_stream_create_rawlog_from_stream(struct ostream *output,
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen struct ostream *rawlog_output,
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen enum iostream_rawlog_flags flags)
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen{
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen struct rawlog_ostream *rstream;
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen rstream = i_new(struct rawlog_ostream, 1);
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen rstream->ostream.sendv = o_stream_rawlog_sendv;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen rstream->ostream.iostream.close = o_stream_rawlog_close;
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen
76d4ff1c1b31a1a09f6cbfe613a8d0efe62cbfd2Timo Sirainen rstream->riostream.rawlog_output = rawlog_output;
f1ed4fa248aaf6841ba638b9d66b2738d9f7aa18Timo Sirainen iostream_rawlog_init(&rstream->riostream, flags, FALSE);
93936b4e7179f97ca490c863f666f378ebb08905Timo Sirainen return o_stream_create(&rstream->ostream, output,
93936b4e7179f97ca490c863f666f378ebb08905Timo Sirainen o_stream_get_fd(output));
be6ad6e46ecb8c7126b421819046e7f4857a2babTimo Sirainen}