2 * ausearch-lol.c - linked list of linked lists library
3 * Copyright (c) 2008,2010,2014 Red Hat Inc., Durham, North Carolina.
6 * This software may be freely redistributed and/or modified under the
7 * terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2, or (at your option) any
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to the
18 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * Steve Grubb <sgrubb@redhat.com>
24 #include "ausearch-lol.h"
29 #include "ausearch-common.h"
32 #define ARRAY_LIMIT 80
35 void lol_create(lol *lo)
37 int size = ARRAY_LIMIT * sizeof(lolnode);
40 lo->limit = ARRAY_LIMIT;
41 lo->array = (lolnode *)malloc(size);
42 memset(lo->array, 0, size);
45 void lol_clear(lol *lo)
49 for (i=0; i<=lo->maxi; i++) {
50 if (lo->array[i].status) {
51 list_clear(lo->array[i].l);
60 static void lol_append(lol *lo, llist *l)
66 for(i=0; i<lo->limit; i++) {
67 lolnode *cur = &lo->array[i];
68 if (cur->status == L_EMPTY) {
70 cur->status = L_BUILDING;
76 // Overran the array...lets make it bigger
77 new_size = sizeof(lolnode) * (lo->limit + ARRAY_LIMIT);
78 ptr = realloc(lo->array, new_size);
81 memset(&lo->array[lo->limit], 0, sizeof(lolnode) * ARRAY_LIMIT);
83 lo->array[i].status = L_BUILDING;
85 lo->limit += ARRAY_LIMIT;
89 static int str2event(char *s, event *e)
94 ptr = strchr(s+10, ':');
96 e->serial = strtoul(ptr+1, NULL, 10);
102 ptr = strchr(s, '.');
104 e->milli = strtoul(ptr+1, NULL, 10);
110 e->sec = strtoul(s, NULL, 10);
116 static int inline events_are_equal(event *e1, event *e2)
118 if (!(e1->serial == e2->serial && e1->milli == e2->milli &&
121 if (e1->node && e2->node) {
122 if (strcmp(e1->node, e2->node))
124 } else if (e1->node || e2->node)
130 * This function will look at the line and pick out pieces of it.
132 static int extract_timestamp(const char *b, event *e)
134 char *ptr, *tmp, *tnode, *ttype;
138 tmp = strndupa(b, 340);
140 tmp = strndupa(b, 80);
141 ptr = audit_strsplit(tmp);
143 // Check to see if this is the node info
146 ptr = audit_strsplit(NULL);
150 // at this point we have type=
153 // Now should be pointing to msg=
154 ptr = audit_strsplit(NULL);
159 ptr = strchr(ptr, '(');
161 // now we should be pointed at the timestamp
164 eptr = strchr(ptr, ')');
167 if (str2event(ptr, e)) {
169 "Error extracting time stamp (%s)\n",
172 } else if ((start_time && e->sec < start_time)
173 || (end_time && e->sec > end_time))
177 e->node = strdup(tnode);
178 e->type = audit_name_to_msg_type(ttype);
182 // else we have a bad line
184 // else we have a bad line
186 // else we have a bad line
190 // This function will check events to see if they are complete
191 // FIXME: Can we think of other ways to determine if the event is done?
192 static void check_events(lol *lo, time_t sec)
196 for(i=0;i<=lo->maxi; i++) {
197 lolnode *cur = &lo->array[i];
198 if (cur->status == L_BUILDING) {
199 // If 2 seconds have elapsed, we are done
200 if (cur->l->e.sec + 2 < sec) {
201 cur->status = L_COMPLETE;
203 } else if (cur->l->e.type < AUDIT_FIRST_EVENT ||
204 cur->l->e.type >= AUDIT_FIRST_ANOM_MSG) {
205 // If known to be 1 record event, we are done
206 cur->status = L_COMPLETE;
213 // This function adds a new record to an existing linked list
214 // or creates a new one if its a new event
215 int lol_add_record(lol *lo, char *buff)
223 // Short circuit if event is not of interest
224 if (extract_timestamp(buff, &e) == 0)
227 ptr = strrchr(buff, 0x0a);
230 n.message=strdup(buff);
233 // Now see where this belongs
234 for (i=0; i<=lo->maxi; i++) {
235 if (lo->array[i].status == L_BUILDING) {
237 if (events_are_equal(&l->e, &e)) {
238 free((char *)e.node);
244 // Create new event and fill it in
245 l = malloc(sizeof(llist));
247 l->e.milli = e.milli;
249 l->e.serial = e.serial;
254 check_events(lo, e.sec);
258 // This function will mark all events as "done"
259 void terminate_all_events(lol *lo)
263 for (i=0; i<=lo->maxi; i++) {
264 lolnode *cur = &lo->array[i];
265 if (cur->status == L_BUILDING) {
266 cur->status = L_COMPLETE;
270 //printf("maxi = %d\n",lo->maxi);
273 /* Search the list for any event that is ready to go. The caller
274 * takes custody of the memory */
275 llist* get_ready_event(lol *lo)
282 for (i=0; i<=lo->maxi; i++) {
283 lolnode *cur = &lo->array[i];
284 if (cur->status == L_COMPLETE) {
285 cur->status = L_EMPTY;