source: trunk/src/sh_fifo.c@ 478

Last change on this file since 478 was 272, checked in by katerina, 15 years ago

Fixes tickets #190, #191, #192, #193, and #194.

File size: 8.1 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 {
183 MUNLOCK(getit->data, (len+1));
184 ;
185 }
186 if (getit->s_xtra)
187 SH_FREE(getit->s_xtra);
188 SH_FREE(getit->data);
189 SH_FREE(getit);
190 ++retval;
191 }
192 }
193 }
194 return retval;
195}
196
197/* push an item on the head of the list
198 */
199int push_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str)
200{
201 struct dlist * item;
202 size_t len;
203
204 SL_ENTER(_("push_list"));
205
206 if (indat == NULL || fifo == NULL)
207 {
208 SL_RETURN((-1), _("push_list"));
209 }
210
211 if (fifo->fifo_cts > SH_FIFO_MAX)
212 {
213 SL_RETURN((-1), _("push_list"));
214 }
215
216 len = sl_strlen(indat);
217
218 if (len == 0)
219 {
220 SL_RETURN((-1), _("push_list"));
221 }
222 item = SH_ALLOC(sizeof(struct dlist));
223 item->data = SH_ALLOC(len+1);
224
225 if (NULL != sl_strstr (indat, _("LOGKEY")))
226 {
227 MLOCK(item->data, (len+1));
228 ;
229 }
230
231 sl_strlcpy (item->data, indat, len+1);
232 item->data[len] = '\0';
233
234 item->i_xtra = in_i;
235 if (in_str)
236 item->s_xtra = sh_util_strdup(in_str);
237 else
238 item->s_xtra = NULL;
239 item->transact = 0;
240
241 if (fifo->tail_ptr == NULL)
242 {
243 fifo->tail_ptr = item;
244 item->prev = NULL;
245 }
246 else
247 {
248 fifo->head_ptr->prev = item;
249 item->prev = NULL;
250 }
251
252 item->next = fifo->head_ptr;
253 fifo->head_ptr = item;
254
255 ++(fifo->fifo_cts);
256
257 SL_RETURN((fifo->fifo_cts), _("push_list"));
258}
259
260/* push an item on the tail of the list
261 */
262int push_tail_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str)
263{
264 struct dlist * item;
265 size_t len;
266
267 SL_ENTER(_("push_tail_list"));
268
269 if (indat == NULL || fifo == NULL)
270 {
271 SL_RETURN((-1), _("push_tail_list"));
272 }
273
274 if (fifo->fifo_cts > SH_FIFO_MAX)
275 {
276 SL_RETURN((-1), _("push_tail_list"));
277 }
278
279 len = sl_strlen(indat);
280 if (len == 0)
281 {
282 SL_RETURN((-1), _("push_list"));
283 }
284
285 item = SH_ALLOC(sizeof(struct dlist));
286 item->data = SH_ALLOC(len+1);
287
288 if (NULL != sl_strstr (indat, _("LOGKEY")))
289 {
290 MLOCK(item->data, (len+1));
291 ;
292 }
293
294 sl_strlcpy (item->data, indat, len+1);
295 item->data[len] = '\0';
296
297 item->i_xtra = in_i;
298 if (in_str)
299 item->s_xtra = sh_util_strdup(in_str);
300 else
301 item->s_xtra = NULL;
302 item->transact = 0;
303
304 if (fifo->head_ptr == NULL)
305 {
306 item->next = NULL;
307 fifo->head_ptr = item;
308 }
309 else
310 {
311 item->next = NULL;
312 fifo->tail_ptr->next = item;
313 }
314
315 item->prev = fifo->tail_ptr;
316 fifo->tail_ptr = item;
317
318 ++(fifo->fifo_cts);
319
320 SL_RETURN((0), _("push_tail_list"));
321}
322
323/* pop an item from the tail of the list
324 */
325/*@null@*/ char * pop_list (SH_FIFO * fifo)
326{
327 size_t len;
328 struct dlist * getit;
329 char * retval;
330
331 SL_ENTER(_("pop_list"));
332
333 if (fifo == NULL || fifo->tail_ptr == NULL)
334 {
335 SL_RETURN (NULL, _("pop_list"));
336 }
337
338 getit = fifo->tail_ptr;
339
340 if (getit->prev == NULL) /* last element */
341 {
342 fifo->tail_ptr = NULL;
343 fifo->head_ptr = NULL;
344 }
345 else
346 {
347 fifo->tail_ptr = getit->prev;
348 fifo->tail_ptr->next = getit->next;
349 }
350
351 len = sl_strlen(getit->data);
352 retval = SH_ALLOC(len+1);
353 sl_strlcpy (retval, getit->data, len+1);
354
355 memset(getit->data, 0, len);
356
357 if (NULL != sl_strstr (retval, _("LOGKEY")))
358 {
359 MUNLOCK(getit->data, (len+1));
360 ;
361 }
362
363 if (getit->s_xtra)
364 SH_FREE(getit->s_xtra);
365 SH_FREE(getit->data);
366 SH_FREE(getit);
367
368 --(fifo->fifo_cts);
369
370 SL_RETURN (retval, _("pop_list"));
371}
372
373
374
375
Note: See TracBrowser for help on using the repository browser.