~ubuntu-branches/ubuntu/raring/audit/raring

« back to all changes in this revision

Viewing changes to src/ausearch-lol.c

  • Committer: Bazaar Package Importer
  • Author(s): Philipp Matthias Hahn
  • Date: 2009-01-11 18:51:38 UTC
  • mfrom: (1.1.7 upstream) (3.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20090111185138-329kq0gg5xndhf8j
Tags: 1.7.11-1
* New upstream release.
  - Update debian/patches/mode.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* ausearch-lol.c - linked list of linked lists library
 
3
* Copyright (c) 2008 Red Hat Inc., Durham, North Carolina.
 
4
* All Rights Reserved. 
 
5
*
 
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
 
9
* 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; see the file COPYING. If not, write to the
 
18
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
*
 
20
* Authors:
 
21
*   Steve Grubb <sgrubb@redhat.com>
 
22
*/
 
23
 
 
24
#include "ausearch-lol.h"
 
25
#include <stdlib.h>
 
26
#include <errno.h>
 
27
#include <string.h>
 
28
#include <stdio.h>
 
29
#include "ausearch-common.h"
 
30
 
 
31
#define ARRAY_LIMIT 80
 
32
static int ready = 0;
 
33
 
 
34
void lol_create(lol *lo)
 
35
{
 
36
        int size = ARRAY_LIMIT * sizeof(lolnode);
 
37
 
 
38
        lo->maxi = -1;
 
39
        lo->limit = ARRAY_LIMIT;
 
40
        lo->array = (lolnode *)malloc(size);
 
41
        memset(lo->array, 0, size);
 
42
}
 
43
 
 
44
void lol_clear(lol *lo)
 
45
{
 
46
        int i;
 
47
 
 
48
        for (i=0; i<=lo->maxi; i++) {
 
49
                if (lo->array[i].status) {
 
50
                        list_clear(lo->array[i].l);
 
51
                        free(lo->array[i].l);
 
52
                }
 
53
        }
 
54
        free(lo->array);
 
55
        lo->array = NULL;
 
56
        lo->maxi = -1;
 
57
}
 
58
 
 
59
static void lol_append(lol *lo, llist *l)
 
60
{
 
61
        int i, new_size;
 
62
        lolnode *ptr;
 
63
 
 
64
        for(i=0; i<lo->limit; i++) {
 
65
                lolnode *cur = &lo->array[i];
 
66
                if (cur->status == 0) {
 
67
                        cur->l = l;
 
68
                        cur->status = 1;
 
69
                        if (i > lo->maxi)
 
70
                                lo->maxi = i;
 
71
                        return;
 
72
                }
 
73
        }
 
74
        // Overran the array...lets make it bigger
 
75
        new_size = sizeof(lolnode) * (lo->limit + ARRAY_LIMIT);
 
76
        ptr = realloc(lo->array, new_size);
 
77
        if (ptr) {
 
78
                lo->array = ptr;
 
79
                memset(&lo->array[lo->limit], 0, sizeof(lolnode) * ARRAY_LIMIT);
 
80
                lo->array[i].l = l;
 
81
                lo->array[i].status = 1;
 
82
                lo->maxi = i;
 
83
                lo->limit += ARRAY_LIMIT;
 
84
        }
 
85
}
 
86
 
 
87
static int str2event(char *s, event *e)
 
88
{
 
89
        char *ptr;
 
90
 
 
91
        errno = 0;
 
92
        ptr = strchr(s+10, ':');
 
93
        if (ptr) {
 
94
                e->serial = strtoul(ptr+1, NULL, 10);
 
95
                *ptr = 0;
 
96
                if (errno)
 
97
                        return -1;
 
98
        } else
 
99
                e->serial = 0;
 
100
        ptr = strchr(s, '.');
 
101
        if (ptr) {
 
102
                e->milli = strtoul(ptr+1, NULL, 10);
 
103
                *ptr = 0;
 
104
                if (errno)
 
105
                        return -1;
 
106
        } else
 
107
                e->milli = 0;
 
108
        e->sec = strtoul(s, NULL, 10);
 
109
        if (errno)
 
110
                return -1;
 
111
        return 0;
 
112
}
 
113
 
 
114
static int inline events_are_equal(event *e1, event *e2)
 
115
{
 
116
        if (!(e1->serial == e2->serial && e1->milli == e2->milli &&
 
117
                                        e1->sec == e2->sec))
 
118
                return 0;
 
119
        if (e1->node && e2->node) {
 
120
                if (strcmp(e1->node, e2->node))
 
121
                        return 0;
 
122
        } else if (e1->node || e2->node)
 
123
                return 0;
 
124
        return 1;
 
125
}
 
126
 
 
127
/*
 
128
 * This function will look at the line and pick out pieces of it.
 
129
 */
 
130
static void extract_timestamp(const char *b, event *e)
 
131
{
 
132
        char *ptr, *tmp;
 
133
 
 
134
        e->node = NULL;
 
135
        tmp = strndupa(b, 120);
 
136
        ptr = strtok(tmp, " ");
 
137
        if (ptr) {
 
138
                // Check to see if this is the node info
 
139
                if (*ptr == 'n') {
 
140
                        e->node = strdup(ptr+5);
 
141
                        ptr = strtok(NULL, " ");
 
142
                }
 
143
 
 
144
                // at this point we have type=
 
145
                e->type = audit_name_to_msg_type(ptr+5);
 
146
 
 
147
                // Now should be pointing to msg=
 
148
                ptr = strtok(NULL, " ");
 
149
                if (ptr) {
 
150
                        if (*(ptr+9) == '(')
 
151
                                ptr+=9;
 
152
                        else
 
153
                                ptr = strchr(ptr, '(');
 
154
                        if (ptr) {
 
155
                        // now we should be pointed at the timestamp
 
156
                                char *eptr;
 
157
                                ptr++;
 
158
                                eptr = strchr(ptr, ')');
 
159
                                if (eptr)
 
160
                                        *eptr = 0;
 
161
                                if (str2event(ptr, e)) {
 
162
                                        fprintf(stderr,
 
163
                                          "Error extracting time stamp (%s)\n",
 
164
                                                ptr);
 
165
                                }
 
166
                        }
 
167
                        // else we have a bad line
 
168
                }
 
169
                // else we have a bad line
 
170
        }
 
171
        // else we have a bad line
 
172
}
 
173
 
 
174
// This function will check events to see if they are complete 
 
175
static void check_events(lol *lo, time_t sec)
 
176
{
 
177
        int i;
 
178
 
 
179
        for(i=0;i<=lo->maxi; i++) {
 
180
                lolnode *cur = &lo->array[i];
 
181
                if (cur->status == 1) {
 
182
                        // If 2 seconds have elapsed, we are done
 
183
                        if (cur->l->e.sec + 2 < sec) { 
 
184
                                cur->status = 2;
 
185
                                ready++;
 
186
                        } else if (cur->l->e.type < AUDIT_FIRST_EVENT ||
 
187
                                    cur->l->e.type >= AUDIT_FIRST_ANOM_MSG) {
 
188
                                // If known to be 1 record event, we are done
 
189
                                cur->status = 2;
 
190
                                ready++;
 
191
                        } 
 
192
                }
 
193
        }
 
194
}
 
195
 
 
196
// This function adds a new record to an existing linked list
 
197
// or creates a new one if its a new event
 
198
int lol_add_record(lol *lo, char *buff)
 
199
{
 
200
        int i;
 
201
        lnode n;
 
202
        event e;
 
203
        char *ptr;
 
204
        llist *l;
 
205
 
 
206
        ptr = strrchr(buff, 0x0a);
 
207
        if (ptr)
 
208
                *ptr = 0;
 
209
        extract_timestamp(buff, &e);
 
210
 
 
211
        // Short circuit if event is not of interest
 
212
        if ((start_time && e.sec < start_time) ||
 
213
                        (end_time && e.sec > end_time)) {
 
214
                free((char *)e.node);
 
215
                return 0;
 
216
        } else {
 
217
                n.message=strdup(buff);
 
218
                n.type = e.type;
 
219
        }
 
220
 
 
221
        // Now see where this belongs
 
222
        for (i=0; i<=lo->maxi; i++) {
 
223
                if (lo->array[i].status == 1) {
 
224
                        l = lo->array[i].l;
 
225
                        if (events_are_equal(&l->e, &e)) {
 
226
                                free((char *)e.node);
 
227
                                list_append(l, &n);
 
228
                                return 1;
 
229
                        }
 
230
                }
 
231
        }
 
232
        // Create new event and fill it in
 
233
        l = malloc(sizeof(llist));
 
234
        list_create(l);
 
235
        l->e.milli = e.milli;
 
236
        l->e.sec = e.sec;
 
237
        l->e.serial = e.serial;
 
238
        l->e.node = e.node;
 
239
        l->e.type = e.type;
 
240
        list_append(l, &n);
 
241
        lol_append(lo, l);
 
242
        check_events(lo,  e.sec);
 
243
        return 1;
 
244
}
 
245
 
 
246
// This function will mark all events as "done"
 
247
void terminate_all_events(lol *lo)
 
248
{
 
249
        int i;
 
250
 
 
251
        for (i=0; i<=lo->maxi; i++) {
 
252
                lolnode *cur = &lo->array[i];
 
253
                if (cur->status == 1) {
 
254
                        cur->status = 2;
 
255
                        ready++;
 
256
                }
 
257
        }
 
258
}
 
259
 
 
260
/* Search the list for any event that is ready to go. The caller
 
261
 * takes custody of the memory */
 
262
llist* get_ready_event(lol *lo)
 
263
{
 
264
        int i;
 
265
 
 
266
        if (ready == 0)
 
267
                return NULL;
 
268
 
 
269
        for (i=0; i<=lo->maxi; i++) {
 
270
                lolnode *cur = &lo->array[i];
 
271
                if (cur->status == 2) {
 
272
                        cur->status = 0;
 
273
                        ready--;
 
274
                        return cur->l;
 
275
                }
 
276
        }
 
277
 
 
278
        return NULL;
 
279
}
 
280