1 /*****
2 *
3 * Copyright (C) 2003-2015 CS-SI. All Rights Reserved.
4 * Author: Nicolas Delon <nicolas.delon@prelude-ids.com>
5 * Author: Yoann Vandoorselaere <yoann.v@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
27 #include <sys/types.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 #include <ctype.h>
32 #include <assert.h>
33
34 #include "prelude-list.h"
35 #include "prelude-log.h"
36 #include "prelude-inttypes.h"
37 #include "prelude-string.h"
38 #include "prelude-error.h"
39 #include "common.h"
40
41 #include "idmef.h"
42 #include "idmef-value-type.h"
43
44 #define CHUNK_SIZE 16
45 #define FLOAT_TOLERANCE 0.0001
46
47
48 #ifndef MAX
49 # define MAX(x, y) ((x) > (y) ? (x) : (y))
50 #endif
51
52 #ifndef ABS
53 # define ABS(x) (((x) < 0) ? -(x) : (x))
54 #endif
55
56
57 #define idmef_value_new_decl(mtype, vname, vtype) \
58 int idmef_value_new_ ## vname (idmef_value_t **value, vtype val) { \
59 int ret; \
60 \
61 ret = idmef_value_create(value, IDMEF_VALUE_TYPE_ ## mtype); \
62 if ( ret < 0 ) \
63 return ret; \
64 \
65 (*value)->type.data. vname ## _val = val; \
66 \
67 return 0; \
68 }
69
70
71 #define idmef_value_set_decl(mtype, vname, vtype) \
72 int idmef_value_set_ ## vname (idmef_value_t *value, vtype val) \
73 { \
74 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION)); \
75 \
76 if ( value->own_data ) \
77 idmef_value_type_destroy(&value->type); \
78 \
79 value->type.id = IDMEF_VALUE_TYPE_ ## mtype; \
80 value->type.data. vname ## _val = val; \
81 value->own_data = TRUE; \
82 \
83 return 0; \
84 }
85
86 #define idmef_value_get_decl(mtype, vname, vtype) \
87 vtype idmef_value_get_ ## vname (const idmef_value_t *val) \
88 { \
89 prelude_return_val_if_fail(val, (vtype) 0); \
90 \
91 if ( val->type.id != IDMEF_VALUE_TYPE_ ## mtype ) \
92 return (vtype) 0; \
93 \
94 return val->type.data. vname ## _val; \
95 }
96
97
98 #define idmef_value_decl(mtype, vname, vtype) \
99 idmef_value_new_decl(mtype, vname, vtype) \
100 idmef_value_get_decl(mtype, vname, vtype) \
101 idmef_value_set_decl(mtype, vname, vtype)
102
103
104
105 #define CASTCHK(ntype, fval, src, dst) \
106 if ( ! (src == dst && (src < 1) == (dst < 1)) ) \
107 return prelude_error_verbose(PRELUDE_ERROR_GENERIC, \
108 "Value '%" fval "' is incompatible with output type '%s'", \
109 src, idmef_value_type_to_string(ntype))
110
111
112
113 #define FLOATCHK(ntype, fval, src, dst) \
114 if ( reldif(src, dst) > FLOAT_TOLERANCE ) \
115 return prelude_error_verbose(PRELUDE_ERROR_GENERIC, \
116 "Value '%" fval "' is incompatible with output type '%s'", \
117 src, idmef_value_type_to_string(ntype))
118
119
120 #define VALUE_CAST_CHECK(v, itype_t, itype, iformat, ntype) do { \
121 itype_t src = idmef_value_get_ ##itype(value); \
122 \
123 if ( ntype == IDMEF_VALUE_TYPE_INT8 ) { \
124 CASTCHK(ntype, iformat, src, (int8_t) src); \
125 idmef_value_set_int8(value, src); \
126 \
127 } else if ( ntype == IDMEF_VALUE_TYPE_UINT8 ) { \
128 CASTCHK(ntype, iformat, src, (uint8_t) src); \
129 idmef_value_set_uint8(value, src); \
130 \
131 } else if ( ntype == IDMEF_VALUE_TYPE_INT16 ) { \
132 CASTCHK(ntype, iformat, src, (int16_t) src); \
133 idmef_value_set_int16(value, src); \
134 \
135 } else if ( ntype == IDMEF_VALUE_TYPE_UINT16 ) { \
136 CASTCHK(ntype, iformat, src, (uint16_t) src); \
137 idmef_value_set_uint16(value, src); \
138 \
139 } else if ( ntype == IDMEF_VALUE_TYPE_INT32 ) { \
140 CASTCHK(ntype, iformat, src, (int32_t) src); \
141 idmef_value_set_int32(value, src); \
142 \
143 } else if ( ntype == IDMEF_VALUE_TYPE_UINT32 ) { \
144 CASTCHK(ntype, iformat, src, (uint32_t) src); \
145 idmef_value_set_uint32(value, src); \
146 \
147 } else if ( ntype == IDMEF_VALUE_TYPE_INT64 ) { \
148 CASTCHK(ntype, iformat, src, (int64_t) src); \
149 idmef_value_set_int64(value, src); \
150 \
151 } else if ( ntype == IDMEF_VALUE_TYPE_UINT64 ) { \
152 CASTCHK(ntype, iformat, src, (uint64_t) src); \
153 idmef_value_set_uint64(value, src); \
154 \
155 } else if ( ntype == IDMEF_VALUE_TYPE_FLOAT ) { \
156 FLOATCHK(ntype, iformat, src, (float) src); \
157 idmef_value_set_float(value, src); \
158 \
159 } else if ( ntype == IDMEF_VALUE_TYPE_DOUBLE ) { \
160 FLOATCHK(ntype, iformat, src, (double) src); \
161 idmef_value_set_double(value, src); \
162 \
163 } else return prelude_error_verbose(PRELUDE_ERROR_GENERIC, \
164 "Unable to handle output type '%s' for integer cast", \
165 idmef_value_type_to_string(ntype)); \
166 } while(0)
167
168
169
170 typedef struct compare {
171 unsigned int match;
172 idmef_value_t *val2;
173 idmef_criterion_operator_t operator;
174 } compare_t;
175
176
177
178 struct idmef_value {
179 int list_elems;
180 int list_max;
181 int refcount;
182 prelude_bool_t own_data;
183 idmef_value_t **list;
184 idmef_value_type_t type;
185 };
186
187
188 /*
189 * Returns the relative difference of two real numbers: 0.0 if they are
190 * exactly the same, otherwise, the ratio of the difference to the
191 * larger of the two.
192 */
reldif(double a,double b)193 static double reldif(double a, double b)
194 {
195 double c = ABS(a);
196 double d = ABS(b);
197
198 d = MAX(c, d);
199
200 return d == 0.0 ? 0.0 : ABS(a - b) / d;
201 }
202
203
string_isdigit(const char * s)204 static int string_isdigit(const char *s)
205 {
206 while ( *s ) {
207 if ( ! isdigit((int) *s) )
208 return -1;
209 s++;
210 }
211
212 return 0;
213 }
214
215
idmef_value_create(idmef_value_t ** ret,idmef_value_type_id_t type_id)216 static int idmef_value_create(idmef_value_t **ret, idmef_value_type_id_t type_id)
217 {
218 *ret = calloc(1, sizeof(**ret));
219 if ( ! *ret )
220 return prelude_error_from_errno(errno);
221
222 (*ret)->refcount = 1;
223 (*ret)->own_data = TRUE;
224 (*ret)->type.id = type_id;
225
226 return 0;
227 }
228
229
230
idmef_value_decl(INT8,int8,int8_t)231 idmef_value_decl(INT8, int8, int8_t)
232 idmef_value_decl(UINT8, uint8, uint8_t)
233 idmef_value_decl(INT16, int16, int16_t)
234 idmef_value_decl(UINT16, uint16, uint16_t)
235 idmef_value_decl(INT32, int32, int32_t)
236 idmef_value_decl(UINT32, uint32, uint32_t)
237 idmef_value_decl(INT64, int64, int64_t)
238 idmef_value_decl(UINT64, uint64, uint64_t)
239 idmef_value_decl(FLOAT, float, float)
240 idmef_value_decl(DOUBLE, double, double)
241 idmef_value_decl(STRING, string, prelude_string_t *)
242 idmef_value_decl(DATA, data, idmef_data_t *)
243 idmef_value_decl(TIME, time, idmef_time_t *)
244
245
246
247 int idmef_value_get_enum(const idmef_value_t *value)
248 {
249 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
250
251 if ( value->type.id != IDMEF_VALUE_TYPE_ENUM )
252 return 0;
253
254 return value->type.data.enum_val.value;
255 }
256
257
idmef_value_set_class(idmef_value_t * value,idmef_class_id_t class,void * object)258 int idmef_value_set_class(idmef_value_t *value, idmef_class_id_t class, void *object)
259 {
260 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
261 prelude_return_val_if_fail(object, prelude_error(PRELUDE_ERROR_ASSERTION));
262
263 if ( value->own_data )
264 idmef_value_type_destroy(&value->type);
265
266 value->own_data = TRUE;
267 value->type.data.class_val.object = object;
268 value->type.data.class_val.class_id = class;
269
270 return 0;
271 }
272
273
idmef_value_new_class(idmef_value_t ** value,idmef_class_id_t class,void * object)274 int idmef_value_new_class(idmef_value_t **value, idmef_class_id_t class, void *object)
275 {
276 int ret;
277
278 prelude_return_val_if_fail(object, prelude_error(PRELUDE_ERROR_ASSERTION));
279
280 ret = idmef_value_create(value, IDMEF_VALUE_TYPE_CLASS);
281 if ( ret < 0 )
282 return ret;
283
284 (*value)->type.data.class_val.object = object;
285 (*value)->type.data.class_val.class_id = class;
286
287 return ret;
288 }
289
290
idmef_value_set_enum_from_numeric(idmef_value_t * value,idmef_class_id_t class,int val)291 int idmef_value_set_enum_from_numeric(idmef_value_t *value, idmef_class_id_t class, int val)
292 {
293 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
294
295 if ( value->own_data )
296 idmef_value_type_destroy(&value->type);
297
298 value->own_data = TRUE;
299 value->type.id = IDMEF_VALUE_TYPE_ENUM;
300 value->type.data.enum_val.value = val;
301 value->type.data.enum_val.class_id = class;
302
303 return 0;
304 }
305
306
idmef_value_set_enum_from_string(idmef_value_t * value,idmef_class_id_t class,const char * buf)307 int idmef_value_set_enum_from_string(idmef_value_t *value, idmef_class_id_t class, const char *buf)
308 {
309 int ret;
310
311 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
312 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
313
314 ret = idmef_class_enum_to_numeric(class, buf);
315 if ( ret < 0 )
316 return ret;
317
318 return idmef_value_set_enum_from_numeric(value, class, ret);
319 }
320
321
idmef_value_set_enum(idmef_value_t * value,idmef_class_id_t class,const char * buf)322 int idmef_value_set_enum(idmef_value_t *value, idmef_class_id_t class, const char *buf)
323 {
324 int ret;
325
326 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
327 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
328
329 if ( string_isdigit(buf) == 0 )
330 ret = idmef_value_set_enum_from_numeric(value, class, atoi(buf));
331 else
332 ret = idmef_value_set_enum_from_string(value, class, buf);
333
334 return ret;
335 }
336
337
idmef_value_new_enum_from_numeric(idmef_value_t ** value,idmef_class_id_t class,int val)338 int idmef_value_new_enum_from_numeric(idmef_value_t **value, idmef_class_id_t class, int val)
339 {
340 int ret;
341
342 ret = idmef_value_create(value, IDMEF_VALUE_TYPE_ENUM);
343 if ( ret < 0 )
344 return ret;
345
346 (*value)->type.data.enum_val.value = val;
347 (*value)->type.data.enum_val.class_id = class;
348
349 return ret;
350 }
351
352
idmef_value_new_enum_from_string(idmef_value_t ** value,idmef_class_id_t class,const char * buf)353 int idmef_value_new_enum_from_string(idmef_value_t **value, idmef_class_id_t class, const char *buf)
354 {
355 int ret;
356
357 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
358
359 ret = idmef_class_enum_to_numeric(class, buf);
360 if ( ret < 0 )
361 return ret;
362
363 return idmef_value_new_enum_from_numeric(value, class, ret);
364 }
365
366
367
idmef_value_new_enum(idmef_value_t ** value,idmef_class_id_t class,const char * buf)368 int idmef_value_new_enum(idmef_value_t **value, idmef_class_id_t class, const char *buf)
369 {
370 int ret;
371
372 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
373
374 if ( string_isdigit(buf) == 0 )
375 ret = idmef_value_new_enum_from_numeric(value, class, atoi(buf));
376 else
377 ret = idmef_value_new_enum_from_string(value, class, buf);
378
379 return ret;
380 }
381
382
idmef_value_new_list(idmef_value_t ** value)383 int idmef_value_new_list(idmef_value_t **value)
384 {
385 int ret;
386
387 ret = idmef_value_create(value, IDMEF_VALUE_TYPE_LIST);
388 if ( ret < 0 )
389 return ret;
390
391 (*value)->list = malloc(CHUNK_SIZE * sizeof(idmef_value_t *));
392 if ( ! (*value)->list ) {
393 free(*value);
394 return prelude_error_from_errno(errno);
395 }
396
397 (*value)->list_elems = 0;
398 (*value)->list_max = CHUNK_SIZE - 1;
399
400 return 0;
401 }
402
403
404
idmef_value_list_add(idmef_value_t * list,idmef_value_t * item)405 int idmef_value_list_add(idmef_value_t *list, idmef_value_t *item)
406 {
407 prelude_return_val_if_fail(list, prelude_error(PRELUDE_ERROR_ASSERTION));
408
409 if ( list->list_elems == list->list_max ) {
410
411 list->list = realloc(list->list, (list->list_max + 1 + CHUNK_SIZE) * sizeof(idmef_value_t *));
412 if ( ! list->list )
413 return prelude_error_from_errno(errno);
414
415 list->list_max += CHUNK_SIZE;
416 }
417
418 list->list[list->list_elems++] = item;
419
420 return 0;
421 }
422
423
424
idmef_value_is_list(const idmef_value_t * list)425 prelude_bool_t idmef_value_is_list(const idmef_value_t *list)
426 {
427 prelude_return_val_if_fail(list, FALSE);
428 return (list->list) ? TRUE : FALSE;
429 }
430
431
432
idmef_value_list_is_empty(const idmef_value_t * list)433 prelude_bool_t idmef_value_list_is_empty(const idmef_value_t *list)
434 {
435 prelude_return_val_if_fail(list, TRUE);
436 return (list->list_elems) ? FALSE : TRUE;
437 }
438
439
440
441
idmef_value_new(idmef_value_t ** value,idmef_value_type_id_t type,void * ptr)442 int idmef_value_new(idmef_value_t **value, idmef_value_type_id_t type, void *ptr)
443 {
444 int ret;
445
446 prelude_return_val_if_fail(ptr, prelude_error(PRELUDE_ERROR_ASSERTION));
447
448 ret = idmef_value_create(value, type);
449 if ( ret < 0 )
450 return ret;
451
452 (*value)->type.data.data_val = ptr;
453
454 return 0;
455 }
456
457
458
idmef_value_new_from_string(idmef_value_t ** value,idmef_value_type_id_t type,const char * buf)459 int idmef_value_new_from_string(idmef_value_t **value, idmef_value_type_id_t type, const char *buf)
460 {
461 int ret;
462
463 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
464
465 ret = idmef_value_create(value, type);
466 if ( ret < 0 )
467 return ret;
468
469 ret = idmef_value_type_read(&(*value)->type, buf);
470 if ( ret < 0 ) {
471 free(*value);
472 return ret;
473 }
474
475 return 0;
476 }
477
478
479
idmef_value_new_from_path(idmef_value_t ** value,idmef_path_t * path,const char * buf)480 int idmef_value_new_from_path(idmef_value_t **value, idmef_path_t *path, const char *buf)
481 {
482 int ret;
483 idmef_class_id_t class;
484 idmef_value_type_id_t value_type;
485
486 prelude_return_val_if_fail(path, prelude_error(PRELUDE_ERROR_ASSERTION));
487 prelude_return_val_if_fail(buf, prelude_error(PRELUDE_ERROR_ASSERTION));
488
489 value_type = idmef_path_get_value_type(path, -1);
490 if ( value_type < 0 )
491 return value_type;
492
493 if ( value_type != IDMEF_VALUE_TYPE_ENUM )
494 ret = idmef_value_new_from_string(value, value_type, buf);
495 else {
496 class = idmef_path_get_class(path, -1);
497 if ( class < 0 )
498 return class;
499
500 ret = idmef_value_new_enum(value, class, buf);
501 }
502
503 return ret;
504 }
505
506
507
idmef_value_set_own_data(idmef_value_t * value,prelude_bool_t own_data)508 static int idmef_value_set_own_data(idmef_value_t *value, prelude_bool_t own_data)
509 {
510 int cnt;
511
512 if ( ! value->list )
513 value->own_data = own_data;
514
515 else for ( cnt = 0 ; cnt < value->list_elems; cnt++ ) {
516 if ( value->list[cnt] )
517 idmef_value_set_own_data(value->list[cnt], own_data);
518 }
519
520 return 0;
521 }
522
523
524
525
idmef_value_have_own_data(idmef_value_t * value)526 int idmef_value_have_own_data(idmef_value_t *value)
527 {
528 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
529 return idmef_value_set_own_data(value, TRUE);
530 }
531
532
533
idmef_value_dont_have_own_data(idmef_value_t * value)534 int idmef_value_dont_have_own_data(idmef_value_t *value)
535 {
536 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
537 return idmef_value_set_own_data(value, FALSE);
538 }
539
540
541
idmef_value_get_type(const idmef_value_t * value)542 idmef_value_type_id_t idmef_value_get_type(const idmef_value_t *value)
543 {
544 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
545 return value->type.id;
546 }
547
548
549
idmef_value_get_class(const idmef_value_t * value)550 idmef_class_id_t idmef_value_get_class(const idmef_value_t *value)
551 {
552 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
553
554 if ( value->type.id == IDMEF_VALUE_TYPE_CLASS )
555 return value->type.data.class_val.class_id;
556
557 else if ( value->type.id == IDMEF_VALUE_TYPE_ENUM )
558 return value->type.data.enum_val.class_id;
559
560 return -1;
561 }
562
563
564
idmef_value_get_object(const idmef_value_t * value)565 void *idmef_value_get_object(const idmef_value_t *value)
566 {
567 prelude_return_val_if_fail(value, NULL);
568 return (value->type.id == IDMEF_VALUE_TYPE_CLASS) ? value->type.data.class_val.object : NULL;
569 }
570
571
value_ro2rw(const idmef_value_t * value)572 inline static idmef_value_t *value_ro2rw(const idmef_value_t *value)
573 {
574 union {
575 idmef_value_t *rw;
576 const idmef_value_t *ro;
577 } val;
578
579 val.ro = value;
580
581 return val.rw;
582 }
583
584
idmef_value_iterate(const idmef_value_t * value,int (* callback)(idmef_value_t * ptr,void * extra),void * extra)585 int idmef_value_iterate(const idmef_value_t *value,
586 int (*callback)(idmef_value_t *ptr, void *extra), void *extra)
587 {
588 int i, ret;
589
590 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
591 prelude_return_val_if_fail(callback, prelude_error(PRELUDE_ERROR_ASSERTION));
592
593 if ( ! value->list )
594 return callback(value_ro2rw(value), extra);
595
596 for ( i = 0; i < value->list_elems; i++ ) {
597
598 ret = callback(value->list[i], extra);
599 if ( ret < 0 )
600 return ret;
601 }
602
603 return 0;
604 }
605
606
607
idmef_value_iterate_reversed(const idmef_value_t * value,int (* callback)(idmef_value_t * ptr,void * extra),void * extra)608 int idmef_value_iterate_reversed(const idmef_value_t *value,
609 int (*callback)(idmef_value_t *ptr, void *extra), void *extra)
610 {
611 int i, ret;
612
613 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
614 prelude_return_val_if_fail(callback, prelude_error(PRELUDE_ERROR_ASSERTION));
615
616 if ( ! value->list )
617 return callback(value_ro2rw(value), extra);
618
619 for ( i = value->list_elems - 1; i >= 0; i-- ) {
620
621 ret = callback(value->list[i], extra);
622 if ( ret < 0 )
623 return ret;
624 }
625
626 return 0;
627 }
628
629
630
idmef_value_get_nth2(const idmef_value_t * val,int index,idmef_value_t ** ret)631 int idmef_value_get_nth2(const idmef_value_t *val, int index, idmef_value_t **ret)
632 {
633 prelude_return_val_if_fail(val, prelude_error(PRELUDE_ERROR_ASSERTION));
634 prelude_return_val_if_fail(index <= val->list_elems, prelude_error(PRELUDE_ERROR_ASSERTION));
635
636 if ( index == 0 && ! val->list ) {
637 *ret = value_ro2rw(val);
638 return 1;
639 }
640
641 else if ( index >= 0 && index < val->list_elems ) {
642 *ret = val->list[index];
643 return 1;
644 }
645
646 else if ( index >= val->list_elems )
647 return 0;
648
649 else return -1;
650 }
651
652
653
idmef_value_get_nth(const idmef_value_t * val,int n)654 idmef_value_t *idmef_value_get_nth(const idmef_value_t *val, int n)
655 {
656 int ret;
657 idmef_value_t *rv;
658
659 prelude_return_val_if_fail(val, NULL);
660
661 ret = idmef_value_get_nth2(val, n, &rv);
662 if ( ret != 1 )
663 return NULL;
664
665 return rv;
666 }
667
668
669
idmef_value_get_count(const idmef_value_t * val)670 int idmef_value_get_count(const idmef_value_t *val)
671 {
672 prelude_return_val_if_fail(val, prelude_error(PRELUDE_ERROR_ASSERTION));
673 return val->list ? val->list_elems : 1;
674 }
675
676
677
678
idmef_value_list_clone(const idmef_value_t * val,idmef_value_t ** dst)679 static int idmef_value_list_clone(const idmef_value_t *val, idmef_value_t **dst)
680 {
681 int cnt, ret;
682
683 ret = idmef_value_create(dst, val->type.id);
684 if ( ret < 0 )
685 return ret;
686
687 (*dst)->list_elems = val->list_elems;
688 (*dst)->list_max = val->list_max;
689 (*dst)->list = malloc(((*dst)->list_elems + 1) * sizeof((*dst)->list));
690
691 for ( cnt = 0; cnt < (*dst)->list_elems; cnt++ ) {
692 if ( ! val->list[cnt] ) {
693 (*dst)->list[cnt] = NULL;
694 continue;
695 }
696
697 ret = idmef_value_clone(val->list[cnt], &((*dst)->list[cnt]));
698 if ( ret < 0 ) {
699 while ( --cnt >= 0 ) {
700 if ( (*dst)->list[cnt] )
701 idmef_value_destroy((*dst)->list[cnt]);
702 }
703 }
704
705 free((*dst)->list);
706 free(*dst);
707
708 return -1;
709 }
710
711 return 0;
712 }
713
714
715
idmef_value_clone(const idmef_value_t * val,idmef_value_t ** dst)716 int idmef_value_clone(const idmef_value_t *val, idmef_value_t **dst)
717 {
718 int ret;
719
720 prelude_return_val_if_fail(val, prelude_error(PRELUDE_ERROR_ASSERTION));
721
722 if ( val->list )
723 return idmef_value_list_clone(val, dst);
724
725 ret = idmef_value_create(dst, val->type.id);
726 if ( ret < 0 )
727 return ret;
728
729 ret = idmef_value_type_clone(&val->type, &(*dst)->type);
730 if ( ret < 0 )
731 free(*dst);
732
733 return ret;
734 }
735
736
737
idmef_value_ref(idmef_value_t * val)738 idmef_value_t *idmef_value_ref(idmef_value_t *val)
739 {
740 prelude_return_val_if_fail(val, NULL);
741
742 val->refcount++;
743
744 return val;
745 }
746
747
748
idmef_value_to_string(const idmef_value_t * value,prelude_string_t * out)749 int idmef_value_to_string(const idmef_value_t *value, prelude_string_t *out)
750 {
751 int i, ret;
752 idmef_value_t *val;
753
754 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
755 prelude_return_val_if_fail(out, prelude_error(PRELUDE_ERROR_ASSERTION));
756
757 if ( idmef_value_is_list(value) ) {
758 ret = prelude_string_cat(out, "(");
759 if ( ret < 0 )
760 return ret;
761 }
762
763 for ( i = 0; i < idmef_value_get_count(value); i++ ) {
764 val = idmef_value_get_nth(value, i);
765
766 if ( idmef_value_is_list(val) ) {
767 ret = prelude_string_cat(out, "(");
768 if ( ret < 0 )
769 return ret;
770
771 ret = idmef_value_to_string(val, out);
772 if ( ret < 0 )
773 return ret;
774
775 ret = prelude_string_cat(out, ")");
776 if ( ret < 0 )
777 return ret;
778 } else {
779 if ( i ) {
780 ret = prelude_string_cat(out, ", ");
781 if ( ret < 0 )
782 return ret;
783 }
784
785 ret = idmef_value_type_write(&val->type, out);
786 if ( ret < 0 )
787 return ret;
788 }
789 }
790
791 if ( idmef_value_is_list(value) ) {
792 ret = prelude_string_cat(out, ")");
793 if ( ret < 0 )
794 return ret;
795 }
796
797 return 0;
798 }
799
800
801
idmef_value_print(const idmef_value_t * val,prelude_io_t * fd)802 int idmef_value_print(const idmef_value_t *val, prelude_io_t *fd)
803 {
804 int ret;
805 prelude_string_t *out;
806
807 prelude_return_val_if_fail(val, prelude_error(PRELUDE_ERROR_ASSERTION));
808 prelude_return_val_if_fail(fd, prelude_error(PRELUDE_ERROR_ASSERTION));
809
810 ret = prelude_string_new(&out);
811 if ( ret < 0 )
812 return ret;
813
814 ret = idmef_value_type_write(&val->type, out);
815 if ( ret < 0 ) {
816 prelude_string_destroy(out);
817 return ret;
818 }
819
820 return prelude_io_write(fd, prelude_string_get_string(out), prelude_string_get_len(out));
821 }
822
823
824
idmef_value_get(const idmef_value_t * val,void * res)825 int idmef_value_get(const idmef_value_t *val, void *res)
826 {
827 prelude_return_val_if_fail(val, prelude_error(PRELUDE_ERROR_ASSERTION));
828 prelude_return_val_if_fail(res, prelude_error(PRELUDE_ERROR_ASSERTION));
829
830 return idmef_value_type_copy(&val->type, res);
831 }
832
833
834
idmef_value_match_internal(idmef_value_t * val1,void * extra)835 static int idmef_value_match_internal(idmef_value_t *val1, void *extra)
836 {
837 int ret;
838 compare_t *compare = extra;
839
840 if ( idmef_value_is_list(val1) )
841 ret = idmef_value_iterate(val1, idmef_value_match_internal, extra);
842
843 else if ( compare->val2 && idmef_value_is_list(compare->val2) ) {
844 ret = idmef_value_match(compare->val2, val1, compare->operator);
845 if ( ret < 0 )
846 return ret;
847
848 compare->match += ret;
849 }
850
851 else {
852 ret = idmef_value_type_compare(&val1->type, &compare->val2->type, compare->operator);
853 if ( ret == 0 )
854 compare->match++;
855 }
856
857 return ret;
858 }
859
860
861
862 /**
863 * idmef_value_match:
864 * @val1: Pointer to a #idmef_value_t object.
865 * @val2: Pointer to a #idmef_value_t object.
866 * @op: operator to use for matching.
867 *
868 * Match @val1 and @val2 using @op.
869 *
870 * Returns: the number of match, 0 for none, a negative value if an error occured.
871 */
idmef_value_match(idmef_value_t * val1,idmef_value_t * val2,idmef_criterion_operator_t op)872 int idmef_value_match(idmef_value_t *val1, idmef_value_t *val2, idmef_criterion_operator_t op)
873 {
874 int ret;
875 compare_t compare;
876
877 prelude_return_val_if_fail(val1, prelude_error(PRELUDE_ERROR_ASSERTION));
878 prelude_return_val_if_fail(val2, prelude_error(PRELUDE_ERROR_ASSERTION));
879
880 compare.match = 0;
881 compare.val2 = val2;
882 compare.operator = op;
883
884 ret = idmef_value_iterate(val1, idmef_value_match_internal, &compare);
885 if ( ret < 0 )
886 return ret;
887
888 return compare.match;
889 }
890
891
892
893 /**
894 * idmef_value_check_operator:
895 * @value: Pointer to a #idmef_value_t object.
896 * @op: Type of operator to check @value for.
897 *
898 * Check whether @op can apply to @value.
899 *
900 * Returns: 0 on success, a negative value if an error occured.
901 */
idmef_value_check_operator(const idmef_value_t * value,idmef_criterion_operator_t op)902 int idmef_value_check_operator(const idmef_value_t *value, idmef_criterion_operator_t op)
903 {
904 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
905 return idmef_value_type_check_operator(value->type.id, op);
906 }
907
908
909
910 /**
911 * idmef_value_get_applicable_operators:
912 * @value: Pointer to a #idmef_value_t object.
913 * @result: Pointer where the result will be stored.
914 *
915 * Store all operator supported by @value in @result.
916 *
917 * Returns: 0 on success, a negative value if an error occured.
918 */
919
idmef_value_get_applicable_operators(const idmef_value_t * value,idmef_criterion_operator_t * result)920 int idmef_value_get_applicable_operators(const idmef_value_t *value, idmef_criterion_operator_t *result)
921 {
922 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
923
924 return idmef_value_type_get_applicable_operators(value->type.id, result);
925 }
926
927
928
929 /**
930 * idmef_value_destroy:
931 * @val: Pointer to a #idmef_value_t object.
932 *
933 * Decrement refcount and destroy @value if it reach 0.
934 */
idmef_value_destroy(idmef_value_t * val)935 void idmef_value_destroy(idmef_value_t *val)
936 {
937 int i;
938
939 prelude_return_if_fail(val);
940
941 if ( --val->refcount )
942 return;
943
944 if ( val->list ) {
945 for ( i = 0; i < val->list_elems; i++ ) {
946 if ( val->list[i] )
947 idmef_value_destroy(val->list[i]);
948 }
949
950 free(val->list);
951 }
952
953 /*
954 * Actual destructor starts here
955 */
956 if ( val->own_data )
957 idmef_value_type_destroy(&val->type);
958
959 free(val);
960 }
961
962
cast_to_data(idmef_value_t * input)963 static int cast_to_data(idmef_value_t *input)
964 {
965 int ret;
966 idmef_data_t *data;
967 idmef_value_type_id_t vtype = idmef_value_get_type(input);
968
969 if ( vtype == IDMEF_VALUE_TYPE_STRING ) {
970 prelude_string_t *str = idmef_value_get_string(input);
971
972 ret = idmef_data_new_char_string_dup_fast(&data, prelude_string_get_string(str), prelude_string_get_len(str));
973 if ( ret < 0 )
974 return ret;
975
976 return idmef_value_set_data(input, data);
977 }
978
979 else if ( vtype == IDMEF_VALUE_TYPE_INT8 ) {
980 ret = idmef_data_new_int(&data, idmef_value_get_int8(input));
981 if ( ret < 0 )
982 return ret;
983
984 return idmef_value_set_data(input, data);
985 }
986
987 else if ( vtype == IDMEF_VALUE_TYPE_UINT8 ) {
988 ret = idmef_data_new_int(&data, idmef_value_get_uint8(input));
989 if ( ret < 0 )
990 return ret;
991
992 return idmef_value_set_data(input, data);
993 }
994
995 else if ( vtype == IDMEF_VALUE_TYPE_INT16 ) {
996 ret = idmef_data_new_int(&data, idmef_value_get_int16(input));
997 if ( ret < 0 )
998 return ret;
999
1000 return idmef_value_set_data(input, data);
1001 }
1002
1003 else if ( vtype == IDMEF_VALUE_TYPE_UINT16 ) {
1004 ret = idmef_data_new_int(&data, idmef_value_get_uint16(input));
1005 if ( ret < 0 )
1006 return ret;
1007
1008 return idmef_value_set_data(input, data);
1009 }
1010
1011 else if ( vtype == IDMEF_VALUE_TYPE_INT32 ) {
1012 ret = idmef_data_new_int(&data, idmef_value_get_int32(input));
1013 if ( ret < 0 )
1014 return ret;
1015
1016 return idmef_value_set_data(input, data);
1017 }
1018
1019 else if ( vtype == IDMEF_VALUE_TYPE_UINT32 ) {
1020 ret = idmef_data_new_int(&data, idmef_value_get_uint32(input));
1021 if ( ret < 0 )
1022 return ret;
1023
1024 return idmef_value_set_data(input, data);
1025 }
1026
1027 else if ( vtype == IDMEF_VALUE_TYPE_INT64 ) {
1028 ret = idmef_data_new_int(&data, idmef_value_get_int64(input));
1029 if ( ret < 0 )
1030 return ret;
1031
1032 return idmef_value_set_data(input, data);
1033 }
1034
1035 else if ( vtype == IDMEF_VALUE_TYPE_UINT64 ) {
1036 ret = idmef_data_new_int(&data, idmef_value_get_uint64(input));
1037 if ( ret < 0 )
1038 return ret;
1039
1040 return idmef_value_set_data(input, data);
1041 }
1042
1043 else if ( vtype == IDMEF_VALUE_TYPE_TIME ) {
1044 ret = idmef_data_new_time(&data, idmef_time_ref(idmef_value_get_time(input)));
1045 if ( ret < 0 )
1046 return ret;
1047
1048 return idmef_value_set_data(input, data);
1049 }
1050
1051 else if ( vtype == IDMEF_VALUE_TYPE_FLOAT ) {
1052 int64_t v = idmef_value_get_float(input);
1053
1054 if ( v == idmef_value_get_float(input) )
1055 ret = idmef_data_new_int(&data, v);
1056 else
1057 ret = idmef_data_new_float(&data, idmef_value_get_float(input));
1058
1059 if ( ret < 0 )
1060 return ret;
1061
1062 return idmef_value_set_data(input, data);
1063 }
1064
1065 else if ( vtype == IDMEF_VALUE_TYPE_DOUBLE ) {
1066 int64_t v = idmef_value_get_double(input);
1067
1068 if ( v == idmef_value_get_double(input) )
1069 ret = idmef_data_new_int(&data, v);
1070 else
1071 ret = idmef_data_new_float(&data, idmef_value_get_double(input));
1072
1073 if ( ret < 0 )
1074 return ret;
1075
1076 return idmef_value_set_data(input, data);
1077 }
1078
1079 return prelude_error_verbose(PRELUDE_ERROR_GENERIC,
1080 "Unable to cast input type '%s' to 'data'",
1081 idmef_value_type_to_string(vtype));
1082 }
1083
1084
cast_to_time(idmef_value_t * value)1085 static int cast_to_time(idmef_value_t *value)
1086 {
1087 int ret = -1;
1088 idmef_time_t *time;
1089
1090 if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_STRING ) {
1091 ret = idmef_time_new_from_string(&time, prelude_string_get_string(idmef_value_get_string(value)));
1092 if ( ret < 0 )
1093 return ret;
1094
1095 idmef_value_set_time(value, time);
1096 }
1097
1098 else if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_INT32 ) {
1099 time_t val = idmef_value_get_int32(value);
1100
1101 ret = idmef_time_new_from_time(&time, &val);
1102 if ( ret < 0 )
1103 return ret;
1104
1105 idmef_value_set_time(value, time);
1106 }
1107
1108 else if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_UINT32 ) {
1109 time_t val = idmef_value_get_uint32(value);
1110
1111 ret = idmef_time_new_from_time(&time, &val);
1112 if ( ret < 0 )
1113 return ret;
1114
1115 idmef_value_set_time(value, time);
1116 }
1117
1118 else if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_INT64 ) {
1119 time_t val = idmef_value_get_int64(value);
1120
1121 ret = idmef_time_new_from_time(&time, &val);
1122 if ( ret < 0 )
1123 return ret;
1124
1125 idmef_value_set_time(value, time);
1126 }
1127
1128 else if ( idmef_value_get_type(value) == IDMEF_VALUE_TYPE_UINT64 ) {
1129 time_t val = idmef_value_get_uint64(value);
1130
1131 ret = idmef_time_new_from_time(&time, &val);
1132 if ( ret < 0 )
1133 return ret;
1134
1135 idmef_value_set_time(value, time);
1136 }
1137
1138 return ret;
1139 }
1140
1141
1142
cast_to_string(idmef_value_t * value)1143 static int cast_to_string(idmef_value_t *value)
1144 {
1145 int ret;
1146 prelude_string_t *out;
1147
1148 ret = prelude_string_new(&out);
1149 if ( ret < 0 )
1150 return ret;
1151
1152 ret = idmef_value_type_write(&value->type, out);
1153 if ( ret < 0 ) {
1154 prelude_string_destroy(out);
1155 return ret;
1156 }
1157
1158 idmef_value_set_string(value, out);
1159
1160 return 0;
1161 }
1162
1163
1164
cast_from_string(idmef_value_t * value,idmef_value_type_id_t ntype)1165 static int cast_from_string(idmef_value_t *value, idmef_value_type_id_t ntype)
1166 {
1167 int ret;
1168 idmef_value_type_t vt;
1169 prelude_string_t *str = idmef_value_get_string(value);
1170
1171 vt.id = ntype;
1172
1173 ret = idmef_value_type_read(&vt, prelude_string_get_string(str));
1174 if ( ret < 0 )
1175 return ret;
1176
1177 if ( value->own_data )
1178 idmef_value_type_destroy(&value->type);
1179
1180 memcpy(&value->type, &vt, sizeof(value->type));
1181
1182 return 0;
1183 }
1184
1185
1186
_idmef_value_cast(idmef_value_t * value,idmef_value_type_id_t ntype,idmef_class_id_t id)1187 int _idmef_value_cast(idmef_value_t *value, idmef_value_type_id_t ntype, idmef_class_id_t id)
1188 {
1189 idmef_value_type_id_t otype;
1190
1191 prelude_return_val_if_fail(value, prelude_error(PRELUDE_ERROR_ASSERTION));
1192
1193 otype = idmef_value_get_type(value);
1194 prelude_log_debug(3, "converting '%s' to '%s'.\n",
1195 idmef_value_type_to_string(otype),
1196 idmef_value_type_to_string(ntype));
1197
1198 if ( ntype == IDMEF_VALUE_TYPE_DATA )
1199 return cast_to_data(value);
1200
1201 else if ( ntype == IDMEF_VALUE_TYPE_TIME )
1202 return cast_to_time(value);
1203
1204 else if ( ntype == IDMEF_VALUE_TYPE_STRING )
1205 return cast_to_string(value);
1206
1207 else if ( ntype == IDMEF_VALUE_TYPE_ENUM && idmef_value_get_type(value) == IDMEF_VALUE_TYPE_STRING ) {
1208 prelude_string_t *str = idmef_value_get_string(value);
1209 return idmef_value_set_enum_from_string(value, id, prelude_string_get_string(str));
1210 }
1211
1212 else if ( otype == IDMEF_VALUE_TYPE_INT8 )
1213 VALUE_CAST_CHECK(value, int8_t, int8, PRELUDE_PRId8, ntype);
1214
1215 else if ( otype == IDMEF_VALUE_TYPE_UINT8 )
1216 VALUE_CAST_CHECK(value, uint8_t, uint8, PRELUDE_PRIu8, ntype);
1217
1218 else if ( otype == IDMEF_VALUE_TYPE_INT16 )
1219 VALUE_CAST_CHECK(value, int16_t, int16, PRELUDE_PRId16, ntype);
1220
1221 else if ( otype == IDMEF_VALUE_TYPE_UINT16 )
1222 VALUE_CAST_CHECK(value, uint16_t, uint16, PRELUDE_PRIu16, ntype);
1223
1224 else if ( otype == IDMEF_VALUE_TYPE_INT32 )
1225 VALUE_CAST_CHECK(value, int32_t, int32, PRELUDE_PRId32, ntype);
1226
1227 else if ( otype == IDMEF_VALUE_TYPE_UINT32 )
1228 VALUE_CAST_CHECK(value, uint32_t, uint32, PRELUDE_PRIu32, ntype);
1229
1230 else if ( otype == IDMEF_VALUE_TYPE_INT64 )
1231 VALUE_CAST_CHECK(value, int64_t, int64, PRELUDE_PRId64, ntype);
1232
1233 else if ( otype == IDMEF_VALUE_TYPE_UINT64 )
1234 VALUE_CAST_CHECK(value, uint64_t, uint64, PRELUDE_PRIu64, ntype);
1235
1236 else if ( otype == IDMEF_VALUE_TYPE_FLOAT )
1237 VALUE_CAST_CHECK(value, float, float, "f", ntype);
1238
1239 else if ( otype == IDMEF_VALUE_TYPE_DOUBLE )
1240 VALUE_CAST_CHECK(value, double, double, "f", ntype);
1241
1242 else if ( otype == IDMEF_VALUE_TYPE_STRING )
1243 return cast_from_string(value, ntype);
1244
1245 else return prelude_error_verbose(PRELUDE_ERROR_GENERIC,
1246 "Unable to cast input type '%s' to '%s'",
1247 idmef_value_type_to_string(value->type.id),
1248 idmef_value_type_to_string(ntype));
1249
1250 return 0;
1251 }
1252
1253
1254
_idmef_value_copy_internal(const idmef_value_t * val,idmef_value_type_id_t res_type,idmef_class_id_t res_id,void * res)1255 int _idmef_value_copy_internal(const idmef_value_t *val,
1256 idmef_value_type_id_t res_type, idmef_class_id_t res_id, void *res)
1257 {
1258 int ret;
1259
1260 prelude_return_val_if_fail(val, prelude_error(PRELUDE_ERROR_ASSERTION));
1261 prelude_return_val_if_fail(res, prelude_error(PRELUDE_ERROR_ASSERTION));
1262
1263 if ( res_type == val->type.id )
1264 ret = idmef_value_type_copy(&val->type, res);
1265 else {
1266 idmef_value_t copy;
1267
1268 memcpy(©, val, sizeof(copy));
1269 idmef_value_dont_have_own_data(©);
1270
1271 ret = _idmef_value_cast(©, res_type, res_id);
1272 if ( ret < 0 )
1273 return ret;
1274
1275 ret = idmef_value_type_copy(©.type, res);
1276 if ( val->own_data )
1277 idmef_value_type_destroy(©.type);
1278 }
1279
1280 return ret;
1281 }
1282