dovecot-2.0: log: Log input wasn't read correctly.
dovecot at dovecot.org
dovecot at dovecot.org
Tue Oct 6 20:24:07 EEST 2009
details: http://hg.dovecot.org/dovecot-2.0/rev/ff4c83871f4d
changeset: 9976:ff4c83871f4d
user: Timo Sirainen <tss at iki.fi>
date: Tue Oct 06 13:24:01 2009 -0400
description:
log: Log input wasn't read correctly.
diffstat:
1 file changed, 52 insertions(+), 41 deletions(-)
src/log/log-connection.c | 93 +++++++++++++++++++++++++---------------------
diffs (146 lines):
diff -r 173435e81938 -r ff4c83871f4d src/log/log-connection.c
--- a/src/log/log-connection.c Tue Oct 06 13:16:11 2009 -0400
+++ b/src/log/log-connection.c Tue Oct 06 13:24:01 2009 -0400
@@ -3,6 +3,7 @@
#include "common.h"
#include "array.h"
#include "ioloop.h"
+#include "istream.h"
#include "llist.h"
#include "hash.h"
#include "master-interface.h"
@@ -27,6 +28,7 @@ struct log_connection {
int fd;
int listen_fd;
struct io *io;
+ struct istream *input;
char *default_prefix;
/* pid -> struct log_client* */
@@ -155,62 +157,69 @@ static void log_it(struct log_connection
i_set_failure_prefix("log: ");
}
-static bool log_connection_handshake(struct log_connection *log,
- char **data, size_t size)
+static int log_connection_handshake(struct log_connection *log)
{
struct log_service_handshake handshake;
-
- if (size < sizeof(handshake))
- return FALSE;
-
- memcpy(&handshake, *data, sizeof(handshake));
- if (handshake.log_magic != MASTER_LOG_MAGIC)
- return FALSE;
-
- if (handshake.prefix_len <= size - sizeof(handshake)) {
- log->default_prefix = i_strndup(*data + sizeof(handshake),
- handshake.prefix_len);
- *data += sizeof(handshake) + handshake.prefix_len;
- }
+ const unsigned char *data;
+ size_t size;
+ ssize_t ret;
+
+ ret = i_stream_read(log->input);
+ if (ret < 0) {
+ i_error("read(log pipe) failed: %m");
+ return -1;
+ }
+ if ((size_t)ret < sizeof(handshake)) {
+ /* this isn't a handshake */
+ return 0;
+ }
+
+ data = i_stream_get_data(log->input, &size);
+ i_assert(size >= sizeof(handshake));
+ memcpy(&handshake, data, sizeof(handshake));
+
+ if (handshake.log_magic != MASTER_LOG_MAGIC) {
+ /* this isn't a handshake */
+ return 0;
+ }
+
+ if (handshake.prefix_len > size - sizeof(handshake)) {
+ i_error("Missing prefix data in handshake");
+ return -1;
+ }
+ log->default_prefix = i_strndup(data + sizeof(handshake),
+ handshake.prefix_len);
+ i_stream_skip(log->input, sizeof(handshake) + handshake.prefix_len);
+
if (strcmp(log->default_prefix, MASTER_LOG_PREFIX_NAME) == 0) {
if (log->listen_fd != MASTER_LISTEN_FD_FIRST) {
i_error("Received master prefix in handshake "
"from non-master fd %d", log->fd);
- return FALSE;
+ return -1;
}
log->master = TRUE;
}
log->handshaked = TRUE;
- return TRUE;
+ return 0;
}
static void log_connection_input(struct log_connection *log)
{
- char data[PIPE_BUF+1], *p, *line;
- ssize_t ret;
-
- ret = read(log->fd, data, sizeof(data)-1);
- if (ret <= 0) {
- if (ret < 0)
- i_error("read(log pipe) failed: %m");
+ const char *line;
+
+ if (!log->handshaked) {
+ if (log_connection_handshake(log) < 0) {
+ log_connection_destroy(log);
+ return;
+ }
+ }
+
+ while ((line = i_stream_read_next_line(log->input)) != NULL)
+ log_it(log, line);
+
+ if (log->input->stream_errno != 0) {
+ i_error("read(log pipe) failed: %m");
log_connection_destroy(log);
- return;
- }
- data[ret] = '\0';
-
- line = data;
- if (!log->handshaked)
- (void)log_connection_handshake(log, &line, ret);
-
- p = line;
- while ((p = strchr(line, '\n')) != NULL) {
- *p = '\0';
- log_it(log, line);
- line = p + 1;
- }
- if (line - data != ret) {
- i_error("Invalid log line follows: Missing LF");
- log_it(log, line);
}
}
@@ -222,6 +231,7 @@ struct log_connection *log_connection_cr
log->fd = fd;
log->listen_fd = listen_fd;
log->io = io_add(fd, IO_READ, log_connection_input, log);
+ log->input = i_stream_create_fd(fd, PIPE_BUF, FALSE);
log->clients = hash_table_create(default_pool, default_pool, 0,
NULL, NULL);
array_idx_set(&logs_by_fd, listen_fd, &log);
@@ -246,6 +256,7 @@ void log_connection_destroy(struct log_c
hash_table_iterate_deinit(&iter);
hash_table_destroy(&log->clients);
+ i_stream_unref(&log->input);
if (log->io != NULL)
io_remove(&log->io);
if (close(log->fd) < 0)
More information about the dovecot-cvs
mailing list