dovecot-2.1: Added rawlog i/ostreams.
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 21 15:58:45 EEST 2011
details: http://hg.dovecot.org/dovecot-2.1/rev/0860ac364dec
changeset: 13534:0860ac364dec
user: Timo Sirainen <tss at iki.fi>
date: Wed Sep 21 15:57:57 2011 +0300
description:
Added rawlog i/ostreams.
diffstat:
src/lib/Makefile.am | 7 ++
src/lib/iostream-rawlog-private.h | 18 +++++
src/lib/iostream-rawlog.c | 118 ++++++++++++++++++++++++++++++++++++++
src/lib/iostream-rawlog.h | 7 ++
src/lib/istream-rawlog.c | 104 +++++++++++++++++++++++++++++++++
src/lib/istream-rawlog.h | 8 ++
src/lib/ostream-rawlog.c | 62 +++++++++++++++++++
src/lib/ostream-rawlog.h | 8 ++
8 files changed, 332 insertions(+), 0 deletions(-)
diffs (truncated from 403 to 300 lines):
diff -r e0bee6c56a05 -r 0860ac364dec src/lib/Makefile.am
--- a/src/lib/Makefile.am Wed Sep 21 15:54:06 2011 +0300
+++ b/src/lib/Makefile.am Wed Sep 21 15:57:57 2011 +0300
@@ -48,6 +48,7 @@
imem.c \
ipwd.c \
iostream.c \
+ iostream-rawlog.c \
istream.c \
istream-base64-encoder.c \
istream-concat.c \
@@ -56,6 +57,7 @@
istream-file.c \
istream-limit.c \
istream-mmap.c \
+ istream-rawlog.c \
istream-seekable.c \
istream-tee.c \
ioloop.c \
@@ -88,6 +90,7 @@
ostream.c \
ostream-file.c \
ostream-buffer.c \
+ ostream-rawlog.c \
primes.c \
printf-format-fix.c \
process-title.c \
@@ -162,11 +165,14 @@
imem.h \
ipwd.h \
iostream-private.h \
+ iostream-rawlog.h \
+ iostream-rawlog-private.h \
istream.h \
istream-base64-encoder.h \
istream-concat.h \
istream-crlf.h \
istream-private.h \
+ istream-rawlog.h \
istream-seekable.h \
istream-tee.h \
ioloop.h \
@@ -189,6 +195,7 @@
nfs-workarounds.h \
ostream.h \
ostream-private.h \
+ ostream-rawlog.h \
primes.h \
printf-format-fix.h \
process-title.h \
diff -r e0bee6c56a05 -r 0860ac364dec src/lib/iostream-rawlog-private.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/iostream-rawlog-private.h Wed Sep 21 15:57:57 2011 +0300
@@ -0,0 +1,18 @@
+#ifndef IOSTREAM_RAWLOG_PRIVATE_H
+#define IOSTREAM_RAWLOG_PRIVATE_H
+
+struct rawlog_iostream {
+ struct iostream_private *iostream;
+
+ char *rawlog_path;
+ int rawlog_fd;
+
+ bool autoclose_fd;
+ bool write_timestamp;
+};
+
+void iostream_rawlog_write(struct rawlog_iostream *rstream,
+ const unsigned char *data, size_t size);
+void iostream_rawlog_close(struct rawlog_iostream *rstream);
+
+#endif
diff -r e0bee6c56a05 -r 0860ac364dec src/lib/iostream-rawlog.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/iostream-rawlog.c Wed Sep 21 15:57:57 2011 +0300
@@ -0,0 +1,118 @@
+/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "hostpid.h"
+#include "ioloop.h"
+#include "write-full.h"
+#include "istream.h"
+#include "ostream.h"
+#include "istream-rawlog.h"
+#include "ostream-rawlog.h"
+#include "iostream-private.h"
+#include "iostream-rawlog-private.h"
+#include "iostream-rawlog.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+
+static void
+rawlog_write(struct rawlog_iostream *rstream, const void *data, size_t size)
+{
+ if (rstream->rawlog_fd == -1)
+ return;
+
+ if (write_full(rstream->rawlog_fd, data, size) < 0) {
+ i_error("rawlog_istream.write(%s) failed: %m",
+ rstream->rawlog_path);
+ iostream_rawlog_close(rstream);
+ }
+}
+
+static void rawlog_write_timestamp(struct rawlog_iostream *rstream)
+{
+ char buf[MAX_INT_STRLEN + 6 + 2];
+
+ i_snprintf(buf, sizeof(buf), "%lu.%06u ",
+ (unsigned long)ioloop_timeval.tv_sec,
+ (unsigned int)ioloop_timeval.tv_usec);
+ rawlog_write(rstream, buf, strlen(buf));
+}
+
+void iostream_rawlog_write(struct rawlog_iostream *rstream,
+ const unsigned char *data, size_t size)
+{
+ size_t i, start;
+
+ i_assert(size > 0);
+
+ io_loop_time_refresh();
+ if (rstream->write_timestamp)
+ rawlog_write_timestamp(rstream);
+
+ for (start = 0, i = 1; i < size; i++) {
+ if (data[i-1] == '\n') {
+ rawlog_write(rstream, data + start, i - start);
+ rawlog_write_timestamp(rstream);
+ start = i;
+ }
+ }
+ if (start != size)
+ rawlog_write(rstream, data + start, size - start);
+ rstream->write_timestamp = data[size-1] == '\n';
+}
+
+void iostream_rawlog_close(struct rawlog_iostream *rstream)
+{
+ if (rstream->autoclose_fd && rstream->rawlog_fd != -1) {
+ if (close(rstream->rawlog_fd) < 0) {
+ i_error("rawlog_istream.close(%s) failed: %m",
+ rstream->rawlog_path);
+ }
+ }
+ rstream->rawlog_fd = -1;
+ i_free_and_null(rstream->rawlog_path);
+}
+
+int iostream_rawlog_create(const char *dir, struct istream **input,
+ struct ostream **output)
+{
+ static unsigned int counter = 0;
+ const char *in_path, *out_path;
+ struct istream *old_input;
+ struct ostream *old_output;
+ struct tm *tm;
+ char timestamp[50];
+ int in_fd, out_fd;
+
+ tm = localtime(&ioloop_time);
+ if (strftime(timestamp, sizeof(timestamp), "%Y%m%d-%H%M%S", tm) <= 0)
+ i_fatal("strftime() failed");
+
+ counter++;
+ in_path = t_strdup_printf("%s/%s.%s.%u.in",
+ dir, timestamp, my_pid, counter);
+ out_path = t_strdup_printf("%s/%s.%s.%u.out",
+ dir, timestamp, my_pid, counter);
+
+ in_fd = open(in_path, O_CREAT | O_APPEND | O_WRONLY, 0600);
+ if (in_fd == -1) {
+ i_error("creat(%s) failed: %m", in_path);
+ return -1;
+ }
+
+ out_fd = open(out_path, O_CREAT | O_APPEND | O_WRONLY, 0600);
+ if (out_fd == -1) {
+ i_error("creat(%s) failed: %m", out_path);
+ (void)close(in_fd);
+ (void)unlink(in_path);
+ return -1;
+ }
+
+ old_input = *input;
+ old_output = *output;
+ *input = i_stream_create_rawlog(old_input, in_path, in_fd, TRUE);
+ *output = o_stream_create_rawlog(old_output, out_path, out_fd, TRUE);
+ i_stream_unref(&old_input);
+ o_stream_unref(&old_output);
+ return 0;
+}
diff -r e0bee6c56a05 -r 0860ac364dec src/lib/iostream-rawlog.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/iostream-rawlog.h Wed Sep 21 15:57:57 2011 +0300
@@ -0,0 +1,7 @@
+#ifndef IOSTREAM_RAWLOG_H
+#define IOSTREAM_RAWLOG_H
+
+int iostream_rawlog_create(const char *dir, struct istream **input,
+ struct ostream **output);
+
+#endif
diff -r e0bee6c56a05 -r 0860ac364dec src/lib/istream-rawlog.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/istream-rawlog.c Wed Sep 21 15:57:57 2011 +0300
@@ -0,0 +1,104 @@
+/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "iostream-rawlog-private.h"
+#include "istream-private.h"
+#include "istream-rawlog.h"
+
+struct rawlog_istream {
+ struct istream_private istream;
+ struct rawlog_iostream riostream;
+};
+
+static void i_stream_rawlog_close(struct iostream_private *stream)
+{
+ struct rawlog_istream *rstream = (struct rawlog_istream *)stream;
+
+ iostream_rawlog_close(&rstream->riostream);
+}
+
+static void i_stream_rawlog_destroy(struct iostream_private *stream)
+{
+ struct rawlog_istream *rstream = (struct rawlog_istream *)stream;
+ uoff_t v_offset;
+
+ v_offset = rstream->istream.parent_start_offset +
+ rstream->istream.istream.v_offset;
+ if (rstream->istream.parent->seekable ||
+ v_offset > rstream->istream.parent->v_offset) {
+ /* get to same position in parent stream */
+ i_stream_seek(rstream->istream.parent, v_offset);
+ }
+ i_stream_unref(&rstream->istream.parent);
+}
+
+static ssize_t i_stream_rawlog_read(struct istream_private *stream)
+{
+ struct rawlog_istream *rstream = (struct rawlog_istream *)stream;
+ ssize_t ret;
+ size_t pos;
+
+ i_stream_seek(stream->parent, rstream->istream.parent_start_offset +
+ stream->istream.v_offset);
+
+ stream->pos -= stream->skip;
+ stream->skip = 0;
+
+ stream->buffer = i_stream_get_data(stream->parent, &pos);
+ if (pos > stream->pos)
+ ret = 0;
+ else do {
+ if ((ret = i_stream_read(stream->parent)) == -2)
+ return -2;
+
+ stream->istream.stream_errno = stream->parent->stream_errno;
+ stream->istream.eof = stream->parent->eof;
+ stream->buffer = i_stream_get_data(stream->parent, &pos);
+ } while (pos <= stream->pos && ret > 0);
+
+ if (pos <= stream->pos)
+ ret = ret == 0 ? 0 : -1;
+ else {
+ ret = (ssize_t)(pos - stream->pos);
+ iostream_rawlog_write(&rstream->riostream,
+ stream->buffer + stream->pos, ret);
+ }
+ stream->pos = pos;
+ i_assert(ret != -1 || stream->istream.eof ||
+ stream->istream.stream_errno != 0);
+ return ret;
+}
+
+static const struct stat *
+i_stream_rawlog_stat(struct istream_private *stream, bool exact)
+{
+ return i_stream_stat(stream->parent, exact);
+}
+
+struct istream *
+i_stream_create_rawlog(struct istream *input, const char *rawlog_path,
+ int rawlog_fd, bool autoclose_fd)
+{
+ struct rawlog_istream *rstream;
+
+ i_assert(rawlog_path != NULL);
+ i_assert(rawlog_fd != -1);
+
+ rstream = i_new(struct rawlog_istream, 1);
+ rstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
+ rstream->riostream.rawlog_path = i_strdup(rawlog_path);
+ rstream->riostream.rawlog_fd = rawlog_fd;
+ rstream->riostream.autoclose_fd = autoclose_fd;
More information about the dovecot-cvs
mailing list