source: trunk/src/sh_fifo.c@ 248

Last change on this file since 248 was 214, checked in by katerina, 16 years ago

Rewrite mail subsystem for more flexibility (closes ticket #141).

File size: 7.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.
47 */
48sh_string * tag_list (SH_FIFO * fifo, char * tag,
49 int(*valid)(int, const char*, const char*, const void*),
50 const void * info)
51{
52 struct dlist * item;
53 sh_string * result = NULL;
54
55 if (fifo && fifo->fifo_cts > 0)
56 {
57 item = fifo->head_ptr;
58
59 while (item)
60 {
61 if ( (tag && item->s_xtra && 0 == strcmp(item->s_xtra, tag)) ||
62 !(item->s_xtra) )
63 {
64 if (valid == NULL)
65 {
66 item->transact |= SH_FIFO_TAGGED;
67 }
68 else
69 {
70 if (!valid(item->i_xtra, item->data, tag, info))
71 goto skipped;
72 item->transact |= SH_FIFO_TAGGED;
73 }
74 if (!result)
75 {
76 result = sh_string_new_from_lchar(item->data, strlen(item->data));
77 }
78 else
79 {
80 result = sh_string_cat_lchar(result, "\r\n", 2);
81 result = sh_string_add_from_char(result, item->data);
82 }
83 }
84 skipped:
85 item = item->next;
86 }
87 }
88 return result;
89}
90
91void rollback_list (SH_FIFO * fifo)
92{
93 struct dlist * item;
94
95 if (fifo && fifo->fifo_cts > 0)
96 {
97 item = fifo->head_ptr;
98
99 while (item && 0 != (item->transact & SH_FIFO_TAGGED))
100 {
101 item->transact |= SH_FIFO_M_FAIL;
102 item = item->next;
103 }
104 }
105}
106
107void mark_list (SH_FIFO * fifo)
108{
109 struct dlist * item;
110
111 if (fifo && fifo->fifo_cts > 0)
112 {
113 item = fifo->head_ptr;
114
115 while (item && 0 != (item->transact & SH_FIFO_TAGGED))
116 {
117 item->transact |= SH_FIFO_MARKED;
118 item = item->next;
119 }
120 }
121}
122
123void reset_list (SH_FIFO * fifo)
124{
125 struct dlist * item;
126
127 if (fifo && fifo->fifo_cts > 0)
128 {
129 item = fifo->head_ptr;
130
131 while (item)
132 {
133 item->transact = 0;
134 item = item->next;
135 }
136 }
137}
138
139int commit_list (SH_FIFO * fifo)
140{
141 struct dlist * item;
142 struct dlist * getit;
143 int retval = 0;
144
145 if (fifo && fifo->fifo_cts > 0)
146 {
147 item = fifo->head_ptr;
148
149 while (item)
150 {
151 getit = NULL;
152
153 if ( 0 != (item->transact & SH_FIFO_MARKED) && /* sent */
154 0 == (item->transact & SH_FIFO_M_FAIL) ) /* no recipient fail */
155 {
156 if (item == fifo->head_ptr)
157 fifo->head_ptr = item->next;
158 if (item == fifo->tail_ptr)
159 fifo->tail_ptr = item->prev;
160 if (item->prev)
161 item->prev->next = item->next;
162 if (item->next)
163 item->next->prev = item->prev;
164 --(fifo->fifo_cts);
165 getit = item;
166 }
167 item = item->next;
168
169 /* Delete it
170 */
171 if (getit)
172 {
173 size_t len = sl_strlen(getit->data);
174 memset(getit->data, 0, len);
175 if (NULL != sl_strstr (getit->data, _("LOGKEY")))
176 {
177 MUNLOCK(getit->data, (len+1));
178 ;
179 }
180 if (getit->s_xtra)
181 SH_FREE(getit->s_xtra);
182 SH_FREE(getit->data);
183 SH_FREE(getit);
184 ++retval;
185 }
186 }
187 }
188 return retval;
189}
190
191/* push an item on the head of the list
192 */
193int push_list (SH_FIFO * fifo, char * indat, int in_i, const char * in_str)
194{
195 struct dlist * item;
196 size_t len;
197
198 SL_ENTER(_("push_list"));
199
200 if (indat == NULL || fifo == NULL)
201 {
202 SL_RETURN((-1), _("push_list"));
203 }
204
205 if (fifo->fifo_cts > SH_FIFO_MAX)
206 {
207 SL_RETURN((-1), _("push_list"));
208 }
209
210 len = sl_strlen(indat);
211
212 if (len == 0)
213 {
214 SL_RETURN((-1), _("push_list"));
215 }
216 item = SH_ALLOC(sizeof(struct dlist));
217 item->data = SH_ALLOC(len+1);
218
219 if (NULL != sl_strstr (indat, _("LOGKEY")))
220 {
221 MLOCK(item->data, (len+1));
222 ;
223 }
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, 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 {
284 MLOCK(item->data, (len+1));
285 ;
286 }
287
288 sl_strlcpy (item->data, indat, len+1);
289 item->data[len] = '\0';
290
291 item->i_xtra = in_i;
292 if (in_str)
293 item->s_xtra = sh_util_strdup(in_str);
294 else
295 item->s_xtra = NULL;
296 item->transact = 0;
297
298 if (fifo->head_ptr == NULL)
299 {
300 item->next = NULL;
301 fifo->head_ptr = item;
302 }
303 else
304 {
305 item->next = NULL;
306 fifo->tail_ptr->next = item;
307 }
308
309 item->prev = fifo->tail_ptr;
310 fifo->tail_ptr = item;
311
312 ++(fifo->fifo_cts);
313
314 SL_RETURN((0), _("push_tail_list"));
315}
316
317/* pop an item from the tail of the list
318 */
319/*@null@*/ char * pop_list (SH_FIFO * fifo)
320{
321 size_t len;
322 struct dlist * getit;
323 char * retval;
324
325 SL_ENTER(_("pop_list"));
326
327 if (fifo == NULL || fifo->tail_ptr == NULL)
328 {
329 SL_RETURN (NULL, _("pop_list"));
330 }
331
332 getit = fifo->tail_ptr;
333
334 if (getit->prev == NULL) /* last element */
335 {
336 fifo->tail_ptr = NULL;
337 fifo->head_ptr = NULL;
338 }
339 else
340 {
341 fifo->tail_ptr = getit->prev;
342 fifo->tail_ptr->next = getit->next;
343 }
344
345 len = sl_strlen(getit->data);
346 retval = SH_ALLOC(len+1);
347 sl_strlcpy (retval, getit->data, len+1);
348
349 memset(getit->data, 0, len);
350
351 if (NULL != sl_strstr (retval, _("LOGKEY")))
352 {
353 MUNLOCK(getit->data, (len+1));
354 ;
355 }
356
357 if (getit->s_xtra)
358 SH_FREE(getit->s_xtra);
359 SH_FREE(getit->data);
360 SH_FREE(getit);
361
362 --(fifo->fifo_cts);
363
364 SL_RETURN (retval, _("pop_list"));
365}
366
367
368
369
Note: See TracBrowser for help on using the repository browser.