source: trunk/src/sh_log_mark.c@ 561

Last change on this file since 561 was 481, checked in by katerina, 9 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

File size: 6.2 KB
Line 
1#include "config_xor.h"
2
3#ifdef USE_LOGFILE_MONITOR
4
5#include <string.h>
6#include <time.h>
7
8#undef FIL__
9#define FIL__ _("sh_log_mark.c")
10
11
12#include "samhain.h"
13#include "sh_pthread.h"
14#include "sh_mem.h"
15#include "sh_string.h"
16#include "sh_error_min.h"
17#include "sh_log_check.h"
18#include "sh_log_evalrule.h"
19#include "zAVLTree.h"
20
21/* #define DEBUG_MARK */
22
23#ifdef DEBUG_MARK
24static void DEBUG(const char *fmt, ...)
25{
26 va_list ap;
27 va_start(ap, fmt);
28 vfprintf(stderr, fmt, ap); /* flawfinder: ignore *//* we control fmt string */
29 va_end(ap);
30 return;
31}
32#else
33static void DEBUG(const char *fmt, ...)
34{
35 (void) fmt;
36 return;
37}
38#endif
39
40static zAVLTree * marklist = NULL;
41
42struct sh_mark_event
43{
44 sh_string * label;
45 sh_string * queue_id;
46 time_t last_seen;
47 time_t interval;
48 time_t delay;
49 time_t last_reported;
50};
51
52static void sh_marklist_free(void * item)
53{
54 struct sh_mark_event * event = (struct sh_mark_event *) item;
55 if (!event)
56 return;
57 sh_string_destroy(&(event->label));
58 sh_string_destroy(&(event->queue_id));
59 SH_FREE(event);
60 return;
61}
62
63void sh_log_mark_destroy()
64{
65 zAVLFreeTree(marklist, sh_marklist_free);
66}
67
68static zAVLKey sh_log_mark_getkey(void const *item)
69{
70 return ((const struct sh_mark_event *)item)->label->str;
71}
72
73int sh_log_mark_add (const char * label, time_t interval, const char * qlabel)
74{
75 struct sh_mark_event * event;
76
77 if (!(marklist))
78 {
79 marklist = zAVLAllocTree(sh_log_mark_getkey, zAVL_KEY_STRING);
80 }
81
82 event = (struct sh_mark_event *) zAVLSearch(marklist, label);
83 if (event)
84 {
85 event->interval = interval;
86 sh_string_destroy(&(event->queue_id));
87 event->queue_id = sh_string_new_from_lchar(qlabel, strlen(qlabel));
88 return 0;
89 }
90
91 event = SH_ALLOC(sizeof(struct sh_mark_event));
92
93 event->last_seen = time(NULL);
94 event->interval = interval;
95 event->delay = 0;
96 event->last_reported = 0;
97 event->label = sh_string_new_from_lchar(label, strlen(label));
98 event->queue_id = sh_string_new_from_lchar(qlabel, strlen(qlabel));
99
100 if (0 != zAVLInsert(marklist, event))
101 {
102 sh_marklist_free(event);
103 return -1;
104 }
105 return 0;
106}
107
108void sh_log_mark_update (sh_string * label, time_t timestamp)
109{
110 struct sh_mark_event * event =
111 (struct sh_mark_event *) zAVLSearch (marklist, sh_string_str(label));
112
113 DEBUG("debug: running mark update for %s\n", sh_string_str(label));
114
115 if (event)
116 {
117 DEBUG("debug: updating, timestamp %lu, last_seen %lu, interval %d\n",
118 (unsigned long)timestamp, (unsigned long) event->last_seen,
119 (int)event->interval);
120
121 if ((timestamp > event->last_seen) &&
122 (event->interval < (timestamp - event->last_seen)) &&
123 (timestamp > event->last_reported) &&
124 (event->interval < (timestamp - event->last_reported)))
125 {
126 event->delay = timestamp - event->last_seen;
127 DEBUG("debug: updating delay to %d\n", (int) event->delay);
128 }
129 event->last_seen = timestamp;
130 }
131 return;
132}
133
134/* This should allow to get all overdue labels with a for loop like:
135 * for (label = sh_log_mark_first(); label; label = sh_log_mark_next()) {}
136 */
137
138static zAVLCursor mark_cursor;
139
140static struct sh_mark_event * sh_log_mark_cursor(time_t * delay, time_t now,
141 struct sh_mark_event * event)
142{
143 while (event)
144 {
145 DEBUG("debug: echeck, delay %d, now %lu, last_seen %lu, reported %lu\n",
146 (int) event->delay,
147 (unsigned long)now, (unsigned long) event->last_seen,
148 (unsigned long)event->last_reported);
149 if (event->delay > 0)
150 {
151 DEBUG("debug: event delay > 0, value %d\n", (int) event->delay);
152 *delay = event->delay;
153 event->delay = 0;
154 event->last_reported = time(NULL);
155 return event;
156 }
157 else if ((now > event->last_seen) &&
158 (now > event->last_reported) &&
159 (event->interval < (now - event->last_seen)) &&
160 (event->interval < (now - event->last_reported))
161 )
162 {
163 DEBUG("debug: event delay 0, now %lu, last_seen %lu, reported %lu\n",
164 (unsigned long)now, (unsigned long) event->last_seen,
165 (unsigned long)event->last_reported);
166 *delay = now - event->last_seen;
167 event->delay = 0;
168 /* Subtract 1 sec to prevent accumulation of the
169 * one second offset. */
170 event->last_reported = time(NULL) - 1;
171 return event;
172 }
173 event = (struct sh_mark_event *) zAVLNext(&mark_cursor);
174 }
175
176 return NULL;
177}
178
179struct sh_mark_event * sh_log_mark_first(time_t * delay, time_t now)
180{
181 struct sh_mark_event * event =
182 (struct sh_mark_event *) zAVLFirst(&mark_cursor, marklist);
183
184 return sh_log_mark_cursor (delay, now, event);
185}
186
187struct sh_mark_event * sh_log_mark_next(time_t * delay, time_t now)
188{
189 struct sh_mark_event * event =
190 (struct sh_mark_event *) zAVLNext(&mark_cursor);
191
192 return sh_log_mark_cursor (delay, now, event);
193}
194
195static int sh_mark_default_severity = SH_ERR_SEVERE;
196
197int sh_log_set_mark_severity (const char * str)
198{
199 int val = sh_error_convert_level(str);
200 if (val < 0)
201 return -1;
202 sh_mark_default_severity = val;
203 return 0;
204}
205
206static struct sh_mark_event ** dummy_event;
207
208void sh_log_mark_check()
209{
210 struct sh_mark_event * event;
211 time_t now = time(NULL);
212 time_t delay;
213
214 /* variable 'event' might be clobbered by 'longjmp' or 'vfork'
215 */
216 dummy_event = &event;
217
218 DEBUG("debug: running mark check\n");
219 for (event = sh_log_mark_first(&delay, now); event;
220 event = sh_log_mark_next (&delay, now))
221 {
222 int severity;
223 sh_string * alias;
224 SH_MUTEX_LOCK(mutex_thread_nolog);
225
226 severity = sh_log_lookup_severity(sh_string_str(event->queue_id));
227 if (severity < 0)
228 severity = sh_mark_default_severity;
229
230 DEBUG("debug: mark check: queue %s, severity %d\n",
231 sh_string_str(event->queue_id), severity);
232 sh_error_handle (severity,
233 FIL__, __LINE__, 0, MSG_LOGMON_MARK,
234 sh_string_str(event->label),
235 (unsigned long) delay);
236 alias = sh_log_lookup_alias(sh_string_str(event->queue_id));
237 if (alias)
238 {
239 sh_error_mail (sh_string_str(alias), severity,
240 FIL__, __LINE__, 0, MSG_LOGMON_MARK,
241 sh_string_str(event->label),
242 (unsigned long) delay);
243 }
244
245 SH_MUTEX_UNLOCK(mutex_thread_nolog);
246 }
247 return;
248}
249
250#endif
Note: See TracBrowser for help on using the repository browser.