1 /*****
2 *
3 * Copyright (C) 2004-2015 CS-SI. All Rights Reserved.
4 * Author: Nicolas Delon <nicolas.delon@prelude-ids.com>
5 * Author: Yoann Vandoorselaere <yoann@prelude-ids.com>
6 *
7 * This file is part of the Prelude library.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 *****/
24
25 #include "config.h"
26 #include "libmissing.h"
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <sys/types.h>
33 #include <regex.h>
34 #include <stdarg.h>
35 #include <errno.h>
36
37 #include "common.h"
38 #include "prelude-log.h"
39 #include "prelude-error.h"
40 #include "prelude-inttypes.h"
41
42 #include "idmef.h"
43 #include "idmef-criterion-value.h"
44
45
46
47
48 struct match_cb {
49 unsigned int nmatch;
50 unsigned int match;
51 idmef_criterion_value_t *cv;
52 idmef_criterion_operator_t operator;
53 };
54
55
56 struct regex_value {
57 regex_t regex;
58 char *regex_string;
59 };
60
61
62
63 struct idmef_criterion_value {
64
65 void *value;
66 prelude_bool_t value_need_free;
67 idmef_criterion_value_type_t type;
68
69 int (*clone)(const idmef_criterion_value_t *cv, idmef_criterion_value_t *dst);
70 int (*print)(const idmef_criterion_value_t *cv, prelude_io_t *fd);
71 int (*to_string)(const idmef_criterion_value_t *cv, prelude_string_t *out);
72 int (*match)(const idmef_criterion_value_t *cv, idmef_criterion_operator_t operator, idmef_value_t *value);
73 void (*destroy)(idmef_criterion_value_t *cv);
74 };
75
76
77
78 /*
79 * time stuff
80 */
btime_parse_simple(const char * integer,int * out)81 static int btime_parse_simple(const char *integer, int *out)
82 {
83 *out = atoi(integer);
84 return 0;
85 }
86
87
88
89
btime_parse_year(const char * integer,int * out)90 static int btime_parse_year(const char *integer, int *out)
91 {
92 *out = atoi(integer) - 1900;
93 return 0;
94 }
95
96
97
btime_parse_month(const char * value,int * out)98 static int btime_parse_month(const char *value, int *out)
99 {
100 int i;
101 const char *months[] = {
102 "january",
103 "february",
104 "march",
105 "april",
106 "may",
107 "june",
108 "july",
109 "august",
110 "september",
111 "october",
112 "november",
113 "december"
114 };
115
116 if ( isdigit((int) *value) ) {
117 *out = atoi(value) - 1;
118 return 0;
119 }
120
121 for ( i = 0; i < (int) (sizeof(months) / sizeof(*months)); i++ ) {
122 if ( strcasecmp(value, months[i]) == 0 ) {
123 *out = i; /* Numbered 0 to 11 */
124 return 0;
125 }
126 }
127
128 return -1;
129 }
130
131
btime_parse_wday(const char * value,int * out)132 static int btime_parse_wday(const char *value, int *out)
133 {
134 int i;
135 const char *days[] = {
136 "sunday",
137 "monday",
138 "tuesday",
139 /* happy days ! ;) */
140 "wednesday",
141 "thursday",
142 "friday",
143 "saturday",
144 };
145
146 if ( isdigit((int) *value) ) {
147 *out = atoi(value) - 1;
148 return 0;
149 }
150
151 for ( i = 0; i < (int) (sizeof(days) / sizeof(*days)); i++ ) {
152
153 if ( strcasecmp(value, days[i]) == 0 ) {
154 *out = i; /* Numbered 0 (sunday) to 6 */
155 return 0;
156 }
157 }
158
159 return -1;
160 }
161
162
163
integer_compare(time_t matched,time_t wanted,idmef_criterion_operator_t op)164 static int integer_compare(time_t matched, time_t wanted, idmef_criterion_operator_t op)
165 {
166 if ( op & IDMEF_CRITERION_OPERATOR_EQUAL && matched == wanted )
167 return 1;
168
169 if ( op & IDMEF_CRITERION_OPERATOR_LESSER && matched < wanted)
170 return 1;
171
172 if ( op & IDMEF_CRITERION_OPERATOR_GREATER && matched > wanted )
173 return 1;
174
175 return 0;
176 }
177
178
179
do_btime_match(const idmef_criterion_value_t * cv,idmef_criterion_operator_t op,idmef_value_t * value)180 static int do_btime_match(const idmef_criterion_value_t *cv, idmef_criterion_operator_t op, idmef_value_t *value)
181 {
182 int ret;
183 time_t sec;
184 struct tm lt, *comp = cv->value;
185 prelude_bool_t need_full_compare = FALSE;
186
187 if ( idmef_value_get_type(value) != IDMEF_VALUE_TYPE_TIME )
188 return -1;
189
190 sec = idmef_time_get_sec(idmef_value_get_time(value));
191 if ( ! gmtime_r(&sec, <) )
192 return prelude_error_from_errno(errno);
193
194 /*
195 * Apply mask
196 */
197 if ( comp->tm_sec < 0 ) lt.tm_sec = -1;
198 else need_full_compare = TRUE;
199
200 if ( comp->tm_min < 0 ) lt.tm_min = -1;
201 else need_full_compare = TRUE;
202
203 if ( comp->tm_mon < 0 ) lt.tm_mon = -1;
204 else need_full_compare = TRUE;
205
206 if ( comp->tm_hour < 0 ) lt.tm_hour = -1;
207 else need_full_compare = TRUE;
208
209 if ( comp->tm_mday < 0 ) lt.tm_mday = -1;
210 else need_full_compare = TRUE;
211
212 if ( comp->tm_year < 0 ) lt.tm_year = -1;
213 else need_full_compare = TRUE;
214
215 if ( comp->tm_wday < 0 ) lt.tm_wday = -1;
216 if ( comp->tm_yday < 0 ) lt.tm_yday = -1;
217
218 /*
219 * The timegm() function ignores values supplied in the tm_wday
220 * and tm_yday fields, match them manually:
221 */
222 if ( comp->tm_wday >= 0 ) {
223 ret = integer_compare(lt.tm_wday, comp->tm_wday, (need_full_compare) ? op | IDMEF_CRITERION_OPERATOR_EQUAL : op);
224 if ( ret != 1 )
225 return ret;
226 }
227
228 if ( comp->tm_yday >= 0 ) {
229 ret = integer_compare(lt.tm_yday, comp->tm_yday, (need_full_compare) ? op | IDMEF_CRITERION_OPERATOR_EQUAL : op);
230 if ( ret != 1 )
231 return ret;
232 }
233
234 if ( ! need_full_compare )
235 return 1;
236
237 return integer_compare(timegm(<), timegm(comp), op);
238 }
239
240
241
btime_match(const idmef_criterion_value_t * cv,idmef_criterion_operator_t operator,idmef_value_t * value)242 static int btime_match(const idmef_criterion_value_t *cv, idmef_criterion_operator_t operator, idmef_value_t *value)
243 {
244 int ret;
245
246 ret = do_btime_match(cv, operator, value);
247 if ( ret < 0 )
248 return ret;
249
250 if ( operator & IDMEF_CRITERION_OPERATOR_NOT )
251 return (ret == 1) ? 0 : 1;
252 else
253 return (ret == 1) ? 1 : 0;
254 }
255
256
257
btime_to_string(const idmef_criterion_value_t * cv,prelude_string_t * out)258 static int btime_to_string(const idmef_criterion_value_t *cv, prelude_string_t *out)
259 {
260 struct tm *lt = cv->value;
261
262 if ( lt->tm_year != -1 )
263 prelude_string_sprintf(out, "year:%d ", lt->tm_year + 1900);
264
265 if ( lt->tm_yday != -1 )
266 prelude_string_sprintf(out, "yday:%d ", lt->tm_yday);
267
268 if ( lt->tm_mon != -1 )
269 prelude_string_sprintf(out, "month:%d ", lt->tm_mon);
270
271 if ( lt->tm_mday != -1 )
272 prelude_string_sprintf(out, "mday:%d ", lt->tm_mday);
273
274 if ( lt->tm_wday != -1 )
275 prelude_string_sprintf(out, "wday:%d ", lt->tm_wday);
276
277 if ( lt->tm_hour != -1 )
278 prelude_string_sprintf(out, "hour:%d ", lt->tm_hour);
279
280 if ( lt->tm_min != -1 )
281 prelude_string_sprintf(out, "min:%d ", lt->tm_min);
282
283 if ( lt->tm_sec != -1 )
284 prelude_string_sprintf(out, "sec:%d ", lt->tm_sec);
285
286 return 0;
287 }
288
289
btime_print(const idmef_criterion_value_t * cv,prelude_io_t * fd)290 static int btime_print(const idmef_criterion_value_t *cv, prelude_io_t *fd)
291 {
292 int ret;
293 prelude_string_t *out;
294
295 ret = prelude_string_new(&out);
296 if ( ret < 0 )
297 return ret;
298
299 ret = btime_to_string(cv, out);
300 if ( ret < 0 ) {
301 prelude_string_destroy(out);
302 return ret;
303 }
304
305 ret = prelude_io_write(fd, prelude_string_get_string(out), prelude_string_get_len(out));
306 prelude_string_destroy(out);
307
308 return ret;
309 }
310
311
312
btime_clone(const idmef_criterion_value_t * src,idmef_criterion_value_t * dst)313 static int btime_clone(const idmef_criterion_value_t *src, idmef_criterion_value_t *dst)
314 {
315 /*
316 * The API does not allow to change the value of an existing
317 * idmef_criterion_value_t object, so we can simply regerence the source.
318 */
319 dst->value_need_free = FALSE;
320 dst->value = src->value;
321 return 0;
322 }
323
324
325
btime_destroy(idmef_criterion_value_t * cv)326 static void btime_destroy(idmef_criterion_value_t *cv)
327 {
328 if ( cv->value_need_free )
329 free(cv->value);
330 }
331
332
333
334
335 /*
336 * regex stuff
337 */
regex_match(const idmef_criterion_value_t * cv,idmef_criterion_operator_t operator,idmef_value_t * value)338 static int regex_match(const idmef_criterion_value_t *cv, idmef_criterion_operator_t operator, idmef_value_t *value)
339 {
340 int ret;
341 const char *str = NULL;
342 idmef_class_id_t class;
343 struct regex_value *rv = cv->value;
344
345 if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_STRING )
346 str = prelude_string_get_string(idmef_value_get_string(value));
347
348 else if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_ENUM ) {
349 class = idmef_value_get_class(value);
350 str = idmef_class_enum_to_string(class, idmef_value_get_enum(value));
351 }
352
353 else if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_DATA ) {
354 idmef_data_t *data;
355
356 data = idmef_value_get_data(value);
357 if ( idmef_data_get_type(data) == IDMEF_DATA_TYPE_CHAR_STRING )
358 str = idmef_data_get_data(data);
359 }
360
361 if ( ! str )
362 return 0;
363
364 ret = regexec(&rv->regex, str, 0, NULL, 0);
365 if ( operator & IDMEF_CRITERION_OPERATOR_NOT )
366 return (ret == REG_NOMATCH) ? 1 : 0;
367 else
368 return (ret != REG_NOMATCH) ? 1 : 0;
369 }
370
371
372
regex_print(const idmef_criterion_value_t * cv,prelude_io_t * fd)373 static int regex_print(const idmef_criterion_value_t *cv, prelude_io_t *fd)
374 {
375 struct regex_value *rv = cv->value;
376 prelude_io_write(fd, rv->regex_string, strlen(rv->regex_string));
377 return 0;
378 }
379
380
381
regex_to_string(const idmef_criterion_value_t * cv,prelude_string_t * out)382 static int regex_to_string(const idmef_criterion_value_t *cv, prelude_string_t *out)
383 {
384 struct regex_value *rv = cv->value;
385 return prelude_string_cat(out, rv->regex_string);
386 }
387
388
389
regex_clone(const idmef_criterion_value_t * src,idmef_criterion_value_t * dst)390 static int regex_clone(const idmef_criterion_value_t *src, idmef_criterion_value_t *dst)
391 {
392 /*
393 * The API does not allow to change the value of an existing
394 * idmef_criterion_value_t object, so we can simply regerence the source.
395 */
396 dst->value_need_free = FALSE;
397 dst->value = src->value;
398 return 0;
399 }
400
401
402
regex_destroy(idmef_criterion_value_t * cv)403 static void regex_destroy(idmef_criterion_value_t *cv)
404 {
405 struct regex_value *rv;
406
407 if ( ! cv->value_need_free )
408 return;
409
410 rv = cv->value;
411
412 free(rv->regex_string);
413 regfree(&rv->regex);
414 free(rv);
415 }
416
417
418
419
420 /*
421 * value stuff
422 */
value_match(const idmef_criterion_value_t * cv,idmef_criterion_operator_t operator,idmef_value_t * value)423 static int value_match(const idmef_criterion_value_t *cv, idmef_criterion_operator_t operator, idmef_value_t *value)
424 {
425 return idmef_value_match(value, cv->value, operator);
426 }
427
428
429
value_print(const idmef_criterion_value_t * cv,prelude_io_t * fd)430 static int value_print(const idmef_criterion_value_t *cv, prelude_io_t *fd)
431 {
432 return idmef_value_print(cv->value, fd);
433 }
434
435
436
value_to_string(const idmef_criterion_value_t * cv,prelude_string_t * out)437 static int value_to_string(const idmef_criterion_value_t *cv, prelude_string_t *out)
438 {
439 return idmef_value_to_string(cv->value, out);
440 }
441
442
443
value_clone(const idmef_criterion_value_t * cv,idmef_criterion_value_t * dst)444 static int value_clone(const idmef_criterion_value_t *cv, idmef_criterion_value_t *dst)
445 {
446 int ret;
447 idmef_value_t *res;
448
449 ret = idmef_value_clone(cv->value, &res);
450 dst->value = res;
451
452 return ret;
453 }
454
455
456
value_destroy(idmef_criterion_value_t * cv)457 static void value_destroy(idmef_criterion_value_t *cv)
458 {
459 idmef_value_destroy(cv->value);
460 }
461
462
463
464 /*
465 *
466 */
do_match_cb(idmef_value_t * value,void * extra)467 static int do_match_cb(idmef_value_t *value, void *extra)
468 {
469 int ret;
470 struct match_cb *mcb = extra;
471 idmef_criterion_value_t *cv = mcb->cv;
472 idmef_criterion_operator_t operator = mcb->operator;
473
474 if ( idmef_value_is_list(value) )
475 return idmef_value_iterate(value, do_match_cb, mcb);
476
477 ret = cv->match(cv, operator, value);
478 if ( ret < 0 )
479 return ret;
480
481 if ( ret > 0 )
482 mcb->match++;
483 else
484 mcb->nmatch++;
485
486 return 0;
487 }
488
489
idmef_criterion_value_destroy(idmef_criterion_value_t * value)490 void idmef_criterion_value_destroy(idmef_criterion_value_t *value)
491 {
492 value->destroy(value);
493 free(value);
494 }
495
496
497
idmef_criterion_value_clone(const idmef_criterion_value_t * src,idmef_criterion_value_t ** dst)498 int idmef_criterion_value_clone(const idmef_criterion_value_t *src, idmef_criterion_value_t **dst)
499 {
500 int ret;
501
502 ret = idmef_criterion_value_new(dst);
503 if ( ret < 0 )
504 return ret;
505
506 (*dst)->type = src->type;
507 (*dst)->clone = src->clone;
508 (*dst)->print = src->print;
509 (*dst)->to_string = src->to_string;
510 (*dst)->match = src->match;
511 (*dst)->destroy = src->destroy;
512
513 ret = src->clone(src, *dst);
514 if ( ret < 0 ) {
515 free(*dst);
516 return ret;
517 }
518
519 return 0;
520 }
521
522
523
idmef_criterion_value_print(idmef_criterion_value_t * cv,prelude_io_t * fd)524 int idmef_criterion_value_print(idmef_criterion_value_t *cv, prelude_io_t *fd)
525 {
526 return cv->print(cv, fd);
527 }
528
529
530
idmef_criterion_value_to_string(idmef_criterion_value_t * cv,prelude_string_t * out)531 int idmef_criterion_value_to_string(idmef_criterion_value_t *cv, prelude_string_t *out)
532 {
533 return cv->to_string(cv, out);
534 }
535
536
537
idmef_criterion_value_match(idmef_criterion_value_t * cv,idmef_value_t * value,idmef_criterion_operator_t op)538 int idmef_criterion_value_match(idmef_criterion_value_t *cv, idmef_value_t *value,
539 idmef_criterion_operator_t op)
540 {
541 int ret;
542 struct match_cb mcb;
543
544 mcb.cv = cv;
545 mcb.operator = op;
546 mcb.match = mcb.nmatch = 0;
547
548 ret = idmef_value_iterate(value, do_match_cb, &mcb);
549 if ( ret < 0 )
550 return ret;
551
552 /*
553 * When comparing a path to a value using a negative operator, if the
554 * excluded value was found at least once, return a negative match.
555 *
556 * This is required since the 'match' value might also be positive
557 * in case the path contain a list of value.
558 */
559 if ( op & IDMEF_CRITERION_OPERATOR_NOT && mcb.nmatch > 0 )
560 return 0;
561
562 return mcb.match;
563 }
564
565
566
idmef_criterion_value_new(idmef_criterion_value_t ** cv)567 int idmef_criterion_value_new(idmef_criterion_value_t **cv)
568 {
569 *cv = calloc(1, sizeof(**cv));
570 if ( ! *cv )
571 return prelude_error_from_errno(errno);
572
573 (*cv)->value_need_free = TRUE;
574
575 return 0;
576 }
577
578
579
btime_parse_gmtoff(const char * param,int * out)580 static int btime_parse_gmtoff(const char *param, int *out)
581 {
582 *out = atoi(param) * 60 * 60;
583 return 0;
584 }
585
586
btime_parse(struct tm * lt,const char * time)587 static int btime_parse(struct tm *lt, const char *time)
588 {
589 int ret;
590 size_t i;
591 long gmt_offset;
592 char *end = NULL;
593 struct {
594 const char *field;
595 size_t len;
596 void *ptr;
597 int (*func)(const char *param, int *output);
598 } tbl[] = {
599 { "month", 5, <->tm_mon, btime_parse_month },
600 { "wday", 4, <->tm_wday, btime_parse_wday },
601 { "year", 4, <->tm_year, btime_parse_year },
602 { "mday", 4, <->tm_mday, btime_parse_simple },
603 { "yday", 4, <->tm_yday, btime_parse_simple },
604 { "hour", 4, <->tm_hour, btime_parse_simple },
605 { "min", 3, <->tm_min, btime_parse_simple },
606 { "sec", 3, <->tm_sec, btime_parse_simple },
607 { "gmtoff", 6, &gmt_offset, btime_parse_gmtoff }
608 };
609
610 ret = prelude_get_gmt_offset(&gmt_offset);
611 if ( ret < 0 )
612 return ret;
613
614 do {
615 for ( i = 0; i < sizeof(tbl) / sizeof(*tbl); i++ ) {
616
617 if ( strncmp(time, tbl[i].field, tbl[i].len) != 0 )
618 continue;
619
620 if ( time[tbl[i].len] != ':' )
621 continue;
622
623 time += tbl[i].len + 1;
624
625 end = strchr(time, ' ');
626 if ( end ) {
627 *end++ = 0;
628 while ( *end == ' ' ) end++;
629 }
630
631 ret = tbl[i].func(time, tbl[i].ptr);
632 if ( ret < 0 )
633 return -1;
634
635 time = end + 1;
636 break;
637 }
638
639 if ( i == sizeof(tbl) / sizeof(*tbl) )
640 return -1;
641
642 time = end;
643 } while ( time );
644
645 if ( lt->tm_hour != -1 )
646 lt->tm_hour -= (gmt_offset / (60 * 60));
647
648 return 0;
649 }
650
651
652
653
idmef_criterion_value_new_broken_down_time(idmef_criterion_value_t ** cv,const char * time,idmef_criterion_operator_t op)654 int idmef_criterion_value_new_broken_down_time(idmef_criterion_value_t **cv, const char *time, idmef_criterion_operator_t op)
655 {
656 int ret;
657 struct tm *lt;
658
659 ret = idmef_criterion_value_new(cv);
660 if ( ret < 0 )
661 return ret;
662
663 lt = malloc(sizeof(struct tm));
664 if ( ! lt ) {
665 free(*cv);
666 return prelude_error_from_errno(errno);
667 }
668
669 memset(lt, -1, sizeof(*lt));
670
671 ret = btime_parse(lt, time);
672 if ( ret < 0 ) {
673 free(lt);
674 free(*cv);
675 return ret;
676 }
677
678 (*cv)->value = lt;
679 (*cv)->match = btime_match;
680 (*cv)->clone = btime_clone;
681 (*cv)->print = btime_print;
682 (*cv)->destroy = btime_destroy;
683 (*cv)->to_string = btime_to_string;
684 (*cv)->type = IDMEF_CRITERION_VALUE_TYPE_BROKEN_DOWN_TIME;
685
686 return 0;
687 }
688
689
690
691
idmef_criterion_value_new_regex(idmef_criterion_value_t ** cv,const char * regex,idmef_criterion_operator_t op)692 int idmef_criterion_value_new_regex(idmef_criterion_value_t **cv, const char *regex, idmef_criterion_operator_t op)
693 {
694 int ret;
695 struct regex_value *rv;
696 int flags = REG_EXTENDED|REG_NOSUB;
697
698 ret = idmef_criterion_value_new(cv);
699 if ( ret < 0 )
700 return ret;
701
702 rv = (*cv)->value = malloc(sizeof(*rv));
703 if ( ! rv ) {
704 free(*cv);
705 return prelude_error_from_errno(errno);
706 }
707
708 rv->regex_string = strdup(regex);
709 if ( ! rv->regex_string ) {
710 free(rv);
711 free(*cv);
712 return prelude_error_from_errno(errno);
713 }
714
715 if ( op & IDMEF_CRITERION_OPERATOR_NOCASE )
716 flags |= REG_ICASE;
717
718 ret = regcomp(&rv->regex, rv->regex_string, flags);
719 if ( ret != 0 ) {
720 char errbuf[1024];
721
722 regerror(ret, &rv->regex, errbuf, sizeof(errbuf));
723
724 free(rv->regex_string);
725 free(rv);
726 free(*cv);
727
728 return prelude_error_verbose(PRELUDE_ERROR_IDMEF_CRITERION_INVALID_REGEX,
729 "error compiling regex: %s", errbuf);
730 }
731
732 (*cv)->match = regex_match;
733 (*cv)->clone = regex_clone;
734 (*cv)->print = regex_print;
735 (*cv)->destroy = regex_destroy;
736 (*cv)->to_string = regex_to_string;
737 (*cv)->type = IDMEF_CRITERION_VALUE_TYPE_REGEX;
738
739 return 0;
740 }
741
742
743
idmef_criterion_value_new_value(idmef_criterion_value_t ** cv,idmef_value_t * value,idmef_criterion_operator_t op)744 int idmef_criterion_value_new_value(idmef_criterion_value_t **cv,
745 idmef_value_t *value, idmef_criterion_operator_t op)
746 {
747 int ret;
748
749 ret = idmef_value_check_operator(value, op);
750 if ( ret < 0 )
751 return ret;
752
753 ret = idmef_criterion_value_new(cv);
754 if ( ret < 0 )
755 return ret;
756
757 (*cv)->value = value;
758 (*cv)->match = value_match;
759 (*cv)->clone = value_clone;
760 (*cv)->print = value_print;
761 (*cv)->destroy = value_destroy;
762 (*cv)->to_string = value_to_string;
763 (*cv)->type = IDMEF_CRITERION_VALUE_TYPE_VALUE;
764
765 return 0;
766 }
767
768
769
770
idmef_criterion_value_new_from_string(idmef_criterion_value_t ** cv,idmef_path_t * path,const char * value,idmef_criterion_operator_t operator)771 int idmef_criterion_value_new_from_string(idmef_criterion_value_t **cv,
772 idmef_path_t *path, const char *value,
773 idmef_criterion_operator_t operator)
774 {
775 int ret;
776 idmef_value_t *val;
777 idmef_value_type_id_t tid;
778
779 tid = idmef_path_get_value_type(path, -1);
780
781 if ( tid == IDMEF_VALUE_TYPE_TIME ) {
782 ret = idmef_criterion_value_new_broken_down_time(cv, value, operator);
783 if ( ret == 0 )
784 return ret;
785 }
786
787 else if ( operator & IDMEF_CRITERION_OPERATOR_REGEX &&
788 (tid == IDMEF_VALUE_TYPE_STRING || tid == IDMEF_VALUE_TYPE_ENUM || tid == IDMEF_VALUE_TYPE_DATA) )
789 return idmef_criterion_value_new_regex(cv, value, operator);
790
791 /*
792 * It's more understandable for the user if we check the operator
793 * prior to checking the value.
794 */
795 ret = idmef_value_type_check_operator(tid, operator);
796 if ( ret < 0 )
797 return ret;
798
799 if ( tid == IDMEF_VALUE_TYPE_ENUM && operator & IDMEF_CRITERION_OPERATOR_SUBSTR )
800 ret = idmef_value_new_from_string(&val, IDMEF_VALUE_TYPE_STRING, value);
801 else
802 ret = idmef_value_new_from_path(&val, path, value);
803
804 if ( ret < 0 )
805 return ret;
806
807 ret = idmef_criterion_value_new_value(cv, val, operator);
808 if ( ret < 0 ) {
809 idmef_value_destroy(val);
810 return ret;
811 }
812
813 return 0;
814 }
815
816
817
idmef_criterion_value_get_value(idmef_criterion_value_t * cv)818 const idmef_value_t *idmef_criterion_value_get_value(idmef_criterion_value_t *cv)
819 {
820 return cv->type == IDMEF_CRITERION_VALUE_TYPE_VALUE ? cv->value : NULL;
821 }
822
823
824
idmef_criterion_value_get_broken_down_time(idmef_criterion_value_t * cv)825 const struct tm *idmef_criterion_value_get_broken_down_time(idmef_criterion_value_t *cv)
826 {
827 return cv->type == IDMEF_CRITERION_VALUE_TYPE_BROKEN_DOWN_TIME ? cv->value : NULL;
828 }
829
830
831
idmef_criterion_value_get_regex(idmef_criterion_value_t * cv)832 const char *idmef_criterion_value_get_regex(idmef_criterion_value_t *cv)
833 {
834 return cv->type == IDMEF_CRITERION_VALUE_TYPE_REGEX ? ((struct regex_value *)cv->value)->regex_string : NULL;
835 }
836
837
idmef_criterion_value_get_type(idmef_criterion_value_t * cv)838 idmef_criterion_value_type_t idmef_criterion_value_get_type(idmef_criterion_value_t *cv)
839 {
840 return cv->type;
841 }
842