source: trunk/src/sh_fifo.c@ 518

Last change on this file since 518 was 481, checked in by katerina, 9 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.