source: trunk/src/sh_log_mark.c @ 363

Last change on this file since 363 was 363, checked in by katerina, 10 years ago

Change zAVL implementation to allow integer keys.

File size: 6.1 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 ((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.