dovecot-2.2: iostream-rawlog: Added possibility to save input/ou...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Aug 29 16:19:12 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/8ce6d41d2d41
changeset: 14967:8ce6d41d2d41
user: Timo Sirainen <tss at iki.fi>
date: Wed Aug 29 16:18:56 2012 +0300
description:
iostream-rawlog: Added possibility to save input/output to the same file.
diffstat:
src/lib/iostream-rawlog-private.h | 15 +++-
src/lib/iostream-rawlog.c | 161 ++++++++++++++++++++++++++++++-------
src/lib/iostream-rawlog.h | 9 ++
src/lib/istream-rawlog.c | 5 +-
src/lib/istream-rawlog.h | 2 +-
src/lib/ostream-rawlog.c | 5 +-
src/lib/ostream-rawlog.h | 2 +-
7 files changed, 156 insertions(+), 43 deletions(-)
diffs (truncated from 357 to 300 lines):
diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/iostream-rawlog-private.h
--- a/src/lib/iostream-rawlog-private.h Wed Aug 29 16:12:08 2012 +0300
+++ b/src/lib/iostream-rawlog-private.h Wed Aug 29 16:18:56 2012 +0300
@@ -1,16 +1,27 @@
#ifndef IOSTREAM_RAWLOG_PRIVATE_H
#define IOSTREAM_RAWLOG_PRIVATE_H
+#define IOSTREAM_RAWLOG_MAX_PREFIX_LEN 3
+
+enum iostream_rawlog_flags {
+ IOSTREAM_RAWLOG_FLAG_AUTOCLOSE = 0x01,
+ IOSTREAM_RAWLOG_FLAG_BUFFERED = 0x02
+};
+
struct rawlog_iostream {
struct iostream_private *iostream;
+ enum iostream_rawlog_flags flags;
char *rawlog_path;
int rawlog_fd;
+ buffer_t *buffer;
- bool autoclose_fd;
- bool write_timestamp;
+ bool input;
+ bool line_continued;
};
+void iostream_rawlog_init(struct rawlog_iostream *rstream,
+ enum iostream_rawlog_flags flags, bool input);
void iostream_rawlog_write(struct rawlog_iostream *rstream,
const unsigned char *data, size_t size);
void iostream_rawlog_close(struct rawlog_iostream *rstream);
diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/iostream-rawlog.c
--- a/src/lib/iostream-rawlog.c Wed Aug 29 16:12:08 2012 +0300
+++ b/src/lib/iostream-rawlog.c Wed Aug 29 16:18:56 2012 +0300
@@ -3,19 +3,23 @@
#include "lib.h"
#include "hostpid.h"
#include "ioloop.h"
+#include "buffer.h"
+#include "str.h"
#include "write-full.h"
#include "time-util.h"
#include "istream.h"
#include "ostream.h"
+#include "iostream-private.h"
+#include "iostream-rawlog-private.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>
+#define RAWLOG_MAX_LINE_LEN 8192
+
static void
rawlog_write(struct rawlog_iostream *rstream, const void *data, size_t size)
{
@@ -29,43 +33,98 @@
}
}
-static void rawlog_write_timestamp(struct rawlog_iostream *rstream)
+static void
+rawlog_write_timestamp(struct rawlog_iostream *rstream, bool line_ends)
{
- char buf[MAX_INT_STRLEN + 6 + 2];
+ unsigned char data[MAX_INT_STRLEN + 6 + 1 + 3];
+ buffer_t buf;
- if (i_snprintf(buf, sizeof(buf), "%lu.%06u ",
- (unsigned long)ioloop_timeval.tv_sec,
- (unsigned int)ioloop_timeval.tv_usec) < 0)
- i_unreached();
- rawlog_write(rstream, buf, strlen(buf));
+ buffer_create_data(&buf, data, sizeof(data));
+ str_printfa(&buf, "%lu.%06u ",
+ (unsigned long)ioloop_timeval.tv_sec,
+ (unsigned int)ioloop_timeval.tv_usec);
+ if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0) {
+ str_append_c(&buf, rstream->input ? 'I' : 'O');
+ str_append_c(&buf, line_ends ? ':' : '>');
+ str_append_c(&buf, ' ');
+ }
+ rawlog_write(rstream, buf.data, buf.used);
+}
+
+void iostream_rawlog_init(struct rawlog_iostream *rstream,
+ enum iostream_rawlog_flags flags, bool input)
+{
+ rstream->flags = flags;
+ rstream->input = input;
+ if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) != 0)
+ rstream->buffer = buffer_create_dynamic(default_pool, 1024);
+}
+
+static void
+iostream_rawlog_write_unbuffered(struct rawlog_iostream *rstream,
+ const unsigned char *data, size_t size)
+{
+ size_t i, start;
+
+ if (!rstream->line_continued)
+ rawlog_write_timestamp(rstream, TRUE);
+
+ for (start = 0, i = 1; i < size; i++) {
+ if (data[i-1] == '\n') {
+ rawlog_write(rstream, data + start, i - start);
+ rawlog_write_timestamp(rstream, TRUE);
+ start = i;
+ }
+ }
+ if (start != size)
+ rawlog_write(rstream, data + start, size - start);
+ rstream->line_continued = data[size-1] != '\n';
}
void iostream_rawlog_write(struct rawlog_iostream *rstream,
const unsigned char *data, size_t size)
{
- size_t i, start;
+ const unsigned char *p;
+ size_t pos;
+ bool line_ends;
i_assert(size > 0);
io_loop_time_refresh();
- if (rstream->write_timestamp)
- rawlog_write_timestamp(rstream);
+ if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_BUFFERED) == 0) {
+ iostream_rawlog_write_unbuffered(rstream, data, size);
+ return;
+ }
- 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;
+ do {
+ p = memchr(data, '\n', size);
+ if (p != NULL) {
+ line_ends = TRUE;
+ pos = p-data + 1;
+ } else if (rstream->buffer->used + size < RAWLOG_MAX_LINE_LEN) {
+ buffer_append(rstream->buffer, data, size);
+ return;
+ } else {
+ line_ends = FALSE;
+ pos = size;
}
- }
- if (start != size)
- rawlog_write(rstream, data + start, size - start);
- rstream->write_timestamp = data[size-1] == '\n';
+
+ rawlog_write_timestamp(rstream, line_ends);
+ if (rstream->buffer->used > 0) {
+ rawlog_write(rstream, rstream->buffer->data,
+ rstream->buffer->used);
+ }
+ rawlog_write(rstream, data, pos);
+
+ data += pos;
+ size -= pos;
+ } while (size > 0);
}
void iostream_rawlog_close(struct rawlog_iostream *rstream)
{
- if (rstream->autoclose_fd && rstream->rawlog_fd != -1) {
+ if ((rstream->flags & IOSTREAM_RAWLOG_FLAG_AUTOCLOSE) != 0 &&
+ rstream->rawlog_fd != -1) {
if (close(rstream->rawlog_fd) < 0) {
i_error("rawlog_istream.close(%s) failed: %m",
rstream->rawlog_path);
@@ -73,31 +132,39 @@
}
rstream->rawlog_fd = -1;
i_free_and_null(rstream->rawlog_path);
+ if (rstream->buffer != NULL)
+ buffer_free(&rstream->buffer);
}
int iostream_rawlog_create(const char *dir, struct istream **input,
struct ostream **output)
{
static unsigned int counter = 0;
- const char *timestamp, *in_path, *out_path;
+ const char *timestamp, *prefix;
+
+ timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time);
+
+ counter++;
+ prefix = t_strdup_printf("%s/%s.%s.%u", dir, timestamp, my_pid, counter);
+ return iostream_rawlog_create_prefix(prefix, input, output);
+}
+
+int iostream_rawlog_create_prefix(const char *prefix, struct istream **input,
+ struct ostream **output)
+{
+ const char *in_path, *out_path;
struct istream *old_input;
struct ostream *old_output;
int in_fd, out_fd;
- timestamp = t_strflocaltime("%Y%m%d-%H%M%S", ioloop_time);
-
- 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_path = t_strdup_printf("%s.in", prefix);
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_path = t_strdup_printf("%s.out", prefix);
out_fd = open(out_path, O_CREAT | O_APPEND | O_WRONLY, 0600);
if (out_fd == -1) {
i_error("creat(%s) failed: %m", out_path);
@@ -108,9 +175,37 @@
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);
+ *input = i_stream_create_rawlog(old_input, in_path, in_fd,
+ IOSTREAM_RAWLOG_FLAG_AUTOCLOSE);
+ *output = o_stream_create_rawlog(old_output, out_path, out_fd,
+ IOSTREAM_RAWLOG_FLAG_AUTOCLOSE);
i_stream_unref(&old_input);
o_stream_unref(&old_output);
return 0;
}
+
+int iostream_rawlog_create_path(const char *path, struct istream **input,
+ struct ostream **output)
+{
+ struct istream *old_input;
+ struct ostream *old_output;
+ int fd;
+
+ fd = open(path, O_CREAT | O_APPEND | O_WRONLY, 0600);
+ if (fd == -1) {
+ i_error("creat(%s) failed: %m", path);
+ return -1;
+ }
+
+ old_input = *input;
+ old_output = *output;
+ *input = i_stream_create_rawlog(old_input, path, fd,
+ IOSTREAM_RAWLOG_FLAG_AUTOCLOSE |
+ IOSTREAM_RAWLOG_FLAG_BUFFERED);
+ *output = o_stream_create_rawlog(old_output, path, fd,
+ IOSTREAM_RAWLOG_FLAG_AUTOCLOSE |
+ IOSTREAM_RAWLOG_FLAG_BUFFERED);
+ i_stream_unref(&old_input);
+ o_stream_unref(&old_output);
+ return 0;
+}
diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/iostream-rawlog.h
--- a/src/lib/iostream-rawlog.h Wed Aug 29 16:12:08 2012 +0300
+++ b/src/lib/iostream-rawlog.h Wed Aug 29 16:18:56 2012 +0300
@@ -1,8 +1,17 @@
#ifndef IOSTREAM_RAWLOG_H
#define IOSTREAM_RAWLOG_H
+/* Create rawlog *.in and *.out files to the given directory. */
int ATTR_NOWARN_UNUSED_RESULT
iostream_rawlog_create(const char *dir, struct istream **input,
struct ostream **output);
+/* Create rawlog prefix.in and prefix.out files. */
+int ATTR_NOWARN_UNUSED_RESULT
+iostream_rawlog_create_prefix(const char *prefix, struct istream **input,
+ struct ostream **output);
+/* Create rawlog path, writing both input and output to the same file. */
+int ATTR_NOWARN_UNUSED_RESULT
+iostream_rawlog_create_path(const char *path, struct istream **input,
+ struct ostream **output);
#endif
diff -r fff00bb85ae4 -r 8ce6d41d2d41 src/lib/istream-rawlog.c
--- a/src/lib/istream-rawlog.c Wed Aug 29 16:12:08 2012 +0300
+++ b/src/lib/istream-rawlog.c Wed Aug 29 16:18:56 2012 +0300
@@ -71,7 +71,7 @@
struct istream *
i_stream_create_rawlog(struct istream *input, const char *rawlog_path,
- int rawlog_fd, bool autoclose_fd)
+ int rawlog_fd, enum iostream_rawlog_flags flags)
More information about the dovecot-cvs
mailing list