From: Timo Sirainen Date: Mon, 6 Feb 2012 19:25:37 +0000 (+0200) Subject: log: Forgot to add new files to recent commit. X-Git-Tag: 2.1.rc6~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a3c23e577be41f7521995c5dae19abb2fb4ffb6;p=thirdparty%2Fdovecot%2Fcore.git log: Forgot to add new files to recent commit. --- diff --git a/src/log/doveadm-connection.c b/src/log/doveadm-connection.c new file mode 100644 index 0000000000..9c5f1edddd --- /dev/null +++ b/src/log/doveadm-connection.c @@ -0,0 +1,88 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ostream.h" +#include "str.h" +#include "strescape.h" +#include "master-service.h" +#include "log-error-buffer.h" +#include "doveadm-connection.h" + +#include + +struct doveadm_connection { + struct log_error_buffer *errorbuf; + + int fd; + struct ostream *output; +}; + +static void doveadm_connection_destroy(struct doveadm_connection **_conn); + +static int doveadm_connection_send_errors(struct doveadm_connection *conn) +{ + struct log_error_buffer_iter *iter; + const struct log_error *error; + string_t *str = t_str_new(256); + int ret = 0; + + iter = log_error_buffer_iter_init(conn->errorbuf); + while ((error = log_error_buffer_iter_next(iter)) != NULL) { + str_truncate(str, 0); + str_printfa(str, "%s\t%ld\t", + failure_log_type_names[error->type], + (long)error->timestamp); + str_tabescape_write(str, error->prefix); + str_append_c(str, '\t'); + str_tabescape_write(str, error->text); + str_append_c(str, '\n'); + if (o_stream_send(conn->output, + str_data(str), str_len(str)) < 0) { + ret = -1; + break; + } + } + log_error_buffer_iter_deinit(&iter); + return ret; +} + +static int doveadm_output(struct doveadm_connection *conn) +{ + int ret; + + if ((ret = o_stream_flush(conn->output)) != 0) { + /* error / finished */ + doveadm_connection_destroy(&conn); + } + return 1; +} + +void doveadm_connection_create(struct log_error_buffer *errorbuf, int fd) +{ + struct doveadm_connection *conn; + + conn = i_new(struct doveadm_connection, 1); + conn->errorbuf = errorbuf; + conn->fd = fd; + conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE); + if (doveadm_connection_send_errors(conn) < 0) + doveadm_connection_destroy(&conn); + else { + o_stream_set_flush_callback(conn->output, doveadm_output, conn); + o_stream_set_flush_pending(conn->output, TRUE); + } +} + +static void doveadm_connection_destroy(struct doveadm_connection **_conn) +{ + struct doveadm_connection *conn = *_conn; + + *_conn = NULL; + + o_stream_destroy(&conn->output); + if (close(conn->fd) < 0) + i_error("close(doveadm connection) failed: %m"); + i_free(conn); + + master_service_client_connection_destroyed(master_service); +} diff --git a/src/log/doveadm-connection.h b/src/log/doveadm-connection.h new file mode 100644 index 0000000000..c37eee4dbb --- /dev/null +++ b/src/log/doveadm-connection.h @@ -0,0 +1,6 @@ +#ifndef DOVEADM_CONNECTION_H +#define DOVEADM_CONNECTION_H + +void doveadm_connection_create(struct log_error_buffer *errorbuf, int fd); + +#endif diff --git a/src/log/log-error-buffer.c b/src/log/log-error-buffer.c new file mode 100644 index 0000000000..26e86e8f16 --- /dev/null +++ b/src/log/log-error-buffer.c @@ -0,0 +1,121 @@ +/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "log-error-buffer.h" + +#define LOG_ERROR_BUFFER_MAX_LINES 1000 + +struct log_error_data { + struct log_error_data *next; + + enum log_type type; + time_t timestamp; + unsigned char prefix_text[]; +}; + +struct log_error_buffer { + struct log_error_data *head, *tail; + unsigned int count; +}; + +struct log_error_buffer_iter { + struct log_error_buffer *buf; + struct log_error_data *cur; + struct log_error error; +}; + +struct log_error_buffer *log_error_buffer_init(void) +{ + struct log_error_buffer *buf; + + buf = i_new(struct log_error_buffer, 1); + return buf; +} + +static void log_error_buffer_delete_head(struct log_error_buffer *buf) +{ + struct log_error_data *data; + + i_assert(buf->head != NULL); + + buf->count--; + data = buf->head; + buf->head = data->next; + if (buf->tail == data) { + /* last one */ + buf->tail = NULL; + } + i_free(data); +} + +void log_error_buffer_add(struct log_error_buffer *buf, + const struct log_error *error) +{ + unsigned int prefix_size = strlen(error->prefix)+1; + unsigned int text_size = strlen(error->text)+1; + struct log_error_data *data; + + if (buf->count == LOG_ERROR_BUFFER_MAX_LINES) + log_error_buffer_delete_head(buf); + + /* @UNSAFE */ + data = i_malloc(sizeof(*data) + prefix_size + text_size); + data->type = error->type; + data->timestamp = error->timestamp; + memcpy(data->prefix_text, error->prefix, prefix_size); + memcpy(data->prefix_text + prefix_size, error->text, text_size); + + if (buf->tail != NULL) + buf->tail->next = data; + else + buf->head = data; + buf->tail = data; + buf->count++; +} + +void log_error_buffer_deinit(struct log_error_buffer **_buf) +{ + struct log_error_buffer *buf = *_buf; + + *_buf = NULL; + while (buf->count > 0) + log_error_buffer_delete_head(buf); + i_free(buf); +} + +struct log_error_buffer_iter * +log_error_buffer_iter_init(struct log_error_buffer *buf) +{ + struct log_error_buffer_iter *iter; + + iter = i_new(struct log_error_buffer_iter, 1); + iter->buf = buf; + iter->cur = buf->head; + return iter; +} + +struct log_error * +log_error_buffer_iter_next(struct log_error_buffer_iter *iter) +{ + struct log_error_data *data = iter->cur; + + if (data == NULL) + return NULL; + iter->cur = iter->cur->next; + + iter->error.type = data->type; + iter->error.timestamp = data->timestamp; + iter->error.prefix = (const void *)data->prefix_text; + iter->error.text = (const void *)(data->prefix_text + + strlen(iter->error.prefix) + 1); + return &iter->error; +} + +void log_error_buffer_iter_deinit(struct log_error_buffer_iter **_iter) +{ + struct log_error_buffer_iter *iter = *_iter; + + *_iter = NULL; + + i_free(iter); +} diff --git a/src/log/log-error-buffer.h b/src/log/log-error-buffer.h new file mode 100644 index 0000000000..e863c3565d --- /dev/null +++ b/src/log/log-error-buffer.h @@ -0,0 +1,24 @@ +#ifndef LOG_ERROR_BUFFER_H +#define LOG_ERROR_BUFFER_H + +struct log_error_buffer; + +struct log_error { + enum log_type type; + time_t timestamp; + const char *prefix; + const char *text; +}; + +struct log_error_buffer *log_error_buffer_init(void); +void log_error_buffer_add(struct log_error_buffer *buf, + const struct log_error *error); +void log_error_buffer_deinit(struct log_error_buffer **buf); + +struct log_error_buffer_iter * +log_error_buffer_iter_init(struct log_error_buffer *buf); +struct log_error * +log_error_buffer_iter_next(struct log_error_buffer_iter *iter); +void log_error_buffer_iter_deinit(struct log_error_buffer_iter **iter); + +#endif