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