blob: 608d1ad47df839bc56098711f6c96ef31c9f5650 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
/* Copyright (c) 2013-2018 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[FLEXIBLE_ARRAY_MEMBER];
};
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)
{
size_t prefix_size = strlen(error->prefix)+1;
size_t 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(MALLOC_ADD(sizeof(*data),
MALLOC_ADD(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);
}
|