source: trunk/src/sh_fifo.c @ 481

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

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

File size: 9.8 KB
Line 
1/* SAMHAIN file system integrity testing                                   */
2/* Copyright (C) 1999, 2000 Rainer Wichmann                                */
3/*                                                                         */
4/*  This program is free software; you can redistribute it                 */
5/*  and/or modify                                                          */
6/*  it under the terms of the GNU General Public License as                */
7/*  published by                                                           */
8/*  the Free Software Foundation; either version 2 of the License, or      */
9/*  (at your option) any later version.                                    */
10/*                                                                         */
11/*  This program is distributed in the hope that it will be useful,        */
12/*  but WITHOUT ANY WARRANTY; without even the implied warranty of         */
13/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
14/*  GNU General Public License for more details.                           */
15/*                                                                         */
16/*  You should have received a copy of the GNU General Public License      */
17/*  along with this program; if not, write to the Free Software            */
18/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
19
20#include "config_xor.h"
21
22#include <stdlib.h>
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26
27#undef  FIL__
28#define FIL__  _("sh.fifo.c")
29
30
31#include "samhain.h"
32#include "sh_mem.h"
33#include "sh_unix.h"
34#include "sh_utils.h"
35#include "sh_string.h"
36#include "sh_fifo.h"
37
38#if defined(HAVE_MLOCK) && !defined(HAVE_BROKEN_MLOCK)
39#include <sys/mman.h>
40#endif
41
42#define SH_FIFO_TAGGED 1
43#define SH_FIFO_M_FAIL 2
44#define SH_FIFO_MARKED 4
45
46/* Prepare an email message and return it. Iterate over list on stack and
47 * check for each if it is valid for recipient 'tag'. If yes, add to the
48 * returned string.
49 * okNull == False means that item->s_xtra must be defined
50 */
51sh_string * tag_list (SH_FIFO * fifo, char * tag,
52                      int(*valid)(int, const char*, const char*, const void*),
53                      const void * info, int okNull)
54{
55  struct dlist * item;
56  sh_string * result = NULL;
57
58  if (fifo && fifo->fifo_cts > 0)
59    {
60      item = fifo->head_ptr;
61
62      while (item)
63        {
64          /* Same recipient, or no recipient ( := all )
65           */
66          if ( (tag && item->s_xtra && 0 == strcmp(item->s_xtra, tag)) ||
67               ((okNull == S_TRUE) && !(item->s_xtra)) )
68            {
69              if (valid == NULL)
70                {
71                  item->transact |= SH_FIFO_TAGGED;
72                }
73              else
74                {
75                  /* level, message, recipient, list */
76                  if (!valid(item->i_xtra, item->data, tag, info))
77                    goto skipped;
78                  item->transact |= SH_FIFO_TAGGED;
79                }
80              if (!result)
81                {
82                  result = sh_string_new_from_lchar(item->data, strlen(item->data));
83                }
84              else
85                {
86                  result = sh_string_cat_lchar(result, "\r\n", 2);
87                  result = sh_string_add_from_char(result, item->data);
88                }
89            }
90        skipped:
91          item = item->next;
92        }
93    }
94  return result;
95}
96
97void rollback_list (SH_FIFO * fifo)
98{
99  struct dlist * item;
100
101  if (fifo && fifo->fifo_cts > 0)
102    {
103      item = fifo->head_ptr;
104
105      while (item && 0 != (item->transact & SH_FIFO_TAGGED))
106        {
107          item->transact |= SH_FIFO_M_FAIL;
108          item = item->next;
109        }
110    }
111}
112
113void mark_list (SH_FIFO * fifo)
114{
115  struct dlist * item;
116
117  if (fifo && fifo->fifo_cts > 0)
118    {
119      item = fifo->head_ptr;
120
121      while (item && 0 != (item->transact & SH_FIFO_TAGGED))
122        {
123          item->transact |= SH_FIFO_MARKED;
124          item = item->next;
125        }
126    }
127}
128
129void reset_list (SH_FIFO * fifo)
130{
131  struct dlist * item;
132
133  if (fifo && fifo->fifo_cts > 0)
134    {
135      item = fifo->head_ptr;
136
137      while (item)
138        {
139          item->transact = 0;
140          item = item->next;
141        }
142    }
143}
144
145int commit_list (SH_FIFO * fifo)
146{
147  struct dlist * item;
148  struct dlist * getit;
149  int    retval = 0;
150
151  if (fifo && fifo->fifo_cts > 0)
152    {
153      item = fifo->head_ptr;
154
155      while (item)
156        {
157          getit = NULL;
158
159          if ( 0 != (item->transact & SH_FIFO_MARKED) && /* sent              */
160               0 == (item->transact & SH_FIFO_M_FAIL) )  /* no recipient fail */
161            {
162              if (item == fifo->head_ptr)
163                fifo->head_ptr   = item->next;
164              if (item == fifo->tail_ptr)
165                fifo->tail_ptr   = item->prev;
166              if (item->prev)
167                item->prev->next = item->next;
168              if (item->next)
169                item->next->prev = item->prev;
170              --(fifo->fifo_cts);
171              getit = item;
172            }
173          item  = item->next;
174
175          /* Delete it
176           */
177          if (getit)
178            {
179              size_t len = sl_strlen(getit->data);
180              memset(getit->data, 0, len);
181              if (NULL != sl_strstr (getit->data, _("LOGKEY")))
182                MUNLOCK(getit->data, (len+1));
183              if (getit->s_xtra)
184                SH_FREE(getit->s_xtra);
185              SH_FREE(getit->data);
186              SH_FREE(getit);
187              ++retval;
188            }
189        }
190    }
191  return retval;
192}
193
194/* push an item on the head of the list
195 */
196int push_list (SH_FIFO * fifo, const char * indat, int in_i, const char * in_str)
197{
198  struct dlist * item;
199  size_t         len;
200
201  SL_ENTER(_("push_list"));
202
203  if (indat == NULL || fifo == NULL)
204    {
205      SL_RETURN((-1), _("push_list"));
206    }
207
208  if (fifo->fifo_cts > SH_FIFO_MAX)
209    {
210      SL_RETURN((-1), _("push_list"));
211    }
212
213  len             = sl_strlen(indat);
214
215  if (len == 0)
216    {
217      SL_RETURN((-1), _("push_list"));
218    }
219  item            = SH_ALLOC(sizeof(struct dlist));
220  item->data      = SH_ALLOC(len+1);
221 
222  if (NULL != sl_strstr (indat, _("LOGKEY")))
223    MLOCK(item->data, (len+1));
224
225  sl_strlcpy (item->data, indat, len+1);
226  item->data[len] = '\0';
227
228  item->i_xtra = in_i;
229  if (in_str)
230    item->s_xtra = sh_util_strdup(in_str);
231  else
232    item->s_xtra = NULL;
233  item->transact = 0;
234
235  if (fifo->tail_ptr == NULL)
236    {
237      fifo->tail_ptr = item;
238      item->prev     = NULL;
239    }
240  else
241    {
242      fifo->head_ptr->prev = item;
243      item->prev           = NULL;
244    }
245
246  item->next      = fifo->head_ptr;
247  fifo->head_ptr  = item;
248
249  ++(fifo->fifo_cts);
250
251  SL_RETURN((fifo->fifo_cts), _("push_list"));
252}
253
254/* push an item on the tail of the list
255 */
256int push_tail_list (SH_FIFO * fifo, const char * indat, int in_i, const char * in_str)
257{
258  struct dlist * item;
259  size_t         len;
260
261  SL_ENTER(_("push_tail_list"));
262
263  if (indat == NULL || fifo == NULL)
264    {
265      SL_RETURN((-1), _("push_tail_list"));
266    }
267
268  if (fifo->fifo_cts > SH_FIFO_MAX)
269    {
270      SL_RETURN((-1), _("push_tail_list"));
271    }
272
273  len = sl_strlen(indat);
274  if (len == 0)
275    {
276      SL_RETURN((-1), _("push_list"));
277    }
278
279  item            = SH_ALLOC(sizeof(struct dlist));
280  item->data      = SH_ALLOC(len+1);
281
282  if (NULL != sl_strstr (indat, _("LOGKEY")))
283    MLOCK(item->data, (len+1));
284
285  sl_strlcpy (item->data, indat, len+1);
286  item->data[len] = '\0';
287
288  item->i_xtra = in_i;
289  if (in_str)
290    item->s_xtra = sh_util_strdup(in_str);
291  else
292    item->s_xtra = NULL;
293  item->transact = 0;
294
295  if (fifo->head_ptr == NULL)
296    {
297      item->next     = NULL;
298      fifo->head_ptr = item;
299    }
300  else
301    {
302      item->next           = NULL;
303      fifo->tail_ptr->next = item;
304    }
305
306  item->prev     = fifo->tail_ptr;
307  fifo->tail_ptr = item;
308
309  ++(fifo->fifo_cts);
310
311  SL_RETURN((fifo->fifo_cts), _("push_tail_list"));
312}
313
314/* pop an item from the tail of the list
315 */
316/*@null@*/ char * pop_list (SH_FIFO * fifo)
317{
318  size_t         len;
319  struct dlist * getit;
320  char         * retval;
321
322  SL_ENTER(_("pop_list"));
323
324  if (fifo == NULL || fifo->tail_ptr == NULL)
325    {
326      SL_RETURN (NULL, _("pop_list"));
327    }
328
329  getit       = fifo->tail_ptr;
330
331  if (getit->prev == NULL) /* last element */
332    {
333      fifo->tail_ptr = NULL;
334      fifo->head_ptr = NULL;
335    } 
336  else
337    {
338      fifo->tail_ptr        = getit->prev;
339      fifo->tail_ptr->next  = getit->next;
340    } 
341 
342  len         = sl_strlen(getit->data);
343  retval      = SH_ALLOC(len+1);
344  sl_strlcpy (retval, getit->data, len+1);
345 
346  memset(getit->data, 0, len);
347
348  if (NULL != sl_strstr (retval, _("LOGKEY")))
349    MUNLOCK(getit->data, (len+1));
350
351  if (getit->s_xtra)
352    SH_FREE(getit->s_xtra);
353  SH_FREE(getit->data);
354  SH_FREE(getit);
355
356  --(fifo->fifo_cts);
357
358  SL_RETURN (retval, _("pop_list"));
359}
360
361
362#ifdef SH_CUTEST
363#include "CuTest.h"
364
365void Test_fifo (CuTest *tc) {
366
367  SH_FIFO ff;
368  int ret;
369  char * p;
370
371  fifo_init(&ff);
372
373  p = sh_fifo_pop(&ff);
374  CuAssertPtrEquals(tc, NULL, p);
375
376  /* first sequence */
377  ret = sh_fifo_push(&ff, "one");
378  CuAssertIntEquals(tc,1,ret);
379  ret = sh_fifo_push(&ff, "two");
380  CuAssertIntEquals(tc,2,ret);
381  ret = sh_fifo_push(&ff, "three");
382  CuAssertIntEquals(tc,3,ret);
383
384  p = sh_fifo_pop(&ff);
385  CuAssertPtrNotNull(tc, p);
386  CuAssertStrEquals(tc,"one", p);
387  p = sh_fifo_pop(&ff);
388  CuAssertPtrNotNull(tc, p);
389  CuAssertStrEquals(tc,"two", p);
390  p = sh_fifo_pop(&ff);
391  CuAssertPtrNotNull(tc, p);
392  CuAssertStrEquals(tc,"three", p);
393  p = sh_fifo_pop(&ff);
394  CuAssertPtrEquals(tc, NULL, p);
395
396  /* second sequence */
397  ret = sh_fifo_push(&ff, "one");
398  CuAssertIntEquals(tc,1,ret);
399  p = sh_fifo_pop(&ff);
400  CuAssertPtrNotNull(tc, p);
401  CuAssertStrEquals(tc,"one", p);
402  ret = sh_fifo_push_tail(&ff, "one");
403  CuAssertIntEquals(tc,1,ret);
404  p = sh_fifo_pop(&ff);
405  CuAssertPtrNotNull(tc, p);
406  CuAssertStrEquals(tc,"one", p);
407  p = sh_fifo_pop(&ff);
408  CuAssertPtrEquals(tc, NULL, p);
409
410  /* third sequence */
411  ret = sh_fifo_push(&ff, "one");
412  CuAssertIntEquals(tc,1,ret);
413  ret = sh_fifo_push(&ff, "two");
414  CuAssertIntEquals(tc,2,ret);
415  ret = sh_fifo_push(&ff, "three");
416  CuAssertIntEquals(tc,3,ret);
417
418  p = sh_fifo_pop(&ff);
419  CuAssertPtrNotNull(tc, p);
420  CuAssertStrEquals(tc,"one", p);
421  ret = sh_fifo_push_tail(&ff, p);
422  CuAssertIntEquals(tc,3,ret);
423
424  p = sh_fifo_pop(&ff);
425  CuAssertPtrNotNull(tc, p);
426  CuAssertStrEquals(tc,"one", p);
427  p = sh_fifo_pop(&ff);
428  CuAssertPtrNotNull(tc, p);
429  CuAssertStrEquals(tc,"two", p);
430  p = sh_fifo_pop(&ff);
431  CuAssertPtrNotNull(tc, p);
432  CuAssertStrEquals(tc,"three", p);
433  p = sh_fifo_pop(&ff);
434  CuAssertPtrEquals(tc, NULL, p);
435}
436
437#endif
438
439
440
441
Note: See TracBrowser for help on using the repository browser.